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 Self::CycloneDx => write!(f, "CycloneDX"),
17 Self::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 #[must_use]
97 pub const fn new(name: String) -> Self {
98 Self {
99 name,
100 urls: Vec::new(),
101 contacts: Vec::new(),
102 }
103 }
104}
105
106#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
108pub struct Contact {
109 pub name: Option<String>,
111 pub email: Option<String>,
113 pub phone: Option<String>,
115}
116
117#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
119#[non_exhaustive]
120pub enum ComponentType {
121 Application,
122 Framework,
123 #[default]
124 Library,
125 Container,
126 OperatingSystem,
127 Device,
128 Firmware,
129 File,
130 Data,
131 MachineLearningModel,
132 Platform,
133 DeviceDriver,
134 Cryptographic,
135 Other(String),
136}
137
138impl std::fmt::Display for ComponentType {
139 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
140 match self {
141 Self::Application => write!(f, "application"),
142 Self::Framework => write!(f, "framework"),
143 Self::Library => write!(f, "library"),
144 Self::Container => write!(f, "container"),
145 Self::OperatingSystem => write!(f, "operating-system"),
146 Self::Device => write!(f, "device"),
147 Self::Firmware => write!(f, "firmware"),
148 Self::File => write!(f, "file"),
149 Self::Data => write!(f, "data"),
150 Self::MachineLearningModel => write!(f, "machine-learning-model"),
151 Self::Platform => write!(f, "platform"),
152 Self::DeviceDriver => write!(f, "device-driver"),
153 Self::Cryptographic => write!(f, "cryptographic"),
154 Self::Other(s) => write!(f, "{s}"),
155 }
156 }
157}
158
159#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
161pub struct Hash {
162 pub algorithm: HashAlgorithm,
164 pub value: String,
166}
167
168impl Hash {
169 #[must_use]
171 pub const fn new(algorithm: HashAlgorithm, value: String) -> Self {
172 Self { algorithm, value }
173 }
174}
175
176#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
178pub enum HashAlgorithm {
179 Md5,
180 Sha1,
181 Sha256,
182 Sha384,
183 Sha512,
184 Sha3_256,
185 Sha3_384,
186 Sha3_512,
187 Blake2b256,
188 Blake2b384,
189 Blake2b512,
190 Blake3,
191 Other(String),
192}
193
194impl std::fmt::Display for HashAlgorithm {
195 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
196 match self {
197 Self::Md5 => write!(f, "MD5"),
198 Self::Sha1 => write!(f, "SHA-1"),
199 Self::Sha256 => write!(f, "SHA-256"),
200 Self::Sha384 => write!(f, "SHA-384"),
201 Self::Sha512 => write!(f, "SHA-512"),
202 Self::Sha3_256 => write!(f, "SHA3-256"),
203 Self::Sha3_384 => write!(f, "SHA3-384"),
204 Self::Sha3_512 => write!(f, "SHA3-512"),
205 Self::Blake2b256 => write!(f, "BLAKE2b-256"),
206 Self::Blake2b384 => write!(f, "BLAKE2b-384"),
207 Self::Blake2b512 => write!(f, "BLAKE2b-512"),
208 Self::Blake3 => write!(f, "BLAKE3"),
209 Self::Other(s) => write!(f, "{s}"),
210 }
211 }
212}
213
214#[derive(Debug, Clone, Serialize, Deserialize)]
216pub struct ExternalReference {
217 pub ref_type: ExternalRefType,
219 pub url: String,
221 pub comment: Option<String>,
223 pub hashes: Vec<Hash>,
225}
226
227#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
229pub enum ExternalRefType {
230 Vcs,
231 IssueTracker,
232 Website,
233 Advisories,
234 Bom,
235 MailingList,
236 Social,
237 Chat,
238 Documentation,
239 Support,
240 SourceDistribution,
241 BinaryDistribution,
242 License,
243 BuildMeta,
244 BuildSystem,
245 ReleaseNotes,
246 SecurityContact,
247 ModelCard,
248 Log,
249 Configuration,
250 Evidence,
251 Formulation,
252 Attestation,
253 ThreatModel,
254 AdversaryModel,
255 RiskAssessment,
256 VulnerabilityAssertion,
257 ExploitabilityStatement,
258 Pentest,
259 StaticAnalysis,
260 DynamicAnalysis,
261 RuntimeAnalysis,
262 ComponentAnalysis,
263 Maturity,
264 Certification,
265 QualityMetrics,
266 Codified,
267 Other(String),
268}
269
270impl std::fmt::Display for ExternalRefType {
271 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
272 match self {
273 Self::Vcs => write!(f, "vcs"),
274 Self::IssueTracker => write!(f, "issue-tracker"),
275 Self::Website => write!(f, "website"),
276 Self::Advisories => write!(f, "advisories"),
277 Self::Bom => write!(f, "bom"),
278 Self::MailingList => write!(f, "mailing-list"),
279 Self::Social => write!(f, "social"),
280 Self::Chat => write!(f, "chat"),
281 Self::Documentation => write!(f, "documentation"),
282 Self::Support => write!(f, "support"),
283 Self::SourceDistribution => write!(f, "distribution"),
284 Self::BinaryDistribution => write!(f, "distribution-intake"),
285 Self::License => write!(f, "license"),
286 Self::BuildMeta => write!(f, "build-meta"),
287 Self::BuildSystem => write!(f, "build-system"),
288 Self::ReleaseNotes => write!(f, "release-notes"),
289 Self::SecurityContact => write!(f, "security-contact"),
290 Self::ModelCard => write!(f, "model-card"),
291 Self::Log => write!(f, "log"),
292 Self::Configuration => write!(f, "configuration"),
293 Self::Evidence => write!(f, "evidence"),
294 Self::Formulation => write!(f, "formulation"),
295 Self::Attestation => write!(f, "attestation"),
296 Self::ThreatModel => write!(f, "threat-model"),
297 Self::AdversaryModel => write!(f, "adversary-model"),
298 Self::RiskAssessment => write!(f, "risk-assessment"),
299 Self::VulnerabilityAssertion => write!(f, "vulnerability-assertion"),
300 Self::ExploitabilityStatement => write!(f, "exploitability-statement"),
301 Self::Pentest => write!(f, "pentest-report"),
302 Self::StaticAnalysis => write!(f, "static-analysis-report"),
303 Self::DynamicAnalysis => write!(f, "dynamic-analysis-report"),
304 Self::RuntimeAnalysis => write!(f, "runtime-analysis-report"),
305 Self::ComponentAnalysis => write!(f, "component-analysis-report"),
306 Self::Maturity => write!(f, "maturity-report"),
307 Self::Certification => write!(f, "certification-report"),
308 Self::QualityMetrics => write!(f, "quality-metrics"),
309 Self::Codified => write!(f, "codified"),
310 Self::Other(s) => write!(f, "{s}"),
311 }
312 }
313}
314
315#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
317pub enum DependencyType {
318 DependsOn,
320 OptionalDependsOn,
322 DevDependsOn,
324 BuildDependsOn,
326 TestDependsOn,
328 RuntimeDependsOn,
330 ProvidedDependsOn,
332 Describes,
334 Generates,
336 Contains,
338 AncestorOf,
340 VariantOf,
342 DistributionArtifact,
344 PatchFor,
346 CopyOf,
348 FileAdded,
350 FileDeleted,
352 FileModified,
354 DynamicLink,
356 StaticLink,
358 Other(String),
360}
361
362impl std::fmt::Display for DependencyType {
363 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
364 match self {
365 Self::DependsOn => write!(f, "depends-on"),
366 Self::OptionalDependsOn => write!(f, "optional-depends-on"),
367 Self::DevDependsOn => write!(f, "dev-depends-on"),
368 Self::BuildDependsOn => write!(f, "build-depends-on"),
369 Self::TestDependsOn => write!(f, "test-depends-on"),
370 Self::RuntimeDependsOn => write!(f, "runtime-depends-on"),
371 Self::ProvidedDependsOn => write!(f, "provided-depends-on"),
372 Self::Describes => write!(f, "describes"),
373 Self::Generates => write!(f, "generates"),
374 Self::Contains => write!(f, "contains"),
375 Self::AncestorOf => write!(f, "ancestor-of"),
376 Self::VariantOf => write!(f, "variant-of"),
377 Self::DistributionArtifact => write!(f, "distribution-artifact"),
378 Self::PatchFor => write!(f, "patch-for"),
379 Self::CopyOf => write!(f, "copy-of"),
380 Self::FileAdded => write!(f, "file-added"),
381 Self::FileDeleted => write!(f, "file-deleted"),
382 Self::FileModified => write!(f, "file-modified"),
383 Self::DynamicLink => write!(f, "dynamic-link"),
384 Self::StaticLink => write!(f, "static-link"),
385 Self::Other(s) => write!(f, "{s}"),
386 }
387 }
388}
389
390#[derive(Debug, Clone, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
392pub enum DependencyScope {
393 #[default]
394 Required,
395 Optional,
396 Excluded,
397}
398
399#[derive(Debug, Clone, Default, Serialize, Deserialize)]
401pub struct FormatExtensions {
402 pub cyclonedx: Option<serde_json::Value>,
404 pub spdx: Option<serde_json::Value>,
406}
407
408#[derive(Debug, Clone, Default, Serialize, Deserialize)]
410pub struct ComponentExtensions {
411 pub properties: Vec<Property>,
413 pub annotations: Vec<Annotation>,
415 pub raw: Option<serde_json::Value>,
417}
418
419#[derive(Debug, Clone, Serialize, Deserialize)]
421pub struct Property {
422 pub name: String,
423 pub value: String,
424}
425
426#[derive(Debug, Clone, Serialize, Deserialize)]
428pub struct Annotation {
429 pub annotator: String,
430 pub annotation_date: DateTime<Utc>,
431 pub annotation_type: String,
432 pub comment: String,
433}