Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

X509lax #157

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 18 additions & 36 deletions internal/x509util/cert_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package x509
package x509util

import (
"bytes"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"sync"
)
Expand Down Expand Up @@ -47,7 +48,7 @@ type lazyCert struct {
// constraint is a function to run against a chain when it is a candidate to
// be added to the chain. This allows adding arbitrary constraints that are
// not specified in the certificate itself.
constraint func([]*Certificate) error
constraint func([]*x509.Certificate) error

// getCert returns the certificate.
//
Expand All @@ -57,7 +58,7 @@ type lazyCert struct {
// error in the signature primarily is meant for use in the
// case where a cert file existed on local disk when the program
// started up is deleted later before it's read.
getCert func() (*Certificate, error)
getCert func() (*x509.Certificate, error)
}

// NewCertPool returns a new, empty CertPool.
Expand All @@ -78,7 +79,7 @@ func (s *CertPool) len() int {
}

// cert returns cert index n in s.
func (s *CertPool) cert(n int) (*Certificate, func([]*Certificate) error, error) {
func (s *CertPool) cert(n int) (*x509.Certificate, func([]*x509.Certificate) error, error) {
cert, err := s.lazyCerts[n].getCert()
return cert, s.lazyCerts[n].constraint, err
}
Expand All @@ -103,33 +104,14 @@ func (s *CertPool) Clone() *CertPool {
return p
}

// SystemCertPool returns a copy of the system cert pool.
//
// On Unix systems other than macOS the environment variables SSL_CERT_FILE and
// SSL_CERT_DIR can be used to override the system default locations for the SSL
// certificate file and SSL certificate files directory, respectively. The
// latter can be a colon-separated list.
//
// Any mutations to the returned pool are not written to disk and do not affect
// any other pool returned by SystemCertPool.
//
// New changes in the system cert pool might not be reflected in subsequent calls.
func SystemCertPool() (*CertPool, error) {
if sysRoots := systemRootsPool(); sysRoots != nil {
return sysRoots.Clone(), nil
}

return loadSystemRoots()
}

type potentialParent struct {
cert *Certificate
constraint func([]*Certificate) error
cert *x509.Certificate
constraint func([]*x509.Certificate) error
}

// findPotentialParents returns the certificates in s which might have signed
// cert.
func (s *CertPool) findPotentialParents(cert *Certificate) []potentialParent {
func (s *CertPool) findPotentialParents(cert *x509.Certificate) []potentialParent {
if s == nil {
return nil
}
Expand Down Expand Up @@ -169,19 +151,19 @@ func (s *CertPool) findPotentialParents(cert *Certificate) []potentialParent {
return candidates
}

func (s *CertPool) contains(cert *Certificate) bool {
func (s *CertPool) contains(cert *x509.Certificate) bool {
if s == nil {
return false
}
return s.haveSum[sha256.Sum224(cert.Raw)]
}

// AddCert adds a certificate to a pool.
func (s *CertPool) AddCert(cert *Certificate) {
func (s *CertPool) AddCert(cert *x509.Certificate) {
if cert == nil {
panic("adding nil Certificate to CertPool")
}
s.addCertFunc(sha256.Sum224(cert.Raw), string(cert.RawSubject), func() (*Certificate, error) {
s.addCertFunc(sha256.Sum224(cert.Raw), string(cert.RawSubject), func() (*x509.Certificate, error) {
return cert, nil
}, nil)
}
Expand All @@ -191,7 +173,7 @@ func (s *CertPool) AddCert(cert *Certificate) {
//
// The rawSubject is Certificate.RawSubject and must be non-empty.
// The getCert func may be called 0 or more times.
func (s *CertPool) addCertFunc(rawSum224 sum224, rawSubject string, getCert func() (*Certificate, error), constraint func([]*Certificate) error) {
func (s *CertPool) addCertFunc(rawSum224 sum224, rawSubject string, getCert func() (*x509.Certificate, error), constraint func([]*x509.Certificate) error) {
if getCert == nil {
panic("getCert can't be nil")
}
Expand Down Expand Up @@ -228,18 +210,18 @@ func (s *CertPool) AppendCertsFromPEM(pemCerts []byte) (ok bool) {
}

certBytes := block.Bytes
cert, err := ParseCertificate(certBytes)
cert, err := x509.ParseCertificate(certBytes)
if err != nil {
continue
}
var lazyCert struct {
sync.Once
v *Certificate
v *x509.Certificate
}
s.addCertFunc(sha256.Sum224(cert.Raw), string(cert.RawSubject), func() (*Certificate, error) {
s.addCertFunc(sha256.Sum224(cert.Raw), string(cert.RawSubject), func() (*x509.Certificate, error) {
lazyCert.Do(func() {
// This can't fail, as the same bytes already parsed above.
lazyCert.v, _ = ParseCertificate(certBytes)
lazyCert.v, _ = x509.ParseCertificate(certBytes)
certBytes = nil
})
return lazyCert.v, nil
Expand Down Expand Up @@ -284,11 +266,11 @@ func (s *CertPool) Equal(other *CertPool) bool {
// it will additionally pass the whole chain to constraint to determine its
// validity. If constraint returns a non-nil error, the chain will be discarded.
// constraint may be called concurrently from multiple goroutines.
func (s *CertPool) AddCertWithConstraint(cert *Certificate, constraint func([]*Certificate) error) {
func (s *CertPool) AddCertWithConstraint(cert *x509.Certificate, constraint func([]*x509.Certificate) error) {
if cert == nil {
panic("adding nil Certificate to CertPool")
}
s.addCertFunc(sha256.Sum224(cert.Raw), string(cert.RawSubject), func() (*Certificate, error) {
s.addCertFunc(sha256.Sum224(cert.Raw), string(cert.RawSubject), func() (*x509.Certificate, error) {
return cert, nil
}, constraint)
}
Loading
Loading