From de4e37bf60b865b13d582506fbb40f357a6c5d96 Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Sat, 2 May 2015 11:37:04 -0700 Subject: [PATCH] Implement user-facing revocation. --- wfe/web-front-end.go | 77 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/wfe/web-front-end.go b/wfe/web-front-end.go index a5abcbe94..c995b66b9 100644 --- a/wfe/web-front-end.go +++ b/wfe/web-front-end.go @@ -363,6 +363,83 @@ func (wfe *WebFrontEndImpl) RevokeCertificate(response http.ResponseWriter, requ return } + certStatus, err := wfe.SA.GetCertificateStatus(revokeRequest.Serial) + if err != nil { + wfe.sendError(response, "No such certificate", http.StatusNotFound) + return + } + + if certStatus.Status == core.OCSPStatusRevoked { + wfe.sendError(response, "Certificate already revoked", http.StatusConflict) + return + } + + // TODO: Allow other types of keys. + if requestKey.Rsa == nil { + wfe.sendError(response, "Non-RSA keys not permitted.", http.StatusForbidden) + return + } + // TODO: Implement other methods of validating revocation, e.g. through + // authorizations on account. + if core.KeyDigest(requestKey.Rsa) != core.KeyDigest(parsedCertificate.PublicKey) { + wfe.log.Debug(fmt.Sprintf("Key mismatch for revoke: %s vs %s", + core.KeyDigest(requestKey), + core.KeyDigest(parsedCertificate.PublicKey))) + wfe.sendError(response, + "Revocation request must be signed by private key of cert to be revoked", + http.StatusForbidden) + return + } + + err = wfe.CA.RevokeCertificate(revokeRequest.Serial) + if err != nil { + wfe.sendError(response, + "Failed to revoke certificate", + http.StatusInternalServerError) + } else { + wfe.log.Debug(fmt.Sprintf("Revoked %v", revokeRequest.Serial)) + response.WriteHeader(http.StatusOK) + } +} + +func (wfe *WebFrontEndImpl) NewCertificate(response http.ResponseWriter, request *http.Request) { + if request.Method != "POST" { + wfe.sendError(response, "Method not allowed", http.StatusMethodNotAllowed) + return + } + + body, requestKey, err := verifyPOST(request) + if err != nil { + wfe.sendError(response, "Unable to read/verify body", http.StatusBadRequest) + return + } + + type RevokeRequest struct { + Serial string + } + var revokeRequest RevokeRequest + if err = json.Unmarshal(body, &revokeRequest); err != nil { + fmt.Println("Couldn't unmarshal in revoke request", string(body)) + wfe.sendError(response, "Unable to read/verify body", http.StatusBadRequest) + return + } + if len(revokeRequest.Serial) != 32 { + wfe.log.Debug("Bad serial in revoke request " + revokeRequest.Serial) + wfe.sendError(response, "Unable to read/verify body", http.StatusBadRequest) + return + } + + certDER, err := wfe.SA.GetCertificate(revokeRequest.Serial) + if err != nil { + wfe.sendError(response, "No such certificate", http.StatusNotFound) + return + } + parsedCertificate, err := x509.ParseCertificate(certDER) + if err != nil { + wfe.sendError(response, "Invalid certificate", http.StatusInternalServerError) + return + } + certStatus, err := wfe.SA.GetCertificateStatus(revokeRequest.Serial) if err != nil { wfe.sendError(response, "No such certificate", http.StatusNotFound)