1717
1818import hashlib
1919from enum import Enum
20+ from typing import List , Union
2021
2122"""
2223Uniform set of models to represent objects within a CycloneDX software bill-of-materials.
@@ -69,6 +70,36 @@ class HashType:
6970 _algorithm : HashAlgorithm
7071 _value : str
7172
73+ @staticmethod
74+ def from_composite_str (composite_hash : str ):
75+ """
76+ Attempts to convert a string which includes both the Hash Algorithm and Hash Value and represent using our
77+ internal model classes.
78+
79+ Args:
80+ composite_hash:
81+ Composite Hash string of the format `HASH_ALGORITHM`:`HASH_VALUE`.
82+ Example: `sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b`.
83+
84+ Returns:
85+ An instance of `HashType` when possible, else `None`.
86+ """
87+ algorithm : HashAlgorithm = None
88+ parts = composite_hash .split (':' )
89+
90+ algorithm_prefix = parts [0 ].lower ()
91+ if algorithm_prefix == 'md5' :
92+ algorithm = HashAlgorithm .MD5
93+ elif algorithm_prefix [0 :3 ] == 'sha' :
94+ algorithm = getattr (HashAlgorithm , 'SHA_{}' .format (algorithm_prefix [3 :]))
95+ elif algorithm_prefix [0 :6 ] == 'blake2' :
96+ algorithm = getattr (HashAlgorithm , 'BLAKE2b_{}' .format (algorithm_prefix [6 :]))
97+
98+ return HashType (
99+ algorithm = algorithm ,
100+ hash_value = parts [1 ].lower ()
101+ )
102+
72103 def __init__ (self , algorithm : HashAlgorithm , hash_value : str ):
73104 self ._algorithm = algorithm
74105 self ._value = hash_value
@@ -78,3 +109,95 @@ def get_algorithm(self) -> HashAlgorithm:
78109
79110 def get_hash_value (self ) -> str :
80111 return self ._value
112+
113+
114+ class ExternalReferenceType (Enum ):
115+ """
116+ Enum object that defines the permissible 'types' for an External Reference according to the CycloneDX schema.
117+
118+ .. note::
119+ See the CycloneDX Schema definition: https://cyclonedx.org/docs/1.3/#type_externalReferenceType
120+ """
121+ ADVISORIES = 'advisories'
122+ BOM = 'bom'
123+ BUILD_META = 'build-meta'
124+ BUILD_SYSTEM = 'build-system'
125+ CHAT = 'chat'
126+ DISTRIBUTION = 'distribution'
127+ DOCUMENTATION = 'documentation'
128+ ISSUE_TRACKER = 'issue-tracker'
129+ LICENSE = 'license'
130+ MAILING_LIST = 'mailing-list'
131+ OTHER = 'other'
132+ SOCIAL = 'social'
133+ SCM = 'vcs'
134+ SUPPORT = 'support'
135+ VCS = 'vcs'
136+ WEBSITE = 'website'
137+
138+
139+ class ExternalReference :
140+ """
141+ This is out internal representation of an ExternalReference complex type that can be used in multiple places within
142+ a CycloneDX BOM document.
143+
144+ .. note::
145+ See the CycloneDX Schema definition: https://cyclonedx.org/docs/1.3/#type_externalReference
146+ """
147+ _reference_type : ExternalReferenceType
148+ _url : str
149+ _comment : str
150+ _hashes : List [HashType ] = []
151+
152+ def __init__ (self , reference_type : ExternalReferenceType , url : str , comment : str = None ,
153+ hashes : List [HashType ] = []):
154+ self ._reference_type = reference_type
155+ self ._url = url
156+ self ._comment = comment
157+ self ._hashes = hashes
158+
159+ def add_hash (self , our_hash : HashType ):
160+ """
161+ Adds a hash that pins/identifies this External Reference.
162+
163+ Args:
164+ our_hash:
165+ `HashType` instance
166+ """
167+ self ._hashes .append (our_hash )
168+
169+ def get_comment (self ) -> Union [str , None ]:
170+ """
171+ Get the comment for this External Reference.
172+
173+ Returns:
174+ Any comment as a `str` else `None`.
175+ """
176+ return self ._comment
177+
178+ def get_hashes (self ) -> List [HashType ]:
179+ """
180+ List of cryptographic hashes that identify this External Reference.
181+
182+ Returns:
183+ `List` of `HashType` objects where there are any hashes, else an empty `List`.
184+ """
185+ return self ._hashes
186+
187+ def get_reference_type (self ) -> ExternalReferenceType :
188+ """
189+ Get the type of this External Reference.
190+
191+ Returns:
192+ `ExternalReferenceType` that represents the type of this External Reference.
193+ """
194+ return self ._reference_type
195+
196+ def get_url (self ) -> str :
197+ """
198+ Get the URL/URI for this External Reference.
199+
200+ Returns:
201+ URI as a `str`.
202+ """
203+ return self ._url
0 commit comments