github.com/zmap/zlint@v1.1.0/util/algorithm_identifier.go (about) 1 package util 2 3 import ( 4 "bytes" 5 "encoding/asn1" 6 "errors" 7 "fmt" 8 9 "golang.org/x/crypto/cryptobyte" 10 cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1" 11 ) 12 13 // RSAAlgorithmIDToDER contains DER representations of pkix.AlgorithmIdentifier for different RSA OIDs with Parameters as asn1.NULL 14 var RSAAlgorithmIDToDER = map[string][]byte{ 15 // rsaEncryption 16 "1.2.840.113549.1.1.1": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x1, 0x5, 0x0}, 17 // md2WithRSAEncryption 18 "1.2.840.113549.1.1.2": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x2, 0x5, 0x0}, 19 // md5WithRSAEncryption 20 "1.2.840.113549.1.1.4": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x4, 0x5, 0x0}, 21 // sha-1WithRSAEncryption 22 "1.2.840.113549.1.1.5": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0x5, 0x5, 0x0}, 23 // sha224WithRSAEncryption 24 "1.2.840.113549.1.1.14": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xe, 0x5, 0x0}, 25 // sha256WithRSAEncryption 26 "1.2.840.113549.1.1.11": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xb, 0x5, 0x0}, 27 // sha384WithRSAEncryption 28 "1.2.840.113549.1.1.12": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xc, 0x5, 0x0}, 29 // sha512WithRSAEncryption 30 "1.2.840.113549.1.1.13": {0x30, 0x0d, 0x6, 0x9, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0xd, 0x1, 0x1, 0xd, 0x5, 0x0}, 31 } 32 33 // CheckAlgorithmIDParamNotNULL parses an AlgorithmIdentifier with algorithm OID rsaEncryption to check the Param field is asn1.NULL 34 // Expects DER-encoded AlgorithmIdentifier including tag and length 35 func CheckAlgorithmIDParamNotNULL(algorithmIdentifier []byte, requiredAlgoID asn1.ObjectIdentifier) error { 36 expectedAlgoIDBytes, ok := RSAAlgorithmIDToDER[requiredAlgoID.String()] 37 if !ok { 38 return errors.New("error algorithmID to check is not RSA") 39 } 40 41 algorithmSequence := cryptobyte.String(algorithmIdentifier) 42 43 // byte comparison of algorithm sequence and checking no trailing data is present 44 var algorithmBytes []byte 45 if algorithmSequence.ReadBytes(&algorithmBytes, len(expectedAlgoIDBytes)) { 46 if bytes.Compare(algorithmBytes, expectedAlgoIDBytes) == 0 && algorithmSequence.Empty() { 47 return nil 48 } 49 } 50 51 // re-parse to get an error message detailing what did not match in the byte comparison 52 algorithmSequence = cryptobyte.String(algorithmIdentifier) 53 var algorithm cryptobyte.String 54 if !algorithmSequence.ReadASN1(&algorithm, cryptobyte_asn1.SEQUENCE) { 55 return errors.New("error reading algorithm") 56 } 57 58 encryptionOID := asn1.ObjectIdentifier{} 59 if !algorithm.ReadASN1ObjectIdentifier(&encryptionOID) { 60 return errors.New("error reading algorithm OID") 61 } 62 63 if !encryptionOID.Equal(requiredAlgoID) { 64 return fmt.Errorf("algorithm OID is not equal to %s", requiredAlgoID.String()) 65 } 66 67 if algorithm.Empty() { 68 return errors.New("RSA algorithm identifier missing required NULL parameter") 69 } 70 71 var nullValue cryptobyte.String 72 if !algorithm.ReadASN1(&nullValue, cryptobyte_asn1.NULL) { 73 return errors.New("RSA algorithm identifier with non-NULL parameter") 74 } 75 76 if len(nullValue) != 0 { 77 return errors.New("RSA algorithm identifier with NULL parameter containing data") 78 } 79 80 // ensure algorithm is empty and no trailing data is present 81 if !algorithm.Empty() { 82 return errors.New("RSA algorithm identifier with trailing data") 83 } 84 85 return errors.New("RSA algorithm appears correct, but didn't match byte-wise comparison") 86 }