mirror of
https://github.com/slackhq/nebula.git
synced 2024-12-22 04:08:31 +00:00
77 lines
2.1 KiB
Go
77 lines
2.1 KiB
Go
package cert
|
|
|
|
import (
|
|
"fmt"
|
|
"net/netip"
|
|
"time"
|
|
|
|
"github.com/slackhq/nebula/pkclient"
|
|
)
|
|
|
|
// TBSCertificate represents a certificate intended to be signed.
|
|
// It is invalid to use this structure as a Certificate.
|
|
type TBSCertificate struct {
|
|
Version Version
|
|
Name string
|
|
Networks []netip.Prefix
|
|
UnsafeNetworks []netip.Prefix
|
|
Groups []string
|
|
IsCA bool
|
|
NotBefore time.Time
|
|
NotAfter time.Time
|
|
PublicKey []byte
|
|
Curve Curve
|
|
issuer string
|
|
}
|
|
|
|
// Sign will create a sealed certificate using details provided by the TBSCertificate as long as those
|
|
// details do not violate constraints of the signing certificate.
|
|
// If the TBSCertificate is a CA then signer must be nil.
|
|
func (t *TBSCertificate) Sign(signer Certificate, curve Curve, key []byte) (Certificate, error) {
|
|
return t.sign(signer, curve, key, nil)
|
|
}
|
|
|
|
func (t *TBSCertificate) SignPkcs11(signer Certificate, curve Curve, client *pkclient.PKClient) (Certificate, error) {
|
|
if curve != Curve_P256 {
|
|
return nil, fmt.Errorf("only P256 is supported by PKCS#11")
|
|
}
|
|
|
|
return t.sign(signer, curve, nil, client)
|
|
}
|
|
|
|
func (t *TBSCertificate) sign(signer Certificate, curve Curve, key []byte, client *pkclient.PKClient) (Certificate, error) {
|
|
if curve != t.Curve {
|
|
return nil, fmt.Errorf("curve in cert and private key supplied don't match")
|
|
}
|
|
|
|
//TODO: make sure we have all minimum properties to sign, like a public key
|
|
|
|
if signer != nil {
|
|
if t.IsCA {
|
|
return nil, fmt.Errorf("can not sign a CA certificate with another")
|
|
}
|
|
|
|
err := checkCAConstraints(signer, t.NotBefore, t.NotAfter, t.Groups, t.Networks, t.UnsafeNetworks)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
issuer, err := signer.Fingerprint()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error computing issuer: %v", err)
|
|
}
|
|
t.issuer = issuer
|
|
} else {
|
|
if !t.IsCA {
|
|
return nil, fmt.Errorf("self signed certificates must have IsCA set to true")
|
|
}
|
|
}
|
|
|
|
switch t.Version {
|
|
case Version1:
|
|
return signV1(t, curve, key, client)
|
|
default:
|
|
return nil, fmt.Errorf("unknown cert version %d", t.Version)
|
|
}
|
|
}
|