Skip to content

Commit 4c0b96a

Browse files
committed
crypto/x509: add directory name constraints
Fixes golang#15196 Signed-off-by: Luiz Angelo Daros de Luca <[email protected]>
1 parent 20a838a commit 4c0b96a

File tree

4 files changed

+1454
-23
lines changed

4 files changed

+1454
-23
lines changed

src/crypto/x509/verify.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ package x509
66

77
import (
88
"bytes"
9+
"crypto/x509/pkix"
10+
"encoding/asn1"
911
"errors"
1012
"fmt"
1113
"net"
@@ -498,6 +500,34 @@ func matchDomainConstraint(domain, constraint string) (bool, error) {
498500
return true, nil
499501
}
500502

503+
func matchDirNameConstraint(dirname pkix.RDNSequence, constraint pkix.RDNSequence) (bool, error) {
504+
505+
if len(constraint) > len(dirname) {
506+
return false, nil
507+
}
508+
for i, rdn := range constraint {
509+
if len(rdn) > len(dirname[i]) {
510+
return false, nil
511+
}
512+
for j, const_tv := range rdn {
513+
dirname_tv := dirname[i][j]
514+
if len(const_tv.Type) != len(dirname_tv.Type) {
515+
return false, nil
516+
}
517+
for k, _ := range const_tv.Type {
518+
if const_tv.Type[k] != dirname_tv.Type[k] {
519+
return false, nil
520+
}
521+
}
522+
if const_tv.Value != dirname_tv.Value {
523+
return false, nil
524+
}
525+
}
526+
}
527+
528+
return true, nil
529+
}
530+
501531
// checkNameConstraints checks that c permits a child certificate to claim the
502532
// given name, of type nameType. The argument parsedName contains the parsed
503533
// form of name, suitable for passing to the match function. The total number
@@ -605,6 +635,26 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
605635
}
606636

607637
checkNameConstraints := (certType == intermediateCertificate || certType == rootCertificate) && c.hasNameConstraints()
638+
if checkNameConstraints {
639+
for _, cert := range currentChain {
640+
var subject pkix.RDNSequence
641+
642+
// cert.Subject.ToRDNSequence cannot be used as it ignores unknown RDN
643+
if rest, err := asn1.Unmarshal(cert.RawSubject, &subject); err != nil {
644+
return err
645+
} else if len(rest) != 0 {
646+
return errors.New("x509: trailing data after X.509 subject")
647+
}
648+
649+
if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "directory Name", cert.Subject.String(), subject,
650+
func(parsedName, constraint interface{}) (bool, error) {
651+
return matchDirNameConstraint(parsedName.(pkix.RDNSequence), constraint.(pkix.RDNSequence))
652+
}, c.PermittedDirNames, c.ExcludedDirNames); err != nil {
653+
return err
654+
}
655+
}
656+
}
657+
608658
if checkNameConstraints && leaf.commonNameAsHostname() {
609659
// This is the deprecated, legacy case of depending on the commonName as
610660
// a hostname. We don't enforce name constraints against the CN, but

0 commit comments

Comments
 (0)