]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/crypto/x509/verify.go
crypto/x509: implement AddCertWithConstraint
[gostls13.git] / src / crypto / x509 / verify.go
index 8f9610f8e6d8efcf73e2e74dbccf6c48b204de21..9d3c3246d3098dc474ed1f0b49db3ee316fe9b6c 100644 (file)
@@ -591,22 +591,19 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
        }
        comparisonCount := 0
 
-       var leaf *Certificate
        if certType == intermediateCertificate || certType == rootCertificate {
                if len(currentChain) == 0 {
                        return errors.New("x509: internal error: empty chain when appending CA cert")
                }
-               leaf = currentChain[0]
        }
 
        if (certType == intermediateCertificate || certType == rootCertificate) &&
                c.hasNameConstraints() {
                toCheck := []*Certificate{}
-               if leaf.hasSANExtension() {
-                       toCheck = append(toCheck, leaf)
-               }
-               if c.hasSANExtension() {
-                       toCheck = append(toCheck, c)
+               for _, c := range currentChain {
+                       if c.hasSANExtension() {
+                               toCheck = append(toCheck, c)
+                       }
                }
                for _, sanCert := range toCheck {
                        err := forEachSAN(sanCert.getSANExtension(), func(tag int, data []byte) error {
@@ -755,7 +752,7 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e
                return nil, errNotParsed
        }
        for i := 0; i < opts.Intermediates.len(); i++ {
-               c, err := opts.Intermediates.cert(i)
+               c, _, err := opts.Intermediates.cert(i)
                if err != nil {
                        return nil, fmt.Errorf("crypto/x509: error fetching intermediate: %w", err)
                }
@@ -901,8 +898,8 @@ func (c *Certificate) buildChains(currentChain []*Certificate, sigChecks *int, o
                hintCert *Certificate
        )
 
-       considerCandidate := func(certType int, candidate *Certificate) {
-               if alreadyInChain(candidate, currentChain) {
+       considerCandidate := func(certType int, candidate potentialParent) {
+               if alreadyInChain(candidate.cert, currentChain) {
                        return
                }
 
@@ -915,29 +912,39 @@ func (c *Certificate) buildChains(currentChain []*Certificate, sigChecks *int, o
                        return
                }
 
-               if err := c.CheckSignatureFrom(candidate); err != nil {
+               if err := c.CheckSignatureFrom(candidate.cert); err != nil {
                        if hintErr == nil {
                                hintErr = err
-                               hintCert = candidate
+                               hintCert = candidate.cert
                        }
                        return
                }
 
-               err = candidate.isValid(certType, currentChain, opts)
+               err = candidate.cert.isValid(certType, currentChain, opts)
                if err != nil {
                        if hintErr == nil {
                                hintErr = err
-                               hintCert = candidate
+                               hintCert = candidate.cert
                        }
                        return
                }
 
+               if candidate.constraint != nil {
+                       if err := candidate.constraint(currentChain); err != nil {
+                               if hintErr == nil {
+                                       hintErr = err
+                                       hintCert = candidate.cert
+                               }
+                               return
+                       }
+               }
+
                switch certType {
                case rootCertificate:
-                       chains = append(chains, appendToFreshChain(currentChain, candidate))
+                       chains = append(chains, appendToFreshChain(currentChain, candidate.cert))
                case intermediateCertificate:
                        var childChains [][]*Certificate
-                       childChains, err = candidate.buildChains(appendToFreshChain(currentChain, candidate), sigChecks, opts)
+                       childChains, err = candidate.cert.buildChains(appendToFreshChain(currentChain, candidate.cert), sigChecks, opts)
                        chains = append(chains, childChains...)
                }
        }