diff --git a/smx509/parser.go b/smx509/parser.go index cfb8174..39254dc 100644 --- a/smx509/parser.go +++ b/smx509/parser.go @@ -7,7 +7,6 @@ import ( "crypto/ed25519" "crypto/elliptic" "crypto/rsa" - "crypto/x509" "crypto/x509/pkix" "encoding/asn1" "encoding/pem" @@ -228,10 +227,10 @@ func parseExtension(der cryptobyte.String) (pkix.Extension, error) { return ext, nil } -func parsePublicKey(algo x509.PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) { +func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) { der := cryptobyte.String(keyData.PublicKey.RightAlign()) switch algo { - case x509.RSA: + case RSA: // RSA public keys must have a NULL in the parameters. // See RFC 3279, Section 2.3.1. if !bytes.Equal(keyData.Algorithm.Parameters.FullBytes, asn1.NullBytes) { @@ -261,7 +260,7 @@ func parsePublicKey(algo x509.PublicKeyAlgorithm, keyData *publicKeyInfo) (inter N: p.N, } return pub, nil - case x509.ECDSA: + case ECDSA: paramsDer := cryptobyte.String(keyData.Algorithm.Parameters.FullBytes) namedCurveOID := new(asn1.ObjectIdentifier) if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) { @@ -281,7 +280,7 @@ func parsePublicKey(algo x509.PublicKeyAlgorithm, keyData *publicKeyInfo) (inter Y: y, } return pub, nil - case x509.Ed25519: + case Ed25519: // RFC 8410, Section 3 // > For all of the OIDs, the parameters MUST be absent. if len(keyData.Algorithm.Parameters.FullBytes) != 0 { @@ -291,7 +290,7 @@ func parsePublicKey(algo x509.PublicKeyAlgorithm, keyData *publicKeyInfo) (inter return nil, errors.New("x509: wrong Ed25519 public key size") } return ed25519.PublicKey(der), nil - case x509.DSA: + case DSA: y := new(big.Int) if !der.ReadASN1Integer(y) { return nil, errors.New("x509: invalid DSA public key") @@ -321,7 +320,7 @@ func parsePublicKey(algo x509.PublicKeyAlgorithm, keyData *publicKeyInfo) (inter } } -func parseKeyUsageExtension(der cryptobyte.String) (x509.KeyUsage, error) { +func parseKeyUsageExtension(der cryptobyte.String) (KeyUsage, error) { var usageBits asn1.BitString if !der.ReadASN1BitString(&usageBits) { return 0, errors.New("x509: invalid key usage") @@ -333,7 +332,7 @@ func parseKeyUsageExtension(der cryptobyte.String) (x509.KeyUsage, error) { usage |= 1 << uint(i) } } - return x509.KeyUsage(usage), nil + return KeyUsage(usage), nil } func parseBasicConstraintsExtension(der cryptobyte.String) (bool, int, error) { @@ -420,8 +419,8 @@ func parseSANExtension(der cryptobyte.String) (dnsNames, emailAddresses []string return } -func parseExtKeyUsageExtension(der cryptobyte.String) ([]x509.ExtKeyUsage, []asn1.ObjectIdentifier, error) { - var extKeyUsages []x509.ExtKeyUsage +func parseExtKeyUsageExtension(der cryptobyte.String) ([]ExtKeyUsage, []asn1.ObjectIdentifier, error) { + var extKeyUsages []ExtKeyUsage var unknownUsages []asn1.ObjectIdentifier if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) { return nil, nil, errors.New("x509: invalid extended key usages") diff --git a/smx509/root_windows.go b/smx509/root_windows.go index cb0f255..bd4c319 100644 --- a/smx509/root_windows.go +++ b/smx509/root_windows.go @@ -92,9 +92,9 @@ func checkChainTrustStatus(c *Certificate, chainCtx *syscall.CertChainContext) e status := chainCtx.TrustStatus.ErrorStatus switch status { case syscall.CERT_TRUST_IS_NOT_TIME_VALID: - return x509.CertificateInvalidError{&c.Certificate, x509.Expired, ""} + return CertificateInvalidError{c.asX509(), Expired, ""} case syscall.CERT_TRUST_IS_NOT_VALID_FOR_USAGE: - return x509.CertificateInvalidError{&c.Certificate, x509.IncompatibleUsage, ""} + return CertificateInvalidError{c.asX509(), IncompatibleUsage, ""} // TODO(filippo): surface more error statuses. default: return UnknownAuthorityError{c, nil, nil} @@ -133,9 +133,9 @@ func checkChainSSLServerPolicy(c *Certificate, chainCtx *syscall.CertChainContex if status.Error != 0 { switch status.Error { case syscall.CERT_E_EXPIRED: - return x509.CertificateInvalidError{Cert: &c.Certificate, Reason: x509.Expired, Detail: ""} + return CertificateInvalidError{Cert: c.asX509(), Reason: Expired, Detail: ""} case syscall.CERT_E_CN_NO_MATCH: - return x509.HostnameError{Certificate: &c.Certificate, Host: opts.DNSName} + return x509.HostnameError{Certificate: c.asX509(), Host: opts.DNSName} case syscall.CERT_E_UNTRUSTEDROOT: return UnknownAuthorityError{c, nil, nil} default: @@ -148,7 +148,7 @@ func checkChainSSLServerPolicy(c *Certificate, chainCtx *syscall.CertChainContex // windowsExtKeyUsageOIDs are the C NUL-terminated string representations of the // OIDs for use with the Windows API. -var windowsExtKeyUsageOIDs = make(map[x509.ExtKeyUsage][]byte, len(extKeyUsageOIDs)) +var windowsExtKeyUsageOIDs = make(map[ExtKeyUsage][]byte, len(extKeyUsageOIDs)) func init() { for _, eku := range extKeyUsageOIDs { @@ -183,7 +183,7 @@ func verifyChain(c *Certificate, chainCtx *syscall.CertChainContext, opts *Verif // using spoofed parameters, the signature will be invalid for the correct // ones we parsed. (We don't support custom curves ourselves.) for i, parent := range chain[1:] { - if parent.PublicKeyAlgorithm != x509.ECDSA { + if parent.PublicKeyAlgorithm != ECDSA { continue } if err := parent.CheckSignature(chain[i].SignatureAlgorithm, @@ -208,11 +208,11 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate keyUsages := opts.KeyUsages if len(keyUsages) == 0 { - keyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth} + keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth} } oids := make([]*byte, 0, len(keyUsages)) for _, eku := range keyUsages { - if eku == x509.ExtKeyUsageAny { + if eku == ExtKeyUsageAny { oids = nil break } diff --git a/smx509/verify.go b/smx509/verify.go index 14b70d5..2467153 100644 --- a/smx509/verify.go +++ b/smx509/verify.go @@ -14,6 +14,21 @@ import ( "unicode/utf8" ) +const ( + NotAuthorizedToSign = x509.NotAuthorizedToSign + Expired = x509.Expired + CANotAuthorizedForThisName = x509.CANotAuthorizedForThisName + TooManyIntermediates = x509.TooManyIntermediates + IncompatibleUsage = x509.IncompatibleUsage + NameMismatch = x509.NameMismatch + NameConstraintsWithoutSANs = x509.NameConstraintsWithoutSANs + UnconstrainedName = x509.UnconstrainedName + TooManyConstraints = x509.TooManyConstraints + CANotAuthorizedForExtKeyUsage = x509.CANotAuthorizedForExtKeyUsage +) + +type CertificateInvalidError = x509.CertificateInvalidError + // UnknownAuthorityError results when the certificate issuer is unknown type UnknownAuthorityError struct { Cert *Certificate @@ -66,7 +81,7 @@ type VerifyOptions struct { // KeyUsages specifies which Extended Key Usage values are acceptable. A // chain is accepted if it allows any of the listed values. An empty list // means ExtKeyUsageServerAuth. To accept any key usage, include ExtKeyUsageAny. - KeyUsages []x509.ExtKeyUsage + KeyUsages []ExtKeyUsage // MaxConstraintComparisions is the maximum number of comparisons to // perform when checking a given certificate's name constraints. If @@ -246,18 +261,18 @@ func (c *Certificate) checkNameConstraints(count *int, *count += excludedValue.Len() if *count > maxConstraintComparisons { - return x509.CertificateInvalidError{&c.Certificate, x509.TooManyConstraints, ""} + return CertificateInvalidError{c.asX509(), TooManyConstraints, ""} } for i := 0; i < excludedValue.Len(); i++ { constraint := excludedValue.Index(i).Interface() match, err := match(parsedName, constraint) if err != nil { - return x509.CertificateInvalidError{&c.Certificate, x509.CANotAuthorizedForThisName, err.Error()} + return CertificateInvalidError{c.asX509(), CANotAuthorizedForThisName, err.Error()} } if match { - return x509.CertificateInvalidError{&c.Certificate, x509.CANotAuthorizedForThisName, fmt.Sprintf("%s %q is excluded by constraint %q", nameType, name, constraint)} + return CertificateInvalidError{c.asX509(), CANotAuthorizedForThisName, fmt.Sprintf("%s %q is excluded by constraint %q", nameType, name, constraint)} } } @@ -265,7 +280,7 @@ func (c *Certificate) checkNameConstraints(count *int, *count += permittedValue.Len() if *count > maxConstraintComparisons { - return x509.CertificateInvalidError{&c.Certificate, x509.TooManyConstraints, ""} + return CertificateInvalidError{c.asX509(), TooManyConstraints, ""} } ok := true @@ -274,7 +289,7 @@ func (c *Certificate) checkNameConstraints(count *int, var err error if ok, err = match(parsedName, constraint); err != nil { - return x509.CertificateInvalidError{&c.Certificate, x509.CANotAuthorizedForThisName, err.Error()} + return CertificateInvalidError{c.asX509(), CANotAuthorizedForThisName, err.Error()} } if ok { @@ -283,7 +298,7 @@ func (c *Certificate) checkNameConstraints(count *int, } if !ok { - return x509.CertificateInvalidError{&c.Certificate, x509.CANotAuthorizedForThisName, fmt.Sprintf("%s %q is not permitted by any constraint", nameType, name)} + return CertificateInvalidError{c.asX509(), CANotAuthorizedForThisName, fmt.Sprintf("%s %q is not permitted by any constraint", nameType, name)} } return nil @@ -334,7 +349,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V if len(currentChain) > 0 { child := currentChain[len(currentChain)-1] if !bytes.Equal(child.RawIssuer, c.RawSubject) { - return x509.CertificateInvalidError{&c.Certificate, x509.NameMismatch, ""} + return CertificateInvalidError{c.asX509(), NameMismatch, ""} } } @@ -343,15 +358,15 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V now = time.Now() } if now.Before(c.NotBefore) { - return x509.CertificateInvalidError{ - Cert: &c.Certificate, - Reason: x509.Expired, + return CertificateInvalidError{ + Cert: c.asX509(), + Reason: Expired, Detail: fmt.Sprintf("current time %s is before %s", now.Format(time.RFC3339), c.NotBefore.Format(time.RFC3339)), } } else if now.After(c.NotAfter) { - return x509.CertificateInvalidError{ - Cert: &c.Certificate, - Reason: x509.Expired, + return CertificateInvalidError{ + Cert: c.asX509(), + Reason: Expired, Detail: fmt.Sprintf("current time %s is after %s", now.Format(time.RFC3339), c.NotAfter.Format(time.RFC3339)), } } @@ -458,13 +473,13 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V // encryption key could only be used for Diffie-Hellman key agreement. if certType == intermediateCertificate && (!c.BasicConstraintsValid || !c.IsCA) { - return x509.CertificateInvalidError{&c.Certificate, x509.NotAuthorizedToSign, ""} + return CertificateInvalidError{c.asX509(), NotAuthorizedToSign, ""} } if c.BasicConstraintsValid && c.MaxPathLen >= 0 { numIntermediates := len(currentChain) - 1 if numIntermediates > c.MaxPathLen { - return x509.CertificateInvalidError{&c.Certificate, x509.TooManyIntermediates, ""} + return CertificateInvalidError{c.asX509(), TooManyIntermediates, ""} } } @@ -554,12 +569,12 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e keyUsages := opts.KeyUsages if len(keyUsages) == 0 { - keyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth} + keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth} } // If any key usage is acceptable then we're done. for _, usage := range keyUsages { - if usage == x509.ExtKeyUsageAny { + if usage == ExtKeyUsageAny { return candidateChains, nil } } @@ -571,7 +586,7 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e } if len(chains) == 0 { - return nil, x509.CertificateInvalidError{&c.Certificate, x509.IncompatibleUsage, ""} + return nil, CertificateInvalidError{c.asX509(), IncompatibleUsage, ""} } return chains, nil @@ -798,7 +813,7 @@ func (c *Certificate) VerifyHostname(h string) error { return nil } } - return x509.HostnameError{&c.Certificate, candidateIP} + return x509.HostnameError{c.asX509(), candidateIP} } candidateName := toLowerCaseASCII(h) // Save allocations inside the loop. @@ -820,11 +835,11 @@ func (c *Certificate) VerifyHostname(h string) error { } } } - return x509.HostnameError{&c.Certificate, h} + return x509.HostnameError{c.asX509(), h} } -func checkChainForKeyUsage(chain []*Certificate, keyUsages []x509.ExtKeyUsage) bool { - usages := make([]x509.ExtKeyUsage, len(keyUsages)) +func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool { + usages := make([]ExtKeyUsage, len(keyUsages)) copy(usages, keyUsages) if len(chain) == 0 { @@ -846,13 +861,13 @@ NextCert: } for _, usage := range cert.ExtKeyUsage { - if usage == x509.ExtKeyUsageAny { + if usage == ExtKeyUsageAny { // The certificate is explicitly good for any usage. continue NextCert } } - const invalidUsage x509.ExtKeyUsage = -1 + const invalidUsage ExtKeyUsage = -1 NextRequestedUsage: for i, requestedUsage := range usages { @@ -863,9 +878,9 @@ NextCert: for _, usage := range cert.ExtKeyUsage { if requestedUsage == usage { continue NextRequestedUsage - } else if requestedUsage == x509.ExtKeyUsageServerAuth && - (usage == x509.ExtKeyUsageNetscapeServerGatedCrypto || - usage == x509.ExtKeyUsageMicrosoftServerGatedCrypto) { + } else if requestedUsage == ExtKeyUsageServerAuth && + (usage == ExtKeyUsageNetscapeServerGatedCrypto || + usage == ExtKeyUsageMicrosoftServerGatedCrypto) { // In order to support COMODO // certificate chains, we have to // accept Netscape or Microsoft SGC diff --git a/smx509/verify_test.go b/smx509/verify_test.go index 191d18a..e80423f 100644 --- a/smx509/verify_test.go +++ b/smx509/verify_test.go @@ -26,7 +26,7 @@ type verifyTest struct { dnsName string systemSkip bool systemLax bool - keyUsages []x509.ExtKeyUsage + keyUsages []ExtKeyUsage errorCallback func(*testing.T, error) expectedChains [][]string @@ -135,7 +135,7 @@ var verifyTests = []verifyTest{ intermediates: []string{startComIntermediate}, roots: []string{startComRoot}, currentTime: 1302726541, - keyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny}, + keyUsages: []ExtKeyUsage{ExtKeyUsageAny}, expectedChains: [][]string{ {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, @@ -184,7 +184,7 @@ var verifyTests = []verifyTest{ intermediates: []string{smimeIntermediate}, roots: []string{smimeRoot}, currentTime: 1594673418, - keyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + keyUsages: []ExtKeyUsage{ExtKeyUsageServerAuth}, errorCallback: expectUsageError, }, @@ -194,7 +194,7 @@ var verifyTests = []verifyTest{ intermediates: []string{smimeIntermediate}, roots: []string{smimeRoot}, currentTime: 1594673418, - keyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageEmailProtection}, + keyUsages: []ExtKeyUsage{ExtKeyUsageEmailProtection}, expectedChains: [][]string{ {"CORPORATIVO FICTICIO ACTIVO", "EAEko Herri Administrazioen CA - CA AAPP Vascas (2)", "IZENPE S.A."}, @@ -377,13 +377,13 @@ func expectHostnameError(msg string) func(*testing.T, error) { } func expectExpired(t *testing.T, err error) { - if inval, ok := err.(x509.CertificateInvalidError); !ok || inval.Reason != x509.Expired { + if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != Expired { t.Fatalf("error was not Expired: %v", err) } } func expectUsageError(t *testing.T, err error) { - if inval, ok := err.(x509.CertificateInvalidError); !ok || inval.Reason != x509.IncompatibleUsage { + if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != IncompatibleUsage { t.Fatalf("error was not IncompatibleUsage: %v", err) } } @@ -408,13 +408,13 @@ func expectHashError(t *testing.T, err error) { } func expectNameConstraintsError(t *testing.T, err error) { - if inval, ok := err.(x509.CertificateInvalidError); !ok || inval.Reason != x509.CANotAuthorizedForThisName { + if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != CANotAuthorizedForThisName { t.Fatalf("error was not a CANotAuthorizedForThisName: %v", err) } } func expectNotAuthorizedError(t *testing.T, err error) { - if inval, ok := err.(x509.CertificateInvalidError); !ok || inval.Reason != x509.NotAuthorizedToSign { + if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != NotAuthorizedToSign { t.Fatalf("error was not a NotAuthorizedToSign: %v", err) } } @@ -1721,8 +1721,8 @@ func generateCert(cn string, isCA bool, issuer *x509.Certificate, issuerKey cryp NotBefore: time.Now().Add(-1 * time.Hour), NotAfter: time.Now().Add(24 * time.Hour), - KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, + KeyUsage: KeyUsageKeyEncipherment | KeyUsageDigitalSignature | KeyUsageCertSign, + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth}, BasicConstraintsValid: true, IsCA: isCA, } @@ -1759,14 +1759,14 @@ func TestPathologicalChain(t *testing.T) { roots.AddCert(parent) for i := 1; i < 100; i++ { - parent, parentKey, err = generateCert("Intermediate CA", true, &parent.Certificate, parentKey) + parent, parentKey, err = generateCert("Intermediate CA", true, parent.asX509(), parentKey) if err != nil { t.Fatal(err) } intermediates.AddCert(parent) } - leaf, _, err := generateCert("Leaf", false, &parent.Certificate, parentKey) + leaf, _, err := generateCert("Leaf", false, parent.asX509(), parentKey) if err != nil { t.Fatal(err) } @@ -1798,14 +1798,14 @@ func TestLongChain(t *testing.T) { for i := 1; i < 15; i++ { name := fmt.Sprintf("Intermediate CA #%d", i) - parent, parentKey, err = generateCert(name, true, &parent.Certificate, parentKey) + parent, parentKey, err = generateCert(name, true, parent.asX509(), parentKey) if err != nil { t.Fatal(err) } intermediates.AddCert(parent) } - leaf, _, err := generateCert("Leaf", false, &parent.Certificate, parentKey) + leaf, _, err := generateCert("Leaf", false, parent.asX509(), parentKey) if err != nil { t.Fatal(err) } diff --git a/smx509/x509.go b/smx509/x509.go index ede626a..5a6555d 100644 --- a/smx509/x509.go +++ b/smx509/x509.go @@ -146,8 +146,10 @@ func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) { } // CertificateRequest represents a PKCS #10, certificate signature request. -type CertificateRequest struct { - x509.CertificateRequest +type CertificateRequest x509.CertificateRequest + +func (c *CertificateRequest) asX509() *x509.CertificateRequest { + return (*x509.CertificateRequest)(c) } // These structures reflect the ASN.1 structure of X.509 certificates.: @@ -191,48 +193,82 @@ type authKeyId struct { 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 { - case x509.SHA256WithRSAPSS, x509.SHA384WithRSAPSS, x509.SHA512WithRSAPSS: + case SHA256WithRSAPSS, SHA384WithRSAPSS, SHA512WithRSAPSS: return true default: return false } } +type PublicKeyAlgorithm = x509.PublicKeyAlgorithm + +const ( + UnknownPublicKeyAlgorithm = x509.UnknownPublicKeyAlgorithm + + RSA = x509.RSA + DSA = x509.DSA // Unsupported. + ECDSA = x509.ECDSA + Ed25519 = x509.Ed25519 +) + // pkcs1PublicKey reflects the ASN.1 structure of a PKCS#1 public key. type pkcs1PublicKey struct { N *big.Int E int } -const SM2WithSM3 x509.SignatureAlgorithm = 99 - var signatureAlgorithmDetails = []struct { - algo x509.SignatureAlgorithm + algo SignatureAlgorithm name string oid asn1.ObjectIdentifier - pubKeyAlgo x509.PublicKeyAlgorithm + pubKeyAlgo PublicKeyAlgorithm hash crypto.Hash }{ - {x509.MD2WithRSA, "MD2-RSA", oidSignatureMD2WithRSA, x509.RSA, crypto.Hash(0) /* no value for MD2 */}, - {x509.MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, x509.RSA, crypto.MD5}, - {x509.SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1}, - {x509.SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, x509.RSA, crypto.SHA1}, - {x509.SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256}, - {x509.SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384}, - {x509.SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512}, - {x509.SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA256}, - {x509.SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA384}, - {x509.SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA512}, - {x509.DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1}, - {x509.DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256}, - {x509.ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1}, - {x509.ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256}, - {x509.ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384}, - {x509.ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512}, - {x509.PureEd25519, "Ed25519", oidSignatureEd25519, x509.Ed25519, crypto.Hash(0) /* no pre-hashing */}, - {SM2WithSM3, "SM2-SM3", oidSignatureSM2WithSM3, x509.ECDSA, crypto.Hash(0) /* no pre-hashing */}, + {MD2WithRSA, "MD2-RSA", oidSignatureMD2WithRSA, RSA, crypto.Hash(0) /* no value for MD2 */}, + {MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, RSA, crypto.MD5}, + {SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, RSA, crypto.SHA1}, + {SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, RSA, crypto.SHA1}, + {SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, RSA, crypto.SHA256}, + {SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, RSA, crypto.SHA384}, + {SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, RSA, crypto.SHA512}, + {SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA256}, + {SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA384}, + {SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA512}, + {DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, DSA, crypto.SHA1}, + {DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, DSA, crypto.SHA256}, + {ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, ECDSA, crypto.SHA1}, + {ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, ECDSA, crypto.SHA256}, + {ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, ECDSA, crypto.SHA384}, + {ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, ECDSA, crypto.SHA512}, + {PureEd25519, "Ed25519", oidSignatureEd25519, Ed25519, crypto.Hash(0) /* no pre-hashing */}, + {SM2WithSM3, "SM2-SM3", oidSignatureSM2WithSM3, ECDSA, crypto.Hash(0) /* no pre-hashing */}, } // hashToPSSParameters contains the DER encoded RSA PSS parameters for the @@ -260,12 +296,12 @@ type pssParameters struct { 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) { // RFC 8410, Section 3 // > For all of the OIDs, the parameters MUST be absent. if len(ai.Parameters.FullBytes) != 0 { - return x509.UnknownSignatureAlgorithm + return UnknownSignatureAlgorithm } } @@ -275,7 +311,7 @@ func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) x509.SignatureAlgo return details.algo } } - return x509.UnknownSignatureAlgorithm + return UnknownSignatureAlgorithm } // RSA PSS is special because it encodes important parameters @@ -283,12 +319,12 @@ func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) x509.SignatureAlgo var params pssParameters if _, err := asn1.Unmarshal(ai.Parameters.FullBytes, ¶ms); err != nil { - return x509.UnknownSignatureAlgorithm + return UnknownSignatureAlgorithm } var mgf1HashFunc pkix.AlgorithmIdentifier 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 @@ -301,19 +337,19 @@ func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) x509.SignatureAlgo !mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) || (len(mgf1HashFunc.Parameters.FullBytes) != 0 && !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, asn1.NullBytes)) || params.TrailerField != 1 { - return x509.UnknownSignatureAlgorithm + return UnknownSignatureAlgorithm } switch { case params.Hash.Algorithm.Equal(oidSHA256) && params.SaltLength == 32: - return x509.SHA256WithRSAPSS + return SHA256WithRSAPSS case params.Hash.Algorithm.Equal(oidSHA384) && params.SaltLength == 48: - return x509.SHA384WithRSAPSS + return SHA384WithRSAPSS 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 @@ -337,18 +373,18 @@ var ( oidPublicKeyEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112} ) -func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) x509.PublicKeyAlgorithm { +func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm { switch { case oid.Equal(oidPublicKeyRSA): - return x509.RSA + return RSA case oid.Equal(oidPublicKeyDSA): - return x509.DSA + return DSA case oid.Equal(oidPublicKeyECDSA): - return x509.ECDSA + return ECDSA case oid.Equal(oidPublicKeyEd25519): - return x509.Ed25519 + return Ed25519 } - return x509.UnknownPublicKeyAlgorithm + return UnknownPublicKeyAlgorithm } // http://gmssl.org/docs/oid.html @@ -422,6 +458,22 @@ func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve { return nil } +// KeyUsage represents the set of actions that are valid for a given key. It's +// a bitmap of the KeyUsage* constants. +type KeyUsage = x509.KeyUsage + +const ( + KeyUsageDigitalSignature = x509.KeyUsageDigitalSignature + KeyUsageContentCommitment = x509.KeyUsageContentCommitment + KeyUsageKeyEncipherment = x509.KeyUsageKeyEncipherment + KeyUsageDataEncipherment = x509.KeyUsageDataEncipherment + KeyUsageKeyAgreement = x509.KeyUsageKeyAgreement + KeyUsageCertSign = x509.KeyUsageCertSign + KeyUsageCRLSign = x509.KeyUsageCRLSign + KeyUsageEncipherOnly = x509.KeyUsageEncipherOnly + KeyUsageDecipherOnly = x509.KeyUsageDecipherOnly +) + // RFC 5280, 4.2.1.12 Extended Key Usage // // anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } @@ -451,28 +503,49 @@ var ( oidExtKeyUsageMicrosoftKernelCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 61, 1, 1} ) +// ExtKeyUsage represents an extended set of actions that are valid for a given key. +// Each of the ExtKeyUsage* constants define a unique action. +type ExtKeyUsage = x509.ExtKeyUsage + +const ( + ExtKeyUsageAny = x509.ExtKeyUsageAny + ExtKeyUsageServerAuth = x509.ExtKeyUsageServerAuth + ExtKeyUsageClientAuth = x509.ExtKeyUsageClientAuth + ExtKeyUsageCodeSigning = x509.ExtKeyUsageCodeSigning + ExtKeyUsageEmailProtection = x509.ExtKeyUsageEmailProtection + ExtKeyUsageIPSECEndSystem = x509.ExtKeyUsageIPSECEndSystem + ExtKeyUsageIPSECTunnel = x509.ExtKeyUsageIPSECTunnel + ExtKeyUsageIPSECUser = x509.ExtKeyUsageIPSECUser + ExtKeyUsageTimeStamping = x509.ExtKeyUsageTimeStamping + ExtKeyUsageOCSPSigning = x509.ExtKeyUsageOCSPSigning + ExtKeyUsageMicrosoftServerGatedCrypto = x509.ExtKeyUsageMicrosoftServerGatedCrypto + ExtKeyUsageNetscapeServerGatedCrypto = x509.ExtKeyUsageNetscapeServerGatedCrypto + ExtKeyUsageMicrosoftCommercialCodeSigning = x509.ExtKeyUsageMicrosoftCommercialCodeSigning + ExtKeyUsageMicrosoftKernelCodeSigning = x509.ExtKeyUsageMicrosoftKernelCodeSigning +) + // extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID. var extKeyUsageOIDs = []struct { - extKeyUsage x509.ExtKeyUsage + extKeyUsage ExtKeyUsage oid asn1.ObjectIdentifier }{ - {x509.ExtKeyUsageAny, oidExtKeyUsageAny}, - {x509.ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth}, - {x509.ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth}, - {x509.ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning}, - {x509.ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection}, - {x509.ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem}, - {x509.ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel}, - {x509.ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser}, - {x509.ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping}, - {x509.ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning}, - {x509.ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto}, - {x509.ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto}, - {x509.ExtKeyUsageMicrosoftCommercialCodeSigning, oidExtKeyUsageMicrosoftCommercialCodeSigning}, - {x509.ExtKeyUsageMicrosoftKernelCodeSigning, oidExtKeyUsageMicrosoftKernelCodeSigning}, + {ExtKeyUsageAny, oidExtKeyUsageAny}, + {ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth}, + {ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth}, + {ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning}, + {ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection}, + {ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem}, + {ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel}, + {ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser}, + {ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping}, + {ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning}, + {ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto}, + {ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto}, + {ExtKeyUsageMicrosoftCommercialCodeSigning, oidExtKeyUsageMicrosoftCommercialCodeSigning}, + {ExtKeyUsageMicrosoftKernelCodeSigning, oidExtKeyUsageMicrosoftKernelCodeSigning}, } -func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku x509.ExtKeyUsage, ok bool) { +func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku ExtKeyUsage, ok bool) { for _, pair := range extKeyUsageOIDs { if oid.Equal(pair.oid) { return pair.extKeyUsage, true @@ -481,7 +554,7 @@ func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku x509.ExtKeyUsage, ok boo return } -func oidFromExtKeyUsage(eku x509.ExtKeyUsage) (oid asn1.ObjectIdentifier, ok bool) { +func oidFromExtKeyUsage(eku ExtKeyUsage) (oid asn1.ObjectIdentifier, ok bool) { for _, pair := range extKeyUsageOIDs { if eku == pair.extKeyUsage { return pair.oid, true @@ -491,8 +564,10 @@ func oidFromExtKeyUsage(eku x509.ExtKeyUsage) (oid asn1.ObjectIdentifier, ok boo } // A Certificate represents an X.509 certificate. -type Certificate struct { - x509.Certificate +type Certificate x509.Certificate + +func (c *Certificate) asX509() *x509.Certificate { + return (*x509.Certificate)(c) } func (c *Certificate) Equal(other *Certificate) bool { @@ -519,11 +594,11 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) error { return x509.ConstraintViolationError{} } - if parent.KeyUsage != 0 && parent.KeyUsage&x509.KeyUsageCertSign == 0 { + if parent.KeyUsage != 0 && parent.KeyUsage&KeyUsageCertSign == 0 { return x509.ConstraintViolationError{} } - if parent.PublicKeyAlgorithm == x509.UnknownPublicKeyAlgorithm { + if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm { return x509.ErrUnsupportedAlgorithm } @@ -534,7 +609,7 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) error { // CheckSignature verifies that signature is a valid signature over signed from // 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) } @@ -551,7 +626,7 @@ func (c *Certificate) getSANExtension() []byte { return nil } -func signaturePublicKeyAlgoMismatchError(expectedPubKeyAlgo x509.PublicKeyAlgorithm, pubKey interface{}) error { +func signaturePublicKeyAlgoMismatchError(expectedPubKeyAlgo PublicKeyAlgorithm, pubKey interface{}) error { return fmt.Errorf("x509: signature algorithm specifies an %s public key, but have public key of type %T", expectedPubKeyAlgo.String(), pubKey) } @@ -573,9 +648,9 @@ func verifyECDSAASN1(pub *ecdsa.PublicKey, hash, sig []byte) bool { // checkSignature verifies that signature is a valid signature over signed from // 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 pubKeyAlgo x509.PublicKeyAlgorithm + var pubKeyAlgo PublicKeyAlgorithm isSM2 := (algo == SM2WithSM3) for _, details := range signatureAlgorithmDetails { @@ -587,7 +662,7 @@ func checkSignature(algo x509.SignatureAlgorithm, signed, signature []byte, publ switch hashType { case crypto.Hash(0): - if !isSM2 && pubKeyAlgo != x509.Ed25519 { + if !isSM2 && pubKeyAlgo != Ed25519 { return x509.ErrUnsupportedAlgorithm } case crypto.MD5: @@ -603,7 +678,7 @@ func checkSignature(algo x509.SignatureAlgorithm, signed, signature []byte, publ switch pub := publicKey.(type) { case *rsa.PublicKey: - if pubKeyAlgo != x509.RSA { + if pubKeyAlgo != RSA { return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub) } if isRSAPSS(algo) { @@ -612,7 +687,7 @@ func checkSignature(algo x509.SignatureAlgorithm, signed, signature []byte, publ return rsa.VerifyPKCS1v15(pub, hashType, signed, signature) } case *ecdsa.PublicKey: - if pubKeyAlgo != x509.ECDSA { + if pubKeyAlgo != ECDSA { return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub) } if isSM2 { @@ -624,7 +699,7 @@ func checkSignature(algo x509.SignatureAlgorithm, signed, signature []byte, publ } return case ed25519.PublicKey: - if pubKeyAlgo != x509.Ed25519 { + if pubKeyAlgo != Ed25519 { return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub) } if !ed25519.Verify(pub, signed, signature) { @@ -1000,7 +1075,7 @@ func buildCertExtensions(template *x509.Certificate, subjectIsEmpty bool, author return append(ret[:n], template.ExtraExtensions...), nil } -func marshalKeyUsage(ku x509.KeyUsage) (pkix.Extension, error) { +func marshalKeyUsage(ku KeyUsage) (pkix.Extension, error) { ext := pkix.Extension{Id: oidExtensionKeyUsage, Critical: true} var a [2]byte @@ -1021,7 +1096,7 @@ func marshalKeyUsage(ku x509.KeyUsage) (pkix.Extension, error) { return ext, nil } -func marshalExtKeyUsage(extUsages []x509.ExtKeyUsage, unknownUsages []asn1.ObjectIdentifier) (pkix.Extension, error) { +func marshalExtKeyUsage(extUsages []ExtKeyUsage, unknownUsages []asn1.ObjectIdentifier) (pkix.Extension, error) { ext := pkix.Extension{Id: oidExtensionExtendedKeyUsage} oids := make([]asn1.ObjectIdentifier, len(extUsages)+len(unknownUsages)) @@ -1103,18 +1178,18 @@ func subjectBytes(cert *x509.Certificate) ([]byte, error) { // signingParamsForPublicKey returns the parameters to use for signing with // priv. If requestedSigAlgo is not zero then it overrides the default // signature algorithm. -func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) { - var pubType x509.PublicKeyAlgorithm +func signingParamsForPublicKey(pub interface{}, requestedSigAlgo SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) { + var pubType PublicKeyAlgorithm switch pub := pub.(type) { case *rsa.PublicKey: - pubType = x509.RSA + pubType = RSA hashFunc = crypto.SHA256 sigAlgo.Algorithm = oidSignatureSHA256WithRSA sigAlgo.Parameters = asn1.NullRawValue case *ecdsa.PublicKey: - pubType = x509.ECDSA + pubType = ECDSA switch pub.Curve { case elliptic.P224(), elliptic.P256(): @@ -1134,7 +1209,7 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureA } case ed25519.PublicKey: - pubType = x509.Ed25519 + pubType = Ed25519 sigAlgo.Algorithm = oidSignatureEd25519 default: @@ -1157,7 +1232,7 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureA return } sigAlgo.Algorithm, hashFunc = details.oid, details.hash - if hashFunc == 0 && pubType != x509.Ed25519 && !sigAlgo.Algorithm.Equal(oidSignatureSM2WithSM3) { + if hashFunc == 0 && pubType != Ed25519 && !sigAlgo.Algorithm.Equal(oidSignatureSM2WithSM3) { err = errors.New("x509: cannot sign with hash function requested") return } @@ -1347,7 +1422,7 @@ func CreateCertificate(rand io.Reader, template, parent *x509.Certificate, pub, // Check the signature to ensure the crypto.Signer behaved correctly. sigAlg := getSignatureAlgorithmFromAI(signatureAlgorithm) 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 // signing, not verification. default: @@ -1719,7 +1794,7 @@ func ParseCertificateRequest(asn1Data []byte) (*CertificateRequest, error) { if err != nil { return nil, err } - return &CertificateRequest{*csrR}, nil + return (*CertificateRequest)(csrR), nil } return parseCertificateRequest(&csr) } @@ -1738,7 +1813,7 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error if !oidSignatureSM2WithSM3.Equal(in.SignatureAlgorithm.Algorithm) { return nil, errors.New("unsupport signature algorithm") } - out := &CertificateRequest{x509.CertificateRequest{ + out := &CertificateRequest{ Raw: in.Raw, RawTBSCertificateRequest: in.TBSCSR.Raw, RawSubjectPublicKeyInfo: in.TBSCSR.PublicKey.Raw, @@ -1751,7 +1826,6 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error Version: in.TBSCSR.Version, Attributes: parseRawAttributes(in.TBSCSR.RawAttributes), - }, } var err error @@ -1809,7 +1883,7 @@ func CreateRevocationList(rand io.Reader, template *x509.RevocationList, issuer if issuer == nil { return nil, errors.New("x509: issuer can not be nil") } - if (issuer.KeyUsage & x509.KeyUsageCRLSign) == 0 { + if (issuer.KeyUsage & KeyUsageCRLSign) == 0 { return nil, errors.New("x509: issuer must have the crlSign key usage bit set") } if len(issuer.SubjectKeyId) == 0 { diff --git a/smx509/x509_test.go b/smx509/x509_test.go index 3f4c790..cc49cfe 100644 --- a/smx509/x509_test.go +++ b/smx509/x509_test.go @@ -354,14 +354,14 @@ func Test_CreateCertificateRequest(t *testing.T) { tests := []struct { name string priv interface{} - sigAlgo x509.SignatureAlgorithm + sigAlgo SignatureAlgorithm }{ - {"RSA", testPrivateKey, x509.SHA1WithRSA}, + {"RSA", testPrivateKey, SHA1WithRSA}, {"SM2-256", sm2Priv, SM2WithSM3}, - {"ECDSA-256", ecdsa256Priv, x509.ECDSAWithSHA1}, - {"ECDSA-384", ecdsa384Priv, x509.ECDSAWithSHA1}, - {"ECDSA-521", ecdsa521Priv, x509.ECDSAWithSHA1}, - {"Ed25519", ed25519Priv, x509.PureEd25519}, + {"ECDSA-256", ecdsa256Priv, ECDSAWithSHA1}, + {"ECDSA-384", ecdsa384Priv, ECDSAWithSHA1}, + {"ECDSA-521", ecdsa521Priv, ECDSAWithSHA1}, + {"Ed25519", ed25519Priv, PureEd25519}, } for _, test := range tests { @@ -446,24 +446,24 @@ func TestCreateSelfSignedCertificate(t *testing.T) { name string pub, priv interface{} checkSig bool - sigAlgo x509.SignatureAlgorithm + sigAlgo SignatureAlgorithm }{ - {"RSA/RSA", &testPrivateKey.PublicKey, testPrivateKey, true, x509.SHA1WithRSA}, - {"RSA/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, x509.ECDSAWithSHA384}, + {"RSA/RSA", &testPrivateKey.PublicKey, testPrivateKey, true, SHA1WithRSA}, + {"RSA/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384}, {"RSA/SM2", &testPrivateKey.PublicKey, sm2Priv, false, SM2WithSM3}, - {"ECDSA/RSA", &ecdsaPriv.PublicKey, testPrivateKey, false, x509.SHA256WithRSA}, - {"ECDSA/ECDSA", &ecdsaPriv.PublicKey, ecdsaPriv, true, x509.ECDSAWithSHA1}, + {"ECDSA/RSA", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSA}, + {"ECDSA/ECDSA", &ecdsaPriv.PublicKey, ecdsaPriv, true, ECDSAWithSHA1}, {"ECDSA/SM2", &ecdsaPriv.PublicKey, sm2Priv, false, SM2WithSM3}, - {"SM2/ECDSA", &sm2Priv.PublicKey, ecdsaPriv, false, x509.ECDSAWithSHA1}, - {"RSAPSS/RSAPSS", &testPrivateKey.PublicKey, testPrivateKey, true, x509.SHA256WithRSAPSS}, - {"ECDSA/RSAPSS", &ecdsaPriv.PublicKey, testPrivateKey, false, x509.SHA256WithRSAPSS}, - {"SM2/RSAPSS", &sm2Priv.PublicKey, testPrivateKey, false, x509.SHA256WithRSAPSS}, - {"RSAPSS/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, x509.ECDSAWithSHA384}, - {"Ed25519", ed25519Pub, ed25519Priv, true, x509.PureEd25519}, + {"SM2/ECDSA", &sm2Priv.PublicKey, ecdsaPriv, false, ECDSAWithSHA1}, + {"RSAPSS/RSAPSS", &testPrivateKey.PublicKey, testPrivateKey, true, SHA256WithRSAPSS}, + {"ECDSA/RSAPSS", &ecdsaPriv.PublicKey, testPrivateKey, false, SHA256WithRSAPSS}, + {"SM2/RSAPSS", &sm2Priv.PublicKey, testPrivateKey, false, SHA256WithRSAPSS}, + {"RSAPSS/ECDSA", &testPrivateKey.PublicKey, ecdsaPriv, false, ECDSAWithSHA384}, + {"Ed25519", ed25519Pub, ed25519Priv, true, PureEd25519}, {"SM2", &sm2Priv.PublicKey, sm2Priv, true, SM2WithSM3}, } - testExtKeyUsage := []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth} + testExtKeyUsage := []ExtKeyUsage{ExtKeyUsageClientAuth, ExtKeyUsageServerAuth} testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}} extraExtensionData := []byte("extra extension") @@ -497,7 +497,7 @@ func TestCreateSelfSignedCertificate(t *testing.T) { SignatureAlgorithm: test.sigAlgo, SubjectKeyId: []byte{1, 2, 3, 4}, - KeyUsage: x509.KeyUsageCertSign, + KeyUsage: KeyUsageCertSign, ExtKeyUsage: testExtKeyUsage, UnknownExtKeyUsage: testUnknownExtKeyUsage, @@ -1181,7 +1181,7 @@ func TestCreateRevocationList(t *testing.T) { name: "issuer doesn't have crlSign key usage bit set", key: sm2Priv, issuer: &x509.Certificate{ - KeyUsage: x509.KeyUsageCertSign, + KeyUsage: KeyUsageCertSign, }, template: &x509.RevocationList{}, expectedError: "x509: issuer must have the crlSign key usage bit set", @@ -1190,7 +1190,7 @@ func TestCreateRevocationList(t *testing.T) { name: "issuer missing SubjectKeyId", key: sm2Priv, issuer: &x509.Certificate{ - KeyUsage: x509.KeyUsageCRLSign, + KeyUsage: KeyUsageCRLSign, }, template: &x509.RevocationList{}, expectedError: "x509: issuer certificate doesn't contain a subject key identifier", @@ -1199,7 +1199,7 @@ func TestCreateRevocationList(t *testing.T) { name: "nextUpdate before thisUpdate", key: sm2Priv, issuer: &x509.Certificate{ - KeyUsage: x509.KeyUsageCRLSign, + KeyUsage: KeyUsageCRLSign, Subject: pkix.Name{ CommonName: "testing", }, @@ -1215,7 +1215,7 @@ func TestCreateRevocationList(t *testing.T) { name: "nil Number", key: sm2Priv, issuer: &x509.Certificate{ - KeyUsage: x509.KeyUsageCRLSign, + KeyUsage: KeyUsageCRLSign, Subject: pkix.Name{ CommonName: "testing", }, @@ -1231,14 +1231,14 @@ func TestCreateRevocationList(t *testing.T) { name: "invalid signature algorithm", key: sm2Priv, issuer: &x509.Certificate{ - KeyUsage: x509.KeyUsageCRLSign, + KeyUsage: KeyUsageCRLSign, Subject: pkix.Name{ CommonName: "testing", }, SubjectKeyId: []byte{1, 2, 3}, }, template: &x509.RevocationList{ - SignatureAlgorithm: x509.SHA256WithRSA, + SignatureAlgorithm: SHA256WithRSA, RevokedCertificates: []pkix.RevokedCertificate{ { SerialNumber: big.NewInt(2), @@ -1255,7 +1255,7 @@ func TestCreateRevocationList(t *testing.T) { name: "valid", key: sm2Priv, issuer: &x509.Certificate{ - KeyUsage: x509.KeyUsageCRLSign, + KeyUsage: KeyUsageCRLSign, Subject: pkix.Name{ CommonName: "testing", }, @@ -1277,7 +1277,7 @@ func TestCreateRevocationList(t *testing.T) { name: "valid, Ed25519 key", key: ed25519Priv, issuer: &x509.Certificate{ - KeyUsage: x509.KeyUsageCRLSign, + KeyUsage: KeyUsageCRLSign, Subject: pkix.Name{ CommonName: "testing", }, @@ -1299,14 +1299,14 @@ func TestCreateRevocationList(t *testing.T) { name: "valid, non-default signature algorithm", key: sm2Priv, issuer: &x509.Certificate{ - KeyUsage: x509.KeyUsageCRLSign, + KeyUsage: KeyUsageCRLSign, Subject: pkix.Name{ CommonName: "testing", }, SubjectKeyId: []byte{1, 2, 3}, }, template: &x509.RevocationList{ - SignatureAlgorithm: x509.ECDSAWithSHA512, + SignatureAlgorithm: ECDSAWithSHA512, RevokedCertificates: []pkix.RevokedCertificate{ { SerialNumber: big.NewInt(2), @@ -1322,7 +1322,7 @@ func TestCreateRevocationList(t *testing.T) { name: "valid, extra extension", key: sm2Priv, issuer: &x509.Certificate{ - KeyUsage: x509.KeyUsageCRLSign, + KeyUsage: KeyUsageCRLSign, Subject: pkix.Name{ CommonName: "testing", }, @@ -1350,7 +1350,7 @@ func TestCreateRevocationList(t *testing.T) { name: "valid, empty list", key: sm2Priv, issuer: &x509.Certificate{ - KeyUsage: x509.KeyUsageCRLSign, + KeyUsage: KeyUsageCRLSign, Subject: pkix.Name{ CommonName: "testing", }, @@ -1368,7 +1368,7 @@ func TestCreateRevocationList(t *testing.T) { t.Run(tc.name, func(t *testing.T) { var issuer *Certificate if tc.issuer != nil { - issuer = &Certificate{*tc.issuer} + issuer = (*Certificate)(tc.issuer) } crl, err := CreateRevocationList(rand.Reader, tc.template, issuer, tc.key) if err != nil && tc.expectedError == "" { @@ -1387,7 +1387,7 @@ func TestCreateRevocationList(t *testing.T) { 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) { t.Fatalf("SignatureAlgorithm mismatch: got %v; want %v.", parsedCRL.SignatureAlgorithm, tc.template.SignatureAlgorithm) @@ -1654,7 +1654,7 @@ func TestUnknownExtKey(t *testing.T) { template := &x509.Certificate{ SerialNumber: big.NewInt(10), DNSNames: []string{"foo"}, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsage(-1)}, + ExtKeyUsage: []ExtKeyUsage{ExtKeyUsage(-1)}, } signer, err := rsa.GenerateKey(rand.Reader, 1024) if err != nil { @@ -2095,7 +2095,7 @@ func TestISOOIDInCertificate(t *testing.T) { block, _ := pem.Decode([]byte(certISOOID)) if cert, err := ParseCertificate(block.Bytes); err != nil { 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") } }