assemblyline_models/
lib.rs

1#![allow(clippy::needless_return)]
2use std::fmt::Display;
3
4use serde::Deserialize;
5
6pub mod datastore;
7pub mod config;
8pub mod messages;
9pub mod serialize;
10pub mod meta;
11pub mod types;
12
13pub use meta::ElasticMeta;
14pub use types::classification::{disable_global_classification, set_global_classification};
15
16pub const HEXCHARS: [char; 16] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
17
18pub trait Readable: for <'de> Deserialize<'de> {
19    fn set_from_archive(&mut self, from_archive: bool);
20}
21
22#[derive(Debug)]
23pub enum ModelError {
24    InvalidSha256(String),
25    InvalidMd5(String),
26    InvalidSha1(String),
27    InvalidSid(String),
28    InvalidSSDeep(String),
29    ClassificationNotInitialized,
30    InvalidClassification(Option<assemblyline_markings::errors::Errors>),
31}
32
33impl Display for ModelError {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        match self {
36            ModelError::InvalidSha256(content) => f.write_fmt(format_args!("Invalid value provided for a sha256: {content}")),
37            ModelError::InvalidMd5(content) => f.write_fmt(format_args!("Invalid value provided for a md5: {content}")),
38            ModelError::InvalidSha1(content) => f.write_fmt(format_args!("Invalid value provided for a sha1: {content}")),
39            ModelError::InvalidSid(content) => f.write_fmt(format_args!("Invalid value provided for a sid: {content}")),
40            ModelError::ClassificationNotInitialized => f.write_str("The classification engine has not been initialized."),
41            ModelError::InvalidClassification(_) => f.write_str("An invalid classification string was provided."),
42            ModelError::InvalidSSDeep(content) =>  f.write_fmt(format_args!("Invalid value provided for a ssdeep hash: {content}")),
43        }
44    }
45}
46
47impl From<base62::DecodeError> for ModelError {
48    fn from(value: base62::DecodeError) -> Self {
49        Self::InvalidSid(value.to_string())
50    }
51}
52
53impl From<assemblyline_markings::errors::Errors> for ModelError {
54    fn from(value: assemblyline_markings::errors::Errors) -> Self {
55        Self::InvalidClassification(Some(value))
56    }
57}
58
59impl std::error::Error for ModelError {}
60
61
62const WORDS: [&str; 187] = ["The", "Cyber", "Centre", "stays", "on", "the", "cutting", "edge", "of", "technology", "by", 
63    "working", "with", "commercial", "vendors", "of", "cyber", "security", "technology", "to", "support", "their", 
64    "development", "of", "enhanced", "cyber", "defence", "tools", "To", "do", "this", "our", "experts", "survey", 
65    "the", "cyber", "security", "market", "evaluate", "emerging", "technologies", "in", "order", "to", "determine", 
66    "their", "potential", "to", "improve", "cyber", "security", "across", "the", "country", "The", "Cyber", "Centre", 
67    "supports", "innovation", "by", "collaborating", "with", "all", "levels", "of", "government", "private", "industry", 
68    "academia", "to", "examine", "complex", "problems", "in", "cyber", "security", "We", "are", "constantly", 
69    "engaging", "partners", "to", "promote", "an", "open", "innovative", "environment", "We", "invite", "partners", 
70    "to", "work", "with", "us", "but", "also", "promote", "other", "Government", "of", "Canada", "innovation", 
71    "programs", "One", "of", "our", "key", "partnerships", "is", "with", "the", "Government", "of", "Canada", "Build", 
72    "in", "Canada", "Innovation", "Program", "BCIP", "The", "BCIP", "helps", "Canadian", "companies", "of", "all", 
73    "sizes", "transition", "their", "state", "of", "the", "art", "goods", "services", "from", "the", "laboratory", 
74    "to", "the", "marketplace", "For", "certain", "cyber", "security", "innovations", "the", "Cyber", "Centre", 
75    "performs", "the", "role", "of", "technical", "authority", "We", "evaluate", "participating", "companies", 
76    "new", "technology", "provide", "feedback", "in", "order", "to", "assist", "them", "in", "bringing", "their", 
77    "product", "to", "market", "To", "learn", "more", "about", "selling", "testing", "an", "innovation", "visit", 
78    "the", "BCIP", "website"];
79
80#[cfg(feature = "rand")]
81pub fn random_word<R: rand::Rng + ?Sized>(prng: &mut R) -> String {
82    WORDS[prng.random_range(0..WORDS.len())].to_string()
83}
84
85#[cfg(feature = "rand")]
86pub fn random_words<R: rand::Rng + ?Sized>(prng: &mut R, count: usize) -> Vec<String> {
87    let mut output = vec![];
88    while output.len() < count {
89        output.push(WORDS[prng.random_range(0..WORDS.len())].to_string())
90    }
91    output
92}
93
94#[cfg(feature = "rand")]
95pub fn random_hex<R: rand::prelude::Rng + ?Sized>(rng: &mut R, size: usize) -> String {
96    let mut buffer = String::with_capacity(size);
97    for _ in 0..size {
98        let index = rng.random_range(0..HEXCHARS.len());
99        buffer.push(HEXCHARS[index]);
100    }
101    buffer
102}
103
104#[cfg(test)]
105mod test {
106    use rand::Rng;
107
108    use crate::types::{SSDeepHash, Sha1, Sha256, MD5};
109    
110    #[test]
111    fn random_ssdeep() {
112        let mut prng = rand::rng();
113        for _ in 0..100 {
114            let hash: SSDeepHash = prng.random();
115            assert_eq!(hash, hash.to_string().parse().unwrap());
116        }
117    }
118
119    #[test]
120    fn random_sha256() {
121        let mut prng = rand::rng();
122        for _ in 0..100 {
123            let hash: Sha256 = prng.random();
124            assert_eq!(hash, hash.to_string().parse().unwrap());
125        }
126    }
127
128    #[test]
129    fn random_sha1() {
130        let mut prng = rand::rng();
131        for _ in 0..100 {
132            let hash: Sha1 = prng.random();
133            assert_eq!(hash, hash.to_string().parse().unwrap());
134        }
135    }
136
137    #[test]
138    fn random_md5() {
139        let mut prng = rand::rng();
140        for _ in 0..100 {
141            let hash: MD5 = prng.random();
142            assert_eq!(hash, hash.to_string().parse().unwrap());
143        }
144    }
145}
146