1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
8pub enum SbomFormat {
9 CycloneDx,
10 Spdx,
11}
12
13impl std::fmt::Display for SbomFormat {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 match self {
16 SbomFormat::CycloneDx => write!(f, "CycloneDX"),
17 SbomFormat::Spdx => write!(f, "SPDX"),
18 }
19 }
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct DocumentMetadata {
25 pub format: SbomFormat,
27 pub format_version: String,
29 pub spec_version: String,
31 pub serial_number: Option<String>,
33 pub created: DateTime<Utc>,
35 pub creators: Vec<Creator>,
37 pub name: Option<String>,
39 pub security_contact: Option<String>,
41 pub vulnerability_disclosure_url: Option<String>,
43 pub support_end_date: Option<DateTime<Utc>>,
45}
46
47impl Default for DocumentMetadata {
48 fn default() -> Self {
49 Self {
50 format: SbomFormat::CycloneDx,
51 format_version: String::new(),
52 spec_version: String::new(),
53 serial_number: None,
54 created: Utc::now(),
55 creators: Vec::new(),
56 name: None,
57 security_contact: None,
58 vulnerability_disclosure_url: None,
59 support_end_date: None,
60 }
61 }
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize)]
66pub struct Creator {
67 pub creator_type: CreatorType,
69 pub name: String,
71 pub email: Option<String>,
73}
74
75#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
77pub enum CreatorType {
78 Person,
79 Organization,
80 Tool,
81}
82
83#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
85pub struct Organization {
86 pub name: String,
88 pub urls: Vec<String>,
90 pub contacts: Vec<Contact>,
92}
93
94impl Organization {
95 pub fn new(name: String) -> Self {
97 Self {
98 name,
99 urls: Vec::new(),
100 contacts: Vec::new(),
101 }
102 }
103}
104
105#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
107pub struct Contact {
108 pub name: Option<String>,
110 pub email: Option<String>,
112 pub phone: Option<String>,
114}
115
116#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
118pub enum ComponentType {
119 Application,
120 Framework,
121 #[default]
122 Library,
123 Container,
124 OperatingSystem,
125 Device,
126 Firmware,
127 File,
128 Data,
129 MachineLearningModel,
130 Platform,
131 DeviceDriver,
132 Cryptographic,
133 Other(String),
134}
135
136impl std::fmt::Display for ComponentType {
137 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
138 match self {
139 ComponentType::Application => write!(f, "application"),
140 ComponentType::Framework => write!(f, "framework"),
141 ComponentType::Library => write!(f, "library"),
142 ComponentType::Container => write!(f, "container"),
143 ComponentType::OperatingSystem => write!(f, "operating-system"),
144 ComponentType::Device => write!(f, "device"),
145 ComponentType::Firmware => write!(f, "firmware"),
146 ComponentType::File => write!(f, "file"),
147 ComponentType::Data => write!(f, "data"),
148 ComponentType::MachineLearningModel => write!(f, "machine-learning-model"),
149 ComponentType::Platform => write!(f, "platform"),
150 ComponentType::DeviceDriver => write!(f, "device-driver"),
151 ComponentType::Cryptographic => write!(f, "cryptographic"),
152 ComponentType::Other(s) => write!(f, "{}", s),
153 }
154 }
155}
156
157#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
159pub struct Hash {
160 pub algorithm: HashAlgorithm,
162 pub value: String,
164}
165
166impl Hash {
167 pub fn new(algorithm: HashAlgorithm, value: String) -> Self {
169 Self { algorithm, value }
170 }
171}
172
173#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
175pub enum HashAlgorithm {
176 Md5,
177 Sha1,
178 Sha256,
179 Sha384,
180 Sha512,
181 Sha3_256,
182 Sha3_384,
183 Sha3_512,
184 Blake2b256,
185 Blake2b384,
186 Blake2b512,
187 Blake3,
188 Other(String),
189}
190
191impl std::fmt::Display for HashAlgorithm {
192 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
193 match self {
194 HashAlgorithm::Md5 => write!(f, "MD5"),
195 HashAlgorithm::Sha1 => write!(f, "SHA-1"),
196 HashAlgorithm::Sha256 => write!(f, "SHA-256"),
197 HashAlgorithm::Sha384 => write!(f, "SHA-384"),
198 HashAlgorithm::Sha512 => write!(f, "SHA-512"),
199 HashAlgorithm::Sha3_256 => write!(f, "SHA3-256"),
200 HashAlgorithm::Sha3_384 => write!(f, "SHA3-384"),
201 HashAlgorithm::Sha3_512 => write!(f, "SHA3-512"),
202 HashAlgorithm::Blake2b256 => write!(f, "BLAKE2b-256"),
203 HashAlgorithm::Blake2b384 => write!(f, "BLAKE2b-384"),
204 HashAlgorithm::Blake2b512 => write!(f, "BLAKE2b-512"),
205 HashAlgorithm::Blake3 => write!(f, "BLAKE3"),
206 HashAlgorithm::Other(s) => write!(f, "{}", s),
207 }
208 }
209}
210
211#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct ExternalReference {
214 pub ref_type: ExternalRefType,
216 pub url: String,
218 pub comment: Option<String>,
220 pub hashes: Vec<Hash>,
222}
223
224#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
226pub enum ExternalRefType {
227 Vcs,
228 IssueTracker,
229 Website,
230 Advisories,
231 Bom,
232 MailingList,
233 Social,
234 Chat,
235 Documentation,
236 Support,
237 SourceDistribution,
238 BinaryDistribution,
239 License,
240 BuildMeta,
241 BuildSystem,
242 ReleaseNotes,
243 SecurityContact,
244 ModelCard,
245 Log,
246 Configuration,
247 Evidence,
248 Formulation,
249 Attestation,
250 ThreatModel,
251 AdversaryModel,
252 RiskAssessment,
253 VulnerabilityAssertion,
254 ExploitabilityStatement,
255 Pentest,
256 StaticAnalysis,
257 DynamicAnalysis,
258 RuntimeAnalysis,
259 ComponentAnalysis,
260 Maturity,
261 Certification,
262 QualityMetrics,
263 Codified,
264 Other(String),
265}
266
267impl std::fmt::Display for ExternalRefType {
268 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
269 match self {
270 ExternalRefType::Vcs => write!(f, "vcs"),
271 ExternalRefType::IssueTracker => write!(f, "issue-tracker"),
272 ExternalRefType::Website => write!(f, "website"),
273 ExternalRefType::Advisories => write!(f, "advisories"),
274 ExternalRefType::Bom => write!(f, "bom"),
275 ExternalRefType::MailingList => write!(f, "mailing-list"),
276 ExternalRefType::Social => write!(f, "social"),
277 ExternalRefType::Chat => write!(f, "chat"),
278 ExternalRefType::Documentation => write!(f, "documentation"),
279 ExternalRefType::Support => write!(f, "support"),
280 ExternalRefType::SourceDistribution => write!(f, "distribution"),
281 ExternalRefType::BinaryDistribution => write!(f, "distribution-intake"),
282 ExternalRefType::License => write!(f, "license"),
283 ExternalRefType::BuildMeta => write!(f, "build-meta"),
284 ExternalRefType::BuildSystem => write!(f, "build-system"),
285 ExternalRefType::ReleaseNotes => write!(f, "release-notes"),
286 ExternalRefType::SecurityContact => write!(f, "security-contact"),
287 ExternalRefType::ModelCard => write!(f, "model-card"),
288 ExternalRefType::Log => write!(f, "log"),
289 ExternalRefType::Configuration => write!(f, "configuration"),
290 ExternalRefType::Evidence => write!(f, "evidence"),
291 ExternalRefType::Formulation => write!(f, "formulation"),
292 ExternalRefType::Attestation => write!(f, "attestation"),
293 ExternalRefType::ThreatModel => write!(f, "threat-model"),
294 ExternalRefType::AdversaryModel => write!(f, "adversary-model"),
295 ExternalRefType::RiskAssessment => write!(f, "risk-assessment"),
296 ExternalRefType::VulnerabilityAssertion => write!(f, "vulnerability-assertion"),
297 ExternalRefType::ExploitabilityStatement => write!(f, "exploitability-statement"),
298 ExternalRefType::Pentest => write!(f, "pentest-report"),
299 ExternalRefType::StaticAnalysis => write!(f, "static-analysis-report"),
300 ExternalRefType::DynamicAnalysis => write!(f, "dynamic-analysis-report"),
301 ExternalRefType::RuntimeAnalysis => write!(f, "runtime-analysis-report"),
302 ExternalRefType::ComponentAnalysis => write!(f, "component-analysis-report"),
303 ExternalRefType::Maturity => write!(f, "maturity-report"),
304 ExternalRefType::Certification => write!(f, "certification-report"),
305 ExternalRefType::QualityMetrics => write!(f, "quality-metrics"),
306 ExternalRefType::Codified => write!(f, "codified"),
307 ExternalRefType::Other(s) => write!(f, "{}", s),
308 }
309 }
310}
311
312#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
314pub enum DependencyType {
315 DependsOn,
317 OptionalDependsOn,
319 DevDependsOn,
321 BuildDependsOn,
323 TestDependsOn,
325 RuntimeDependsOn,
327 ProvidedDependsOn,
329 Describes,
331 Generates,
333 Contains,
335 AncestorOf,
337 VariantOf,
339 DistributionArtifact,
341 PatchFor,
343 CopyOf,
345 FileAdded,
347 FileDeleted,
349 FileModified,
351 DynamicLink,
353 StaticLink,
355 Other(String),
357}
358
359impl std::fmt::Display for DependencyType {
360 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
361 match self {
362 DependencyType::DependsOn => write!(f, "depends-on"),
363 DependencyType::OptionalDependsOn => write!(f, "optional-depends-on"),
364 DependencyType::DevDependsOn => write!(f, "dev-depends-on"),
365 DependencyType::BuildDependsOn => write!(f, "build-depends-on"),
366 DependencyType::TestDependsOn => write!(f, "test-depends-on"),
367 DependencyType::RuntimeDependsOn => write!(f, "runtime-depends-on"),
368 DependencyType::ProvidedDependsOn => write!(f, "provided-depends-on"),
369 DependencyType::Describes => write!(f, "describes"),
370 DependencyType::Generates => write!(f, "generates"),
371 DependencyType::Contains => write!(f, "contains"),
372 DependencyType::AncestorOf => write!(f, "ancestor-of"),
373 DependencyType::VariantOf => write!(f, "variant-of"),
374 DependencyType::DistributionArtifact => write!(f, "distribution-artifact"),
375 DependencyType::PatchFor => write!(f, "patch-for"),
376 DependencyType::CopyOf => write!(f, "copy-of"),
377 DependencyType::FileAdded => write!(f, "file-added"),
378 DependencyType::FileDeleted => write!(f, "file-deleted"),
379 DependencyType::FileModified => write!(f, "file-modified"),
380 DependencyType::DynamicLink => write!(f, "dynamic-link"),
381 DependencyType::StaticLink => write!(f, "static-link"),
382 DependencyType::Other(s) => write!(f, "{}", s),
383 }
384 }
385}
386
387#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
389pub enum DependencyScope {
390 #[default]
391 Required,
392 Optional,
393 Excluded,
394}
395
396#[derive(Debug, Clone, Default, Serialize, Deserialize)]
398pub struct FormatExtensions {
399 pub cyclonedx: Option<serde_json::Value>,
401 pub spdx: Option<serde_json::Value>,
403}
404
405#[derive(Debug, Clone, Default, Serialize, Deserialize)]
407pub struct ComponentExtensions {
408 pub properties: Vec<Property>,
410 pub annotations: Vec<Annotation>,
412 pub raw: Option<serde_json::Value>,
414}
415
416#[derive(Debug, Clone, Serialize, Deserialize)]
418pub struct Property {
419 pub name: String,
420 pub value: String,
421}
422
423#[derive(Debug, Clone, Serialize, Deserialize)]
425pub struct Annotation {
426 pub annotator: String,
427 pub annotation_date: DateTime<Utc>,
428 pub annotation_type: String,
429 pub comment: String,
430}