From c75ee0000e1677737e0f05efe8de4c101814b848 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Fri, 19 Aug 2016 13:42:48 -0600 Subject: [PATCH] Fix edge case in stapling; do not allow certs without any names --- caddytls/certificates.go | 40 +++++++++++++++++++++++++++++++--------- caddytls/crypto.go | 6 +++++- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/caddytls/certificates.go b/caddytls/certificates.go index e6d5510d3..db5f5f24b 100644 --- a/caddytls/certificates.go +++ b/caddytls/certificates.go @@ -167,12 +167,28 @@ func makeCertificate(certPEMBlock, keyPEMBlock []byte) (Certificate, error) { if len(tlsCert.Certificate) == 0 { return cert, errors.New("certificate is empty") } + cert.Certificate = tlsCert - // Parse leaf certificate and extract relevant metadata + // Parse leaf certificate, extract relevant metadata, and staple OCSP leaf, err := x509.ParseCertificate(tlsCert.Certificate[0]) if err != nil { return cert, err } + err = fillCertFromLeaf(&cert, leaf) + if err != nil { + return cert, err + } + err = stapleOCSP(&cert, certPEMBlock) + if err != nil { + log.Printf("[WARNING] Stapling OCSP: %v", err) + } + + return cert, nil +} + +// fillCertFromLeaf populates cert.Names and cert.NotAfter +// using data in leaf. +func fillCertFromLeaf(cert *Certificate, leaf *x509.Certificate) error { if leaf.Subject.CommonName != "" { cert.Names = []string{strings.ToLower(leaf.Subject.CommonName)} } @@ -181,15 +197,21 @@ func makeCertificate(certPEMBlock, keyPEMBlock []byte) (Certificate, error) { cert.Names = append(cert.Names, strings.ToLower(name)) } } - cert.NotAfter = leaf.NotAfter - cert.Certificate = tlsCert - - err = stapleOCSP(&cert, certPEMBlock) - if err != nil { - log.Printf("[WARNING] Stapling OCSP: %v", err) + for _, ip := range leaf.IPAddresses { + if ipStr := ip.String(); ipStr != leaf.Subject.CommonName { + cert.Names = append(cert.Names, strings.ToLower(ipStr)) + } } - - return cert, nil + for _, email := range leaf.EmailAddresses { + if email != leaf.Subject.CommonName { + cert.Names = append(cert.Names, strings.ToLower(email)) + } + } + if len(cert.Names) == 0 { + return errors.New("certificate has no names") + } + cert.NotAfter = leaf.NotAfter + return nil } // cacheCertificate adds cert to the in-memory cache. If the cache is diff --git a/caddytls/crypto.go b/caddytls/crypto.go index 25f66b0ac..347f969ca 100644 --- a/caddytls/crypto.go +++ b/caddytls/crypto.go @@ -89,7 +89,11 @@ func stapleOCSP(cert *Certificate, pemBundle []byte) error { // First try to load OCSP staple from storage and see if // we can still use it. // TODO: Use Storage interface instead of disk directly - ocspFileName := cert.Names[0] + "-" + fastHash(pemBundle) + var ocspFileNamePrefix string + if len(cert.Names) > 0 { + ocspFileNamePrefix = cert.Names[0] + "-" + } + ocspFileName := ocspFileNamePrefix + fastHash(pemBundle) ocspCachePath := filepath.Join(ocspFolder, ocspFileName) cachedOCSP, err := ioutil.ReadFile(ocspCachePath) if err == nil {