pkiadm/cmd/pkiadmd/certificate.go
Gibheer bc84bc4a28 add location support
This commit adds basic support for adding, deleting, ... locations. This
needed a bit of rework for the ResourceName, as it was kind of stupid to
have different implementations server internally and in the lib.

There is still some need for cleanup, but it works basically.
2017-05-31 21:03:51 +02:00

131 lines
2.8 KiB
Go

package main
import (
"encoding/pem"
"time"
"github.com/gibheer/pki"
"github.com/gibheer/pkiadm"
)
type (
Certificate struct {
ID string
IsCA bool
Duration time.Duration
PrivateKey pkiadm.ResourceName
Serial pkiadm.ResourceName
CSR pkiadm.ResourceName
CA pkiadm.ResourceName
Data []byte
}
)
func NewCertificate(id string, privateKey, serial, csr, ca pkiadm.ResourceName, isCA bool, duration time.Duration) (*Certificate, error) {
return &Certificate{
ID: id,
PrivateKey: privateKey,
Serial: serial,
CSR: csr,
CA: ca,
IsCA: isCA,
Duration: duration,
}, nil
}
// Return the unique ResourceName
func (c *Certificate) Name() pkiadm.ResourceName {
return pkiadm.ResourceName{c.ID, pkiadm.RTCertificate}
}
// AddDependency registers a depending resource to be retuened by Dependencies()
// Refresh must trigger a rebuild of the resource.
func (c *Certificate) Refresh(lookup *Storage) error {
var ca *pki.Certificate
if !c.IsCA {
cert, err := lookup.GetCertificate(c.CA)
if err != nil {
return err
}
ca, err = cert.GetCertificate()
if err != nil {
return err
}
}
csrRes, err := lookup.GetCSR(c.CSR)
if err != nil {
return err
}
csr, err := csrRes.GetCSR()
if err != nil {
return err
}
pkRes, err := lookup.GetPrivateKey(c.PrivateKey)
if err != nil {
return err
}
pk, err := pkRes.GetKey()
if err != nil {
return err
}
serRes, err := lookup.GetSerial(c.Serial)
if err != nil {
return err
}
serial, err := serRes.Generate()
if err != nil {
return err
}
// now we can start with the real interesting stuff
// TODO add key usage and that stuff
opts := pki.CertificateOptions{
SerialNumber: serial,
NotBefore: time.Now(),
NotAfter: time.Now().Add(c.Duration),
IsCA: c.IsCA,
CALength: 0, // TODO make this an option
}
cert, err := csr.ToCertificate(pk, opts, ca)
if err != nil {
return err
}
block, err := cert.ToPem()
if err != nil {
return err
}
block.Headers = map[string]string{"ID": c.ID}
c.Data = pem.EncodeToMemory(&block)
return nil
}
func (c *Certificate) GetCertificate() (*pki.Certificate, error) {
// TODO fix this, we must check if there is anything else
block, _ := pem.Decode(c.Data)
cert, err := pki.LoadCertificate(block.Bytes)
if err != nil {
return nil, err
}
return cert, nil
}
// Return the PEM output of the contained resource.
func (c *Certificate) Pem() ([]byte, error) { return c.Data, nil }
func (c *Certificate) Checksum() []byte { return Hash(c.Data) }
// DependsOn must return the resource names it is depending on.
func (c *Certificate) DependsOn() []pkiadm.ResourceName {
res := []pkiadm.ResourceName{
c.PrivateKey,
c.Serial,
c.CSR,
}
if !c.IsCA {
res = append(res, c.CA)
}
return res
}