forked from TrueCloudLab/certificates
Add scep authority to context.
This commit is contained in:
parent
216d8f0efb
commit
688f9ceb56
2 changed files with 44 additions and 5 deletions
10
ca/ca.go
10
ca/ca.go
|
@ -225,9 +225,10 @@ func (ca *CA) Init(cfg *config.Config) (*CA, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var scepAuthority *scep.Authority
|
||||||
if ca.shouldServeSCEPEndpoints() {
|
if ca.shouldServeSCEPEndpoints() {
|
||||||
scepPrefix := "scep"
|
scepPrefix := "scep"
|
||||||
scepAuthority, err := scep.New(auth, scep.AuthorityOptions{
|
scepAuthority, err = scep.New(auth, scep.AuthorityOptions{
|
||||||
Service: auth.GetSCEPService(),
|
Service: auth.GetSCEPService(),
|
||||||
DNS: dns,
|
DNS: dns,
|
||||||
Prefix: scepPrefix,
|
Prefix: scepPrefix,
|
||||||
|
@ -279,7 +280,7 @@ func (ca *CA) Init(cfg *config.Config) (*CA, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create context with all the necessary values.
|
// Create context with all the necessary values.
|
||||||
baseContext := buildContext(auth, acmeDB)
|
baseContext := buildContext(auth, scepAuthority, acmeDB)
|
||||||
|
|
||||||
ca.srv = server.New(cfg.Address, handler, tlsConfig)
|
ca.srv = server.New(cfg.Address, handler, tlsConfig)
|
||||||
ca.srv.BaseContext = func(net.Listener) context.Context {
|
ca.srv.BaseContext = func(net.Listener) context.Context {
|
||||||
|
@ -303,7 +304,7 @@ func (ca *CA) Init(cfg *config.Config) (*CA, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// buildContext builds the server base context.
|
// buildContext builds the server base context.
|
||||||
func buildContext(a *authority.Authority, acmeDB acme.DB) context.Context {
|
func buildContext(a *authority.Authority, scepAuthority *scep.Authority, acmeDB acme.DB) context.Context {
|
||||||
ctx := authority.NewContext(context.Background(), a)
|
ctx := authority.NewContext(context.Background(), a)
|
||||||
if authDB := a.GetDatabase(); authDB != nil {
|
if authDB := a.GetDatabase(); authDB != nil {
|
||||||
ctx = db.NewContext(ctx, authDB)
|
ctx = db.NewContext(ctx, authDB)
|
||||||
|
@ -311,6 +312,9 @@ func buildContext(a *authority.Authority, acmeDB acme.DB) context.Context {
|
||||||
if adminDB := a.GetAdminDatabase(); adminDB != nil {
|
if adminDB := a.GetAdminDatabase(); adminDB != nil {
|
||||||
ctx = admin.NewContext(ctx, adminDB)
|
ctx = admin.NewContext(ctx, adminDB)
|
||||||
}
|
}
|
||||||
|
if scepAuthority != nil {
|
||||||
|
ctx = scep.NewContext(ctx, scepAuthority)
|
||||||
|
}
|
||||||
if acmeDB != nil {
|
if acmeDB != nil {
|
||||||
ctx = acme.NewContext(ctx, acmeDB)
|
ctx = acme.NewContext(ctx, acmeDB)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,29 @@ type Authority struct {
|
||||||
signAuth SignAuthority
|
signAuth SignAuthority
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type authorityKey struct{}
|
||||||
|
|
||||||
|
// NewContext adds the given authority to the context.
|
||||||
|
func NewContext(ctx context.Context, a *Authority) context.Context {
|
||||||
|
return context.WithValue(ctx, authorityKey{}, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromContext returns the current authority from the given context.
|
||||||
|
func FromContext(ctx context.Context) (a *Authority, ok bool) {
|
||||||
|
a, ok = ctx.Value(authorityKey{}).(*Authority)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// MustFromContext returns the current authority from the given context. It will
|
||||||
|
// panic if the authority is not in the context.
|
||||||
|
func MustFromContext(ctx context.Context) *Authority {
|
||||||
|
if a, ok := FromContext(ctx); !ok {
|
||||||
|
panic("scep authority is not in the context")
|
||||||
|
} else {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// AuthorityOptions required to create a new SCEP Authority.
|
// AuthorityOptions required to create a new SCEP Authority.
|
||||||
type AuthorityOptions struct {
|
type AuthorityOptions struct {
|
||||||
// Service provides the certificate chain, the signer and the decrypter to the Authority
|
// Service provides the certificate chain, the signer and the decrypter to the Authority
|
||||||
|
@ -40,6 +63,20 @@ type AuthorityOptions struct {
|
||||||
Prefix string
|
Prefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type optionsKey struct{}
|
||||||
|
|
||||||
|
func newOptionsContext(ctx context.Context, o *AuthorityOptions) context.Context {
|
||||||
|
return context.WithValue(ctx, optionsKey{}, o)
|
||||||
|
}
|
||||||
|
|
||||||
|
func optionsFromContext(ctx context.Context) *AuthorityOptions {
|
||||||
|
o, ok := ctx.Value(optionsKey{}).(*AuthorityOptions)
|
||||||
|
if !ok {
|
||||||
|
panic("scep options are not in the context")
|
||||||
|
}
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
// SignAuthority is the interface for a signing authority
|
// SignAuthority is the interface for a signing authority
|
||||||
type SignAuthority interface {
|
type SignAuthority interface {
|
||||||
Sign(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
|
Sign(cr *x509.CertificateRequest, opts provisioner.SignOptions, signOpts ...provisioner.SignOption) ([]*x509.Certificate, error)
|
||||||
|
@ -163,7 +200,6 @@ func (a *Authority) GetCACertificates(ctx context.Context) ([]*x509.Certificate,
|
||||||
|
|
||||||
// DecryptPKIEnvelope decrypts an enveloped message
|
// DecryptPKIEnvelope decrypts an enveloped message
|
||||||
func (a *Authority) DecryptPKIEnvelope(ctx context.Context, msg *PKIMessage) error {
|
func (a *Authority) DecryptPKIEnvelope(ctx context.Context, msg *PKIMessage) error {
|
||||||
|
|
||||||
p7c, err := pkcs7.Parse(msg.P7.Content)
|
p7c, err := pkcs7.Parse(msg.P7.Content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error parsing pkcs7 content: %w", err)
|
return fmt.Errorf("error parsing pkcs7 content: %w", err)
|
||||||
|
@ -210,7 +246,6 @@ func (a *Authority) DecryptPKIEnvelope(ctx context.Context, msg *PKIMessage) err
|
||||||
// SignCSR creates an x509.Certificate based on a CSR template and Cert Authority credentials
|
// SignCSR creates an x509.Certificate based on a CSR template and Cert Authority credentials
|
||||||
// returns a new PKIMessage with CertRep data
|
// returns a new PKIMessage with CertRep data
|
||||||
func (a *Authority) SignCSR(ctx context.Context, csr *x509.CertificateRequest, msg *PKIMessage) (*PKIMessage, error) {
|
func (a *Authority) SignCSR(ctx context.Context, csr *x509.CertificateRequest, msg *PKIMessage) (*PKIMessage, error) {
|
||||||
|
|
||||||
// TODO: intermediate storage of the request? In SCEP it's possible to request a csr/certificate
|
// TODO: intermediate storage of the request? In SCEP it's possible to request a csr/certificate
|
||||||
// to be signed, which can be performed asynchronously / out-of-band. In that case a client can
|
// to be signed, which can be performed asynchronously / out-of-band. In that case a client can
|
||||||
// poll for the status. It seems to be similar as what can happen in ACME, so might want to model
|
// poll for the status. It seems to be similar as what can happen in ACME, so might want to model
|
||||||
|
|
Loading…
Reference in a new issue