diff --git a/test/integration/ari_test.go b/test/integration/ari_test.go deleted file mode 100644 index bda930c5892..00000000000 --- a/test/integration/ari_test.go +++ /dev/null @@ -1,88 +0,0 @@ -//go:build integration - -package integration - -import ( - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/x509/pkix" - "math/big" - "testing" - "time" - - "github.com/eggsampler/acme/v3" - - "github.com/letsencrypt/boulder/test" - ocsp_helper "github.com/letsencrypt/boulder/test/ocsp/helper" -) - -// certID matches the ASN.1 structure of the CertID sequence defined by RFC6960. -type certID struct { - HashAlgorithm pkix.AlgorithmIdentifier - IssuerNameHash []byte - IssuerKeyHash []byte - SerialNumber *big.Int -} - -func TestARI(t *testing.T) { - t.Parallel() - - // Create an account. - client, err := makeClient("mailto:example@letsencrypt.org") - test.AssertNotError(t, err, "creating acme client") - - // Create a private key. - key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - test.AssertNotError(t, err, "creating random cert key") - - // Issue a cert, request ARI, and check that both the suggested window and - // the retry-after header are approximately the right amount of time in the - // future. - name := random_domain() - ir, err := authAndIssue(client, key, []string{name}, true) - test.AssertNotError(t, err, "failed to issue test cert") - - cert := ir.certs[0] - issuer, err := ocsp_helper.GetIssuer(cert) - test.AssertNotError(t, err, "failed to get issuer cert") - - eri, err := client.GetRenewalInfo(cert, issuer, crypto.SHA256) - test.AssertNotError(t, err, "ARI request should have succeeded") - test.AssertEquals(t, eri.SuggestedWindow.Start.Sub(time.Now()).Round(time.Hour), 1415*time.Hour) - test.AssertEquals(t, eri.SuggestedWindow.End.Sub(time.Now()).Round(time.Hour), 1463*time.Hour) - test.AssertEquals(t, eri.RetryAfter.Sub(time.Now()).Round(time.Hour), 6*time.Hour) - - // Revoke the cert, re-request ARI, and the window should now be in the past. - err = client.RevokeCertificate(client.Account, cert, client.PrivateKey, 0) - test.AssertNotError(t, err, "failed to revoke cert") - - eri, err = client.GetRenewalInfo(cert, issuer, crypto.SHA256) - test.AssertNotError(t, err, "ARI request should have succeeded") - test.Assert(t, eri.SuggestedWindow.End.Before(time.Now()), "suggested window should end in the past") - test.Assert(t, eri.SuggestedWindow.Start.Before(eri.SuggestedWindow.End), "suggested window should start before it ends") - - // Check that marking the cert as replaced succeeds, but don't check that - // any server state has been updated (because that doesn't happen, yet). - err = client.UpdateRenewalInfo(client.Account, cert, issuer, crypto.SHA256, true) - test.AssertNotError(t, err, "ARI request should have succeeded") - - // Try to make a new cert for a new domain, but sabotage the CT logs so - // issuance fails. Recover the precert from CT, then request ARI and check - // that it fails, because we don't serve ARI for non-issued certs. - name = random_domain() - err = ctAddRejectHost(name) - test.AssertNotError(t, err, "failed to add ct-test-srv reject host") - _, err = authAndIssue(client, key, []string{name}, true) - test.AssertError(t, err, "expected error from authAndIssue, was nil") - - cert, err = ctFindRejection([]string{name}) - test.AssertNotError(t, err, "failed to find rejected precert") - issuer, err = ocsp_helper.GetIssuer(cert) - test.AssertNotError(t, err, "failed to get issuer cert") - - eri, err = client.GetRenewalInfo(cert, issuer, crypto.SHA256) - test.AssertError(t, err, "ARI request should have failed") - test.AssertEquals(t, err.(acme.Problem).Status, 404) -} diff --git a/wfe2/wfe.go b/wfe2/wfe.go index 9078865e948..ef5273e0844 100644 --- a/wfe2/wfe.go +++ b/wfe2/wfe.go @@ -4,8 +4,6 @@ import ( "bytes" "context" "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" "encoding/base64" "encoding/json" "encoding/pem" @@ -75,7 +73,7 @@ const ( getCertPath = getAPIPrefix + "cert/" // Draft or likely-to-change paths - renewalInfoPath = "/draft-ietf-acme-ari-02/renewalInfo/" + renewalInfoPath = "/draft-ietf-acme-ari-03/renewalInfo/" ) const ( @@ -2200,7 +2198,7 @@ func (wfe *WebFrontEndImpl) determineARIWindow(ctx context.Context, serial strin return core.RenewalInfoSimple(cert.Issued.AsTime(), cert.Expires.AsTime()), nil } -// validateReplacementOrder implements draft-ietf-acme-ari-02. For a new order +// validateReplacementOrder implements draft-ietf-acme-ari-03. For a new order // to be considered a replacement for an existing certificate, the existing // certificate: // 1. MUST NOT have been replaced by another finalized order, @@ -2223,23 +2221,23 @@ func (wfe *WebFrontEndImpl) validateReplacementOrder(ctx context.Context, acct * return "", false, nil } - certID, err := parseCertID(replaces, wfe.issuerCertificates) + decodedSerial, err := parseARICertID(replaces, wfe.issuerCertificates) if err != nil { return "", false, fmt.Errorf("while parsing ARI CertID an error occurred: %w", err) } - exists, err := wfe.sa.ReplacementOrderExists(ctx, &sapb.Serial{Serial: certID.Serial()}) + exists, err := wfe.sa.ReplacementOrderExists(ctx, &sapb.Serial{Serial: decodedSerial}) if err != nil { return "", false, fmt.Errorf("checking replacement status of existing certificate: %w", err) } if exists.Exists { return "", false, berrors.ConflictError( "cannot indicate an order replaces certificate with serial %q, which already has a replacement order", - certID.Serial(), + decodedSerial, ) } - err = wfe.orderMatchesReplacement(ctx, acct, names, certID.Serial()) + err = wfe.orderMatchesReplacement(ctx, acct, names, decodedSerial) if err != nil { // The provided replacement field value failed to meet the required // criteria. We're going to return the error to the caller instead @@ -2247,7 +2245,7 @@ func (wfe *WebFrontEndImpl) validateReplacementOrder(ctx context.Context, acct * return "", false, fmt.Errorf("while checking that this order is a replacement: %w", err) } // This order is a replacement for an existing certificate. - replaces = certID.Serial() + replaces = decodedSerial // For an order to be exempt from rate limits, it must be a replacement // and the request must be made within the suggested renewal window. @@ -2628,86 +2626,21 @@ func (wfe *WebFrontEndImpl) FinalizeOrder(ctx context.Context, logEvent *web.Req } } -// ariCertID is an interface that represents a unique identifier for a -// certificate. It is implemented by both the deprecatedCertID and certID -// structs. -// -// TODO(#7183): Remove this. -type ariCertID interface { - Serial() string -} - -// deprecatedCertID matches the ASN.1 structure of the CertID sequence defined -// by RFC6960. Its fields are exported so that they can be unmarshaled using the -// asn1 package. -// -// TODO(#7183): Remove this. -type deprecatedCertID struct { - HashAlgorithm pkix.AlgorithmIdentifier - IssuerNameHash []byte - IssuerKeyHash []byte - SerialNumber *big.Int -} - -func (c deprecatedCertID) Serial() string { - return core.SerialToString(c.SerialNumber) -} - -// parseDeprecatedCertID parses a unique identifier (certID) for a certificate -// as per the ACME protocol's "renewalInfo" resource, as specified in -// draft-ietf- acme-ari-02. For more details see: -// https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-01#section-4.1. -// -// TODO(#7183): Remove this. -func parseDeprecatedCertID(path string) (ariCertID, error) { - der, err := base64.RawURLEncoding.DecodeString(path) - if err != nil { - return nil, err - } - - var id deprecatedCertID - rest, err := asn1.Unmarshal(der, &id) - if err != nil || len(rest) != 0 { - return deprecatedCertID{}, err - } - - // Verify that the hash algorithm is SHA-256, so people don't use SHA-1 here. - if !id.HashAlgorithm.Algorithm.Equal(asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}) { - return deprecatedCertID{}, errors.New("Request used hash algorithm other than SHA-256") - } - return id, nil -} - -// certID represents a unique identifier (certID) for a certificate as per the -// ACME protocol's "renewalInfo" resource, as specified in draft-ietf-acme-ari- -// 02. The certID is a composite string derived from the base64url-encoded -// keyIdentifier of the certificate's Authority Key Identifier (AKI) and the -// base64url-encoded serial number of the certificate, separated by a period. -// For more details see: -// https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-02#section-4.1. -type certID struct { - keyIdentifier []byte - serialNumber *big.Int -} - -func (c certID) Serial() string { - return core.SerialToString(c.serialNumber) -} - -// parseCertID parses a unique identifier (certID) as specified in -// draft-ietf-acme-ari-02. It takes the composite string as input returns a -// certID struct with the keyIdentifier and serialNumber extracted and decoded. -// For more details see: -// https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-02#section-4.1. -func parseCertID(path string, issuerCertificates map[issuance.NameID]*issuance.Certificate) (ariCertID, error) { +// parseARICertID parses the "certID", a unique identifier specified in +// draft-ietf-acme-ari-03. It takes the composite string as input returns a +// extracted and decoded certificate serial. If the decoded AKID does not match +// any known issuer or the serial number is not valid, an error is returned. For +// more details see: +// https://datatracker.ietf.org/doc/html/draft-ietf-acme-ari-03#section-4.1. +func parseARICertID(path string, issuerCertificates map[issuance.NameID]*issuance.Certificate) (string, error) { parts := strings.Split(path, ".") if len(parts) != 2 || parts[0] == "" || parts[1] == "" { - return certID{}, berrors.MalformedError("Invalid path") + return "", berrors.MalformedError("Invalid path") } akid, err := base64.RawURLEncoding.DecodeString(parts[0]) if err != nil { - return certID{}, berrors.MalformedError("Authority Key Identifier was not base64url-encoded or contained padding: %s", err) + return "", berrors.MalformedError("Authority Key Identifier was not base64url-encoded or contained padding: %s", err) } var found bool @@ -2718,18 +2651,15 @@ func parseCertID(path string, issuerCertificates map[issuance.NameID]*issuance.C } } if !found { - return certID{}, berrors.NotFoundError("path contained an Authority Key Identifier that did not match a known issuer") + return "", berrors.NotFoundError("path contained an Authority Key Identifier that did not match a known issuer") } serialNumber, err := base64.RawURLEncoding.DecodeString(parts[1]) if err != nil { - return certID{}, berrors.NotFoundError("serial number was not base64url-encoded or contained padding: %s", err) + return "", berrors.NotFoundError("serial number was not base64url-encoded or contained padding: %s", err) } - return certID{ - keyIdentifier: akid, - serialNumber: new(big.Int).SetBytes(serialNumber), - }, nil + return core.SerialToString(new(big.Int).SetBytes(serialNumber)), nil } // RenewalInfo is used to get information about the suggested renewal window @@ -2750,23 +2680,17 @@ func (wfe *WebFrontEndImpl) RenewalInfo(ctx context.Context, logEvent *web.Reque return } - // Try parsing certID param using the draft-ietf-acme-ari-01 format. - // TODO(#7183): Remove this. - certID, err := parseDeprecatedCertID(request.URL.Path) + decodedSerial, err := parseARICertID(request.URL.Path, wfe.issuerCertificates) if err != nil { - // Try parsing certID param using the draft-ietf-acme-ari-02 format. - certID, err = parseCertID(request.URL.Path, wfe.issuerCertificates) - if err != nil { - wfe.sendError(response, logEvent, web.ProblemDetailsForError(err, "While parsing ARI CertID an error occurred"), err) - return - } + wfe.sendError(response, logEvent, web.ProblemDetailsForError(err, "While parsing ARI CertID an error occurred"), err) + return } + // We can do all of our processing based just on the serial, because Boulder // does not re-use the same serial across multiple issuers. - serial := certID.Serial() - logEvent.Extra["RequestedSerial"] = serial + logEvent.Extra["RequestedSerial"] = decodedSerial - renewalInfo, err := wfe.determineARIWindow(ctx, serial) + renewalInfo, err := wfe.determineARIWindow(ctx, decodedSerial) if err != nil { if errors.Is(err, berrors.NotFound) { wfe.sendError(response, logEvent, probs.NotFound("Certificate replaced by this order was not found"), nil) @@ -2811,23 +2735,17 @@ func (wfe *WebFrontEndImpl) UpdateRenewal(ctx context.Context, logEvent *web.Req return } - // Try parsing certID param using the draft-ietf-acme-ari-01 format. - // TODO(#7183): Remove this. - certID, err := parseDeprecatedCertID(updateRenewalRequest.CertID) + decodedSerial, err := parseARICertID(updateRenewalRequest.CertID, wfe.issuerCertificates) if err != nil { - // Try parsing certID param using the draft-ietf-acme-ari-02 format. - certID, err = parseCertID(updateRenewalRequest.CertID, wfe.issuerCertificates) - if err != nil { - wfe.sendError(response, logEvent, web.ProblemDetailsForError(err, "While parsing ARI CertID an error occurred"), err) - return - } + wfe.sendError(response, logEvent, web.ProblemDetailsForError(err, "While parsing ARI CertID an error occurred"), err) + return } + // We can do all of our processing based just on the serial, because Boulder // does not re-use the same serial across multiple issuers. - serial := certID.Serial() - logEvent.Extra["RequestedSerial"] = serial + logEvent.Extra["RequestedSerial"] = decodedSerial - metadata, err := wfe.sa.GetSerialMetadata(ctx, &sapb.Serial{Serial: serial}) + metadata, err := wfe.sa.GetSerialMetadata(ctx, &sapb.Serial{Serial: decodedSerial}) if err != nil { wfe.sendError(response, logEvent, probs.NotFound("Certificate not found"), err) return diff --git a/wfe2/wfe_test.go b/wfe2/wfe_test.go index 4f7e5332f16..f6758424598 100644 --- a/wfe2/wfe_test.go +++ b/wfe2/wfe_test.go @@ -9,7 +9,6 @@ import ( "crypto/rand" "crypto/rsa" "crypto/x509" - "crypto/x509/pkix" "encoding/asn1" "encoding/base64" "encoding/json" @@ -3555,70 +3554,27 @@ func TestARI(t *testing.T) { &web.RequestEvent{Endpoint: endpoint, Extra: map[string]interface{}{}} } - // Load the certificate and its issuer. + // Load the leaf certificate. cert, err := core.LoadCert("../test/hierarchy/ee-r3.cert.pem") test.AssertNotError(t, err, "failed to load test certificate") - issuer, err := core.LoadCert("../test/hierarchy/int-r3.cert.pem") - test.AssertNotError(t, err, "failed to load test issuer") - - // Take advantage of OCSP to build the issuer hashes used for - // draft-ietf-acme-ari01. - ocspReqBytes, err := ocsp.CreateRequest(cert, issuer, &ocsp.RequestOptions{Hash: crypto.SHA256}) - test.AssertNotError(t, err, "failed to create ocsp request") - ocspReq, err := ocsp.ParseRequest(ocspReqBytes) - test.AssertNotError(t, err, "failed to parse ocsp request") - - // Ensure that a correct draft-ietf-acme-ari01 query results in a 200. - idBytes, err := asn1.Marshal(deprecatedCertID{ - pkix.AlgorithmIdentifier{ // SHA256 - Algorithm: asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}, - Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, - }, - ocspReq.IssuerNameHash, - ocspReq.IssuerKeyHash, - cert.SerialNumber, - }) - test.AssertNotError(t, err, "failed to marshal certID") - req, event := makeGet(base64.RawURLEncoding.EncodeToString(idBytes), renewalInfoPath) - resp := httptest.NewRecorder() - wfe.RenewalInfo(context.Background(), event, resp, req) - test.AssertEquals(t, resp.Code, http.StatusOK) - test.AssertEquals(t, resp.Header().Get("Retry-After"), "21600") - var ri core.RenewalInfo - err = json.Unmarshal(resp.Body.Bytes(), &ri) - test.AssertNotError(t, err, "unmarshalling renewal info") - test.Assert(t, ri.SuggestedWindow.Start.After(cert.NotBefore), "suggested window begins before cert issuance") - test.Assert(t, ri.SuggestedWindow.End.Before(cert.NotAfter), "suggested window ends after cert expiry") - // Ensure that a correct draft-ietf-acme-ari02 query results in a 200. + // Ensure that a correct draft-ietf-acme-ari03 query results in a 200. certID := fmt.Sprintf("%s.%s", base64.RawURLEncoding.EncodeToString(cert.AuthorityKeyId), base64.RawURLEncoding.EncodeToString(cert.SerialNumber.Bytes()), ) - req, event = makeGet(certID, renewalInfoPath) - resp = httptest.NewRecorder() + req, event := makeGet(certID, renewalInfoPath) + resp := httptest.NewRecorder() wfe.RenewalInfo(context.Background(), event, resp, req) test.AssertEquals(t, resp.Code, http.StatusOK) test.AssertEquals(t, resp.Header().Get("Retry-After"), "21600") + var ri core.RenewalInfo err = json.Unmarshal(resp.Body.Bytes(), &ri) test.AssertNotError(t, err, "unmarshalling renewal info") test.Assert(t, ri.SuggestedWindow.Start.After(cert.NotBefore), "suggested window begins before cert issuance") test.Assert(t, ri.SuggestedWindow.End.Before(cert.NotAfter), "suggested window ends after cert expiry") - // Ensure that a correct draft-ietf-acme-ari01 query for a revoked cert - // results in a renewal window in the past. - msa.status = core.OCSPStatusRevoked - req, event = makeGet(base64.RawURLEncoding.EncodeToString(idBytes), renewalInfoPath) - resp = httptest.NewRecorder() - wfe.RenewalInfo(context.Background(), event, resp, req) - test.AssertEquals(t, resp.Code, http.StatusOK) - test.AssertEquals(t, resp.Header().Get("Retry-After"), "21600") - err = json.Unmarshal(resp.Body.Bytes(), &ri) - test.AssertNotError(t, err, "unmarshalling renewal info") - test.Assert(t, ri.SuggestedWindow.End.Before(wfe.clk.Now()), "suggested window should end in the past") - test.Assert(t, ri.SuggestedWindow.Start.Before(ri.SuggestedWindow.End), "suggested window should start before it ends") - - // Ensure that a correct draft-ietf-acme-ari02 query for a revoked cert + // Ensure that a correct draft-ietf-acme-ari03 query for a revoked cert // results in a renewal window in the past. msa.status = core.OCSPStatusRevoked req, event = makeGet(certID, renewalInfoPath) @@ -3631,25 +3587,7 @@ func TestARI(t *testing.T) { test.Assert(t, ri.SuggestedWindow.End.Before(wfe.clk.Now()), "suggested window should end in the past") test.Assert(t, ri.SuggestedWindow.Start.Before(ri.SuggestedWindow.End), "suggested window should start before it ends") - // Ensure that a draft-ietf-acme-ari01 query for a non-existent serial - // results in a 404. - idBytes, err = asn1.Marshal(deprecatedCertID{ - pkix.AlgorithmIdentifier{ // SHA256 - Algorithm: asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}, - Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, - }, - ocspReq.IssuerNameHash, - ocspReq.IssuerKeyHash, - big.NewInt(0).Add(cert.SerialNumber, big.NewInt(1)), - }) - test.AssertNotError(t, err, "failed to marshal certID") - req, event = makeGet(base64.RawURLEncoding.EncodeToString(idBytes), renewalInfoPath) - resp = httptest.NewRecorder() - wfe.RenewalInfo(context.Background(), event, resp, req) - test.AssertEquals(t, resp.Code, http.StatusNotFound) - test.AssertEquals(t, resp.Header().Get("Retry-After"), "") - - // Ensure that a draft-ietf-acme-ari02 query for a non-existent serial + // Ensure that a draft-ietf-acme-ari03 query for a non-existent serial // results in a 404. certID = fmt.Sprintf("%s.%s", base64.RawURLEncoding.EncodeToString(cert.AuthorityKeyId), @@ -3664,7 +3602,7 @@ func TestARI(t *testing.T) { test.AssertEquals(t, resp.Header().Get("Retry-After"), "") // Ensure that a query with a non-CertID path fails. - req, event = makeGet(base64.RawURLEncoding.EncodeToString(ocspReqBytes), renewalInfoPath) + req, event = makeGet("lolwutsup", renewalInfoPath) resp = httptest.NewRecorder() wfe.RenewalInfo(context.Background(), event, resp, req) test.AssertEquals(t, resp.Code, http.StatusBadRequest) @@ -3695,35 +3633,6 @@ func TestIncidentARI(t *testing.T) { &web.RequestEvent{Endpoint: endpoint, Extra: map[string]interface{}{}} } - // draft-ietf-acme-ari01 - idBytes, err := asn1.Marshal(deprecatedCertID{ - pkix.AlgorithmIdentifier{ // SHA256 - Algorithm: asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}, - Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, - }, - []byte("foo"), - []byte("baz"), - expectSerial, - }) - test.AssertNotError(t, err, "failed to marshal certID") - - req, event := makeGet(base64.RawURLEncoding.EncodeToString(idBytes), renewalInfoPath) - resp := httptest.NewRecorder() - wfe.RenewalInfo(context.Background(), event, resp, req) - test.AssertEquals(t, resp.Code, 200) - test.AssertEquals(t, resp.Header().Get("Retry-After"), "21600") - var ri core.RenewalInfo - err = json.Unmarshal(resp.Body.Bytes(), &ri) - test.AssertNotError(t, err, "unmarshalling renewal info") - // The start of the window should be in the past. - test.AssertEquals(t, ri.SuggestedWindow.Start.Before(wfe.clk.Now()), true) - // The end of the window should be after the start. - test.AssertEquals(t, ri.SuggestedWindow.End.After(ri.SuggestedWindow.Start), true) - // The end of the window should also be in the past. - test.AssertEquals(t, ri.SuggestedWindow.End.Before(wfe.clk.Now()), true) - - // draft-ietf-acme-ari02 - test.AssertNotError(t, err, "failed to load test certificate") var issuer issuance.NameID for k := range wfe.issuerCertificates { // Grab the first known issuer. @@ -3734,12 +3643,13 @@ func TestIncidentARI(t *testing.T) { base64.RawURLEncoding.EncodeToString(wfe.issuerCertificates[issuer].SubjectKeyId), base64.RawURLEncoding.EncodeToString(expectSerial.Bytes()), ) - req, event = makeGet(certID, renewalInfoPath) - resp = httptest.NewRecorder() + req, event := makeGet(certID, renewalInfoPath) + resp := httptest.NewRecorder() wfe.RenewalInfo(context.Background(), event, resp, req) test.AssertEquals(t, resp.Code, 200) test.AssertEquals(t, resp.Header().Get("Retry-After"), "21600") - err = json.Unmarshal(resp.Body.Bytes(), &ri) + var ri core.RenewalInfo + err := json.Unmarshal(resp.Body.Bytes(), &ri) test.AssertNotError(t, err, "unmarshalling renewal info") // The start of the window should be in the past. test.AssertEquals(t, ri.SuggestedWindow.Start.Before(wfe.clk.Now()), true) @@ -3789,12 +3699,6 @@ func TestUpdateARI(t *testing.T) { // Load a cert, its issuer, and use OCSP to compute issuer name/key hashes. cert, err := core.LoadCert("../test/hierarchy/ee-r3.cert.pem") test.AssertNotError(t, err, "failed to load test certificate") - issuer, err := core.LoadCert("../test/hierarchy/int-r3.cert.pem") - test.AssertNotError(t, err, "failed to load test issuer") - ocspReqBytes, err := ocsp.CreateRequest(cert, issuer, &ocsp.RequestOptions{Hash: crypto.SHA256}) - test.AssertNotError(t, err, "failed to create ocsp request") - ocspReq, err := ocsp.ParseRequest(ocspReqBytes) - test.AssertNotError(t, err, "failed to parse ocsp request") // Set up the mock SA. msa := mockSAWithSerialMetadata{wfe.sa, core.SerialToString(cert.SerialNumber), 1} @@ -3812,57 +3716,12 @@ func TestUpdateARI(t *testing.T) { wfe.UpdateRenewal(ctx, newRequestEvent(), responseWriter, req) test.AssertEquals(t, responseWriter.Code, http.StatusBadRequest) - // draft-ietf-acme-ari01 - // Non-sha256 hash algorithm should result in an error. - idBytes, err := asn1.Marshal(deprecatedCertID{ - pkix.AlgorithmIdentifier{ // definitely not SHA256 - Algorithm: asn1.ObjectIdentifier{1, 2, 3, 4, 5}, - Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, - }, - ocspReq.IssuerNameHash, - ocspReq.IssuerKeyHash, - cert.SerialNumber, - }) - test.AssertNotError(t, err, "failed to marshal certID") - body, err := json.Marshal(jsonReq{ - CertID: base64.RawURLEncoding.EncodeToString(idBytes), - Replaced: true, - }) - test.AssertNotError(t, err, "failed to marshal request body") - req = makePost(1, string(body)) - responseWriter = httptest.NewRecorder() - wfe.UpdateRenewal(ctx, newRequestEvent(), responseWriter, req) - test.AssertEquals(t, responseWriter.Code, http.StatusBadRequest) - - // draft-ietf-acme-ari01 - // Unrecognized serial should result in an error. - idBytes, err = asn1.Marshal(deprecatedCertID{ - pkix.AlgorithmIdentifier{ // SHA256 - Algorithm: asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}, - Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, - }, - ocspReq.IssuerNameHash, - ocspReq.IssuerKeyHash, - big.NewInt(12345), - }) - test.AssertNotError(t, err, "failed to marshal certID") - body, err = json.Marshal(jsonReq{ - CertID: base64.RawURLEncoding.EncodeToString(idBytes), - Replaced: true, - }) - test.AssertNotError(t, err, "failed to marshal request body") - req = makePost(1, string(body)) - responseWriter = httptest.NewRecorder() - wfe.UpdateRenewal(ctx, newRequestEvent(), responseWriter, req) - test.AssertEquals(t, responseWriter.Code, http.StatusNotFound) - - // draft-ietf-acme-ari02 // Unrecognized serial should result in an error. certID := fmt.Sprintf("%s.%s", base64.RawURLEncoding.EncodeToString(cert.AuthorityKeyId), base64.RawURLEncoding.EncodeToString(big.NewInt(12345).Bytes()), ) - body, err = json.Marshal(jsonReq{ + body, err := json.Marshal(jsonReq{ CertID: certID, Replaced: true, }) @@ -3872,30 +3731,6 @@ func TestUpdateARI(t *testing.T) { wfe.UpdateRenewal(ctx, newRequestEvent(), responseWriter, req) test.AssertEquals(t, responseWriter.Code, http.StatusNotFound) - // draft-ietf-acme-ari01 - // Recognized serial but owned by the wrong account should result in an error. - msa.regID = 2 - idBytes, err = asn1.Marshal(deprecatedCertID{ - pkix.AlgorithmIdentifier{ // SHA256 - Algorithm: asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}, - Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, - }, - ocspReq.IssuerNameHash, - ocspReq.IssuerKeyHash, - cert.SerialNumber, - }) - test.AssertNotError(t, err, "failed to marshal certID") - body, err = json.Marshal(jsonReq{ - CertID: base64.RawURLEncoding.EncodeToString(idBytes), - Replaced: true, - }) - test.AssertNotError(t, err, "failed to marshal request body") - req = makePost(1, string(body)) - responseWriter = httptest.NewRecorder() - wfe.UpdateRenewal(ctx, newRequestEvent(), responseWriter, req) - test.AssertEquals(t, responseWriter.Code, http.StatusForbidden) - - // draft-ietf-acme-ari02 // Recognized serial but owned by the wrong account should result in an error. msa.regID = 2 certID = fmt.Sprintf("%s.%s", @@ -3912,30 +3747,6 @@ func TestUpdateARI(t *testing.T) { wfe.UpdateRenewal(ctx, newRequestEvent(), responseWriter, req) test.AssertEquals(t, responseWriter.Code, http.StatusForbidden) - // draft-ietf-acme-ari01 - // Recognized serial and owned by the right account should work. - msa.regID = 1 - idBytes, err = asn1.Marshal(deprecatedCertID{ - pkix.AlgorithmIdentifier{ // SHA256 - Algorithm: asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}, - Parameters: asn1.RawValue{Tag: 5 /* ASN.1 NULL */}, - }, - ocspReq.IssuerNameHash, - ocspReq.IssuerKeyHash, - cert.SerialNumber, - }) - test.AssertNotError(t, err, "failed to marshal certID") - body, err = json.Marshal(jsonReq{ - CertID: base64.RawURLEncoding.EncodeToString(idBytes), - Replaced: true, - }) - test.AssertNotError(t, err, "failed to marshal request body") - req = makePost(1, string(body)) - responseWriter = httptest.NewRecorder() - wfe.UpdateRenewal(ctx, newRequestEvent(), responseWriter, req) - test.AssertEquals(t, responseWriter.Code, http.StatusOK) - - // draft-ietf-acme-ari02 // Recognized serial and owned by the right account should work. msa.regID = 1 certID = fmt.Sprintf("%s.%s",