From 43195f357675caa1715a0edfb01637d5f6d6b80e Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Mon, 11 Mar 2019 09:22:31 -0700 Subject: [PATCH] wfe2: Add badSignatureAlgorithm and badPublicKey. (#4105) These error types were added in the process of finalizing ACME. --- probs/probs.go | 54 ++++++++++++++++++++++++++++++++------------- wfe2/verify.go | 6 ++--- wfe2/verify_test.go | 2 +- 3 files changed, 43 insertions(+), 19 deletions(-) diff --git a/probs/probs.go b/probs/probs.go index 907dd3b40..2c3a69a83 100644 --- a/probs/probs.go +++ b/probs/probs.go @@ -7,21 +7,23 @@ import ( // Error types that can be used in ACME payloads const ( - ConnectionProblem = ProblemType("connection") - MalformedProblem = ProblemType("malformed") - ServerInternalProblem = ProblemType("serverInternal") - TLSProblem = ProblemType("tls") - UnauthorizedProblem = ProblemType("unauthorized") - UnknownHostProblem = ProblemType("unknownHost") - RateLimitedProblem = ProblemType("rateLimited") - BadNonceProblem = ProblemType("badNonce") - InvalidEmailProblem = ProblemType("invalidEmail") - RejectedIdentifierProblem = ProblemType("rejectedIdentifier") - AccountDoesNotExistProblem = ProblemType("accountDoesNotExist") - CAAProblem = ProblemType("caa") - DNSProblem = ProblemType("dns") - AlreadyRevokedProblem = ProblemType("alreadyRevoked") - OrderNotReadyProblem = ProblemType("orderNotReady") + ConnectionProblem = ProblemType("connection") + MalformedProblem = ProblemType("malformed") + ServerInternalProblem = ProblemType("serverInternal") + TLSProblem = ProblemType("tls") + UnauthorizedProblem = ProblemType("unauthorized") + UnknownHostProblem = ProblemType("unknownHost") + RateLimitedProblem = ProblemType("rateLimited") + BadNonceProblem = ProblemType("badNonce") + InvalidEmailProblem = ProblemType("invalidEmail") + RejectedIdentifierProblem = ProblemType("rejectedIdentifier") + AccountDoesNotExistProblem = ProblemType("accountDoesNotExist") + CAAProblem = ProblemType("caa") + DNSProblem = ProblemType("dns") + AlreadyRevokedProblem = ProblemType("alreadyRevoked") + OrderNotReadyProblem = ProblemType("orderNotReady") + BadSignatureAlgorithmProblem = ProblemType("badSignatureAlgorithm") + BadPublicKeyProblem = ProblemType("badPublicKey") V1ErrorNS = "urn:acme:error:" V2ErrorNS = "urn:ietf:params:acme:error:" @@ -59,6 +61,8 @@ func ProblemDetailsToStatusCode(prob *ProblemDetails) int { case ConnectionProblem, MalformedProblem, + BadSignatureAlgorithmProblem, + BadPublicKeyProblem, TLSProblem, UnknownHostProblem, BadNonceProblem, @@ -129,6 +133,26 @@ func Malformed(detail string, a ...interface{}) *ProblemDetails { } } +// BadSignatureAlgorithm returns a ProblemDetails with a BadSignatureAlgorithmProblem +// and a 400 Bad Request status code. +func BadSignatureAlgorithm(detail string, a ...interface{}) *ProblemDetails { + return &ProblemDetails{ + Type: BadSignatureAlgorithmProblem, + Detail: fmt.Sprintf(detail, a...), + HTTPStatus: http.StatusBadRequest, + } +} + +// BadPublicKey returns a ProblemDetails with a BadPublicKeyProblem and a 400 Bad +// Request status code. +func BadPublicKey(detail string, a ...interface{}) *ProblemDetails { + return &ProblemDetails{ + Type: BadPublicKeyProblem, + Detail: fmt.Sprintf(detail, a...), + HTTPStatus: http.StatusBadRequest, + } +} + // NotFound returns a ProblemDetails with a MalformedProblem and a 404 Not Found // status code. func NotFound(detail string, a ...interface{}) *ProblemDetails { diff --git a/wfe2/verify.go b/wfe2/verify.go index ba975f0e0..1b2725899 100644 --- a/wfe2/verify.go +++ b/wfe2/verify.go @@ -470,7 +470,7 @@ func (wfe *WebFrontEndImpl) validJWSForKey( // Check that the public key and JWS algorithms match expected if err := checkAlgorithm(jwk, jws); err != nil { wfe.stats.joseErrorCount.With(prometheus.Labels{"type": "JWSAlgorithmCheckFailed"}).Inc() - return nil, probs.Malformed(err.Error()) + return nil, probs.BadSignatureAlgorithm(err.Error()) } // Verify the JWS signature with the public key. @@ -602,7 +602,7 @@ func (wfe *WebFrontEndImpl) validSelfAuthenticatedJWS( // If the key doesn't meet the GoodKey policy return a problem immediately if err := wfe.keyPolicy.GoodKey(pubKey.Key); err != nil { wfe.stats.joseErrorCount.With(prometheus.Labels{"type": "JWKRejectedByGoodKey"}).Inc() - return nil, nil, probs.Malformed(err.Error()) + return nil, nil, probs.BadPublicKey(err.Error()) } // Verify the JWS with the embedded JWK @@ -676,7 +676,7 @@ func (wfe *WebFrontEndImpl) validKeyRollover( // If the key doesn't meet the GoodKey policy return a problem immediately if err := wfe.keyPolicy.GoodKey(jwk.Key); err != nil { wfe.stats.joseErrorCount.With(prometheus.Labels{"type": "KeyRolloverJWKRejectedByGoodKey"}).Inc() - return nil, probs.Malformed(err.Error()) + return nil, probs.BadPublicKey(err.Error()) } // Check that the public key and JWS algorithms match expected diff --git a/wfe2/verify_test.go b/wfe2/verify_test.go index 0ae68e696..201b91c93 100644 --- a/wfe2/verify_test.go +++ b/wfe2/verify_test.go @@ -1161,7 +1161,7 @@ func TestValidJWSForKey(t *testing.T) { JWS: wrongAlgJWS, JWK: goodJWK, ExpectedProblem: &probs.ProblemDetails{ - Type: probs.MalformedProblem, + Type: probs.BadSignatureAlgorithmProblem, Detail: "signature type 'HS256' in JWS header is not supported, expected one of RS256, ES256, ES384 or ES512", HTTPStatus: http.StatusBadRequest, },