1// Copyright 2009 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the go/golang LICENSE file. 4 5package pkcs7 6 7// These are private constants and functions from the crypto/x509 package that 8// are useful when dealing with signatures verified by x509 certificates 9 10import ( 11 "bytes" 12 "crypto" 13 "crypto/x509" 14 "crypto/x509/pkix" 15 "encoding/asn1" 16) 17 18var ( 19 oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2} 20 oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4} 21 oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5} 22 oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11} 23 oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12} 24 oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13} 25 oidSignatureRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10} 26 oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3} 27 oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2} 28 oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1} 29 oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2} 30 oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3} 31 oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4} 32 33 oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1} 34 oidSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2} 35 oidSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3} 36 37 oidMGF1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 8} 38 39 // oidISOSignatureSHA1WithRSA means the same as oidSignatureSHA1WithRSA 40 // but it's specified by ISO. Microsoft's makecert.exe has been known 41 // to produce certificates with this OID. 42 oidISOSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 29} 43) 44 45var signatureAlgorithmDetails = []struct { 46 algo x509.SignatureAlgorithm 47 name string 48 oid asn1.ObjectIdentifier 49 pubKeyAlgo x509.PublicKeyAlgorithm 50 hash crypto.Hash 51}{ 52 {x509.MD2WithRSA, "MD2-RSA", oidSignatureMD2WithRSA, x509.RSA, crypto.Hash(0) /* no value for MD2 */}, 53 {x509.MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, x509.RSA, crypto.MD5}, 54 {x509.SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1}, 55 {x509.SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, x509.RSA, crypto.SHA1}, 56 {x509.SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256}, 57 {x509.SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384}, 58 {x509.SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512}, 59 {x509.SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA256}, 60 {x509.SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA384}, 61 {x509.SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA512}, 62 {x509.DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1}, 63 {x509.DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256}, 64 {x509.ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1}, 65 {x509.ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256}, 66 {x509.ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384}, 67 {x509.ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512}, 68} 69 70// pssParameters reflects the parameters in an AlgorithmIdentifier that 71// specifies RSA PSS. See https://tools.ietf.org/html/rfc3447#appendix-A.2.3 72type pssParameters struct { 73 // The following three fields are not marked as 74 // optional because the default values specify SHA-1, 75 // which is no longer suitable for use in signatures. 76 Hash pkix.AlgorithmIdentifier `asn1:"explicit,tag:0"` 77 MGF pkix.AlgorithmIdentifier `asn1:"explicit,tag:1"` 78 SaltLength int `asn1:"explicit,tag:2"` 79 TrailerField int `asn1:"optional,explicit,tag:3,default:1"` 80} 81 82// asn1.NullBytes is not available prior to Go 1.9 83var nullBytes = []byte{5, 0} 84 85func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) x509.SignatureAlgorithm { 86 if !ai.Algorithm.Equal(oidSignatureRSAPSS) { 87 for _, details := range signatureAlgorithmDetails { 88 if ai.Algorithm.Equal(details.oid) { 89 return details.algo 90 } 91 } 92 return x509.UnknownSignatureAlgorithm 93 } 94 95 // RSA PSS is special because it encodes important parameters 96 // in the Parameters. 97 98 var params pssParameters 99 if _, err := asn1.Unmarshal(ai.Parameters.FullBytes, ¶ms); err != nil { 100 return x509.UnknownSignatureAlgorithm 101 } 102 103 var mgf1HashFunc pkix.AlgorithmIdentifier 104 if _, err := asn1.Unmarshal(params.MGF.Parameters.FullBytes, &mgf1HashFunc); err != nil { 105 return x509.UnknownSignatureAlgorithm 106 } 107 108 // PSS is greatly overburdened with options. This code forces 109 // them into three buckets by requiring that the MGF1 hash 110 // function always match the message hash function (as 111 // recommended in 112 // https://tools.ietf.org/html/rfc3447#section-8.1), that the 113 // salt length matches the hash length, and that the trailer 114 // field has the default value. 115 if !bytes.Equal(params.Hash.Parameters.FullBytes, nullBytes) || 116 !params.MGF.Algorithm.Equal(oidMGF1) || 117 !mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) || 118 !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, nullBytes) || 119 params.TrailerField != 1 { 120 return x509.UnknownSignatureAlgorithm 121 } 122 123 switch { 124 case params.Hash.Algorithm.Equal(oidSHA256) && params.SaltLength == 32: 125 return x509.SHA256WithRSAPSS 126 case params.Hash.Algorithm.Equal(oidSHA384) && params.SaltLength == 48: 127 return x509.SHA384WithRSAPSS 128 case params.Hash.Algorithm.Equal(oidSHA512) && params.SaltLength == 64: 129 return x509.SHA512WithRSAPSS 130 } 131 132 return x509.UnknownSignatureAlgorithm 133} 134