Add CSR to `SCEPCHALLENGE` webhook request body

pull/1523/head
Herman Slatman 8 months ago
parent 98d015b5c3
commit 36f1dd70bf
No known key found for this signature in database
GPG Key ID: F4D8A44EA0A75A4F

@ -143,12 +143,14 @@ var (
// that case, the other webhooks will be skipped. If none of
// the webhooks indicates the value of the challenge was accepted,
// an error is returned.
func (c *challengeValidationController) Validate(ctx context.Context, challenge, transactionID string) error {
func (c *challengeValidationController) Validate(ctx context.Context, csr *x509.CertificateRequest, challenge, transactionID string) error {
for _, wh := range c.webhooks {
req := &webhook.RequestBody{
SCEPChallenge: challenge,
SCEPTransactionID: transactionID,
req, err := webhook.NewRequestBody(webhook.WithX509CertificateRequest(csr))
if err != nil {
return fmt.Errorf("failed creating new webhook request: %w", err)
}
req.SCEPChallenge = challenge
req.SCEPTransactionID = transactionID
resp, err := wh.DoWithContext(ctx, c.client, req, nil) // TODO(hs): support templated URL? Requires some refactoring
if err != nil {
return fmt.Errorf("failed executing webhook request: %w", err)
@ -329,13 +331,13 @@ func (s *SCEP) GetContentEncryptionAlgorithm() int {
// ValidateChallenge validates the provided challenge. It starts by
// selecting the validation method to use, then performs validation
// according to that method.
func (s *SCEP) ValidateChallenge(ctx context.Context, challenge, transactionID string) error {
func (s *SCEP) ValidateChallenge(ctx context.Context, csr *x509.CertificateRequest, challenge, transactionID string) error {
if s.challengeValidationController == nil {
return fmt.Errorf("provisioner %q wasn't initialized", s.Name)
}
switch s.selectValidationMethod() {
case validationMethodWebhook:
return s.challengeValidationController.Validate(ctx, challenge, transactionID)
return s.challengeValidationController.Validate(ctx, csr, challenge, transactionID)
default:
if subtle.ConstantTimeCompare([]byte(s.ChallengePassword), []byte(challenge)) == 0 {
return errors.New("invalid challenge password provided")

@ -141,7 +141,7 @@ func Test_challengeValidationController_Validate(t *testing.T) {
}
ctx := context.Background()
err := c.Validate(ctx, tt.args.challenge, tt.args.transactionID)
err := c.Validate(ctx, nil, tt.args.challenge, tt.args.transactionID)
if tt.expErr != nil {
assert.EqualError(t, err, tt.expErr.Error())
@ -330,7 +330,7 @@ func TestSCEP_ValidateChallenge(t *testing.T) {
require.NoError(t, err)
ctx := context.Background()
err = tt.p.ValidateChallenge(ctx, tt.args.challenge, tt.args.transactionID)
err = tt.p.ValidateChallenge(ctx, nil, tt.args.challenge, tt.args.transactionID)
if tt.expErr != nil {
assert.EqualError(t, err, tt.expErr.Error())
return

@ -315,7 +315,7 @@ func PKIOperation(ctx context.Context, req request) (Response, error) {
// a certificate exists; then it will use RenewalReq. Adding the challenge check here may be a small breaking change for clients.
// We'll have to see how it works out.
if msg.MessageType == microscep.PKCSReq || msg.MessageType == microscep.RenewalReq {
if err := auth.ValidateChallenge(ctx, challengePassword, transactionID); err != nil {
if err := auth.ValidateChallenge(ctx, csr, challengePassword, transactionID); err != nil {
if errors.Is(err, provisioner.ErrSCEPChallengeInvalid) {
return createFailureResponse(ctx, csr, msg, microscep.BadRequest, err)
}

@ -503,9 +503,9 @@ func (a *Authority) GetCACaps(ctx context.Context) []string {
return caps
}
func (a *Authority) ValidateChallenge(ctx context.Context, challenge, transactionID string) error {
func (a *Authority) ValidateChallenge(ctx context.Context, csr *x509.CertificateRequest, challenge, transactionID string) error {
p := provisionerFromContext(ctx)
return p.ValidateChallenge(ctx, challenge, transactionID)
return p.ValidateChallenge(ctx, csr, challenge, transactionID)
}
func (a *Authority) selectDecrypter(ctx context.Context) (cert *x509.Certificate, decrypter crypto.Decrypter, err error) {

@ -20,7 +20,7 @@ type Provisioner interface {
GetDecrypter() (*x509.Certificate, crypto.Decrypter)
GetSigner() (*x509.Certificate, crypto.Signer)
GetContentEncryptionAlgorithm() int
ValidateChallenge(ctx context.Context, challenge, transactionID string) error
ValidateChallenge(ctx context.Context, csr *x509.CertificateRequest, challenge, transactionID string) error
}
// provisionerKey is the key type for storing and searching a

@ -24,6 +24,9 @@ func NewRequestBody(options ...RequestBodyOption) (*RequestBody, error) {
func WithX509CertificateRequest(cr *x509.CertificateRequest) RequestBodyOption {
return func(rb *RequestBody) error {
if cr == nil {
return nil
}
rb.X509CertificateRequest = &X509CertificateRequest{
CertificateRequest: x509util.NewCertificateRequestFromX509(cr),
PublicKeyAlgorithm: cr.PublicKeyAlgorithm.String(),

Loading…
Cancel
Save