spdx_tools.spdx.validation.checksum_validator
1# SPDX-FileCopyrightText: 2022 spdx contributors 2# 3# SPDX-License-Identifier: Apache-2.0 4 5import re 6 7from beartype.typing import Dict, List 8 9from spdx_tools.spdx.model import Checksum, ChecksumAlgorithm 10from spdx_tools.spdx.validation.validation_message import SpdxElementType, ValidationContext, ValidationMessage 11 12# in hexadecimal digits 13algorithm_length: Dict = { 14 ChecksumAlgorithm.SHA1: "40", 15 ChecksumAlgorithm.SHA224: "56", 16 ChecksumAlgorithm.SHA256: "64", 17 ChecksumAlgorithm.SHA384: "96", 18 ChecksumAlgorithm.SHA512: "128", 19 ChecksumAlgorithm.SHA3_256: "64", 20 ChecksumAlgorithm.SHA3_384: "96", 21 ChecksumAlgorithm.SHA3_512: "128", 22 ChecksumAlgorithm.BLAKE2B_256: "64", 23 ChecksumAlgorithm.BLAKE2B_384: "96", 24 ChecksumAlgorithm.BLAKE2B_512: "128", 25 ChecksumAlgorithm.BLAKE3: "256,", # at least 256 bits 26 ChecksumAlgorithm.MD2: "32", 27 ChecksumAlgorithm.MD4: "32", 28 ChecksumAlgorithm.MD5: "32", 29 ChecksumAlgorithm.MD6: "0,512", # between 0 and 512 bits 30 ChecksumAlgorithm.ADLER32: "8", 31} 32 33 34def validate_checksums(checksums: List[Checksum], parent_id: str, spdx_version: str) -> List[ValidationMessage]: 35 validation_messages = [] 36 for checksum in checksums: 37 validation_messages.extend(validate_checksum(checksum, parent_id, spdx_version)) 38 39 return validation_messages 40 41 42def validate_checksum(checksum: Checksum, parent_id: str, spdx_version: str) -> List[ValidationMessage]: 43 validation_messages = [] 44 algorithm = checksum.algorithm 45 context = ValidationContext(parent_id=parent_id, element_type=SpdxElementType.CHECKSUM, full_element=checksum) 46 47 if spdx_version == "SPDX-2.2" and algorithm in [ 48 ChecksumAlgorithm.SHA3_512, 49 ChecksumAlgorithm.SHA3_384, 50 ChecksumAlgorithm.SHA3_256, 51 ChecksumAlgorithm.BLAKE3, 52 ChecksumAlgorithm.BLAKE2B_512, 53 ChecksumAlgorithm.BLAKE2B_384, 54 ChecksumAlgorithm.BLAKE2B_256, 55 ChecksumAlgorithm.ADLER32, 56 ]: 57 return [ValidationMessage(f"{checksum.algorithm.name} is not supported in SPDX-2.2", context)] 58 59 if not re.match("^[0-9a-f]{" + algorithm_length[algorithm] + "}$", checksum.value): 60 if algorithm == ChecksumAlgorithm.BLAKE3: 61 length = "at least 256" 62 elif algorithm == ChecksumAlgorithm.MD6: 63 length = "between 0 and 512" 64 else: 65 length = algorithm_length[algorithm] 66 validation_messages.append( 67 ValidationMessage( 68 f"value of {algorithm} must consist of {length} lowercase hexadecimal digits, but is: " 69 f"{checksum.value} (length: {len(checksum.value)} digits)", 70 context, 71 ) 72 ) 73 74 return validation_messages
algorithm_length: dict =
{<ChecksumAlgorithm.SHA1: 1>: '40', <ChecksumAlgorithm.SHA224: 2>: '56', <ChecksumAlgorithm.SHA256: 3>: '64', <ChecksumAlgorithm.SHA384: 4>: '96', <ChecksumAlgorithm.SHA512: 5>: '128', <ChecksumAlgorithm.SHA3_256: 6>: '64', <ChecksumAlgorithm.SHA3_384: 7>: '96', <ChecksumAlgorithm.SHA3_512: 8>: '128', <ChecksumAlgorithm.BLAKE2B_256: 9>: '64', <ChecksumAlgorithm.BLAKE2B_384: 10>: '96', <ChecksumAlgorithm.BLAKE2B_512: 11>: '128', <ChecksumAlgorithm.BLAKE3: 12>: '256,', <ChecksumAlgorithm.MD2: 13>: '32', <ChecksumAlgorithm.MD4: 14>: '32', <ChecksumAlgorithm.MD5: 15>: '32', <ChecksumAlgorithm.MD6: 16>: '0,512', <ChecksumAlgorithm.ADLER32: 17>: '8'}
def
validate_checksums( checksums: list[spdx_tools.spdx.model.checksum.Checksum], parent_id: str, spdx_version: str) -> list[spdx_tools.spdx.validation.validation_message.ValidationMessage]:
def
validate_checksum( checksum: spdx_tools.spdx.model.checksum.Checksum, parent_id: str, spdx_version: str) -> list[spdx_tools.spdx.validation.validation_message.ValidationMessage]:
43def validate_checksum(checksum: Checksum, parent_id: str, spdx_version: str) -> List[ValidationMessage]: 44 validation_messages = [] 45 algorithm = checksum.algorithm 46 context = ValidationContext(parent_id=parent_id, element_type=SpdxElementType.CHECKSUM, full_element=checksum) 47 48 if spdx_version == "SPDX-2.2" and algorithm in [ 49 ChecksumAlgorithm.SHA3_512, 50 ChecksumAlgorithm.SHA3_384, 51 ChecksumAlgorithm.SHA3_256, 52 ChecksumAlgorithm.BLAKE3, 53 ChecksumAlgorithm.BLAKE2B_512, 54 ChecksumAlgorithm.BLAKE2B_384, 55 ChecksumAlgorithm.BLAKE2B_256, 56 ChecksumAlgorithm.ADLER32, 57 ]: 58 return [ValidationMessage(f"{checksum.algorithm.name} is not supported in SPDX-2.2", context)] 59 60 if not re.match("^[0-9a-f]{" + algorithm_length[algorithm] + "}$", checksum.value): 61 if algorithm == ChecksumAlgorithm.BLAKE3: 62 length = "at least 256" 63 elif algorithm == ChecksumAlgorithm.MD6: 64 length = "between 0 and 512" 65 else: 66 length = algorithm_length[algorithm] 67 validation_messages.append( 68 ValidationMessage( 69 f"value of {algorithm} must consist of {length} lowercase hexadecimal digits, but is: " 70 f"{checksum.value} (length: {len(checksum.value)} digits)", 71 context, 72 ) 73 ) 74 75 return validation_messages