Merge pull request #15 from easyops-cn/polish

Alias x509 types
This commit is contained in:
Sun Yimin 2022-01-20 18:50:26 +08:00 committed by GitHub
commit 1e51a02c60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 267 additions and 179 deletions

View File

@ -7,7 +7,6 @@ import (
"crypto/ed25519" "crypto/ed25519"
"crypto/elliptic" "crypto/elliptic"
"crypto/rsa" "crypto/rsa"
"crypto/x509"
"crypto/x509/pkix" "crypto/x509/pkix"
"encoding/asn1" "encoding/asn1"
"encoding/pem" "encoding/pem"
@ -228,10 +227,10 @@ func parseExtension(der cryptobyte.String) (pkix.Extension, error) {
return ext, nil 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()) der := cryptobyte.String(keyData.PublicKey.RightAlign())
switch algo { switch algo {
case x509.RSA: case RSA:
// RSA public keys must have a NULL in the parameters. // RSA public keys must have a NULL in the parameters.
// See RFC 3279, Section 2.3.1. // See RFC 3279, Section 2.3.1.
if !bytes.Equal(keyData.Algorithm.Parameters.FullBytes, asn1.NullBytes) { if !bytes.Equal(keyData.Algorithm.Parameters.FullBytes, asn1.NullBytes) {
@ -261,7 +260,7 @@ func parsePublicKey(algo x509.PublicKeyAlgorithm, keyData *publicKeyInfo) (inter
N: p.N, N: p.N,
} }
return pub, nil return pub, nil
case x509.ECDSA: case ECDSA:
paramsDer := cryptobyte.String(keyData.Algorithm.Parameters.FullBytes) paramsDer := cryptobyte.String(keyData.Algorithm.Parameters.FullBytes)
namedCurveOID := new(asn1.ObjectIdentifier) namedCurveOID := new(asn1.ObjectIdentifier)
if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) { if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) {
@ -281,7 +280,7 @@ func parsePublicKey(algo x509.PublicKeyAlgorithm, keyData *publicKeyInfo) (inter
Y: y, Y: y,
} }
return pub, nil return pub, nil
case x509.Ed25519: case Ed25519:
// 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(keyData.Algorithm.Parameters.FullBytes) != 0 { 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 nil, errors.New("x509: wrong Ed25519 public key size")
} }
return ed25519.PublicKey(der), nil return ed25519.PublicKey(der), nil
case x509.DSA: case DSA:
y := new(big.Int) y := new(big.Int)
if !der.ReadASN1Integer(y) { if !der.ReadASN1Integer(y) {
return nil, errors.New("x509: invalid DSA public key") 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 var usageBits asn1.BitString
if !der.ReadASN1BitString(&usageBits) { if !der.ReadASN1BitString(&usageBits) {
return 0, errors.New("x509: invalid key usage") return 0, errors.New("x509: invalid key usage")
@ -333,7 +332,7 @@ func parseKeyUsageExtension(der cryptobyte.String) (x509.KeyUsage, error) {
usage |= 1 << uint(i) usage |= 1 << uint(i)
} }
} }
return x509.KeyUsage(usage), nil return KeyUsage(usage), nil
} }
func parseBasicConstraintsExtension(der cryptobyte.String) (bool, int, error) { func parseBasicConstraintsExtension(der cryptobyte.String) (bool, int, error) {
@ -420,8 +419,8 @@ func parseSANExtension(der cryptobyte.String) (dnsNames, emailAddresses []string
return return
} }
func parseExtKeyUsageExtension(der cryptobyte.String) ([]x509.ExtKeyUsage, []asn1.ObjectIdentifier, error) { func parseExtKeyUsageExtension(der cryptobyte.String) ([]ExtKeyUsage, []asn1.ObjectIdentifier, error) {
var extKeyUsages []x509.ExtKeyUsage var extKeyUsages []ExtKeyUsage
var unknownUsages []asn1.ObjectIdentifier var unknownUsages []asn1.ObjectIdentifier
if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) { if !der.ReadASN1(&der, cryptobyte_asn1.SEQUENCE) {
return nil, nil, errors.New("x509: invalid extended key usages") return nil, nil, errors.New("x509: invalid extended key usages")

View File

@ -92,9 +92,9 @@ func checkChainTrustStatus(c *Certificate, chainCtx *syscall.CertChainContext) e
status := chainCtx.TrustStatus.ErrorStatus status := chainCtx.TrustStatus.ErrorStatus
switch status { switch status {
case syscall.CERT_TRUST_IS_NOT_TIME_VALID: 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: 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. // TODO(filippo): surface more error statuses.
default: default:
return UnknownAuthorityError{c, nil, nil} return UnknownAuthorityError{c, nil, nil}
@ -133,9 +133,9 @@ func checkChainSSLServerPolicy(c *Certificate, chainCtx *syscall.CertChainContex
if status.Error != 0 { if status.Error != 0 {
switch status.Error { switch status.Error {
case syscall.CERT_E_EXPIRED: 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: 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: case syscall.CERT_E_UNTRUSTEDROOT:
return UnknownAuthorityError{c, nil, nil} return UnknownAuthorityError{c, nil, nil}
default: default:
@ -148,7 +148,7 @@ func checkChainSSLServerPolicy(c *Certificate, chainCtx *syscall.CertChainContex
// windowsExtKeyUsageOIDs are the C NUL-terminated string representations of the // windowsExtKeyUsageOIDs are the C NUL-terminated string representations of the
// OIDs for use with the Windows API. // 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() { func init() {
for _, eku := range extKeyUsageOIDs { 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 // using spoofed parameters, the signature will be invalid for the correct
// ones we parsed. (We don't support custom curves ourselves.) // ones we parsed. (We don't support custom curves ourselves.)
for i, parent := range chain[1:] { for i, parent := range chain[1:] {
if parent.PublicKeyAlgorithm != x509.ECDSA { if parent.PublicKeyAlgorithm != ECDSA {
continue continue
} }
if err := parent.CheckSignature(chain[i].SignatureAlgorithm, if err := parent.CheckSignature(chain[i].SignatureAlgorithm,
@ -208,11 +208,11 @@ func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate
keyUsages := opts.KeyUsages keyUsages := opts.KeyUsages
if len(keyUsages) == 0 { if len(keyUsages) == 0 {
keyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth} keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
} }
oids := make([]*byte, 0, len(keyUsages)) oids := make([]*byte, 0, len(keyUsages))
for _, eku := range keyUsages { for _, eku := range keyUsages {
if eku == x509.ExtKeyUsageAny { if eku == ExtKeyUsageAny {
oids = nil oids = nil
break break
} }

View File

@ -14,6 +14,21 @@ import (
"unicode/utf8" "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 // UnknownAuthorityError results when the certificate issuer is unknown
type UnknownAuthorityError struct { type UnknownAuthorityError struct {
Cert *Certificate Cert *Certificate
@ -66,7 +81,7 @@ type VerifyOptions struct {
// KeyUsages specifies which Extended Key Usage values are acceptable. A // KeyUsages specifies which Extended Key Usage values are acceptable. A
// chain is accepted if it allows any of the listed values. An empty list // chain is accepted if it allows any of the listed values. An empty list
// means ExtKeyUsageServerAuth. To accept any key usage, include ExtKeyUsageAny. // means ExtKeyUsageServerAuth. To accept any key usage, include ExtKeyUsageAny.
KeyUsages []x509.ExtKeyUsage KeyUsages []ExtKeyUsage
// MaxConstraintComparisions is the maximum number of comparisons to // MaxConstraintComparisions is the maximum number of comparisons to
// perform when checking a given certificate's name constraints. If // perform when checking a given certificate's name constraints. If
@ -246,18 +261,18 @@ func (c *Certificate) checkNameConstraints(count *int,
*count += excludedValue.Len() *count += excludedValue.Len()
if *count > maxConstraintComparisons { if *count > maxConstraintComparisons {
return x509.CertificateInvalidError{&c.Certificate, x509.TooManyConstraints, ""} return CertificateInvalidError{c.asX509(), TooManyConstraints, ""}
} }
for i := 0; i < excludedValue.Len(); i++ { for i := 0; i < excludedValue.Len(); i++ {
constraint := excludedValue.Index(i).Interface() constraint := excludedValue.Index(i).Interface()
match, err := match(parsedName, constraint) match, err := match(parsedName, constraint)
if err != nil { if err != nil {
return x509.CertificateInvalidError{&c.Certificate, x509.CANotAuthorizedForThisName, err.Error()} return CertificateInvalidError{c.asX509(), CANotAuthorizedForThisName, err.Error()}
} }
if match { 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() *count += permittedValue.Len()
if *count > maxConstraintComparisons { if *count > maxConstraintComparisons {
return x509.CertificateInvalidError{&c.Certificate, x509.TooManyConstraints, ""} return CertificateInvalidError{c.asX509(), TooManyConstraints, ""}
} }
ok := true ok := true
@ -274,7 +289,7 @@ func (c *Certificate) checkNameConstraints(count *int,
var err error var err error
if ok, err = match(parsedName, constraint); err != nil { 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 { if ok {
@ -283,7 +298,7 @@ func (c *Certificate) checkNameConstraints(count *int,
} }
if !ok { 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 return nil
@ -334,7 +349,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
if len(currentChain) > 0 { if len(currentChain) > 0 {
child := currentChain[len(currentChain)-1] child := currentChain[len(currentChain)-1]
if !bytes.Equal(child.RawIssuer, c.RawSubject) { 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() now = time.Now()
} }
if now.Before(c.NotBefore) { if now.Before(c.NotBefore) {
return x509.CertificateInvalidError{ return CertificateInvalidError{
Cert: &c.Certificate, Cert: c.asX509(),
Reason: x509.Expired, Reason: Expired,
Detail: fmt.Sprintf("current time %s is before %s", now.Format(time.RFC3339), c.NotBefore.Format(time.RFC3339)), Detail: fmt.Sprintf("current time %s is before %s", now.Format(time.RFC3339), c.NotBefore.Format(time.RFC3339)),
} }
} else if now.After(c.NotAfter) { } else if now.After(c.NotAfter) {
return x509.CertificateInvalidError{ return CertificateInvalidError{
Cert: &c.Certificate, Cert: c.asX509(),
Reason: x509.Expired, Reason: Expired,
Detail: fmt.Sprintf("current time %s is after %s", now.Format(time.RFC3339), c.NotAfter.Format(time.RFC3339)), 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. // encryption key could only be used for Diffie-Hellman key agreement.
if certType == intermediateCertificate && (!c.BasicConstraintsValid || !c.IsCA) { 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 { if c.BasicConstraintsValid && c.MaxPathLen >= 0 {
numIntermediates := len(currentChain) - 1 numIntermediates := len(currentChain) - 1
if numIntermediates > c.MaxPathLen { 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 keyUsages := opts.KeyUsages
if len(keyUsages) == 0 { if len(keyUsages) == 0 {
keyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth} keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
} }
// If any key usage is acceptable then we're done. // If any key usage is acceptable then we're done.
for _, usage := range keyUsages { for _, usage := range keyUsages {
if usage == x509.ExtKeyUsageAny { if usage == ExtKeyUsageAny {
return candidateChains, nil return candidateChains, nil
} }
} }
@ -571,7 +586,7 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e
} }
if len(chains) == 0 { if len(chains) == 0 {
return nil, x509.CertificateInvalidError{&c.Certificate, x509.IncompatibleUsage, ""} return nil, CertificateInvalidError{c.asX509(), IncompatibleUsage, ""}
} }
return chains, nil return chains, nil
@ -798,7 +813,7 @@ func (c *Certificate) VerifyHostname(h string) error {
return nil return nil
} }
} }
return x509.HostnameError{&c.Certificate, candidateIP} return x509.HostnameError{c.asX509(), candidateIP}
} }
candidateName := toLowerCaseASCII(h) // Save allocations inside the loop. 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 { func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool {
usages := make([]x509.ExtKeyUsage, len(keyUsages)) usages := make([]ExtKeyUsage, len(keyUsages))
copy(usages, keyUsages) copy(usages, keyUsages)
if len(chain) == 0 { if len(chain) == 0 {
@ -846,13 +861,13 @@ NextCert:
} }
for _, usage := range cert.ExtKeyUsage { for _, usage := range cert.ExtKeyUsage {
if usage == x509.ExtKeyUsageAny { if usage == ExtKeyUsageAny {
// The certificate is explicitly good for any usage. // The certificate is explicitly good for any usage.
continue NextCert continue NextCert
} }
} }
const invalidUsage x509.ExtKeyUsage = -1 const invalidUsage ExtKeyUsage = -1
NextRequestedUsage: NextRequestedUsage:
for i, requestedUsage := range usages { for i, requestedUsage := range usages {
@ -863,9 +878,9 @@ NextCert:
for _, usage := range cert.ExtKeyUsage { for _, usage := range cert.ExtKeyUsage {
if requestedUsage == usage { if requestedUsage == usage {
continue NextRequestedUsage continue NextRequestedUsage
} else if requestedUsage == x509.ExtKeyUsageServerAuth && } else if requestedUsage == ExtKeyUsageServerAuth &&
(usage == x509.ExtKeyUsageNetscapeServerGatedCrypto || (usage == ExtKeyUsageNetscapeServerGatedCrypto ||
usage == x509.ExtKeyUsageMicrosoftServerGatedCrypto) { usage == ExtKeyUsageMicrosoftServerGatedCrypto) {
// In order to support COMODO // In order to support COMODO
// certificate chains, we have to // certificate chains, we have to
// accept Netscape or Microsoft SGC // accept Netscape or Microsoft SGC

View File

@ -26,7 +26,7 @@ type verifyTest struct {
dnsName string dnsName string
systemSkip bool systemSkip bool
systemLax bool systemLax bool
keyUsages []x509.ExtKeyUsage keyUsages []ExtKeyUsage
errorCallback func(*testing.T, error) errorCallback func(*testing.T, error)
expectedChains [][]string expectedChains [][]string
@ -135,7 +135,7 @@ var verifyTests = []verifyTest{
intermediates: []string{startComIntermediate}, intermediates: []string{startComIntermediate},
roots: []string{startComRoot}, roots: []string{startComRoot},
currentTime: 1302726541, currentTime: 1302726541,
keyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny}, keyUsages: []ExtKeyUsage{ExtKeyUsageAny},
expectedChains: [][]string{ expectedChains: [][]string{
{"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"}, {"dnssec-exp", "StartCom Class 1", "StartCom Certification Authority"},
@ -184,7 +184,7 @@ var verifyTests = []verifyTest{
intermediates: []string{smimeIntermediate}, intermediates: []string{smimeIntermediate},
roots: []string{smimeRoot}, roots: []string{smimeRoot},
currentTime: 1594673418, currentTime: 1594673418,
keyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, keyUsages: []ExtKeyUsage{ExtKeyUsageServerAuth},
errorCallback: expectUsageError, errorCallback: expectUsageError,
}, },
@ -194,7 +194,7 @@ var verifyTests = []verifyTest{
intermediates: []string{smimeIntermediate}, intermediates: []string{smimeIntermediate},
roots: []string{smimeRoot}, roots: []string{smimeRoot},
currentTime: 1594673418, currentTime: 1594673418,
keyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageEmailProtection}, keyUsages: []ExtKeyUsage{ExtKeyUsageEmailProtection},
expectedChains: [][]string{ expectedChains: [][]string{
{"CORPORATIVO FICTICIO ACTIVO", "EAEko Herri Administrazioen CA - CA AAPP Vascas (2)", "IZENPE S.A."}, {"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) { 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) t.Fatalf("error was not Expired: %v", err)
} }
} }
func expectUsageError(t *testing.T, err error) { 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) 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) { 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) t.Fatalf("error was not a CANotAuthorizedForThisName: %v", err)
} }
} }
func expectNotAuthorizedError(t *testing.T, err error) { 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) 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), NotBefore: time.Now().Add(-1 * time.Hour),
NotAfter: time.Now().Add(24 * time.Hour), NotAfter: time.Now().Add(24 * time.Hour),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, KeyUsage: KeyUsageKeyEncipherment | KeyUsageDigitalSignature | KeyUsageCertSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth},
BasicConstraintsValid: true, BasicConstraintsValid: true,
IsCA: isCA, IsCA: isCA,
} }
@ -1759,14 +1759,14 @@ func TestPathologicalChain(t *testing.T) {
roots.AddCert(parent) roots.AddCert(parent)
for i := 1; i < 100; i++ { 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 { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
intermediates.AddCert(parent) intermediates.AddCert(parent)
} }
leaf, _, err := generateCert("Leaf", false, &parent.Certificate, parentKey) leaf, _, err := generateCert("Leaf", false, parent.asX509(), parentKey)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -1798,14 +1798,14 @@ func TestLongChain(t *testing.T) {
for i := 1; i < 15; i++ { for i := 1; i < 15; i++ {
name := fmt.Sprintf("Intermediate CA #%d", 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 { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
intermediates.AddCert(parent) intermediates.AddCert(parent)
} }
leaf, _, err := generateCert("Leaf", false, &parent.Certificate, parentKey) leaf, _, err := generateCert("Leaf", false, parent.asX509(), parentKey)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }

View File

@ -146,8 +146,10 @@ func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) {
} }
// CertificateRequest represents a PKCS #10, certificate signature request. // CertificateRequest represents a PKCS #10, certificate signature request.
type CertificateRequest struct { type CertificateRequest x509.CertificateRequest
x509.CertificateRequest
func (c *CertificateRequest) asX509() *x509.CertificateRequest {
return (*x509.CertificateRequest)(c)
} }
// These structures reflect the ASN.1 structure of X.509 certificates.: // These structures reflect the ASN.1 structure of X.509 certificates.:
@ -191,48 +193,82 @@ 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
} }
} }
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. // pkcs1PublicKey reflects the ASN.1 structure of a PKCS#1 public key.
type pkcs1PublicKey struct { type pkcs1PublicKey struct {
N *big.Int N *big.Int
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 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, RSA, crypto.Hash(0) /* no value for MD2 */},
{x509.MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, x509.RSA, crypto.MD5}, {MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, RSA, crypto.MD5},
{x509.SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, x509.RSA, crypto.SHA1}, {SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, RSA, crypto.SHA1},
{x509.SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, x509.RSA, crypto.SHA1}, {SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, RSA, crypto.SHA1},
{x509.SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, x509.RSA, crypto.SHA256}, {SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, RSA, crypto.SHA256},
{x509.SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, x509.RSA, crypto.SHA384}, {SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, RSA, crypto.SHA384},
{x509.SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, x509.RSA, crypto.SHA512}, {SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, RSA, crypto.SHA512},
{x509.SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA256}, {SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA256},
{x509.SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA384}, {SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA384},
{x509.SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, x509.RSA, crypto.SHA512}, {SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA512},
{x509.DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, x509.DSA, crypto.SHA1}, {DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, DSA, crypto.SHA1},
{x509.DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, x509.DSA, crypto.SHA256}, {DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, DSA, crypto.SHA256},
{x509.ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, x509.ECDSA, crypto.SHA1}, {ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, ECDSA, crypto.SHA1},
{x509.ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, x509.ECDSA, crypto.SHA256}, {ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, ECDSA, crypto.SHA256},
{x509.ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, x509.ECDSA, crypto.SHA384}, {ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, ECDSA, crypto.SHA384},
{x509.ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, x509.ECDSA, crypto.SHA512}, {ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, ECDSA, crypto.SHA512},
{x509.PureEd25519, "Ed25519", oidSignatureEd25519, x509.Ed25519, crypto.Hash(0) /* no pre-hashing */}, {PureEd25519, "Ed25519", oidSignatureEd25519, Ed25519, crypto.Hash(0) /* no pre-hashing */},
{SM2WithSM3, "SM2-SM3", oidSignatureSM2WithSM3, x509.ECDSA, 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 // 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"` 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 +311,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 +319,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 +337,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
@ -337,18 +373,18 @@ var (
oidPublicKeyEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112} oidPublicKeyEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
) )
func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) x509.PublicKeyAlgorithm { func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm {
switch { switch {
case oid.Equal(oidPublicKeyRSA): case oid.Equal(oidPublicKeyRSA):
return x509.RSA return RSA
case oid.Equal(oidPublicKeyDSA): case oid.Equal(oidPublicKeyDSA):
return x509.DSA return DSA
case oid.Equal(oidPublicKeyECDSA): case oid.Equal(oidPublicKeyECDSA):
return x509.ECDSA return ECDSA
case oid.Equal(oidPublicKeyEd25519): case oid.Equal(oidPublicKeyEd25519):
return x509.Ed25519 return Ed25519
} }
return x509.UnknownPublicKeyAlgorithm return UnknownPublicKeyAlgorithm
} }
// http://gmssl.org/docs/oid.html // http://gmssl.org/docs/oid.html
@ -422,6 +458,22 @@ func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
return nil 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 // RFC 5280, 4.2.1.12 Extended Key Usage
// //
// anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } // 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} 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. // extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID.
var extKeyUsageOIDs = []struct { var extKeyUsageOIDs = []struct {
extKeyUsage x509.ExtKeyUsage extKeyUsage ExtKeyUsage
oid asn1.ObjectIdentifier oid asn1.ObjectIdentifier
}{ }{
{x509.ExtKeyUsageAny, oidExtKeyUsageAny}, {ExtKeyUsageAny, oidExtKeyUsageAny},
{x509.ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth}, {ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth},
{x509.ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth}, {ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth},
{x509.ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning}, {ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning},
{x509.ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection}, {ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection},
{x509.ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem}, {ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem},
{x509.ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel}, {ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel},
{x509.ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser}, {ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser},
{x509.ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping}, {ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping},
{x509.ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning}, {ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning},
{x509.ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto}, {ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto},
{x509.ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto}, {ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto},
{x509.ExtKeyUsageMicrosoftCommercialCodeSigning, oidExtKeyUsageMicrosoftCommercialCodeSigning}, {ExtKeyUsageMicrosoftCommercialCodeSigning, oidExtKeyUsageMicrosoftCommercialCodeSigning},
{x509.ExtKeyUsageMicrosoftKernelCodeSigning, oidExtKeyUsageMicrosoftKernelCodeSigning}, {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 { for _, pair := range extKeyUsageOIDs {
if oid.Equal(pair.oid) { if oid.Equal(pair.oid) {
return pair.extKeyUsage, true return pair.extKeyUsage, true
@ -481,7 +554,7 @@ func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku x509.ExtKeyUsage, ok boo
return return
} }
func oidFromExtKeyUsage(eku x509.ExtKeyUsage) (oid asn1.ObjectIdentifier, ok bool) { func oidFromExtKeyUsage(eku ExtKeyUsage) (oid asn1.ObjectIdentifier, ok bool) {
for _, pair := range extKeyUsageOIDs { for _, pair := range extKeyUsageOIDs {
if eku == pair.extKeyUsage { if eku == pair.extKeyUsage {
return pair.oid, true 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. // A Certificate represents an X.509 certificate.
type Certificate struct { type Certificate x509.Certificate
x509.Certificate
func (c *Certificate) asX509() *x509.Certificate {
return (*x509.Certificate)(c)
} }
func (c *Certificate) Equal(other *Certificate) bool { func (c *Certificate) Equal(other *Certificate) bool {
@ -519,11 +594,11 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {
return x509.ConstraintViolationError{} return x509.ConstraintViolationError{}
} }
if parent.KeyUsage != 0 && parent.KeyUsage&x509.KeyUsageCertSign == 0 { if parent.KeyUsage != 0 && parent.KeyUsage&KeyUsageCertSign == 0 {
return x509.ConstraintViolationError{} return x509.ConstraintViolationError{}
} }
if parent.PublicKeyAlgorithm == x509.UnknownPublicKeyAlgorithm { if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {
return x509.ErrUnsupportedAlgorithm 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 // 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)
} }
@ -551,7 +626,7 @@ func (c *Certificate) getSANExtension() []byte {
return nil 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) 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 // 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 PublicKeyAlgorithm
isSM2 := (algo == SM2WithSM3) isSM2 := (algo == SM2WithSM3)
for _, details := range signatureAlgorithmDetails { for _, details := range signatureAlgorithmDetails {
@ -587,7 +662,7 @@ func checkSignature(algo x509.SignatureAlgorithm, signed, signature []byte, publ
switch hashType { switch hashType {
case crypto.Hash(0): case crypto.Hash(0):
if !isSM2 && pubKeyAlgo != x509.Ed25519 { if !isSM2 && pubKeyAlgo != Ed25519 {
return x509.ErrUnsupportedAlgorithm return x509.ErrUnsupportedAlgorithm
} }
case crypto.MD5: case crypto.MD5:
@ -603,7 +678,7 @@ func checkSignature(algo x509.SignatureAlgorithm, signed, signature []byte, publ
switch pub := publicKey.(type) { switch pub := publicKey.(type) {
case *rsa.PublicKey: case *rsa.PublicKey:
if pubKeyAlgo != x509.RSA { if pubKeyAlgo != RSA {
return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub) return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)
} }
if isRSAPSS(algo) { if isRSAPSS(algo) {
@ -612,7 +687,7 @@ func checkSignature(algo x509.SignatureAlgorithm, signed, signature []byte, publ
return rsa.VerifyPKCS1v15(pub, hashType, signed, signature) return rsa.VerifyPKCS1v15(pub, hashType, signed, signature)
} }
case *ecdsa.PublicKey: case *ecdsa.PublicKey:
if pubKeyAlgo != x509.ECDSA { if pubKeyAlgo != ECDSA {
return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub) return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)
} }
if isSM2 { if isSM2 {
@ -624,7 +699,7 @@ func checkSignature(algo x509.SignatureAlgorithm, signed, signature []byte, publ
} }
return return
case ed25519.PublicKey: case ed25519.PublicKey:
if pubKeyAlgo != x509.Ed25519 { if pubKeyAlgo != Ed25519 {
return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub) return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)
} }
if !ed25519.Verify(pub, signed, signature) { 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 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} ext := pkix.Extension{Id: oidExtensionKeyUsage, Critical: true}
var a [2]byte var a [2]byte
@ -1021,7 +1096,7 @@ func marshalKeyUsage(ku x509.KeyUsage) (pkix.Extension, error) {
return ext, nil 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} ext := pkix.Extension{Id: oidExtensionExtendedKeyUsage}
oids := make([]asn1.ObjectIdentifier, len(extUsages)+len(unknownUsages)) 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 // 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 PublicKeyAlgorithm
switch pub := pub.(type) { switch pub := pub.(type) {
case *rsa.PublicKey: case *rsa.PublicKey:
pubType = x509.RSA pubType = RSA
hashFunc = crypto.SHA256 hashFunc = crypto.SHA256
sigAlgo.Algorithm = oidSignatureSHA256WithRSA sigAlgo.Algorithm = oidSignatureSHA256WithRSA
sigAlgo.Parameters = asn1.NullRawValue sigAlgo.Parameters = asn1.NullRawValue
case *ecdsa.PublicKey: case *ecdsa.PublicKey:
pubType = x509.ECDSA pubType = ECDSA
switch pub.Curve { switch pub.Curve {
case elliptic.P224(), elliptic.P256(): case elliptic.P224(), elliptic.P256():
@ -1134,7 +1209,7 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureA
} }
case ed25519.PublicKey: case ed25519.PublicKey:
pubType = x509.Ed25519 pubType = Ed25519
sigAlgo.Algorithm = oidSignatureEd25519 sigAlgo.Algorithm = oidSignatureEd25519
default: default:
@ -1157,7 +1232,7 @@ func signingParamsForPublicKey(pub interface{}, requestedSigAlgo x509.SignatureA
return return
} }
sigAlgo.Algorithm, hashFunc = details.oid, details.hash 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") err = errors.New("x509: cannot sign with hash function requested")
return 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. // 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:
@ -1719,7 +1794,7 @@ func ParseCertificateRequest(asn1Data []byte) (*CertificateRequest, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &CertificateRequest{*csrR}, nil return (*CertificateRequest)(csrR), nil
} }
return parseCertificateRequest(&csr) return parseCertificateRequest(&csr)
} }
@ -1738,7 +1813,7 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error
if !oidSignatureSM2WithSM3.Equal(in.SignatureAlgorithm.Algorithm) { if !oidSignatureSM2WithSM3.Equal(in.SignatureAlgorithm.Algorithm) {
return nil, errors.New("unsupport signature algorithm") return nil, errors.New("unsupport signature algorithm")
} }
out := &CertificateRequest{x509.CertificateRequest{ out := &CertificateRequest{
Raw: in.Raw, Raw: in.Raw,
RawTBSCertificateRequest: in.TBSCSR.Raw, RawTBSCertificateRequest: in.TBSCSR.Raw,
RawSubjectPublicKeyInfo: in.TBSCSR.PublicKey.Raw, RawSubjectPublicKeyInfo: in.TBSCSR.PublicKey.Raw,
@ -1751,7 +1826,6 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error
Version: in.TBSCSR.Version, Version: in.TBSCSR.Version,
Attributes: parseRawAttributes(in.TBSCSR.RawAttributes), Attributes: parseRawAttributes(in.TBSCSR.RawAttributes),
},
} }
var err error var err error
@ -1809,7 +1883,7 @@ func CreateRevocationList(rand io.Reader, template *x509.RevocationList, issuer
if issuer == nil { if issuer == nil {
return nil, errors.New("x509: issuer can not be 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") return nil, errors.New("x509: issuer must have the crlSign key usage bit set")
} }
if len(issuer.SubjectKeyId) == 0 { if len(issuer.SubjectKeyId) == 0 {

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,24 +446,24 @@ 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},
} }
testExtKeyUsage := []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth} testExtKeyUsage := []ExtKeyUsage{ExtKeyUsageClientAuth, ExtKeyUsageServerAuth}
testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}} testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}}
extraExtensionData := []byte("extra extension") extraExtensionData := []byte("extra extension")
@ -497,7 +497,7 @@ func TestCreateSelfSignedCertificate(t *testing.T) {
SignatureAlgorithm: test.sigAlgo, SignatureAlgorithm: test.sigAlgo,
SubjectKeyId: []byte{1, 2, 3, 4}, SubjectKeyId: []byte{1, 2, 3, 4},
KeyUsage: x509.KeyUsageCertSign, KeyUsage: KeyUsageCertSign,
ExtKeyUsage: testExtKeyUsage, ExtKeyUsage: testExtKeyUsage,
UnknownExtKeyUsage: testUnknownExtKeyUsage, UnknownExtKeyUsage: testUnknownExtKeyUsage,
@ -1181,7 +1181,7 @@ func TestCreateRevocationList(t *testing.T) {
name: "issuer doesn't have crlSign key usage bit set", name: "issuer doesn't have crlSign key usage bit set",
key: sm2Priv, key: sm2Priv,
issuer: &x509.Certificate{ issuer: &x509.Certificate{
KeyUsage: x509.KeyUsageCertSign, KeyUsage: KeyUsageCertSign,
}, },
template: &x509.RevocationList{}, template: &x509.RevocationList{},
expectedError: "x509: issuer must have the crlSign key usage bit set", expectedError: "x509: issuer must have the crlSign key usage bit set",
@ -1190,7 +1190,7 @@ func TestCreateRevocationList(t *testing.T) {
name: "issuer missing SubjectKeyId", name: "issuer missing SubjectKeyId",
key: sm2Priv, key: sm2Priv,
issuer: &x509.Certificate{ issuer: &x509.Certificate{
KeyUsage: x509.KeyUsageCRLSign, KeyUsage: KeyUsageCRLSign,
}, },
template: &x509.RevocationList{}, template: &x509.RevocationList{},
expectedError: "x509: issuer certificate doesn't contain a subject key identifier", expectedError: "x509: issuer certificate doesn't contain a subject key identifier",
@ -1199,7 +1199,7 @@ func TestCreateRevocationList(t *testing.T) {
name: "nextUpdate before thisUpdate", name: "nextUpdate before thisUpdate",
key: sm2Priv, key: sm2Priv,
issuer: &x509.Certificate{ issuer: &x509.Certificate{
KeyUsage: x509.KeyUsageCRLSign, KeyUsage: KeyUsageCRLSign,
Subject: pkix.Name{ Subject: pkix.Name{
CommonName: "testing", CommonName: "testing",
}, },
@ -1215,7 +1215,7 @@ func TestCreateRevocationList(t *testing.T) {
name: "nil Number", name: "nil Number",
key: sm2Priv, key: sm2Priv,
issuer: &x509.Certificate{ issuer: &x509.Certificate{
KeyUsage: x509.KeyUsageCRLSign, KeyUsage: KeyUsageCRLSign,
Subject: pkix.Name{ Subject: pkix.Name{
CommonName: "testing", CommonName: "testing",
}, },
@ -1231,14 +1231,14 @@ func TestCreateRevocationList(t *testing.T) {
name: "invalid signature algorithm", name: "invalid signature algorithm",
key: sm2Priv, key: sm2Priv,
issuer: &x509.Certificate{ issuer: &x509.Certificate{
KeyUsage: x509.KeyUsageCRLSign, KeyUsage: KeyUsageCRLSign,
Subject: pkix.Name{ Subject: pkix.Name{
CommonName: "testing", CommonName: "testing",
}, },
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),
@ -1255,7 +1255,7 @@ func TestCreateRevocationList(t *testing.T) {
name: "valid", name: "valid",
key: sm2Priv, key: sm2Priv,
issuer: &x509.Certificate{ issuer: &x509.Certificate{
KeyUsage: x509.KeyUsageCRLSign, KeyUsage: KeyUsageCRLSign,
Subject: pkix.Name{ Subject: pkix.Name{
CommonName: "testing", CommonName: "testing",
}, },
@ -1277,7 +1277,7 @@ func TestCreateRevocationList(t *testing.T) {
name: "valid, Ed25519 key", name: "valid, Ed25519 key",
key: ed25519Priv, key: ed25519Priv,
issuer: &x509.Certificate{ issuer: &x509.Certificate{
KeyUsage: x509.KeyUsageCRLSign, KeyUsage: KeyUsageCRLSign,
Subject: pkix.Name{ Subject: pkix.Name{
CommonName: "testing", CommonName: "testing",
}, },
@ -1299,14 +1299,14 @@ func TestCreateRevocationList(t *testing.T) {
name: "valid, non-default signature algorithm", name: "valid, non-default signature algorithm",
key: sm2Priv, key: sm2Priv,
issuer: &x509.Certificate{ issuer: &x509.Certificate{
KeyUsage: x509.KeyUsageCRLSign, KeyUsage: KeyUsageCRLSign,
Subject: pkix.Name{ Subject: pkix.Name{
CommonName: "testing", CommonName: "testing",
}, },
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),
@ -1322,7 +1322,7 @@ func TestCreateRevocationList(t *testing.T) {
name: "valid, extra extension", name: "valid, extra extension",
key: sm2Priv, key: sm2Priv,
issuer: &x509.Certificate{ issuer: &x509.Certificate{
KeyUsage: x509.KeyUsageCRLSign, KeyUsage: KeyUsageCRLSign,
Subject: pkix.Name{ Subject: pkix.Name{
CommonName: "testing", CommonName: "testing",
}, },
@ -1350,7 +1350,7 @@ func TestCreateRevocationList(t *testing.T) {
name: "valid, empty list", name: "valid, empty list",
key: sm2Priv, key: sm2Priv,
issuer: &x509.Certificate{ issuer: &x509.Certificate{
KeyUsage: x509.KeyUsageCRLSign, KeyUsage: KeyUsageCRLSign,
Subject: pkix.Name{ Subject: pkix.Name{
CommonName: "testing", CommonName: "testing",
}, },
@ -1368,7 +1368,7 @@ func TestCreateRevocationList(t *testing.T) {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
var issuer *Certificate var issuer *Certificate
if tc.issuer != nil { if tc.issuer != nil {
issuer = &Certificate{*tc.issuer} issuer = (*Certificate)(tc.issuer)
} }
crl, err := CreateRevocationList(rand.Reader, tc.template, issuer, tc.key) crl, err := CreateRevocationList(rand.Reader, tc.template, issuer, tc.key)
if err != nil && tc.expectedError == "" { if err != nil && tc.expectedError == "" {
@ -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)
@ -1654,7 +1654,7 @@ func TestUnknownExtKey(t *testing.T) {
template := &x509.Certificate{ template := &x509.Certificate{
SerialNumber: big.NewInt(10), SerialNumber: big.NewInt(10),
DNSNames: []string{"foo"}, DNSNames: []string{"foo"},
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsage(-1)}, ExtKeyUsage: []ExtKeyUsage{ExtKeyUsage(-1)},
} }
signer, err := rsa.GenerateKey(rand.Reader, 1024) signer, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil { if err != nil {
@ -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")
} }
} }