diff options
author | Gibheer <gibheer@gmail.com> | 2015-03-16 16:48:42 +0100 |
---|---|---|
committer | Gibheer <gibheer@gmail.com> | 2015-03-16 16:48:42 +0100 |
commit | 362fe8ff381893f8396090435ae77fd0a2492b4a (patch) | |
tree | 496913a3e150c71095b8e0d97e897809c700b64b /certificate.go | |
parent | d4d2d4c09ba082113e0ea232149d50c9c8b9cbfd (diff) |
finalize creation of a certificate
With the options it is now finished. The only stuff left to do is to add
all options provided by the go API. But this should be sufficient.
Diffstat (limited to 'certificate.go')
-rw-r--r-- | certificate.go | 46 |
1 files changed, 39 insertions, 7 deletions
diff --git a/certificate.go b/certificate.go index b597834..e118833 100644 --- a/certificate.go +++ b/certificate.go @@ -5,7 +5,10 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/pem" + "fmt" + "math/big" "net" + "time" ) const PemLabelCertificateRequest = "CERTIFICATE REQUEST" @@ -14,13 +17,20 @@ type ( CertificateData struct { Subject pkix.Name - DnsNames []string + DNSNames []string EmailAddresses []string - IpAddresses []net.IP + IPAddresses []net.IP } Certificate x509.Certificate CertificateRequest x509.CertificateRequest + + CertificateOptions struct { + SerialNumber *big.Int + NotBefore time.Time + NotAfter time.Time // Validity bounds. + KeyUsage x509.KeyUsage + } ) func NewCertificateData() *CertificateData { @@ -33,8 +43,8 @@ func (c *CertificateData) ToCertificateRequest(private_key PrivateKey) (*Certifi csr := &x509.CertificateRequest{} csr.Subject = c.Subject - csr.DNSNames = c.DnsNames - csr.IPAddresses = c.IpAddresses + csr.DNSNames = c.DNSNames + csr.IPAddresses = c.IPAddresses csr.EmailAddresses = c.EmailAddresses csr_asn1, err := x509.CreateCertificateRequest(rand.Reader, csr, private_key.PrivateKey()) @@ -58,20 +68,37 @@ func (c *CertificateRequest) MarshalPem() (marshalledPemBlock, error) { // Convert the certificate sign request to a certificate using the private key // of the signer and the certificate of the signer. // If the certificate is null, the sign request will be used to sign itself. +// Please also see the certificate options struct for information on mandatory fields. // For more information, please read http://golang.org/pkg/crypto/x509/#CreateCertificate -func (c *CertificateRequest) ToCertificate(private_key PrivateKey, ca *Certificate) (*Certificate, error) { +func (c *CertificateRequest) ToCertificate(private_key PrivateKey, + cert_opts CertificateOptions, ca *Certificate) (*Certificate, error) { + + if err := cert_opts.Valid(); err != nil { return nil, err } + template := &x509.Certificate{} template.Subject = c.Subject template.DNSNames = c.DNSNames template.IPAddresses = c.IPAddresses template.EmailAddresses = c.EmailAddresses + // if no ca is given, we have to set IsCA to self sign + if ca == nil { + template.IsCA = true + } + + template.NotBefore = cert_opts.NotBefore + template.NotAfter = cert_opts.NotAfter + template.KeyUsage = cert_opts.KeyUsage + template.SerialNumber = cert_opts.SerialNumber + var cert_asn1 []byte var err error + // if we have no ca which can sign the cert, a self signed cert is wanted + // (or isn't it? Maybe we should split creation of the template? But that would be ugly) if ca == nil { - cert_asn1, err = x509.CreateCertificate(rand.Reader, template, template, c.PublicKey, private_key) + cert_asn1, err = x509.CreateCertificate(rand.Reader, template, template, c.PublicKey, private_key.PrivateKey()) } else { - cert_asn1, err = x509.CreateCertificate(rand.Reader, template, (*x509.Certificate)(ca), c.PublicKey, private_key) + cert_asn1, err = x509.CreateCertificate(rand.Reader, template, (*x509.Certificate)(ca), c.PublicKey, private_key.PrivateKey()) } if err != nil { return nil, err } return LoadCertificate(cert_asn1) @@ -83,3 +110,8 @@ func LoadCertificate(raw []byte) (*Certificate, error) { if err != nil { return nil, err } return (*Certificate)(cert), nil } + +func (co *CertificateOptions) Valid() error { + if co.SerialNumber == nil { return fmt.Errorf("No serial number set!") } + return nil +} |