diff --git a/smx509/root_windows.go b/smx509/root_windows.go index 476aa9d..949902b 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 x509.CertificateInvalidError{c.asX509(), x509.Expired, ""} case syscall.CERT_TRUST_IS_NOT_VALID_FOR_USAGE: - return x509.CertificateInvalidError{&c.Certificate, x509.IncompatibleUsage, ""} + return x509.CertificateInvalidError{c.asX509(), x509.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 x509.CertificateInvalidError{Cert: c.asX509(), Reason: x509.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: diff --git a/smx509/verify.go b/smx509/verify.go index a52c375..5f564de 100644 --- a/smx509/verify.go +++ b/smx509/verify.go @@ -246,18 +246,18 @@ func (c *Certificate) checkNameConstraints(count *int, *count += excludedValue.Len() if *count > maxConstraintComparisons { - return x509.CertificateInvalidError{&c.Certificate, x509.TooManyConstraints, ""} + return x509.CertificateInvalidError{c.asX509(), x509.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 x509.CertificateInvalidError{c.asX509(), x509.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 x509.CertificateInvalidError{c.asX509(), x509.CANotAuthorizedForThisName, fmt.Sprintf("%s %q is excluded by constraint %q", nameType, name, constraint)} } } @@ -265,7 +265,7 @@ func (c *Certificate) checkNameConstraints(count *int, *count += permittedValue.Len() if *count > maxConstraintComparisons { - return x509.CertificateInvalidError{&c.Certificate, x509.TooManyConstraints, ""} + return x509.CertificateInvalidError{c.asX509(), x509.TooManyConstraints, ""} } ok := true @@ -274,7 +274,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 x509.CertificateInvalidError{c.asX509(), x509.CANotAuthorizedForThisName, err.Error()} } if ok { @@ -283,7 +283,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 x509.CertificateInvalidError{c.asX509(), x509.CANotAuthorizedForThisName, fmt.Sprintf("%s %q is not permitted by any constraint", nameType, name)} } return nil @@ -334,7 +334,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 x509.CertificateInvalidError{c.asX509(), x509.NameMismatch, ""} } } @@ -344,13 +344,13 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V } if now.Before(c.NotBefore) { return x509.CertificateInvalidError{ - Cert: &c.Certificate, + Cert: c.asX509(), Reason: x509.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, + Cert: c.asX509(), Reason: x509.Expired, Detail: fmt.Sprintf("current time %s is after %s", now.Format(time.RFC3339), c.NotAfter.Format(time.RFC3339)), } @@ -458,13 +458,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 x509.CertificateInvalidError{c.asX509(), x509.NotAuthorizedToSign, ""} } if c.BasicConstraintsValid && c.MaxPathLen >= 0 { numIntermediates := len(currentChain) - 1 if numIntermediates > c.MaxPathLen { - return x509.CertificateInvalidError{&c.Certificate, x509.TooManyIntermediates, ""} + return x509.CertificateInvalidError{c.asX509(), x509.TooManyIntermediates, ""} } } @@ -571,7 +571,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, x509.CertificateInvalidError{c.asX509(), x509.IncompatibleUsage, ""} } return chains, nil @@ -798,7 +798,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,7 +820,7 @@ func (c *Certificate) VerifyHostname(h string) error { } } } - return x509.HostnameError{&c.Certificate, h} + return x509.HostnameError{c.asX509(), h} } func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool { diff --git a/smx509/verify_test.go b/smx509/verify_test.go index edc0592..0c3606c 100644 --- a/smx509/verify_test.go +++ b/smx509/verify_test.go @@ -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 82036df..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.: @@ -562,8 +564,10 @@ func oidFromExtKeyUsage(eku ExtKeyUsage) (oid asn1.ObjectIdentifier, ok bool) { } // 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 { @@ -1790,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) } @@ -1809,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, @@ -1822,7 +1826,6 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error Version: in.TBSCSR.Version, Attributes: parseRawAttributes(in.TBSCSR.RawAttributes), - }, } var err error diff --git a/smx509/x509_test.go b/smx509/x509_test.go index b214135..cc49cfe 100644 --- a/smx509/x509_test.go +++ b/smx509/x509_test.go @@ -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 == "" {