Gibheer
bc84bc4a28
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.
131 lines
2.8 KiB
Go
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
|
|
}
|