diff --git a/authority/provisioner/scep.go b/authority/provisioner/scep.go index 3e3e77b9..0c514275 100644 --- a/authority/provisioner/scep.go +++ b/authority/provisioner/scep.go @@ -196,8 +196,6 @@ func (c *notificationController) Success(ctx context.Context, csr *x509.Certific return fmt.Errorf("failed creating new webhook request: %w", err) } req.X509Certificate.Raw = cert.Raw // adding the full certificate DER bytes - - // TODO(hs): more properties required? req.SCEPTransactionID = transactionID resp, err := wh.DoWithContext(ctx, c.client, req, nil) if err != nil { @@ -211,14 +209,15 @@ func (c *notificationController) Success(ctx context.Context, csr *x509.Certific return nil } -func (c *notificationController) Failure(ctx context.Context, csr *x509.CertificateRequest, transactionID string) error { +func (c *notificationController) Failure(ctx context.Context, csr *x509.CertificateRequest, transactionID string, errorCode int, errorDescription string) error { for _, wh := range c.webhooks { req, err := webhook.NewRequestBody(webhook.WithX509CertificateRequest(csr)) if err != nil { return fmt.Errorf("failed creating new webhook request: %w", err) } - // TODO(hs): more properties, such as error message / code required? req.SCEPTransactionID = transactionID + req.SCEPErrorCode = errorCode + req.SCEPErrorDescription = errorDescription resp, err := wh.DoWithContext(ctx, c.client, req, nil) if err != nil { return fmt.Errorf("failed executing webhook request: %w", err) @@ -427,11 +426,11 @@ func (s *SCEP) NotifySuccess(ctx context.Context, csr *x509.CertificateRequest, return s.notificationController.Success(ctx, csr, cert, transactionID) } -func (s *SCEP) NotifyFailure(ctx context.Context, csr *x509.CertificateRequest, transactionID string) error { +func (s *SCEP) NotifyFailure(ctx context.Context, csr *x509.CertificateRequest, transactionID string, errorCode int, errorDescription string) error { if s.notificationController == nil { return fmt.Errorf("provisioner %q wasn't initialized", s.Name) } - return s.notificationController.Failure(ctx, csr, transactionID) + return s.notificationController.Failure(ctx, csr, transactionID, errorCode, errorDescription) } type validationMethod string diff --git a/scep/api/api.go b/scep/api/api.go index f7beb7a1..74259a8e 100644 --- a/scep/api/api.go +++ b/scep/api/api.go @@ -333,6 +333,9 @@ func PKIOperation(ctx context.Context, req request) (Response, error) { certRep, err := auth.SignCSR(ctx, csr, msg) if err != nil { + // default to ERROR_INTERNAL_ERROR: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/18d8fbe8-a967-4f1c-ae50-99ca8e491d2d + errorCode := 0x0000054F + errorDescription := err.Error() if notifyErr := auth.NotifyFailure(ctx, csr, transactionID); notifyErr != nil { // TODO(hs): ignore this error case? It's not critical if the notification fails; but logging it might be good _ = notifyErr diff --git a/scep/authority.go b/scep/authority.go index 027d11fe..292c7004 100644 --- a/scep/authority.go +++ b/scep/authority.go @@ -513,9 +513,9 @@ func (a *Authority) NotifySuccess(ctx context.Context, csr *x509.CertificateRequ return p.NotifySuccess(ctx, csr, cert, transactionID) } -func (a *Authority) NotifyFailure(ctx context.Context, csr *x509.CertificateRequest, transactionID string) error { +func (a *Authority) NotifyFailure(ctx context.Context, csr *x509.CertificateRequest, transactionID string, errorCode int, errorDescription string) error { p := provisionerFromContext(ctx) - return p.NotifyFailure(ctx, csr, transactionID) + return p.NotifyFailure(ctx, csr, transactionID, errorCode, errorDescription) } func (a *Authority) selectDecrypter(ctx context.Context) (cert *x509.Certificate, decrypter crypto.Decrypter, err error) { diff --git a/scep/provisioner.go b/scep/provisioner.go index cb894c05..3df4b367 100644 --- a/scep/provisioner.go +++ b/scep/provisioner.go @@ -22,7 +22,7 @@ type Provisioner interface { GetContentEncryptionAlgorithm() int ValidateChallenge(ctx context.Context, csr *x509.CertificateRequest, challenge, transactionID string) error NotifySuccess(ctx context.Context, csr *x509.CertificateRequest, cert *x509.Certificate, transactionID string) error - NotifyFailure(ctx context.Context, csr *x509.CertificateRequest, transactionID string) error + NotifyFailure(ctx context.Context, csr *x509.CertificateRequest, transactionID string, errorCode int, errorDescription string) error } // provisionerKey is the key type for storing and searching a diff --git a/webhook/types.go b/webhook/types.go index 330250f5..4c443969 100644 --- a/webhook/types.go +++ b/webhook/types.go @@ -81,8 +81,10 @@ type RequestBody struct { SSHCertificateRequest *SSHCertificateRequest `json:"sshCertificateRequest,omitempty"` SSHCertificate *SSHCertificate `json:"sshCertificate,omitempty"` // Only set for SCEP challenge validation requests - SCEPChallenge string `json:"scepChallenge,omitempty"` - SCEPTransactionID string `json:"scepTransactionID,omitempty"` + SCEPChallenge string `json:"scepChallenge,omitempty"` + SCEPTransactionID string `json:"scepTransactionID,omitempty"` + SCEPErrorCode int `json:"scepErrorCode,omitempty"` + SCEPErrorDescription string `json:"scepErrorDescription,omitempty"` // Only set for X5C provisioners X5CCertificate *X5CCertificate `json:"x5cCertificate,omitempty"` // Set for X5C, AWS, GCP, and Azure provisioners