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  }