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() {
|
||||
scepPrefix := "scep"
|
||||
scepAuthority, err := scep.New(auth, scep.AuthorityOptions{
|
||||
scepAuthority, err = scep.New(auth, scep.AuthorityOptions{
|
||||
Service: auth.GetSCEPService(),
|
||||
DNS: dns,
|
||||
Prefix: scepPrefix,
|
||||
|
@ -279,7 +280,7 @@ func (ca *CA) Init(cfg *config.Config) (*CA, error) {
|
|||
}
|
||||
|
||||
// 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.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.
|
||||
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)
|
||||
if authDB := a.GetDatabase(); authDB != nil {
|
||||
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 {
|
||||
ctx = admin.NewContext(ctx, adminDB)
|
||||
}
|
||||
if scepAuthority != nil {
|
||||
ctx = scep.NewContext(ctx, scepAuthority)
|
||||
}
|
||||
if acmeDB != nil {
|
||||
ctx = acme.NewContext(ctx, acmeDB)
|
||||
}
|
||||
|
|
|
@ -27,6 +27,29 @@ type Authority struct {
|
|||
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.
|
||||
type AuthorityOptions struct {
|
||||
// Service provides the certificate chain, the signer and the decrypter to the Authority
|
||||
|
@ -40,6 +63,20 @@ type AuthorityOptions struct {
|
|||
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
|
||||
type SignAuthority interface {
|
||||
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
|
||||
func (a *Authority) DecryptPKIEnvelope(ctx context.Context, msg *PKIMessage) error {
|
||||
|
||||
p7c, err := pkcs7.Parse(msg.P7.Content)
|
||||
if err != nil {
|
||||
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
|
||||
// returns a new PKIMessage with CertRep data
|
||||
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
|
||||
// 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
|
||||
|
|
Loading…
Reference in a new issue