@@ -26,6 +26,7 @@ import (
2626
2727 "github.com/jmhodges/clock"
2828 "github.com/prometheus/client_golang/prometheus"
29+ "golang.org/x/crypto/ocsp"
2930 "google.golang.org/grpc"
3031 "google.golang.org/protobuf/types/known/emptypb"
3132 jose "gopkg.in/square/go-jose.v2"
@@ -2934,6 +2935,56 @@ func TestRevokeCertificateValid(t *testing.T) {
29342935 test .AssertEquals (t , responseWriter .Body .String (), "" )
29352936}
29362937
2938+ // A revocation request with reason == keyCompromise should only succeed
2939+ // if it was signed by the private key.
2940+ func TestRevokeCertificateKeyCompromiseValid (t * testing.T ) {
2941+ wfe , _ := setupWFE (t )
2942+ wfe .SA = newMockSAWithCert (t , wfe .SA , core .OCSPStatusGood )
2943+
2944+ mockLog := wfe .log .(* blog.Mock )
2945+ mockLog .Clear ()
2946+
2947+ keyPemBytes , err := ioutil .ReadFile ("../test/hierarchy/ee-r3.key.pem" )
2948+ test .AssertNotError (t , err , "Failed to load key" )
2949+ key := loadKey (t , keyPemBytes )
2950+
2951+ revocationReason := revocation .Reason (ocsp .KeyCompromise )
2952+ revokeRequestJSON , err := makeRevokeRequestJSON (& revocationReason )
2953+ test .AssertNotError (t , err , "Failed to make revokeRequestJSON" )
2954+ _ , _ , jwsBody := signRequestEmbed (t ,
2955+ key , "http://localhost/revoke-cert" , string (revokeRequestJSON ), wfe .nonceService )
2956+
2957+ responseWriter := httptest .NewRecorder ()
2958+ wfe .RevokeCertificate (ctx , newRequestEvent (), responseWriter ,
2959+ makePostRequestWithPath ("revoke-cert" , jwsBody ))
2960+ test .AssertEquals (t , responseWriter .Code , 200 )
2961+ test .AssertEquals (t , responseWriter .Body .String (), "" )
2962+ test .AssertDeepEquals (t , mockLog .GetAllMatching ("Authorizing revocation" ), []string {
2963+ `INFO: [AUDIT] Authorizing revocation JSON={"Serial":"000000000000000000001d72443db5189821","Reason":1,"RegID":0,"Method":"privkey"}` ,
2964+ })
2965+ }
2966+
2967+ func TestRevokeCertificateKeyCompromiseInvalid (t * testing.T ) {
2968+ wfe , _ := setupWFE (t )
2969+ wfe .SA = newMockSAWithCert (t , wfe .SA , core .OCSPStatusGood )
2970+
2971+ revocationReason := revocation .Reason (ocsp .KeyCompromise )
2972+ revokeRequestJSON , err := makeRevokeRequestJSON (& revocationReason )
2973+ test .AssertNotError (t , err , "Failed to make revokeRequestJSON" )
2974+ // NOTE: this account doesn't have any authorizations for the
2975+ // names in the cert, but it is the account that issued it
2976+ // originally
2977+ _ , _ , jwsBody := signRequestKeyID (
2978+ t , 1 , nil , "http://localhost/revoke-cert" , string (revokeRequestJSON ), wfe .nonceService )
2979+
2980+ responseWriter := httptest .NewRecorder ()
2981+ wfe .RevokeCertificate (ctx , newRequestEvent (), responseWriter ,
2982+ makePostRequestWithPath ("revoke-cert" , jwsBody ))
2983+
2984+ test .AssertEquals (t , responseWriter .Code , 403 )
2985+ test .AssertEquals (t , responseWriter .Body .String (), "{\n \" type\" : \" urn:ietf:params:acme:error:unauthorized\" ,\n \" detail\" : \" Revocation with reason keyCompromise is only supported by signing with the certificate private key\" ,\n \" status\" : 403\n }" )
2986+ }
2987+
29372988// Invalid revocation request: although signed with the cert key, the cert
29382989// wasn't issued by any issuer the Boulder is aware of.
29392990func TestRevokeCertificateNotIssued (t * testing.T ) {
@@ -3048,6 +3099,9 @@ func TestRevokeCertificateIssuingAccount(t *testing.T) {
30483099 wfe , _ := setupWFE (t )
30493100 wfe .SA = newMockSAWithCert (t , wfe .SA , core .OCSPStatusGood )
30503101
3102+ mockLog := wfe .log .(* blog.Mock )
3103+ mockLog .Clear ()
3104+
30513105 revokeRequestJSON , err := makeRevokeRequestJSON (nil )
30523106 test .AssertNotError (t , err , "Failed to make revokeRequestJSON" )
30533107 // NOTE: this account doesn't have any authorizations for the
@@ -3062,6 +3116,9 @@ func TestRevokeCertificateIssuingAccount(t *testing.T) {
30623116
30633117 test .AssertEquals (t , responseWriter .Code , 200 )
30643118 test .AssertEquals (t , responseWriter .Body .String (), "" )
3119+ test .AssertDeepEquals (t , mockLog .GetAllMatching ("Authorizing revocation" ), []string {
3120+ `INFO: [AUDIT] Authorizing revocation JSON={"Serial":"000000000000000000001d72443db5189821","Reason":0,"RegID":1,"Method":"owner"}` ,
3121+ })
30653122}
30663123
30673124type mockSAWithValidAuthz struct {
@@ -3085,6 +3142,9 @@ func TestRevokeCertificateWithAuthorizations(t *testing.T) {
30853142 wfe , _ := setupWFE (t )
30863143 wfe .SA = mockSAWithValidAuthz {newMockSAWithCert (t , wfe .SA , core .OCSPStatusGood )}
30873144
3145+ mockLog := wfe .log .(* blog.Mock )
3146+ mockLog .Clear ()
3147+
30883148 revokeRequestJSON , err := makeRevokeRequestJSON (nil )
30893149 test .AssertNotError (t , err , "Failed to make revokeRequestJSON" )
30903150
@@ -3099,6 +3159,9 @@ func TestRevokeCertificateWithAuthorizations(t *testing.T) {
30993159 makePostRequestWithPath ("revoke-cert" , jwsBody ))
31003160 test .AssertEquals (t , responseWriter .Code , 200 )
31013161 test .AssertEquals (t , responseWriter .Body .String (), "" )
3162+ test .AssertDeepEquals (t , mockLog .GetAllMatching ("Authorizing revocation" ), []string {
3163+ `INFO: [AUDIT] Authorizing revocation JSON={"Serial":"000000000000000000001d72443db5189821","Reason":0,"RegID":5,"Method":"authorizations"}` ,
3164+ })
31023165}
31033166
31043167// A revocation request signed by an unauthorized key.
0 commit comments