@@ -3459,12 +3459,14 @@ func TestARI(t *testing.T) {
34593459 msa := newMockSAWithCert (t , wfe .sa )
34603460 wfe .sa = msa
34613461
3462+ err := features .Set (map [string ]bool {"ServeRenewalInfo" : true })
3463+ test .AssertNotError (t , err , "setting feature flag" )
3464+ defer features .Reset ()
3465+
34623466 makeGet := func (path , endpoint string ) (* http.Request , * web.RequestEvent ) {
34633467 return & http.Request {URL : & url.URL {Path : path }, Method : "GET" },
34643468 & web.RequestEvent {Endpoint : endpoint , Extra : map [string ]interface {}{}}
34653469 }
3466- _ = features .Set (map [string ]bool {"ServeRenewalInfo" : true })
3467- defer features .Reset ()
34683470
34693471 // Load the certificate and its issuer.
34703472 cert , err := core .LoadCert ("../test/hierarchy/ee-r3.cert.pem" )
@@ -3586,12 +3588,14 @@ func TestIncidentARI(t *testing.T) {
35863588 expectSerialString := core .SerialToString (big .NewInt (12345 ))
35873589 wfe .sa = newMockSAWithIncident (wfe .sa , []string {expectSerialString })
35883590
3591+ err := features .Set (map [string ]bool {"ServeRenewalInfo" : true })
3592+ test .AssertNotError (t , err , "setting feature flag" )
3593+ defer features .Reset ()
3594+
35893595 makeGet := func (path , endpoint string ) (* http.Request , * web.RequestEvent ) {
35903596 return & http.Request {URL : & url.URL {Path : path }, Method : "GET" },
35913597 & web.RequestEvent {Endpoint : endpoint , Extra : map [string ]interface {}{}}
35923598 }
3593- _ = features .Set (map [string ]bool {"ServeRenewalInfo" : true })
3594- defer features .Reset ()
35953599
35963600 idBytes , err := asn1 .Marshal (certID {
35973601 pkix.AlgorithmIdentifier { // SHA256
@@ -3620,6 +3624,157 @@ func TestIncidentARI(t *testing.T) {
36203624 test .AssertEquals (t , ri .SuggestedWindow .End .Before (wfe .clk .Now ()), true )
36213625}
36223626
3627+ type mockSAWithSerialMetadata struct {
3628+ sapb.StorageAuthorityReadOnlyClient
3629+ serial string
3630+ regID int64
3631+ }
3632+
3633+ // GetSerialMetadata returns fake metadata if it recognizes the given serial.
3634+ func (sa * mockSAWithSerialMetadata ) GetSerialMetadata (_ context.Context , req * sapb.Serial , _ ... grpc.CallOption ) (* sapb.SerialMetadata , error ) {
3635+ if req .Serial != sa .serial {
3636+ return nil , berrors .NotFoundError ("metadata for certificate with serial %q not found" , req .Serial )
3637+ }
3638+
3639+ return & sapb.SerialMetadata {
3640+ Serial : sa .serial ,
3641+ RegistrationID : sa .regID ,
3642+ }, nil
3643+ }
3644+
3645+ // TestUpdateARI tests that requests for real certs issued to the correct regID
3646+ // are accepted, while all others result in errors.
3647+ func TestUpdateARI (t * testing.T ) {
3648+ wfe , _ , signer := setupWFE (t )
3649+
3650+ err := features .Set (map [string ]bool {"ServeRenewalInfo" : true })
3651+ test .AssertNotError (t , err , "setting feature flag" )
3652+ defer features .Reset ()
3653+
3654+ makePost := func (regID int64 , body string ) * http.Request {
3655+ signedURL := fmt .Sprintf ("http://localhost%s" , renewalInfoPath )
3656+ _ , _ , jwsBody := signer .byKeyID (regID , nil , signedURL , body )
3657+ return makePostRequestWithPath (renewalInfoPath , jwsBody )
3658+ }
3659+
3660+ type jsonReq struct {
3661+ CertID string `json:"certID"`
3662+ Replaced bool `json:"replaced"`
3663+ }
3664+
3665+ // Load a cert, its issuer, and use OCSP to compute issuer name/key hashes.
3666+ cert , err := core .LoadCert ("../test/hierarchy/ee-r3.cert.pem" )
3667+ test .AssertNotError (t , err , "failed to load test certificate" )
3668+ issuer , err := core .LoadCert ("../test/hierarchy/int-r3.cert.pem" )
3669+ test .AssertNotError (t , err , "failed to load test issuer" )
3670+ ocspReqBytes , err := ocsp .CreateRequest (cert , issuer , & ocsp.RequestOptions {Hash : crypto .SHA256 })
3671+ test .AssertNotError (t , err , "failed to create ocsp request" )
3672+ ocspReq , err := ocsp .ParseRequest (ocspReqBytes )
3673+ test .AssertNotError (t , err , "failed to parse ocsp request" )
3674+
3675+ // Set up the mock SA.
3676+ msa := mockSAWithSerialMetadata {wfe .sa , core .SerialToString (cert .SerialNumber ), 1 }
3677+ wfe .sa = & msa
3678+
3679+ // An empty POST should result in an error.
3680+ req := makePost (1 , "" )
3681+ responseWriter := httptest .NewRecorder ()
3682+ wfe .UpdateRenewal (ctx , newRequestEvent (), responseWriter , req )
3683+ test .AssertEquals (t , responseWriter .Code , http .StatusBadRequest )
3684+
3685+ // Non-certID base64 should result in an error.
3686+ req = makePost (1 , "aGVsbG8gd29ybGQK" ) // $ echo "hello world" | base64
3687+ responseWriter = httptest .NewRecorder ()
3688+ wfe .UpdateRenewal (ctx , newRequestEvent (), responseWriter , req )
3689+ test .AssertEquals (t , responseWriter .Code , http .StatusBadRequest )
3690+
3691+ // Non-sha256 hash algorithm should result in an error.
3692+ idBytes , err := asn1 .Marshal (certID {
3693+ pkix.AlgorithmIdentifier { // definitely not SHA256
3694+ Algorithm : asn1.ObjectIdentifier {1 , 2 , 3 , 4 , 5 },
3695+ Parameters : asn1.RawValue {Tag : 5 /* ASN.1 NULL */ },
3696+ },
3697+ ocspReq .IssuerNameHash ,
3698+ ocspReq .IssuerKeyHash ,
3699+ cert .SerialNumber ,
3700+ })
3701+ test .AssertNotError (t , err , "failed to marshal certID" )
3702+ body , err := json .Marshal (jsonReq {
3703+ CertID : base64 .RawURLEncoding .EncodeToString (idBytes ),
3704+ Replaced : true ,
3705+ })
3706+ test .AssertNotError (t , err , "failed to marshal request body" )
3707+ req = makePost (1 , string (body ))
3708+ responseWriter = httptest .NewRecorder ()
3709+ wfe .UpdateRenewal (ctx , newRequestEvent (), responseWriter , req )
3710+ test .AssertEquals (t , responseWriter .Code , http .StatusBadRequest )
3711+
3712+ // Unrecognized serial should result in an error.
3713+ idBytes , err = asn1 .Marshal (certID {
3714+ pkix.AlgorithmIdentifier { // SHA256
3715+ Algorithm : asn1.ObjectIdentifier {2 , 16 , 840 , 1 , 101 , 3 , 4 , 2 , 1 },
3716+ Parameters : asn1.RawValue {Tag : 5 /* ASN.1 NULL */ },
3717+ },
3718+ ocspReq .IssuerNameHash ,
3719+ ocspReq .IssuerKeyHash ,
3720+ big .NewInt (12345 ),
3721+ })
3722+ test .AssertNotError (t , err , "failed to marshal certID" )
3723+ body , err = json .Marshal (jsonReq {
3724+ CertID : base64 .RawURLEncoding .EncodeToString (idBytes ),
3725+ Replaced : true ,
3726+ })
3727+ test .AssertNotError (t , err , "failed to marshal request body" )
3728+ req = makePost (1 , string (body ))
3729+ responseWriter = httptest .NewRecorder ()
3730+ wfe .UpdateRenewal (ctx , newRequestEvent (), responseWriter , req )
3731+ test .AssertEquals (t , responseWriter .Code , http .StatusNotFound )
3732+
3733+ // Recognized serial but owned by the wrong account should result in an error.
3734+ msa .regID = 2
3735+ idBytes , err = asn1 .Marshal (certID {
3736+ pkix.AlgorithmIdentifier { // SHA256
3737+ Algorithm : asn1.ObjectIdentifier {2 , 16 , 840 , 1 , 101 , 3 , 4 , 2 , 1 },
3738+ Parameters : asn1.RawValue {Tag : 5 /* ASN.1 NULL */ },
3739+ },
3740+ ocspReq .IssuerNameHash ,
3741+ ocspReq .IssuerKeyHash ,
3742+ cert .SerialNumber ,
3743+ })
3744+ test .AssertNotError (t , err , "failed to marshal certID" )
3745+ body , err = json .Marshal (jsonReq {
3746+ CertID : base64 .RawURLEncoding .EncodeToString (idBytes ),
3747+ Replaced : true ,
3748+ })
3749+ test .AssertNotError (t , err , "failed to marshal request body" )
3750+ req = makePost (1 , string (body ))
3751+ responseWriter = httptest .NewRecorder ()
3752+ wfe .UpdateRenewal (ctx , newRequestEvent (), responseWriter , req )
3753+ test .AssertEquals (t , responseWriter .Code , http .StatusForbidden )
3754+
3755+ // Recognized serial and owned by the right account should work.
3756+ msa .regID = 1
3757+ idBytes , err = asn1 .Marshal (certID {
3758+ pkix.AlgorithmIdentifier { // SHA256
3759+ Algorithm : asn1.ObjectIdentifier {2 , 16 , 840 , 1 , 101 , 3 , 4 , 2 , 1 },
3760+ Parameters : asn1.RawValue {Tag : 5 /* ASN.1 NULL */ },
3761+ },
3762+ ocspReq .IssuerNameHash ,
3763+ ocspReq .IssuerKeyHash ,
3764+ cert .SerialNumber ,
3765+ })
3766+ test .AssertNotError (t , err , "failed to marshal certID" )
3767+ body , err = json .Marshal (jsonReq {
3768+ CertID : base64 .RawURLEncoding .EncodeToString (idBytes ),
3769+ Replaced : true ,
3770+ })
3771+ test .AssertNotError (t , err , "failed to marshal request body" )
3772+ req = makePost (1 , string (body ))
3773+ responseWriter = httptest .NewRecorder ()
3774+ wfe .UpdateRenewal (ctx , newRequestEvent (), responseWriter , req )
3775+ test .AssertEquals (t , responseWriter .Code , http .StatusOK )
3776+ }
3777+
36233778func TestOldTLSInbound (t * testing.T ) {
36243779 wfe , _ , _ := setupWFE (t )
36253780 req := & http.Request {
0 commit comments