From a7e2ebb7d2d2cb4309857cc0d4b711e759502686 Mon Sep 17 00:00:00 2001 From: Mariano Cano Date: Thu, 9 Jul 2020 15:17:59 -0700 Subject: [PATCH] Fix creation of certificate without templates. --- x509util/certificate.go | 5 +++-- x509util/certificate_request.go | 26 ++++++++++++++++++++++++-- x509util/extensions.go | 9 +++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/x509util/certificate.go b/x509util/certificate.go index c5569ddd..c6af8459 100644 --- a/x509util/certificate.go +++ b/x509util/certificate.go @@ -48,9 +48,10 @@ func NewCertificate(cr *x509.CertificateRequest, opts ...Option) (*Certificate, return nil, err } - // If no template use only the certificate request. + // If no template use only the certificate request with the default leaf key + // usages. if o.CertBuffer == nil { - return newCertificateRequest(cr).GetCertificate(), nil + return newCertificateRequest(cr).GetLeafCertificate(), nil } // With templates diff --git a/x509util/certificate_request.go b/x509util/certificate_request.go index 6cc14141..4bb02359 100644 --- a/x509util/certificate_request.go +++ b/x509util/certificate_request.go @@ -1,6 +1,9 @@ package x509util -import "crypto/x509" +import ( + "crypto/rsa" + "crypto/x509" +) type CertificateRequest struct { Version int `json:"version"` @@ -17,6 +20,10 @@ type CertificateRequest struct { } func newCertificateRequest(cr *x509.CertificateRequest) *CertificateRequest { + extensions := make([]Extension, len(cr.Extensions)) + for i, e := range cr.Extensions { + extensions[i] = newExtension(e) + } return &CertificateRequest{ Version: cr.Version, Subject: newSubject(cr.Subject), @@ -24,7 +31,7 @@ func newCertificateRequest(cr *x509.CertificateRequest) *CertificateRequest { EmailAddresses: cr.EmailAddresses, IPAddresses: cr.IPAddresses, URIs: cr.URIs, - Extensions: nil, + Extensions: extensions, PublicKey: cr.PublicKey, PublicKeyAlgorithm: cr.PublicKeyAlgorithm, Signature: cr.Signature, @@ -44,3 +51,18 @@ func (c *CertificateRequest) GetCertificate() *Certificate { PublicKeyAlgorithm: c.PublicKeyAlgorithm, } } + +func (c *CertificateRequest) GetLeafCertificate() *Certificate { + keyUsage := x509.KeyUsageDigitalSignature + if _, ok := c.PublicKey.(*rsa.PublicKey); ok { + keyUsage |= x509.KeyUsageKeyEncipherment + } + + cert := c.GetCertificate() + cert.KeyUsage = KeyUsage(keyUsage) + cert.ExtKeyUsage = ExtKeyUsage([]x509.ExtKeyUsage{ + x509.ExtKeyUsageServerAuth, + x509.ExtKeyUsageClientAuth, + } + return cert +} diff --git a/x509util/extensions.go b/x509util/extensions.go index 2b1c8527..8c7eecf4 100644 --- a/x509util/extensions.go +++ b/x509util/extensions.go @@ -54,6 +54,15 @@ type Extension struct { Value []byte `json:"value"` } +// newExtensions creates an Extension from a standard pkix.Extension. +func newExtension(e pkix.Extension) Extension { + return Extension{ + ID: ObjectIdentifier(e.Id), + Critical: e.Critical, + Value: e.Value, + } +} + // Set adds the extension to the given X509 certificate. func (e Extension) Set(c *x509.Certificate) { c.ExtraExtensions = append(c.ExtraExtensions, pkix.Extension{