Alias x509 types

Alias x509 types
This commit is contained in:
徐胖 2022-01-20 17:46:00 +08:00
parent ec03b0c5b6
commit f98e80a8d6
2 changed files with 80 additions and 57 deletions

View File

@ -191,9 +191,34 @@ type authKeyId struct {
Id []byte `asn1:"optional,tag:0"` Id []byte `asn1:"optional,tag:0"`
} }
func isRSAPSS(algo x509.SignatureAlgorithm) bool { type SignatureAlgorithm = x509.SignatureAlgorithm
const (
UnknownSignatureAlgorithm = x509.UnknownSignatureAlgorithm
MD2WithRSA = x509.MD2WithRSA
MD5WithRSA = x509.MD5WithRSA // Only supported for signing, not verification.
SHA1WithRSA = x509.SHA1WithRSA
SHA256WithRSA = x509.SHA256WithRSA
SHA384WithRSA = x509.SHA384WithRSA
SHA512WithRSA = x509.SHA512WithRSA
DSAWithSHA1 = x509.DSAWithSHA1 // Unsupported.
DSAWithSHA256 = x509.DSAWithSHA256 // Unsupported.
ECDSAWithSHA1 = x509.ECDSAWithSHA1
ECDSAWithSHA256 = x509.ECDSAWithSHA256
ECDSAWithSHA384 = x509.ECDSAWithSHA384
ECDSAWithSHA512 = x509.ECDSAWithSHA512
SHA256WithRSAPSS = x509.SHA256WithRSAPSS
SHA384WithRSAPSS = x509.SHA384WithRSAPSS
SHA512WithRSAPSS = x509.SHA512WithRSAPSS
PureEd25519 = x509.PureEd25519
SM2WithSM3 SignatureAlgorithm = 99
)
func isRSAPSS(algo SignatureAlgorithm) bool {
switch algo { switch algo {
case x509.SHA256WithRSAPSS, x509.SHA384WithRSAPSS, x509.SHA512WithRSAPSS: case SHA256WithRSAPSS, SHA384WithRSAPSS, SHA512WithRSAPSS:
return true return true
default: default:
return false return false
@ -206,32 +231,30 @@ type pkcs1PublicKey struct {
E int E int
} }
const SM2WithSM3 x509.SignatureAlgorithm = 99
var signatureAlgorithmDetails = []struct { var signatureAlgorithmDetails = []struct {
algo x509.SignatureAlgorithm algo SignatureAlgorithm
name string name string
oid asn1.ObjectIdentifier oid asn1.ObjectIdentifier
pubKeyAlgo x509.PublicKeyAlgorithm pubKeyAlgo x509.PublicKeyAlgorithm
hash crypto.Hash hash crypto.Hash
}{ }{
{x509.MD2WithRSA, "MD2-RSA", oidSignatureMD2WithRSA, x509.RSA, crypto.Hash(0) /* no value for MD2 */}, {MD2WithRSA, "MD2-RSA", oidSignatureMD2WithRSA, x509.RSA, crypto.Hash(0) /* no value for MD2 */},
{x509.MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, x509.RSA, crypto.MD5}, {MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, x509.RSA, crypto.MD5},
{x509.SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1}, {SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1},
{x509.SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, x509.RSA, crypto.SHA1}, {SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, x509.RSA, crypto.SHA1},
{x509.SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256}, {SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256},
{x509.SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384}, {SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384},
{x509.SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512}, {SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512},
{x509.SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA256}, {SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA256},
{x509.SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA384}, {SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA384},
{x509.SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA512}, {SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA512},
{x509.DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1}, {DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1},
{x509.DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256}, {DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256},
{x509.ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1}, {ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1},
{x509.ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256}, {ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256},
{x509.ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384}, {ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384},
{x509.ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512}, {ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512},
{x509.PureEd25519, "Ed25519", oidSignatureEd25519, x509.Ed25519, crypto.Hash(0) /* no pre-hashing */}, {PureEd25519, "Ed25519", oidSignatureEd25519, x509.Ed25519, crypto.Hash(0) /* no pre-hashing */},
{SM2WithSM3, "SM2-SM3", oidSignatureSM2WithSM3, x509.ECDSA, crypto.Hash(0) /* no pre-hashing */}, {SM2WithSM3, "SM2-SM3", oidSignatureSM2WithSM3, x509.ECDSA, crypto.Hash(0) /* no pre-hashing */},
} }
@ -260,12 +283,12 @@ type pssParameters struct {
TrailerField int `asn1:"optional,explicit,tag:3,default:1"` TrailerField int `asn1:"optional,explicit,tag:3,default:1"`
} }
func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) x509.SignatureAlgorithm { func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgorithm {
if ai.Algorithm.Equal(oidSignatureEd25519) { if ai.Algorithm.Equal(oidSignatureEd25519) {
// RFC 8410, Section 3 // RFC 8410, Section 3
// > For all of the OIDs, the parameters MUST be absent. // > For all of the OIDs, the parameters MUST be absent.
if len(ai.Parameters.FullBytes) != 0 { if len(ai.Parameters.FullBytes) != 0 {
return x509.UnknownSignatureAlgorithm return UnknownSignatureAlgorithm
} }
} }
@ -275,7 +298,7 @@ func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) x509.SignatureAlgo
return details.algo return details.algo
} }
} }
return x509.UnknownSignatureAlgorithm return UnknownSignatureAlgorithm
} }
// RSA PSS is special because it encodes important parameters // RSA PSS is special because it encodes important parameters
@ -283,12 +306,12 @@ func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) x509.SignatureAlgo
var params pssParameters var params pssParameters
if _, err := asn1.Unmarshal(ai.Parameters.FullBytes, &params); err != nil { if _, err := asn1.Unmarshal(ai.Parameters.FullBytes, &params); err != nil {
return x509.UnknownSignatureAlgorithm return UnknownSignatureAlgorithm
} }
var mgf1HashFunc pkix.AlgorithmIdentifier var mgf1HashFunc pkix.AlgorithmIdentifier
if _, err := asn1.Unmarshal(params.MGF.Parameters.FullBytes, &mgf1HashFunc); err != nil { if _, err := asn1.Unmarshal(params.MGF.Parameters.FullBytes, &mgf1HashFunc); err != nil {
return x509.UnknownSignatureAlgorithm return UnknownSignatureAlgorithm
} }
// PSS is greatly overburdened with options. This code forces them into // PSS is greatly overburdened with options. This code forces them into
@ -301,19 +324,19 @@ func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) x509.SignatureAlgo
!mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) || !mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) ||
(len(mgf1HashFunc.Parameters.FullBytes) != 0 && !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, asn1.NullBytes)) || (len(mgf1HashFunc.Parameters.FullBytes) != 0 && !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, asn1.NullBytes)) ||
params.TrailerField != 1 { params.TrailerField != 1 {
return x509.UnknownSignatureAlgorithm return UnknownSignatureAlgorithm
} }
switch { switch {
case params.Hash.Algorithm.Equal(oidSHA256) && params.SaltLength == 32: case params.Hash.Algorithm.Equal(oidSHA256) && params.SaltLength == 32:
return x509.SHA256WithRSAPSS return SHA256WithRSAPSS
case params.Hash.Algorithm.Equal(oidSHA384) && params.SaltLength == 48: case params.Hash.Algorithm.Equal(oidSHA384) && params.SaltLength == 48:
return x509.SHA384WithRSAPSS return SHA384WithRSAPSS
case params.Hash.Algorithm.Equal(oidSHA512) && params.SaltLength == 64: case params.Hash.Algorithm.Equal(oidSHA512) && params.SaltLength == 64:
return x509.SHA512WithRSAPSS return SHA512WithRSAPSS
} }
return x509.UnknownSignatureAlgorithm return UnknownSignatureAlgorithm
} }
// RFC 3279, 2.3 Public Key Algorithms // RFC 3279, 2.3 Public Key Algorithms
@ -534,7 +557,7 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
// CheckSignature verifies that signature is a valid signature over signed from // CheckSignature verifies that signature is a valid signature over signed from
// c's public key. // c's public key.
func (c *Certificate) CheckSignature(algo x509.SignatureAlgorithm, signed, signature []byte) error { func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) error {
return checkSignature(algo, signed, signature, c.PublicKey) return checkSignature(algo, signed, signature, c.PublicKey)
} }
@ -573,7 +596,7 @@ func verifyECDSAASN1(pub *ecdsa.PublicKey, hash, sig []byte) bool {
// checkSignature verifies that signature is a valid signature over signed from // checkSignature verifies that signature is a valid signature over signed from
// a crypto.PublicKey. // a crypto.PublicKey.
func checkSignature(algo x509.SignatureAlgorithm, signed, signature []byte, publicKey crypto.PublicKey) (err error) { func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey crypto.PublicKey) (err error) {
var hashType crypto.Hash var hashType crypto.Hash
var pubKeyAlgo x509.PublicKeyAlgorithm var pubKeyAlgo x509.PublicKeyAlgorithm
@ -1103,7 +1126,7 @@ func subjectBytes(cert *x509.Certificate) ([]byte, error) {
// signingParamsForPublicKey returns the parameters to use for signing with // signingParamsForPublicKey returns the parameters to use for signing with
// priv. If requestedSigAlgo is not zero then it overrides the default // priv. If requestedSigAlgo is not zero then it overrides the default
// signature algorithm. // signature algorithm.
func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) { func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) {
var pubType x509.PublicKeyAlgorithm var pubType x509.PublicKeyAlgorithm
switch pub := pub.(type) { switch pub := pub.(type) {
@ -1347,7 +1370,7 @@ func CreateCertificate(rand io.Reader, template, parent *x509.Certificate, pub,
// Check the signature to ensure the crypto.Signer behaved correctly. // Check the signature to ensure the crypto.Signer behaved correctly.
sigAlg := getSignatureAlgorithmFromAI(signatureAlgorithm) sigAlg := getSignatureAlgorithmFromAI(signatureAlgorithm)
switch sigAlg { switch sigAlg {
case x509.MD5WithRSA, x509.SHA1WithRSA, x509.ECDSAWithSHA1: case MD5WithRSA, SHA1WithRSA, ECDSAWithSHA1:
// We skip the check if the signature algorithm is only supported for // We skip the check if the signature algorithm is only supported for
// signing, not verification. // signing, not verification.
default: default:

View File

@ -354,14 +354,14 @@ func Test_CreateCertificateRequest(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
priv interface{} priv interface{}
sigAlgo x509.SignatureAlgorithm sigAlgo SignatureAlgorithm
}{ }{
{"RSA", testPrivateKey, x509.SHA1WithRSA}, {"RSA", testPrivateKey, SHA1WithRSA},
{"SM2-256", sm2Priv, SM2WithSM3}, {"SM2-256", sm2Priv, SM2WithSM3},
{"ECDSA-256", ecdsa256Priv, x509.ECDSAWithSHA1}, {"ECDSA-256", ecdsa256Priv, ECDSAWithSHA1},
{"ECDSA-384", ecdsa384Priv, x509.ECDSAWithSHA1}, {"ECDSA-384", ecdsa384Priv, ECDSAWithSHA1},
{"ECDSA-521", ecdsa521Priv, x509.ECDSAWithSHA1}, {"ECDSA-521", ecdsa521Priv, ECDSAWithSHA1},
{"Ed25519", ed25519Priv, x509.PureEd25519}, {"Ed25519", ed25519Priv, PureEd25519},
} }
for _, test := range tests { for _, test := range tests {
@ -446,20 +446,20 @@ func TestCreateSelfSignedCertificate(t *testing.T) {
name string name string
pub, priv interface{} pub, priv interface{}
checkSig bool checkSig bool
sigAlgo x509.SignatureAlgorithm sigAlgo SignatureAlgorithm
}{ }{
{"RSA/RSA", &testPrivateKey.PublicKey, testPrivateKey, true, x509.SHA1WithRSA}, {"RSA/RSA", &testPrivateKey.PublicKey, testPrivateKey, true, SHA1WithRSA},
{"RSA/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, x509.ECDSAWithSHA384}, {"RSA/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384},
{"RSA/SM2", &testPrivateKey.PublicKey, sm2Priv, false, SM2WithSM3}, {"RSA/SM2", &testPrivateKey.PublicKey, sm2Priv, false, SM2WithSM3},
{"ECDSA/RSA", &ecdsaPriv.PublicKey, testPrivateKey, false, x509.SHA256WithRSA}, {"ECDSA/RSA", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSA},
{"ECDSA/ECDSA", &ecdsaPriv.PublicKey, ecdsaPriv, true, x509.ECDSAWithSHA1}, {"ECDSA/ECDSA", &ecdsaPriv.PublicKey, ecdsaPriv, true, ECDSAWithSHA1},
{"ECDSA/SM2", &ecdsaPriv.PublicKey, sm2Priv, false, SM2WithSM3}, {"ECDSA/SM2", &ecdsaPriv.PublicKey, sm2Priv, false, SM2WithSM3},
{"SM2/ECDSA", &sm2Priv.PublicKey, ecdsaPriv, false, x509.ECDSAWithSHA1}, {"SM2/ECDSA", &sm2Priv.PublicKey, ecdsaPriv, false, ECDSAWithSHA1},
{"RSAPSS/RSAPSS", &testPrivateKey.PublicKey, testPrivateKey, true, x509.SHA256WithRSAPSS}, {"RSAPSS/RSAPSS", &testPrivateKey.PublicKey, testPrivateKey, true, SHA256WithRSAPSS},
{"ECDSA/RSAPSS", &ecdsaPriv.PublicKey, testPrivateKey, false, x509.SHA256WithRSAPSS}, {"ECDSA/RSAPSS", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSAPSS},
{"SM2/RSAPSS", &sm2Priv.PublicKey, testPrivateKey, false, x509.SHA256WithRSAPSS}, {"SM2/RSAPSS", &sm2Priv.PublicKey, testPrivateKey, false, SHA256WithRSAPSS},
{"RSAPSS/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, x509.ECDSAWithSHA384}, {"RSAPSS/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384},
{"Ed25519", ed25519Pub, ed25519Priv, true, x509.PureEd25519}, {"Ed25519", ed25519Pub, ed25519Priv, true, PureEd25519},
{"SM2", &sm2Priv.PublicKey, sm2Priv, true, SM2WithSM3}, {"SM2", &sm2Priv.PublicKey, sm2Priv, true, SM2WithSM3},
} }
@ -1238,7 +1238,7 @@ func TestCreateRevocationList(t *testing.T) {
SubjectKeyId: []byte{1, 2, 3}, SubjectKeyId: []byte{1, 2, 3},
}, },
template: &x509.RevocationList{ template: &x509.RevocationList{
SignatureAlgorithm: x509.SHA256WithRSA, SignatureAlgorithm: SHA256WithRSA,
RevokedCertificates: []pkix.RevokedCertificate{ RevokedCertificates: []pkix.RevokedCertificate{
{ {
SerialNumber: big.NewInt(2), SerialNumber: big.NewInt(2),
@ -1306,7 +1306,7 @@ func TestCreateRevocationList(t *testing.T) {
SubjectKeyId: []byte{1, 2, 3}, SubjectKeyId: []byte{1, 2, 3},
}, },
template: &x509.RevocationList{ template: &x509.RevocationList{
SignatureAlgorithm: x509.ECDSAWithSHA512, SignatureAlgorithm: ECDSAWithSHA512,
RevokedCertificates: []pkix.RevokedCertificate{ RevokedCertificates: []pkix.RevokedCertificate{
{ {
SerialNumber: big.NewInt(2), SerialNumber: big.NewInt(2),
@ -1387,7 +1387,7 @@ func TestCreateRevocationList(t *testing.T) {
t.Fatalf("Failed to parse generated CRL: %s", err) t.Fatalf("Failed to parse generated CRL: %s", err)
} }
if tc.template.SignatureAlgorithm != x509.UnknownSignatureAlgorithm && if tc.template.SignatureAlgorithm != UnknownSignatureAlgorithm &&
parsedCRL.SignatureAlgorithm.Algorithm.Equal(signatureAlgorithmDetails[tc.template.SignatureAlgorithm].oid) { parsedCRL.SignatureAlgorithm.Algorithm.Equal(signatureAlgorithmDetails[tc.template.SignatureAlgorithm].oid) {
t.Fatalf("SignatureAlgorithm mismatch: got %v; want %v.", parsedCRL.SignatureAlgorithm, t.Fatalf("SignatureAlgorithm mismatch: got %v; want %v.", parsedCRL.SignatureAlgorithm,
tc.template.SignatureAlgorithm) tc.template.SignatureAlgorithm)
@ -2095,7 +2095,7 @@ func TestISOOIDInCertificate(t *testing.T) {
block, _ := pem.Decode([]byte(certISOOID)) block, _ := pem.Decode([]byte(certISOOID))
if cert, err := ParseCertificate(block.Bytes); err != nil { if cert, err := ParseCertificate(block.Bytes); err != nil {
t.Errorf("certificate with ISO OID failed to parse: %s", err) t.Errorf("certificate with ISO OID failed to parse: %s", err)
} else if cert.SignatureAlgorithm == x509.UnknownSignatureAlgorithm { } else if cert.SignatureAlgorithm == UnknownSignatureAlgorithm {
t.Errorf("ISO OID not recognised in certificate") t.Errorf("ISO OID not recognised in certificate")
} }
} }