From 56d90534004d0eedc2005b56e5f98f055932cd00 Mon Sep 17 00:00:00 2001 From: David Schneider Date: Sat, 27 Jul 2024 18:54:17 +0200 Subject: [PATCH] Refacotr pcert library --- cert.go | 233 +++++++++++++++++++------------ cert_test.go | 18 ++- cmd/pcert/certificate_options.go | 143 ------------------- cmd/pcert/flags.go | 18 +++ example_test.go | 31 +++- profile.go | 27 ++-- 6 files changed, 217 insertions(+), 253 deletions(-) diff --git a/cert.go b/cert.go index e090eab..6bee540 100644 --- a/cert.go +++ b/cert.go @@ -3,13 +3,15 @@ package pcert import ( "crypto" "crypto/rand" - "crypto/sha1" "crypto/x509" "crypto/x509/pkix" + "encoding/asn1" "errors" "fmt" "io" "math/big" + "net" + "net/url" "reflect" "time" ) @@ -20,121 +22,67 @@ const ( ) // Create creates a x509.Certificate and a key with the default key options. See CreateWithKeyOptions for more details. -func Create(cert, signCert *x509.Certificate, signKey crypto.PrivateKey) (certPEM, keyPEM []byte, err error) { +func CreateCertificate(cert, signCert *x509.Certificate, signKey crypto.PrivateKey) (certDER []byte, privateKey crypto.PrivateKey, err error) { return CreateWithKeyOptions(cert, KeyOptions{}, signCert, signKey) } -// CreateWithKeyOptions creates a key and certificate. The certificate is signed +// CreateCertificateWithKeyOptions creates a key and certificate. The certificate is signed // used signCert and signKey. If signCert or signKey are nil, a self-signed // certificate will be created. The certificate and the key are returned PEM encoded. -func CreateWithKeyOptions(cert *x509.Certificate, keyOptions KeyOptions, signCert *x509.Certificate, signKey crypto.PrivateKey) (certPEM, keyPEM []byte, err error) { +func CreateWithKeyOptions(cert *x509.Certificate, keyOptions KeyOptions, signCert *x509.Certificate, signKey crypto.PrivateKey) (certDER []byte, privateKey crypto.PrivateKey, err error) { priv, pub, err := GenerateKey(keyOptions) if err != nil { - return - } - - keyPEM, err = EncodeKey(priv) - if err != nil { - return + return nil, nil, err } // If signCert and signKey are missing we self sign the certificate if signCert == nil && signKey == nil { - certPEM, err = Sign(cert, pub, cert, priv) - } else if signCert != nil && signKey != nil { - certPEM, err = Sign(cert, pub, signCert, signKey) - } else { - if signCert == nil { - return nil, nil, fmt.Errorf("certificate for signing missing") - } - return nil, nil, fmt.Errorf("private key for signing missing") - } - return certPEM, keyPEM, err -} - -// Sign set some defaults on a certificate and signs it with the signCert and -// the signKey. The following defaults are set they are not set explicitly in the -// certificate: -// -// - SubjectKeyId is generated based on the publicKey -// - The AuthorityKeyId is set based on the SubjectKeyId of the signCert -// - NotBefore is set to time.Now() -// - NotAfter is set to NotBefore + DefaultValidityPeriod -// - SerialNumber is set to a randomly generated serial number -// -// The created certificate is returned PEM encoded. -func Sign(cert *x509.Certificate, publicKey any, signCert *x509.Certificate, signKey any) (certPEM []byte, err error) { - if cert.SubjectKeyId == nil { - subjectKeyID, err := getSubjectKeyID(publicKey) - if err != nil { - return nil, err - } - cert.SubjectKeyId = subjectKeyID - } - if cert.AuthorityKeyId == nil { - // TODO: is probably already done in Go - cert.AuthorityKeyId = signCert.SubjectKeyId - } - - if cert.NotBefore.IsZero() { - cert.NotBefore = time.Now() + signCert = cert + signKey = priv } - if cert.NotAfter.IsZero() { - cert.NotAfter = cert.NotBefore.Add(DefaultValidityPeriod) + if signCert == nil { + return nil, nil, fmt.Errorf("signing certificate cannot be nil") } - - if cert.SerialNumber == nil { - serialNumber, err := generateSerial(rand.Reader) - if err != nil { - return nil, err - } - cert.SerialNumber = serialNumber + if signKey == nil { + return nil, nil, fmt.Errorf("signing key cannot be nil") } - der, err := x509.CreateCertificate(rand.Reader, cert, signCert, publicKey, signKey) + certDER, err = x509.CreateCertificate(rand.Reader, cert, signCert, pub, signKey) if err != nil { - return nil, err + return nil, nil, err } - - return Encode(der), nil + return certDER, priv, err } // Request creates a CSR and a key. The key is created with the default key // options. See RequestWithKeyOptions for more details. -func Request(csr *x509.CertificateRequest) (csrPEM, keyPEM []byte, err error) { - return RequestWithKeyOptions(csr, KeyOptions{}) +func CreateRequest(csr *x509.CertificateRequest) (csrPEM []byte, privateKey crypto.PrivateKey, err error) { + return CreateRequestWithKeyOptions(csr, KeyOptions{}) } // RequestWithKeyOptions creates a CSR and a key based on key options. The key is // created with the default key options. -func RequestWithKeyOptions(csr *x509.CertificateRequest, keyOptions KeyOptions) (csrPEM, keyPEM []byte, err error) { +func CreateRequestWithKeyOptions(csr *x509.CertificateRequest, keyOptions KeyOptions) (csrPEM []byte, privateKey crypto.PrivateKey, err error) { priv, _, err := GenerateKey(keyOptions) if err != nil { return } - keyPEM, err = EncodeKey(priv) + csrDER, err := x509.CreateCertificateRequest(rand.Reader, csr, priv) if err != nil { return } - der, err := x509.CreateCertificateRequest(rand.Reader, csr, priv) - if err != nil { - return - } - - csrPEM = EncodeCSR(der) - - return + return csrDER, priv, nil } // SignCSR applies the settings from csr and return the signed certificate -func SignCSR(csr *x509.CertificateRequest, cert, signCert *x509.Certificate, signKey any) (certPEM []byte, err error) { +func CreateCertificateWithCSR(csr *x509.CertificateRequest, cert, signCert *x509.Certificate, signKey any) (certDER []byte, err error) { // TODO: settings from cert should take precedence applyCSR(csr, cert) - return Sign(cert, csr.PublicKey, signCert, signKey) + return x509.CreateCertificate(rand.Reader, cert, signCert, csr.PublicKey, signKey) } // apply values of CSR to certificate @@ -166,26 +114,16 @@ func applyCSR(csr *x509.CertificateRequest, cert *x509.Certificate) { } } -func getSubjectKeyID(pub crypto.PublicKey) ([]byte, error) { - encodedPub, err := x509.MarshalPKIXPublicKey(pub) - if err != nil { - return nil, err - } - - pubHash := sha1.Sum(encodedPub) - return pubHash[:], nil -} - // GenerateSerial produces an RFC 5280 conformant serial number to be used // in a certificate. The serial number will be a positive integer, no more // than 20 octets in length, generated using the provided random source. // // Code from: https://go-review.googlesource.com/c/go/+/479120/3/src/crypto/x509/x509.go#2485 -func generateSerial(rand io.Reader) (*big.Int, error) { +func generateSerial() (*big.Int, error) { randBytes := make([]byte, 20) for i := 0; i < 10; i++ { // get 20 random bytes - _, err := io.ReadFull(rand, randBytes) + _, err := io.ReadFull(rand.Reader, randBytes) if err != nil { return nil, err } @@ -201,3 +139,124 @@ func generateSerial(rand io.Reader) (*big.Int, error) { } return nil, errors.New("x509: failed to generate serial number because the random source returns only zeros") } + +func NewCertificate(opts *CertificateOptions) *x509.Certificate { + if opts == nil { + opts = &CertificateOptions{} + } + cert := &x509.Certificate{ + SignatureAlgorithm: opts.SignatureAlgorithm, + SerialNumber: opts.SerialNumber, + Subject: opts.Subject, + NotBefore: opts.NotBefore, + NotAfter: opts.NotAfter, + KeyUsage: opts.KeyUsage, + ExtraExtensions: opts.ExtraExtensions, + ExtKeyUsage: opts.ExtKeyUsage, + UnknownExtKeyUsage: opts.UnknownExtKeyUsage, + BasicConstraintsValid: opts.BasicConstraintsValid, + IsCA: opts.IsCA, + SubjectKeyId: opts.SubjectKeyId, + AuthorityKeyId: opts.AuthorityKeyId, + OCSPServer: opts.OCSPServer, + IssuingCertificateURL: opts.IssuingCertificateURL, + DNSNames: opts.DNSNames, + EmailAddresses: opts.EmailAddresses, + IPAddresses: opts.IPAddresses, + URIs: opts.URIs, + PermittedDNSDomainsCritical: opts.PermittedDNSDomainsCritical, + PermittedDNSDomains: opts.PermittedDNSDomains, + ExcludedDNSDomains: opts.ExcludedDNSDomains, + PermittedIPRanges: opts.PermittedIPRanges, + ExcludedIPRanges: opts.ExcludedIPRanges, + PermittedEmailAddresses: opts.PermittedEmailAddresses, + ExcludedEmailAddresses: opts.ExcludedEmailAddresses, + PermittedURIDomains: opts.PermittedURIDomains, + ExcludedURIDomains: opts.ExcludedURIDomains, + CRLDistributionPoints: opts.CRLDistributionPoints, + PolicyIdentifiers: opts.PolicyIdentifiers, + Policies: opts.Policies, + } + + if opts.MaxPathLen != nil { + cert.MaxPathLen = *opts.MaxPathLen + cert.MaxPathLenZero = true + } + + if cert.NotBefore.IsZero() { + cert.NotBefore = time.Now() + } + if cert.NotAfter.IsZero() { + if opts.Expiry == 0 { + cert.NotAfter = cert.NotBefore.Add(DefaultValidityPeriod) + } else { + cert.NotAfter = cert.NotBefore.Add(opts.Expiry) + } + } + + if cert.SerialNumber == nil { + var err error + cert.SerialNumber, err = generateSerial() + if err != nil { + // reading randomness failed + panic(err.Error()) + } + } + return cert +} + +// CertificateOptions represents all options which can be set using +// CreateCertificate (see Go docs of it). Further it offers Expiry to set a +// validity duration instead of absolute times. +type CertificateOptions struct { + SignatureAlgorithm x509.SignatureAlgorithm + + SerialNumber *big.Int + Subject pkix.Name + + NotBefore, NotAfter time.Time // Validity bounds. + Expiry time.Duration + + KeyUsage x509.KeyUsage + ExtKeyUsage []x509.ExtKeyUsage // Sequence of extended key usages. + + ExtraExtensions []pkix.Extension + UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package. + + BasicConstraintsValid bool + IsCA bool + // if nil MaxPathLen = 0, MaxPathLenZero = false + // else: MaxPathLen = *this, MaxPathLenZero = true + MaxPathLen *int + + // if CA defaults to sha something something + SubjectKeyId []byte + // gets defaulted to parent.SubjectKeyID + AuthorityKeyId []byte + + OCSPServer []string + IssuingCertificateURL []string + + // SAN + DNSNames []string + EmailAddresses []string + IPAddresses []net.IP + URIs []*url.URL + + // Name constraints + PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical. + PermittedDNSDomains []string + ExcludedDNSDomains []string + PermittedIPRanges []*net.IPNet + ExcludedIPRanges []*net.IPNet + PermittedEmailAddresses []string + ExcludedEmailAddresses []string + PermittedURIDomains []string + ExcludedURIDomains []string + + // CRL Distribution Points + CRLDistributionPoints []string + + PolicyIdentifiers []asn1.ObjectIdentifier + Policies []x509.OID +} diff --git a/cert_test.go b/cert_test.go index 3bb1828..3b7d185 100644 --- a/cert_test.go +++ b/cert_test.go @@ -9,13 +9,19 @@ import ( ) func createAndParse(name string, signCert *x509.Certificate, signKey crypto.PrivateKey) (*x509.Certificate, crypto.PrivateKey, error) { - crt := &x509.Certificate{ + crt := NewCertificate(&CertificateOptions{ Subject: pkix.Name{ CommonName: name, }, + }) + + certDER, key, err := CreateCertificate(crt, signCert, signKey) + if err != nil { + return nil, nil, err } - certPEM, keyPEM, err := Create(crt, signCert, signKey) + certPEM := Encode(certDER) + keyPEM, err := EncodeKey(key) if err != nil { return nil, nil, err } @@ -78,8 +84,8 @@ func TestCreate_missing_key(t *testing.T) { t.Fatal("no error returned") } - if !strings.Contains(err.Error(), "key for signing missing") { - t.Fatalf("error does not contain string 'key for signing missing': %s", err.Error()) + if !strings.Contains(err.Error(), "signing key cannot be nil") { + t.Fatalf("error does not contain string 'signing key cannot be nil': %s", err.Error()) } } @@ -98,7 +104,7 @@ func TestCreate_missing_certificate(t *testing.T) { t.Fatal("no error returned") } - if !strings.Contains(err.Error(), "certificate for signing missing") { - t.Fatalf("error does not contain string 'certificate for signing missing': %s", err.Error()) + if !strings.Contains(err.Error(), "signing certificate cannot be nil") { + t.Fatalf("error does not contain string 'signing certificate cannot be nil': %s", err.Error()) } } diff --git a/cmd/pcert/certificate_options.go b/cmd/pcert/certificate_options.go index 3f0e346..ec79678 100644 --- a/cmd/pcert/certificate_options.go +++ b/cmd/pcert/certificate_options.go @@ -13,146 +13,3 @@ import ( "github.com/spf13/pflag" ) - -const ( - defaultDuration = time.Hour * 24 * 365 -) - -func NewCertificate(opts *CertificateOptions) *x509.Certificate { - if opts == nil { - opts = &CertificateOptions{} - } - cert := &x509.Certificate{ - SignatureAlgorithm: opts.SignatureAlgorithm, - SerialNumber: opts.SerialNumber, - Subject: opts.Subject, - NotBefore: opts.NotBefore, - NotAfter: opts.NotAfter, - KeyUsage: opts.KeyUsage, - ExtraExtensions: opts.ExtraExtensions, - ExtKeyUsage: opts.ExtKeyUsage, - UnknownExtKeyUsage: opts.UnknownExtKeyUsage, - BasicConstraintsValid: opts.BasicConstraintsValid, - IsCA: opts.IsCA, - SubjectKeyId: opts.SubjectKeyId, - AuthorityKeyId: opts.AuthorityKeyId, - OCSPServer: opts.OCSPServer, - IssuingCertificateURL: opts.IssuingCertificateURL, - DNSNames: opts.DNSNames, - EmailAddresses: opts.EmailAddresses, - IPAddresses: opts.IPAddresses, - URIs: opts.URIs, - PermittedDNSDomainsCritical: opts.PermittedDNSDomainsCritical, - PermittedDNSDomains: opts.PermittedDNSDomains, - ExcludedDNSDomains: opts.ExcludedDNSDomains, - PermittedIPRanges: opts.PermittedIPRanges, - ExcludedIPRanges: opts.ExcludedIPRanges, - PermittedEmailAddresses: opts.PermittedEmailAddresses, - ExcludedEmailAddresses: opts.ExcludedEmailAddresses, - PermittedURIDomains: opts.PermittedURIDomains, - ExcludedURIDomains: opts.ExcludedURIDomains, - CRLDistributionPoints: opts.CRLDistributionPoints, - PolicyIdentifiers: opts.PolicyIdentifiers, - Policies: opts.Policies, - } - - if opts.MaxPathLen != nil { - cert.MaxPathLen = *opts.MaxPathLen - cert.MaxPathLenZero = true - } - - if cert.NotBefore.IsZero() { - cert.NotBefore = time.Now() - } - if cert.NotAfter.IsZero() { - if opts.Expiry == 0 { - cert.NotAfter = cert.NotBefore.Add(defaultDuration) - } else { - cert.NotAfter = cert.NotBefore.Add(opts.Expiry) - } - } - - if cert.SerialNumber == nil { - serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) - randomSerialNumber, err := rand.Int(rand.Reader, serialNumberLimit) - if err != nil { - panic("failed to obtain randomness:" + err.Error()) - } - cert.SerialNumber = randomSerialNumber - } - return cert -} - -// CertificateOptions represents all options which can be set using -// CreateCertificate (see Go docs of it). Further it offers Expiry to set a -// validity duration instead of absolute times. -type CertificateOptions struct { - SignatureAlgorithm x509.SignatureAlgorithm - - SerialNumber *big.Int - Subject pkix.Name - - NotBefore, NotAfter time.Time // Validity bounds. - Expiry time.Duration - - KeyUsage x509.KeyUsage - ExtKeyUsage []x509.ExtKeyUsage // Sequence of extended key usages. - - ExtraExtensions []pkix.Extension - UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package. - - BasicConstraintsValid bool - IsCA bool - // if nil MaxPathLen = 0, MaxPathLenZero = false - // else: MaxPathLen = *this, MaxPathLenZero = true - MaxPathLen *int - - // if CA defaults to sha something something - SubjectKeyId []byte - // gets defaulted to parent.SubjectKeyID - AuthorityKeyId []byte - - OCSPServer []string - IssuingCertificateURL []string - - // SAN - DNSNames []string - EmailAddresses []string - IPAddresses []net.IP - URIs []*url.URL - - // Name constraints - PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical. - PermittedDNSDomains []string - ExcludedDNSDomains []string - PermittedIPRanges []*net.IPNet - ExcludedIPRanges []*net.IPNet - PermittedEmailAddresses []string - ExcludedEmailAddresses []string - PermittedURIDomains []string - ExcludedURIDomains []string - - // CRL Distribution Points - CRLDistributionPoints []string - - PolicyIdentifiers []asn1.ObjectIdentifier - Policies []x509.OID -} - -func (co *CertificateOptions) BindFlags(fs *pflag.FlagSet) { - fs.StringSliceVar(&co.DNSNames, "dns", []string{}, "DNS subject alternative name.") - fs.StringSliceVar(&co.EmailAddresses, "email", []string{}, "Email subject alternative name.") - fs.IPSliceVar(&co.IPAddresses, "ip", []net.IP{}, "IP subject alternative name.") - fs.Var(newURISliceValue(&co.URIs), "uri", "URI subject alternative name.") - fs.Var(newSignAlgValue(&co.SignatureAlgorithm), "sign-alg", "Signature Algorithm. See 'pcert list' for available algorithms.") - fs.Var(newTimeValue(&co.NotBefore), "not-before", fmt.Sprintf("Not valid before time in RFC3339 format (e.g. '%s').", time.Now().UTC().Format(time.RFC3339))) - fs.Var(newTimeValue(&co.NotAfter), "not-after", fmt.Sprintf("Not valid after time in RFC3339 format (e.g. '%s').", time.Now().Add(time.Hour*24*60).UTC().Format(time.RFC3339))) - fs.Var(newSubjectValue(&co.Subject), "subject", "Subject in the form '/C=CH/O=My Org/OU=My Team'.") - - //fs.BoolVar(&co.BasicConstraintsValid, "basic-constraints", cert.BasicConstraintsValid, "Add basic constraints extension.") - //fs.BoolVar(&co.IsCA, "is-ca", cert.IsCA, "Mark certificate as CA in the basic constraints. Only takes effect if --basic-constraints is true.") - //fs.Var(newMaxPathLengthValue(co), "max-path-length", "Sets the max path length in the basic constraints.") - - fs.Var(newKeyUsageValue(&co.KeyUsage), "key-usage", "Set the key usage. See 'pcert list' for available key usages.") - fs.Var(newExtKeyUsageValue(&co.ExtKeyUsage), "ext-key-usage", "Set the extended key usage. See 'pcert list' for available extended key usages.") -} diff --git a/cmd/pcert/flags.go b/cmd/pcert/flags.go index e953738..3125bc7 100644 --- a/cmd/pcert/flags.go +++ b/cmd/pcert/flags.go @@ -62,3 +62,21 @@ func RegisterCertificateRequestCompletionFuncs(cmd *cobra.Command) { func RegisterKeyCompletionFuncs(cmd *cobra.Command) { _ = cmd.RegisterFlagCompletionFunc("key-alg", keyAlgorithmCompletionFunc) } + +func BindCertificateOptionsFlags(fs *pflag.FlagSet, co *pcert.CertificateOptions) { + fs.StringSliceVar(&co.DNSNames, "dns", []string{}, "DNS subject alternative name.") + fs.StringSliceVar(&co.EmailAddresses, "email", []string{}, "Email subject alternative name.") + fs.IPSliceVar(&co.IPAddresses, "ip", []net.IP{}, "IP subject alternative name.") + fs.Var(newURISliceValue(&co.URIs), "uri", "URI subject alternative name.") + fs.Var(newSignAlgValue(&co.SignatureAlgorithm), "sign-alg", "Signature Algorithm. See 'pcert list' for available algorithms.") + fs.Var(newTimeValue(&co.NotBefore), "not-before", fmt.Sprintf("Not valid before time in RFC3339 format (e.g. '%s').", time.Now().UTC().Format(time.RFC3339))) + fs.Var(newTimeValue(&co.NotAfter), "not-after", fmt.Sprintf("Not valid after time in RFC3339 format (e.g. '%s').", time.Now().Add(time.Hour*24*60).UTC().Format(time.RFC3339))) + fs.Var(newSubjectValue(&co.Subject), "subject", "Subject in the form '/C=CH/O=My Org/OU=My Team'.") + + //fs.BoolVar(&co.BasicConstraintsValid, "basic-constraints", cert.BasicConstraintsValid, "Add basic constraints extension.") + //fs.BoolVar(&co.IsCA, "is-ca", cert.IsCA, "Mark certificate as CA in the basic constraints. Only takes effect if --basic-constraints is true.") + //fs.Var(newMaxPathLengthValue(co), "max-path-length", "Sets the max path length in the basic constraints.") + + fs.Var(newKeyUsageValue(&co.KeyUsage), "key-usage", "Set the key usage. See 'pcert list' for available key usages.") + fs.Var(newExtKeyUsageValue(&co.ExtKeyUsage), "ext-key-usage", "Set the extended key usage. See 'pcert list' for available extended key usages.") +} diff --git a/example_test.go b/example_test.go index 340263d..66668d5 100644 --- a/example_test.go +++ b/example_test.go @@ -12,16 +12,23 @@ func ExampleCreate_selfSigned() { cert := NewServerCertificate("localhost") // self-signed - certPEM, keyPEM, err := Create(cert, nil, nil) + certDER, key, err := CreateCertificate(cert, nil, nil) if err != nil { log.Fatal(err) } - err = os.WriteFile("server.crt", certPEM, 0o644) + keyPEM, err := EncodeKey(key) if err != nil { log.Fatal(err) } - err = os.WriteFile("server.crt", keyPEM, 0o600) + + certPEM := Encode(certDER) + + err = os.WriteFile("server.crt", certPEM, 0644) + if err != nil { + log.Fatal(err) + } + err = os.WriteFile("server.crt", keyPEM, 0600) if err != nil { log.Fatal(err) } @@ -43,11 +50,18 @@ func ExampleCreate_signed() { // create signed server certificate cert := NewServerCertificate("localhost") - certPEM, keyPEM, err := Create(cert, rootCACert, rootCAKey) + certDER, key, err := CreateCertificate(cert, rootCACert, rootCAKey) if err != nil { log.Fatal(err) } + keyPEM, err := EncodeKey(key) + if err != nil { + log.Fatal(err) + } + + certPEM := Encode(certDER) + err = os.WriteFile("server.crt", certPEM, 0o644) if err != nil { log.Fatal(err) @@ -67,11 +81,18 @@ func ExampleCreateWithKeyOptions() { Size: 4096, } - certPEM, keyPEM, err := CreateWithKeyOptions(cert, keyOptions, nil, nil) + certDER, key, err := CreateWithKeyOptions(cert, keyOptions, nil, nil) + if err != nil { + log.Fatal(err) + } + + keyPEM, err := EncodeKey(key) if err != nil { log.Fatal(err) } + certPEM := Encode(certDER) + _, _ = os.Stdout.Write(certPEM) _, _ = os.Stdout.Write(keyPEM) } diff --git a/profile.go b/profile.go index 080c912..4c993ea 100644 --- a/profile.go +++ b/profile.go @@ -9,19 +9,14 @@ const ( defaultKeyUsage = x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature ) -// NewCertificate returns a new certificate which have the CommonName set to name -func NewCertificate(name string) *x509.Certificate { - return &x509.Certificate{ - Subject: pkix.Name{ - CommonName: name, - }, - } -} - // NewClientCertificate returns a new certificate. The CommonName is set to name // and typical client certificate settings are set (see SetClientProfile function). func NewClientCertificate(name string) *x509.Certificate { - cert := NewCertificate(name) + cert := NewCertificate(&CertificateOptions{ + Subject: pkix.Name{ + CommonName: name, + }, + }) SetClientProfile(cert) return cert } @@ -29,7 +24,11 @@ func NewClientCertificate(name string) *x509.Certificate { // NewServerCertificate returns a new certificate. The CommonName is set to name // and typical server certificate settings are set (see SetServerProfile function). func NewServerCertificate(name string) *x509.Certificate { - cert := NewCertificate(name) + cert := NewCertificate(&CertificateOptions{ + Subject: pkix.Name{ + CommonName: name, + }, + }) SetServerProfile(cert) return cert } @@ -37,7 +36,11 @@ func NewServerCertificate(name string) *x509.Certificate { // NewCACertificate returns a new certificate. The CommonName is set to name and // typical CA certificate settings are set (see SetCAProfile function). func NewCACertificate(name string) *x509.Certificate { - cert := NewCertificate(name) + cert := NewCertificate(&CertificateOptions{ + Subject: pkix.Name{ + CommonName: name, + }, + }) SetCAProfile(cert) return cert }