Add handling of options

This commit is contained in:
Herman Slatman 2021-02-26 12:32:43 +01:00
parent 19f0397fe9
commit 4322933588
No known key found for this signature in database
GPG key ID: F4D8A44EA0A75A4F
3 changed files with 57 additions and 40 deletions

View file

@ -235,12 +235,12 @@ func (h *Handler) GetCACert(w http.ResponseWriter, r *http.Request, scepResponse
func (h *Handler) GetCACaps(w http.ResponseWriter, r *http.Request, scepResponse SCEPResponse) error { func (h *Handler) GetCACaps(w http.ResponseWriter, r *http.Request, scepResponse SCEPResponse) error {
ctx := r.Context() //ctx := r.Context()
_, err := ProvisionerFromContext(ctx) // _, err := ProvisionerFromContext(ctx)
if err != nil { // if err != nil {
return err // return err
} // }
// TODO: get the actual capabilities from provisioner config // TODO: get the actual capabilities from provisioner config
scepResponse.Data = formatCapabilities(defaultCapabilities) scepResponse.Data = formatCapabilities(defaultCapabilities)
@ -250,6 +250,8 @@ func (h *Handler) GetCACaps(w http.ResponseWriter, r *http.Request, scepResponse
func (h *Handler) PKIOperation(w http.ResponseWriter, r *http.Request, scepRequest SCEPRequest, scepResponse SCEPResponse) error { func (h *Handler) PKIOperation(w http.ResponseWriter, r *http.Request, scepRequest SCEPRequest, scepResponse SCEPResponse) error {
ctx := r.Context()
msg, err := microscep.ParsePKIMessage(scepRequest.Message) msg, err := microscep.ParsePKIMessage(scepRequest.Message)
if err != nil { if err != nil {
return err return err
@ -262,7 +264,7 @@ func (h *Handler) PKIOperation(w http.ResponseWriter, r *http.Request, scepReque
Raw: msg.Raw, Raw: msg.Raw,
} }
if err := h.Auth.DecryptPKIEnvelope(pkimsg); err != nil { if err := h.Auth.DecryptPKIEnvelope(ctx, pkimsg); err != nil {
return err return err
} }
@ -271,7 +273,7 @@ func (h *Handler) PKIOperation(w http.ResponseWriter, r *http.Request, scepReque
} }
csr := pkimsg.CSRReqMessage.CSR csr := pkimsg.CSRReqMessage.CSR
id, err := createKeyIdentifier(csr.PublicKey) subjectKeyID, err := createKeyIdentifier(csr.PublicKey)
if err != nil { if err != nil {
return err return err
} }
@ -286,16 +288,17 @@ func (h *Handler) PKIOperation(w http.ResponseWriter, r *http.Request, scepReque
Subject: csr.Subject, Subject: csr.Subject,
NotBefore: time.Now().Add(-600).UTC(), NotBefore: time.Now().Add(-600).UTC(),
NotAfter: time.Now().AddDate(0, 0, days).UTC(), NotAfter: time.Now().AddDate(0, 0, days).UTC(),
SubjectKeyId: id, SubjectKeyId: subjectKeyID,
KeyUsage: x509.KeyUsageDigitalSignature, KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{ ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageClientAuth,
}, },
SignatureAlgorithm: csr.SignatureAlgorithm, SignatureAlgorithm: csr.SignatureAlgorithm,
EmailAddresses: csr.EmailAddresses, EmailAddresses: csr.EmailAddresses,
DNSNames: csr.DNSNames,
} }
certRep, err := h.Auth.SignCSR(pkimsg, template) certRep, err := h.Auth.SignCSR(ctx, pkimsg, template)
if err != nil { if err != nil {
return err return err
} }
@ -381,17 +384,3 @@ func contentHeader(operation string, certNum int) string {
return "text/plain" return "text/plain"
} }
} }
// ProvisionerFromContext searches the context for a provisioner. Returns the
// provisioner or an error.
func ProvisionerFromContext(ctx context.Context) (scep.Provisioner, error) {
val := ctx.Value(acme.ProvisionerContextKey)
if val == nil {
return nil, errors.New("provisioner expected in request context")
}
p, ok := val.(scep.Provisioner)
if !ok || p == nil {
return nil, errors.New("provisioner in context is not a SCEP provisioner")
}
return p, nil
}

View file

@ -2,6 +2,7 @@ package scep
import ( import (
"bytes" "bytes"
"context"
"crypto/x509" "crypto/x509"
"errors" "errors"
"fmt" "fmt"
@ -54,8 +55,8 @@ type Interface interface {
GetCACertificates() ([]*x509.Certificate, error) GetCACertificates() ([]*x509.Certificate, error)
//GetSigningKey() (*rsa.PrivateKey, error) //GetSigningKey() (*rsa.PrivateKey, error)
DecryptPKIEnvelope(*PKIMessage) error DecryptPKIEnvelope(ctx context.Context, msg *PKIMessage) error
SignCSR(msg *PKIMessage, template *x509.Certificate) (*PKIMessage, error) SignCSR(ctx context.Context, msg *PKIMessage, template *x509.Certificate) (*PKIMessage, error)
} }
// Authority is the layer that handles all SCEP interactions. // Authority is the layer that handles all SCEP interactions.
@ -156,7 +157,7 @@ func (a *Authority) GetCACertificates() ([]*x509.Certificate, error) {
} }
// DecryptPKIEnvelope decrypts an enveloped message // DecryptPKIEnvelope decrypts an enveloped message
func (a *Authority) DecryptPKIEnvelope(msg *PKIMessage) error { func (a *Authority) DecryptPKIEnvelope(ctx context.Context, msg *PKIMessage) error {
data := msg.Raw data := msg.Raw
@ -221,14 +222,19 @@ func (a *Authority) DecryptPKIEnvelope(msg *PKIMessage) error {
return nil return nil
} }
// SignCSR creates an x509.Certificate based on a 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 (msg *PKIMessage) SignCSR(crtAuth *x509.Certificate, keyAuth *rsa.PrivateKey, template *x509.Certificate) (*PKIMessage, error) { //func (msg *PKIMessage) SignCSR(crtAuth *x509.Certificate, keyAuth *rsa.PrivateKey, template *x509.Certificate) (*PKIMessage, error) {
func (a *Authority) SignCSR(msg *PKIMessage, template *x509.Certificate) (*PKIMessage, error) { func (a *Authority) SignCSR(ctx context.Context, msg *PKIMessage, template *x509.Certificate) (*PKIMessage, error) {
p, err := ProvisionerFromContext(ctx)
if err != nil {
return nil, err
}
// check if CSRReqMessage has already been decrypted // check if CSRReqMessage has already been decrypted
if msg.CSRReqMessage.CSR == nil { if msg.CSRReqMessage.CSR == nil {
if err := a.DecryptPKIEnvelope(msg); err != nil { if err := a.DecryptPKIEnvelope(ctx, msg); err != nil {
return nil, err return nil, err
} }
} }
@ -238,13 +244,17 @@ func (a *Authority) SignCSR(msg *PKIMessage, template *x509.Certificate) (*PKIMe
// Template data // Template data
data := x509util.NewTemplateData() data := x509util.NewTemplateData()
data.SetCommonName(csr.Subject.CommonName) data.SetCommonName(csr.Subject.CommonName)
//data.Set(x509util.SANsKey, sans) data.SetSANs(csr.DNSNames)
// templateOptions, err := provisioner.TemplateOptions(p.GetOptions(), data) // TODO: proper options
// if err != nil { opts := provisioner.SignOptions{}
// return nil, ServerInternalErr(errors.Wrapf(err, "error creating template options from ACME provisioner")) signOps := []provisioner.SignOption{}
// }
// signOps = append(signOps, templateOptions) templateOptions, err := provisioner.TemplateOptions(p.GetOptions(), data)
if err != nil {
return nil, fmt.Errorf("error creating template options from SCEP provisioner")
}
signOps = append(signOps, templateOptions)
// // Create and store a new certificate. // // Create and store a new certificate.
// certChain, err := auth.Sign(csr, provisioner.SignOptions{ // certChain, err := auth.Sign(csr, provisioner.SignOptions{
@ -255,11 +265,7 @@ func (a *Authority) SignCSR(msg *PKIMessage, template *x509.Certificate) (*PKIMe
// return nil, ServerInternalErr(errors.Wrapf(err, "error generating certificate for order %s", o.ID)) // return nil, ServerInternalErr(errors.Wrapf(err, "error generating certificate for order %s", o.ID))
// } // }
// TODO: proper options certs, err := a.signAuth.Sign(csr, opts, signOps...)
signOps := provisioner.SignOptions{}
signOps2 := []provisioner.SignOption{}
certs, err := a.signAuth.Sign(csr, signOps, signOps2...)
if err != nil { if err != nil {
return nil, err return nil, err
} }

22
scep/common.go Normal file
View file

@ -0,0 +1,22 @@
package scep
import (
"context"
"errors"
"github.com/smallstep/certificates/acme"
)
// ProvisionerFromContext searches the context for a SCEP provisioner.
// Returns the provisioner or an error.
func ProvisionerFromContext(ctx context.Context) (Provisioner, error) {
val := ctx.Value(acme.ProvisionerContextKey)
if val == nil {
return nil, errors.New("provisioner expected in request context")
}
p, ok := val.(Provisioner)
if !ok || p == nil {
return nil, errors.New("provisioner in context is not a SCEP provisioner")
}
return p, nil
}