xref: /aosp_15_r20/external/cronet/net/test/revocation_builder.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2020 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/test/revocation_builder.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <string_view>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include "base/containers/span.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/hash/sha1.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/test/bind.h"
14*6777b538SAndroid Build Coastguard Worker #include "net/cert/asn1_util.h"
15*6777b538SAndroid Build Coastguard Worker #include "net/cert/time_conversions.h"
16*6777b538SAndroid Build Coastguard Worker #include "net/cert/x509_util.h"
17*6777b538SAndroid Build Coastguard Worker #include "net/test/cert_builder.h"
18*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
19*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/bytestring.h"
20*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/mem.h"
21*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/pki/input.h"
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker namespace net {
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker namespace {
26*6777b538SAndroid Build Coastguard Worker 
Sha1()27*6777b538SAndroid Build Coastguard Worker std::string Sha1() {
28*6777b538SAndroid Build Coastguard Worker   // SEQUENCE { OBJECT_IDENTIFIER { 1.3.14.3.2.26 } }
29*6777b538SAndroid Build Coastguard Worker   const uint8_t kSHA1[] = {0x30, 0x07, 0x06, 0x05, 0x2b,
30*6777b538SAndroid Build Coastguard Worker                            0x0e, 0x03, 0x02, 0x1a};
31*6777b538SAndroid Build Coastguard Worker   return std::string(std::begin(kSHA1), std::end(kSHA1));
32*6777b538SAndroid Build Coastguard Worker }
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker // Adds bytes (specified as a StringPiece) to the given CBB.
35*6777b538SAndroid Build Coastguard Worker // The argument ordering follows the boringssl CBB_* api style.
CBBAddBytes(CBB * cbb,std::string_view bytes)36*6777b538SAndroid Build Coastguard Worker bool CBBAddBytes(CBB* cbb, std::string_view bytes) {
37*6777b538SAndroid Build Coastguard Worker   return CBB_add_bytes(cbb, reinterpret_cast<const uint8_t*>(bytes.data()),
38*6777b538SAndroid Build Coastguard Worker                        bytes.size());
39*6777b538SAndroid Build Coastguard Worker }
40*6777b538SAndroid Build Coastguard Worker 
41*6777b538SAndroid Build Coastguard Worker // Adds bytes (specified as a span) to the given CBB.
42*6777b538SAndroid Build Coastguard Worker // The argument ordering follows the boringssl CBB_* api style.
CBBAddBytes(CBB * cbb,base::span<const uint8_t> data)43*6777b538SAndroid Build Coastguard Worker bool CBBAddBytes(CBB* cbb, base::span<const uint8_t> data) {
44*6777b538SAndroid Build Coastguard Worker   return CBB_add_bytes(cbb, data.data(), data.size());
45*6777b538SAndroid Build Coastguard Worker }
46*6777b538SAndroid Build Coastguard Worker 
47*6777b538SAndroid Build Coastguard Worker // Adds a GeneralizedTime value to the given CBB.
48*6777b538SAndroid Build Coastguard Worker // The argument ordering follows the boringssl CBB_* api style.
CBBAddGeneralizedTime(CBB * cbb,const base::Time & time)49*6777b538SAndroid Build Coastguard Worker bool CBBAddGeneralizedTime(CBB* cbb, const base::Time& time) {
50*6777b538SAndroid Build Coastguard Worker   bssl::der::GeneralizedTime generalized_time;
51*6777b538SAndroid Build Coastguard Worker   if (!EncodeTimeAsGeneralizedTime(time, &generalized_time)) {
52*6777b538SAndroid Build Coastguard Worker     return false;
53*6777b538SAndroid Build Coastguard Worker   }
54*6777b538SAndroid Build Coastguard Worker   CBB time_cbb;
55*6777b538SAndroid Build Coastguard Worker   uint8_t out[bssl::der::kGeneralizedTimeLength];
56*6777b538SAndroid Build Coastguard Worker   if (!bssl::der::EncodeGeneralizedTime(generalized_time, out) ||
57*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(cbb, &time_cbb, CBS_ASN1_GENERALIZEDTIME) ||
58*6777b538SAndroid Build Coastguard Worker       !CBBAddBytes(&time_cbb, out) || !CBB_flush(cbb)) {
59*6777b538SAndroid Build Coastguard Worker     return false;
60*6777b538SAndroid Build Coastguard Worker   }
61*6777b538SAndroid Build Coastguard Worker   return true;
62*6777b538SAndroid Build Coastguard Worker }
63*6777b538SAndroid Build Coastguard Worker 
64*6777b538SAndroid Build Coastguard Worker // Finalizes the CBB to a std::string.
FinishCBB(CBB * cbb)65*6777b538SAndroid Build Coastguard Worker std::string FinishCBB(CBB* cbb) {
66*6777b538SAndroid Build Coastguard Worker   size_t cbb_len;
67*6777b538SAndroid Build Coastguard Worker   uint8_t* cbb_bytes;
68*6777b538SAndroid Build Coastguard Worker 
69*6777b538SAndroid Build Coastguard Worker   if (!CBB_finish(cbb, &cbb_bytes, &cbb_len)) {
70*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE() << "CBB_finish() failed";
71*6777b538SAndroid Build Coastguard Worker     return std::string();
72*6777b538SAndroid Build Coastguard Worker   }
73*6777b538SAndroid Build Coastguard Worker 
74*6777b538SAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> delete_bytes(cbb_bytes);
75*6777b538SAndroid Build Coastguard Worker   return std::string(reinterpret_cast<char*>(cbb_bytes), cbb_len);
76*6777b538SAndroid Build Coastguard Worker }
77*6777b538SAndroid Build Coastguard Worker 
PKeyToSPK(const EVP_PKEY * pkey)78*6777b538SAndroid Build Coastguard Worker std::string PKeyToSPK(const EVP_PKEY* pkey) {
79*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
80*6777b538SAndroid Build Coastguard Worker   if (!CBB_init(cbb.get(), 64) || !EVP_marshal_public_key(cbb.get(), pkey)) {
81*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
82*6777b538SAndroid Build Coastguard Worker     return std::string();
83*6777b538SAndroid Build Coastguard Worker   }
84*6777b538SAndroid Build Coastguard Worker   std::string spki = FinishCBB(cbb.get());
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker   std::string_view spk;
87*6777b538SAndroid Build Coastguard Worker   if (!asn1::ExtractSubjectPublicKeyFromSPKI(spki, &spk)) {
88*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
89*6777b538SAndroid Build Coastguard Worker     return std::string();
90*6777b538SAndroid Build Coastguard Worker   }
91*6777b538SAndroid Build Coastguard Worker 
92*6777b538SAndroid Build Coastguard Worker   // ExtractSubjectPublicKeyFromSPKI() includes the unused bit count. For this
93*6777b538SAndroid Build Coastguard Worker   // application, the unused bit count must be zero, and is not included in the
94*6777b538SAndroid Build Coastguard Worker   // result.
95*6777b538SAndroid Build Coastguard Worker   if (spk.empty() || spk[0] != '\0') {
96*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
97*6777b538SAndroid Build Coastguard Worker     return std::string();
98*6777b538SAndroid Build Coastguard Worker   }
99*6777b538SAndroid Build Coastguard Worker   spk.remove_prefix(1);
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker   return std::string(spk);
102*6777b538SAndroid Build Coastguard Worker }
103*6777b538SAndroid Build Coastguard Worker 
104*6777b538SAndroid Build Coastguard Worker // Returns a DER-encoded bssl::OCSPResponse with the given |response_status|.
105*6777b538SAndroid Build Coastguard Worker // |response_type| and |response| are optional and may be empty.
EncodeOCSPResponse(bssl::OCSPResponse::ResponseStatus response_status,bssl::der::Input response_type,std::string response)106*6777b538SAndroid Build Coastguard Worker std::string EncodeOCSPResponse(
107*6777b538SAndroid Build Coastguard Worker     bssl::OCSPResponse::ResponseStatus response_status,
108*6777b538SAndroid Build Coastguard Worker     bssl::der::Input response_type,
109*6777b538SAndroid Build Coastguard Worker     std::string response) {
110*6777b538SAndroid Build Coastguard Worker   // RFC 6960 section 4.2.1:
111*6777b538SAndroid Build Coastguard Worker   //
112*6777b538SAndroid Build Coastguard Worker   //    bssl::OCSPResponse ::= SEQUENCE {
113*6777b538SAndroid Build Coastguard Worker   //       responseStatus         OCSPResponseStatus,
114*6777b538SAndroid Build Coastguard Worker   //       responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
115*6777b538SAndroid Build Coastguard Worker   //
116*6777b538SAndroid Build Coastguard Worker   //    OCSPResponseStatus ::= ENUMERATED {
117*6777b538SAndroid Build Coastguard Worker   //        successful            (0),  -- Response has valid confirmations
118*6777b538SAndroid Build Coastguard Worker   //        malformedRequest      (1),  -- Illegal confirmation request
119*6777b538SAndroid Build Coastguard Worker   //        internalError         (2),  -- Internal error in issuer
120*6777b538SAndroid Build Coastguard Worker   //        tryLater              (3),  -- Try again later
121*6777b538SAndroid Build Coastguard Worker   //                                    -- (4) is not used
122*6777b538SAndroid Build Coastguard Worker   //        sigRequired           (5),  -- Must sign the request
123*6777b538SAndroid Build Coastguard Worker   //        unauthorized          (6)   -- Request unauthorized
124*6777b538SAndroid Build Coastguard Worker   //    }
125*6777b538SAndroid Build Coastguard Worker   //
126*6777b538SAndroid Build Coastguard Worker   //    The value for responseBytes consists of an OBJECT IDENTIFIER and a
127*6777b538SAndroid Build Coastguard Worker   //    response syntax identified by that OID encoded as an OCTET STRING.
128*6777b538SAndroid Build Coastguard Worker   //
129*6777b538SAndroid Build Coastguard Worker   //    ResponseBytes ::=       SEQUENCE {
130*6777b538SAndroid Build Coastguard Worker   //        responseType   OBJECT IDENTIFIER,
131*6777b538SAndroid Build Coastguard Worker   //        response       OCTET STRING }
132*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
133*6777b538SAndroid Build Coastguard Worker   CBB ocsp_response, ocsp_response_status, ocsp_response_bytes,
134*6777b538SAndroid Build Coastguard Worker       ocsp_response_bytes_sequence, ocsp_response_type,
135*6777b538SAndroid Build Coastguard Worker       ocsp_response_octet_string;
136*6777b538SAndroid Build Coastguard Worker 
137*6777b538SAndroid Build Coastguard Worker   if (!CBB_init(cbb.get(), 64 + response_type.size() + response.size()) ||
138*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(cbb.get(), &ocsp_response, CBS_ASN1_SEQUENCE) ||
139*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&ocsp_response, &ocsp_response_status,
140*6777b538SAndroid Build Coastguard Worker                     CBS_ASN1_ENUMERATED) ||
141*6777b538SAndroid Build Coastguard Worker       !CBB_add_u8(&ocsp_response_status,
142*6777b538SAndroid Build Coastguard Worker                   static_cast<uint8_t>(response_status))) {
143*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
144*6777b538SAndroid Build Coastguard Worker     return std::string();
145*6777b538SAndroid Build Coastguard Worker   }
146*6777b538SAndroid Build Coastguard Worker 
147*6777b538SAndroid Build Coastguard Worker   if (!response_type.empty()) {
148*6777b538SAndroid Build Coastguard Worker     if (!CBB_add_asn1(&ocsp_response, &ocsp_response_bytes,
149*6777b538SAndroid Build Coastguard Worker                       CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
150*6777b538SAndroid Build Coastguard Worker         !CBB_add_asn1(&ocsp_response_bytes, &ocsp_response_bytes_sequence,
151*6777b538SAndroid Build Coastguard Worker                       CBS_ASN1_SEQUENCE) ||
152*6777b538SAndroid Build Coastguard Worker         !CBB_add_asn1(&ocsp_response_bytes_sequence, &ocsp_response_type,
153*6777b538SAndroid Build Coastguard Worker                       CBS_ASN1_OBJECT) ||
154*6777b538SAndroid Build Coastguard Worker         !CBBAddBytes(&ocsp_response_type, response_type) ||
155*6777b538SAndroid Build Coastguard Worker         !CBB_add_asn1(&ocsp_response_bytes_sequence,
156*6777b538SAndroid Build Coastguard Worker                       &ocsp_response_octet_string, CBS_ASN1_OCTETSTRING) ||
157*6777b538SAndroid Build Coastguard Worker         !CBBAddBytes(&ocsp_response_octet_string, response)) {
158*6777b538SAndroid Build Coastguard Worker       ADD_FAILURE();
159*6777b538SAndroid Build Coastguard Worker       return std::string();
160*6777b538SAndroid Build Coastguard Worker     }
161*6777b538SAndroid Build Coastguard Worker   }
162*6777b538SAndroid Build Coastguard Worker 
163*6777b538SAndroid Build Coastguard Worker   return FinishCBB(cbb.get());
164*6777b538SAndroid Build Coastguard Worker }
165*6777b538SAndroid Build Coastguard Worker 
166*6777b538SAndroid Build Coastguard Worker // Adds a DER-encoded OCSP SingleResponse to |responses_cbb|.
167*6777b538SAndroid Build Coastguard Worker // |issuer_name_hash| and |issuer_key_hash| should be binary SHA1 hashes.
AddOCSPSingleResponse(CBB * responses_cbb,const OCSPBuilderSingleResponse & response,const std::string & issuer_name_hash,const std::string & issuer_key_hash)168*6777b538SAndroid Build Coastguard Worker bool AddOCSPSingleResponse(CBB* responses_cbb,
169*6777b538SAndroid Build Coastguard Worker                            const OCSPBuilderSingleResponse& response,
170*6777b538SAndroid Build Coastguard Worker                            const std::string& issuer_name_hash,
171*6777b538SAndroid Build Coastguard Worker                            const std::string& issuer_key_hash) {
172*6777b538SAndroid Build Coastguard Worker   // RFC 6960 section 4.2.1:
173*6777b538SAndroid Build Coastguard Worker   //
174*6777b538SAndroid Build Coastguard Worker   //    SingleResponse ::= SEQUENCE {
175*6777b538SAndroid Build Coastguard Worker   //       certID                       CertID,
176*6777b538SAndroid Build Coastguard Worker   //       certStatus                   CertStatus,
177*6777b538SAndroid Build Coastguard Worker   //       thisUpdate                   GeneralizedTime,
178*6777b538SAndroid Build Coastguard Worker   //       nextUpdate         [0]       EXPLICIT GeneralizedTime OPTIONAL,
179*6777b538SAndroid Build Coastguard Worker   //       singleExtensions   [1]       EXPLICIT Extensions OPTIONAL }
180*6777b538SAndroid Build Coastguard Worker   //
181*6777b538SAndroid Build Coastguard Worker   //    CertStatus ::= CHOICE {
182*6777b538SAndroid Build Coastguard Worker   //        good        [0]     IMPLICIT NULL,
183*6777b538SAndroid Build Coastguard Worker   //        revoked     [1]     IMPLICIT RevokedInfo,
184*6777b538SAndroid Build Coastguard Worker   //        unknown     [2]     IMPLICIT UnknownInfo }
185*6777b538SAndroid Build Coastguard Worker   //
186*6777b538SAndroid Build Coastguard Worker   //    RevokedInfo ::= SEQUENCE {
187*6777b538SAndroid Build Coastguard Worker   //        revocationTime              GeneralizedTime,
188*6777b538SAndroid Build Coastguard Worker   //        revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
189*6777b538SAndroid Build Coastguard Worker   //
190*6777b538SAndroid Build Coastguard Worker   //    UnknownInfo ::= NULL
191*6777b538SAndroid Build Coastguard Worker   //
192*6777b538SAndroid Build Coastguard Worker   // RFC 6960 section 4.1.1:
193*6777b538SAndroid Build Coastguard Worker   //   CertID          ::=     SEQUENCE {
194*6777b538SAndroid Build Coastguard Worker   //        hashAlgorithm       AlgorithmIdentifier,
195*6777b538SAndroid Build Coastguard Worker   //        issuerNameHash      OCTET STRING, -- Hash of issuer's DN
196*6777b538SAndroid Build Coastguard Worker   //        issuerKeyHash       OCTET STRING, -- Hash of issuer's public key
197*6777b538SAndroid Build Coastguard Worker   //        serialNumber        CertificateSerialNumber }
198*6777b538SAndroid Build Coastguard Worker   //
199*6777b538SAndroid Build Coastguard Worker   //  The contents of CertID include the following fields:
200*6777b538SAndroid Build Coastguard Worker   //
201*6777b538SAndroid Build Coastguard Worker   //    o  hashAlgorithm is the hash algorithm used to generate the
202*6777b538SAndroid Build Coastguard Worker   //       issuerNameHash and issuerKeyHash values.
203*6777b538SAndroid Build Coastguard Worker   //
204*6777b538SAndroid Build Coastguard Worker   //    o  issuerNameHash is the hash of the issuer's distinguished name
205*6777b538SAndroid Build Coastguard Worker   //       (DN).  The hash shall be calculated over the DER encoding of the
206*6777b538SAndroid Build Coastguard Worker   //       issuer's name field in the certificate being checked.
207*6777b538SAndroid Build Coastguard Worker   //
208*6777b538SAndroid Build Coastguard Worker   //    o  issuerKeyHash is the hash of the issuer's public key.  The hash
209*6777b538SAndroid Build Coastguard Worker   //       shall be calculated over the value (excluding tag and length) of
210*6777b538SAndroid Build Coastguard Worker   //       the subject public key field in the issuer's certificate.
211*6777b538SAndroid Build Coastguard Worker   //
212*6777b538SAndroid Build Coastguard Worker   //    o  serialNumber is the serial number of the certificate for which
213*6777b538SAndroid Build Coastguard Worker   //       status is being requested.
214*6777b538SAndroid Build Coastguard Worker 
215*6777b538SAndroid Build Coastguard Worker   CBB single_response, issuer_name_hash_cbb, issuer_key_hash_cbb, cert_id;
216*6777b538SAndroid Build Coastguard Worker   if (!CBB_add_asn1(responses_cbb, &single_response, CBS_ASN1_SEQUENCE) ||
217*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&single_response, &cert_id, CBS_ASN1_SEQUENCE) ||
218*6777b538SAndroid Build Coastguard Worker       !CBBAddBytes(&cert_id, Sha1()) ||
219*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&cert_id, &issuer_name_hash_cbb, CBS_ASN1_OCTETSTRING) ||
220*6777b538SAndroid Build Coastguard Worker       !CBBAddBytes(&issuer_name_hash_cbb, issuer_name_hash) ||
221*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&cert_id, &issuer_key_hash_cbb, CBS_ASN1_OCTETSTRING) ||
222*6777b538SAndroid Build Coastguard Worker       !CBBAddBytes(&issuer_key_hash_cbb, issuer_key_hash) ||
223*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1_uint64(&cert_id, response.serial)) {
224*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
225*6777b538SAndroid Build Coastguard Worker     return false;
226*6777b538SAndroid Build Coastguard Worker   }
227*6777b538SAndroid Build Coastguard Worker 
228*6777b538SAndroid Build Coastguard Worker   unsigned int cert_status_tag_number;
229*6777b538SAndroid Build Coastguard Worker   switch (response.cert_status) {
230*6777b538SAndroid Build Coastguard Worker     case bssl::OCSPRevocationStatus::GOOD:
231*6777b538SAndroid Build Coastguard Worker       cert_status_tag_number = CBS_ASN1_CONTEXT_SPECIFIC | 0;
232*6777b538SAndroid Build Coastguard Worker       break;
233*6777b538SAndroid Build Coastguard Worker     case bssl::OCSPRevocationStatus::REVOKED:
234*6777b538SAndroid Build Coastguard Worker       cert_status_tag_number =
235*6777b538SAndroid Build Coastguard Worker           CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1;
236*6777b538SAndroid Build Coastguard Worker       break;
237*6777b538SAndroid Build Coastguard Worker     case bssl::OCSPRevocationStatus::UNKNOWN:
238*6777b538SAndroid Build Coastguard Worker       cert_status_tag_number = CBS_ASN1_CONTEXT_SPECIFIC | 2;
239*6777b538SAndroid Build Coastguard Worker       break;
240*6777b538SAndroid Build Coastguard Worker   }
241*6777b538SAndroid Build Coastguard Worker 
242*6777b538SAndroid Build Coastguard Worker   CBB cert_status_cbb;
243*6777b538SAndroid Build Coastguard Worker   if (!CBB_add_asn1(&single_response, &cert_status_cbb,
244*6777b538SAndroid Build Coastguard Worker                     cert_status_tag_number)) {
245*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
246*6777b538SAndroid Build Coastguard Worker     return false;
247*6777b538SAndroid Build Coastguard Worker   }
248*6777b538SAndroid Build Coastguard Worker   if (response.cert_status == bssl::OCSPRevocationStatus::REVOKED &&
249*6777b538SAndroid Build Coastguard Worker       !CBBAddGeneralizedTime(&cert_status_cbb, response.revocation_time)) {
250*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
251*6777b538SAndroid Build Coastguard Worker     return false;
252*6777b538SAndroid Build Coastguard Worker   }
253*6777b538SAndroid Build Coastguard Worker 
254*6777b538SAndroid Build Coastguard Worker   CBB next_update_cbb;
255*6777b538SAndroid Build Coastguard Worker   if (!CBBAddGeneralizedTime(&single_response, response.this_update) ||
256*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&single_response, &next_update_cbb,
257*6777b538SAndroid Build Coastguard Worker                     CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
258*6777b538SAndroid Build Coastguard Worker       !CBBAddGeneralizedTime(&next_update_cbb, response.next_update)) {
259*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
260*6777b538SAndroid Build Coastguard Worker     return false;
261*6777b538SAndroid Build Coastguard Worker   }
262*6777b538SAndroid Build Coastguard Worker 
263*6777b538SAndroid Build Coastguard Worker   return CBB_flush(responses_cbb);
264*6777b538SAndroid Build Coastguard Worker }
265*6777b538SAndroid Build Coastguard Worker 
266*6777b538SAndroid Build Coastguard Worker }  // namespace
267*6777b538SAndroid Build Coastguard Worker 
BuildOCSPResponseError(bssl::OCSPResponse::ResponseStatus response_status)268*6777b538SAndroid Build Coastguard Worker std::string BuildOCSPResponseError(
269*6777b538SAndroid Build Coastguard Worker     bssl::OCSPResponse::ResponseStatus response_status) {
270*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(response_status, bssl::OCSPResponse::ResponseStatus::SUCCESSFUL);
271*6777b538SAndroid Build Coastguard Worker   return EncodeOCSPResponse(response_status, bssl::der::Input(), std::string());
272*6777b538SAndroid Build Coastguard Worker }
273*6777b538SAndroid Build Coastguard Worker 
BuildOCSPResponse(const std::string & responder_subject,EVP_PKEY * responder_key,base::Time produced_at,const std::vector<OCSPBuilderSingleResponse> & responses)274*6777b538SAndroid Build Coastguard Worker std::string BuildOCSPResponse(
275*6777b538SAndroid Build Coastguard Worker     const std::string& responder_subject,
276*6777b538SAndroid Build Coastguard Worker     EVP_PKEY* responder_key,
277*6777b538SAndroid Build Coastguard Worker     base::Time produced_at,
278*6777b538SAndroid Build Coastguard Worker     const std::vector<OCSPBuilderSingleResponse>& responses) {
279*6777b538SAndroid Build Coastguard Worker   std::string responder_name_hash = base::SHA1HashString(responder_subject);
280*6777b538SAndroid Build Coastguard Worker   std::string responder_key_hash =
281*6777b538SAndroid Build Coastguard Worker       base::SHA1HashString(PKeyToSPK(responder_key));
282*6777b538SAndroid Build Coastguard Worker 
283*6777b538SAndroid Build Coastguard Worker   // RFC 6960 section 4.2.1:
284*6777b538SAndroid Build Coastguard Worker   //
285*6777b538SAndroid Build Coastguard Worker   //    ResponseData ::= SEQUENCE {
286*6777b538SAndroid Build Coastguard Worker   //       version              [0] EXPLICIT Version DEFAULT v1,
287*6777b538SAndroid Build Coastguard Worker   //       responderID              ResponderID,
288*6777b538SAndroid Build Coastguard Worker   //       producedAt               GeneralizedTime,
289*6777b538SAndroid Build Coastguard Worker   //       responses                SEQUENCE OF SingleResponse,
290*6777b538SAndroid Build Coastguard Worker   //       responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
291*6777b538SAndroid Build Coastguard Worker   //
292*6777b538SAndroid Build Coastguard Worker   //    ResponderID ::= CHOICE {
293*6777b538SAndroid Build Coastguard Worker   //       byName               [1] Name,
294*6777b538SAndroid Build Coastguard Worker   //       byKey                [2] KeyHash }
295*6777b538SAndroid Build Coastguard Worker   //
296*6777b538SAndroid Build Coastguard Worker   //    KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key
297*6777b538SAndroid Build Coastguard Worker   //    (excluding the tag and length fields)
298*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB tbs_cbb;
299*6777b538SAndroid Build Coastguard Worker   CBB response_data, responder_id, responder_id_by_key, responses_cbb;
300*6777b538SAndroid Build Coastguard Worker   if (!CBB_init(tbs_cbb.get(), 64) ||
301*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(tbs_cbb.get(), &response_data, CBS_ASN1_SEQUENCE) ||
302*6777b538SAndroid Build Coastguard Worker       // Version is the default v1, so it is not encoded.
303*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&response_data, &responder_id,
304*6777b538SAndroid Build Coastguard Worker                     CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 2) ||
305*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&responder_id, &responder_id_by_key,
306*6777b538SAndroid Build Coastguard Worker                     CBS_ASN1_OCTETSTRING) ||
307*6777b538SAndroid Build Coastguard Worker       !CBBAddBytes(&responder_id_by_key, responder_key_hash) ||
308*6777b538SAndroid Build Coastguard Worker       !CBBAddGeneralizedTime(&response_data, produced_at) ||
309*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&response_data, &responses_cbb, CBS_ASN1_SEQUENCE)) {
310*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
311*6777b538SAndroid Build Coastguard Worker     return std::string();
312*6777b538SAndroid Build Coastguard Worker   }
313*6777b538SAndroid Build Coastguard Worker 
314*6777b538SAndroid Build Coastguard Worker   for (const auto& response : responses) {
315*6777b538SAndroid Build Coastguard Worker     if (!AddOCSPSingleResponse(&responses_cbb, response, responder_name_hash,
316*6777b538SAndroid Build Coastguard Worker                                responder_key_hash)) {
317*6777b538SAndroid Build Coastguard Worker       return std::string();
318*6777b538SAndroid Build Coastguard Worker     }
319*6777b538SAndroid Build Coastguard Worker   }
320*6777b538SAndroid Build Coastguard Worker 
321*6777b538SAndroid Build Coastguard Worker   // responseExtensions not currently supported.
322*6777b538SAndroid Build Coastguard Worker 
323*6777b538SAndroid Build Coastguard Worker   return BuildOCSPResponseWithResponseData(responder_key,
324*6777b538SAndroid Build Coastguard Worker                                            FinishCBB(tbs_cbb.get()));
325*6777b538SAndroid Build Coastguard Worker }
326*6777b538SAndroid Build Coastguard Worker 
BuildOCSPResponseWithResponseData(EVP_PKEY * responder_key,const std::string & tbs_response_data,std::optional<bssl::SignatureAlgorithm> signature_algorithm)327*6777b538SAndroid Build Coastguard Worker std::string BuildOCSPResponseWithResponseData(
328*6777b538SAndroid Build Coastguard Worker     EVP_PKEY* responder_key,
329*6777b538SAndroid Build Coastguard Worker     const std::string& tbs_response_data,
330*6777b538SAndroid Build Coastguard Worker     std::optional<bssl::SignatureAlgorithm> signature_algorithm) {
331*6777b538SAndroid Build Coastguard Worker   //    For a basic OCSP responder, responseType will be id-pkix-ocsp-basic.
332*6777b538SAndroid Build Coastguard Worker   //
333*6777b538SAndroid Build Coastguard Worker   //    id-pkix-ocsp           OBJECT IDENTIFIER ::= { id-ad-ocsp }
334*6777b538SAndroid Build Coastguard Worker   //    id-pkix-ocsp-basic     OBJECT IDENTIFIER ::= { id-pkix-ocsp 1 }
335*6777b538SAndroid Build Coastguard Worker   //
336*6777b538SAndroid Build Coastguard Worker   //    The value for response SHALL be the DER encoding of
337*6777b538SAndroid Build Coastguard Worker   //    BasicOCSPResponse.
338*6777b538SAndroid Build Coastguard Worker   //
339*6777b538SAndroid Build Coastguard Worker   //    BasicOCSPResponse       ::= SEQUENCE {
340*6777b538SAndroid Build Coastguard Worker   //       tbsResponseData      ResponseData,
341*6777b538SAndroid Build Coastguard Worker   //       signatureAlgorithm   AlgorithmIdentifier,
342*6777b538SAndroid Build Coastguard Worker   //       signature            BIT STRING,
343*6777b538SAndroid Build Coastguard Worker   //       certs            [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
344*6777b538SAndroid Build Coastguard Worker   //
345*6777b538SAndroid Build Coastguard Worker   //    The value for signature SHALL be computed on the hash of the DER
346*6777b538SAndroid Build Coastguard Worker   //    encoding of ResponseData.  The responder MAY include certificates in
347*6777b538SAndroid Build Coastguard Worker   //    the certs field of BasicOCSPResponse that help the OCSP client verify
348*6777b538SAndroid Build Coastguard Worker   //    the responder's signature.  If no certificates are included, then
349*6777b538SAndroid Build Coastguard Worker   //    certs SHOULD be absent.
350*6777b538SAndroid Build Coastguard Worker   //
351*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB basic_ocsp_response_cbb;
352*6777b538SAndroid Build Coastguard Worker   CBB basic_ocsp_response, signature;
353*6777b538SAndroid Build Coastguard Worker   if (!responder_key) {
354*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
355*6777b538SAndroid Build Coastguard Worker     return std::string();
356*6777b538SAndroid Build Coastguard Worker   }
357*6777b538SAndroid Build Coastguard Worker   if (!signature_algorithm)
358*6777b538SAndroid Build Coastguard Worker     signature_algorithm =
359*6777b538SAndroid Build Coastguard Worker         CertBuilder::DefaultSignatureAlgorithmForKey(responder_key);
360*6777b538SAndroid Build Coastguard Worker   if (!signature_algorithm) {
361*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
362*6777b538SAndroid Build Coastguard Worker     return std::string();
363*6777b538SAndroid Build Coastguard Worker   }
364*6777b538SAndroid Build Coastguard Worker   std::string signature_algorithm_tlv =
365*6777b538SAndroid Build Coastguard Worker       CertBuilder::SignatureAlgorithmToDer(*signature_algorithm);
366*6777b538SAndroid Build Coastguard Worker   if (signature_algorithm_tlv.empty() ||
367*6777b538SAndroid Build Coastguard Worker       !CBB_init(basic_ocsp_response_cbb.get(), 64 + tbs_response_data.size()) ||
368*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(basic_ocsp_response_cbb.get(), &basic_ocsp_response,
369*6777b538SAndroid Build Coastguard Worker                     CBS_ASN1_SEQUENCE) ||
370*6777b538SAndroid Build Coastguard Worker       !CBBAddBytes(&basic_ocsp_response, tbs_response_data) ||
371*6777b538SAndroid Build Coastguard Worker       !CBBAddBytes(&basic_ocsp_response, signature_algorithm_tlv) ||
372*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&basic_ocsp_response, &signature, CBS_ASN1_BITSTRING) ||
373*6777b538SAndroid Build Coastguard Worker       !CBB_add_u8(&signature, 0 /* no unused bits */) ||
374*6777b538SAndroid Build Coastguard Worker       !CertBuilder::SignData(*signature_algorithm, tbs_response_data,
375*6777b538SAndroid Build Coastguard Worker                              responder_key, &signature)) {
376*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
377*6777b538SAndroid Build Coastguard Worker     return std::string();
378*6777b538SAndroid Build Coastguard Worker   }
379*6777b538SAndroid Build Coastguard Worker 
380*6777b538SAndroid Build Coastguard Worker   // certs field not currently supported.
381*6777b538SAndroid Build Coastguard Worker 
382*6777b538SAndroid Build Coastguard Worker   return EncodeOCSPResponse(bssl::OCSPResponse::ResponseStatus::SUCCESSFUL,
383*6777b538SAndroid Build Coastguard Worker                             bssl::der::Input(bssl::kBasicOCSPResponseOid),
384*6777b538SAndroid Build Coastguard Worker                             FinishCBB(basic_ocsp_response_cbb.get()));
385*6777b538SAndroid Build Coastguard Worker }
386*6777b538SAndroid Build Coastguard Worker 
BuildCrlWithSigner(const std::string & crl_issuer_subject,EVP_PKEY * crl_issuer_key,const std::vector<uint64_t> & revoked_serials,const std::string & signature_algorithm_tlv,base::OnceCallback<bool (std::string,CBB *)> signer)387*6777b538SAndroid Build Coastguard Worker std::string BuildCrlWithSigner(
388*6777b538SAndroid Build Coastguard Worker     const std::string& crl_issuer_subject,
389*6777b538SAndroid Build Coastguard Worker     EVP_PKEY* crl_issuer_key,
390*6777b538SAndroid Build Coastguard Worker     const std::vector<uint64_t>& revoked_serials,
391*6777b538SAndroid Build Coastguard Worker     const std::string& signature_algorithm_tlv,
392*6777b538SAndroid Build Coastguard Worker     base::OnceCallback<bool(std::string, CBB*)> signer) {
393*6777b538SAndroid Build Coastguard Worker   if (!crl_issuer_key) {
394*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
395*6777b538SAndroid Build Coastguard Worker     return std::string();
396*6777b538SAndroid Build Coastguard Worker   }
397*6777b538SAndroid Build Coastguard Worker   //    TBSCertList  ::=  SEQUENCE  {
398*6777b538SAndroid Build Coastguard Worker   //         version                 Version OPTIONAL,
399*6777b538SAndroid Build Coastguard Worker   //                                      -- if present, MUST be v2
400*6777b538SAndroid Build Coastguard Worker   //         signature               AlgorithmIdentifier,
401*6777b538SAndroid Build Coastguard Worker   //         issuer                  Name,
402*6777b538SAndroid Build Coastguard Worker   //         thisUpdate              Time,
403*6777b538SAndroid Build Coastguard Worker   //         nextUpdate              Time OPTIONAL,
404*6777b538SAndroid Build Coastguard Worker   //         revokedCertificates     SEQUENCE OF SEQUENCE  {
405*6777b538SAndroid Build Coastguard Worker   //              userCertificate         CertificateSerialNumber,
406*6777b538SAndroid Build Coastguard Worker   //              revocationDate          Time,
407*6777b538SAndroid Build Coastguard Worker   //              crlEntryExtensions      Extensions OPTIONAL
408*6777b538SAndroid Build Coastguard Worker   //                                       -- if present, version MUST be v2
409*6777b538SAndroid Build Coastguard Worker   //                                   }  OPTIONAL,
410*6777b538SAndroid Build Coastguard Worker   //         crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
411*6777b538SAndroid Build Coastguard Worker   //                                       -- if present, version MUST be v2
412*6777b538SAndroid Build Coastguard Worker   //                                   }
413*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB tbs_cbb;
414*6777b538SAndroid Build Coastguard Worker   CBB tbs_cert_list, revoked_serials_cbb;
415*6777b538SAndroid Build Coastguard Worker   if (!CBB_init(tbs_cbb.get(), 10) ||
416*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(tbs_cbb.get(), &tbs_cert_list, CBS_ASN1_SEQUENCE) ||
417*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1_uint64(&tbs_cert_list, 1 /* V2 */) ||
418*6777b538SAndroid Build Coastguard Worker       !CBBAddBytes(&tbs_cert_list, signature_algorithm_tlv) ||
419*6777b538SAndroid Build Coastguard Worker       !CBBAddBytes(&tbs_cert_list, crl_issuer_subject) ||
420*6777b538SAndroid Build Coastguard Worker       !x509_util::CBBAddTime(&tbs_cert_list,
421*6777b538SAndroid Build Coastguard Worker                              base::Time::Now() - base::Days(1)) ||
422*6777b538SAndroid Build Coastguard Worker       !x509_util::CBBAddTime(&tbs_cert_list,
423*6777b538SAndroid Build Coastguard Worker                              base::Time::Now() + base::Days(6))) {
424*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
425*6777b538SAndroid Build Coastguard Worker     return std::string();
426*6777b538SAndroid Build Coastguard Worker   }
427*6777b538SAndroid Build Coastguard Worker   if (!revoked_serials.empty()) {
428*6777b538SAndroid Build Coastguard Worker     if (!CBB_add_asn1(&tbs_cert_list, &revoked_serials_cbb,
429*6777b538SAndroid Build Coastguard Worker                       CBS_ASN1_SEQUENCE)) {
430*6777b538SAndroid Build Coastguard Worker       ADD_FAILURE();
431*6777b538SAndroid Build Coastguard Worker       return std::string();
432*6777b538SAndroid Build Coastguard Worker     }
433*6777b538SAndroid Build Coastguard Worker     for (const int64_t revoked_serial : revoked_serials) {
434*6777b538SAndroid Build Coastguard Worker       CBB revoked_serial_cbb;
435*6777b538SAndroid Build Coastguard Worker       if (!CBB_add_asn1(&revoked_serials_cbb, &revoked_serial_cbb,
436*6777b538SAndroid Build Coastguard Worker                         CBS_ASN1_SEQUENCE) ||
437*6777b538SAndroid Build Coastguard Worker           !CBB_add_asn1_uint64(&revoked_serial_cbb, revoked_serial) ||
438*6777b538SAndroid Build Coastguard Worker           !x509_util::CBBAddTime(&revoked_serial_cbb,
439*6777b538SAndroid Build Coastguard Worker                                  base::Time::Now() - base::Days(1)) ||
440*6777b538SAndroid Build Coastguard Worker           !CBB_flush(&revoked_serials_cbb)) {
441*6777b538SAndroid Build Coastguard Worker         ADD_FAILURE();
442*6777b538SAndroid Build Coastguard Worker         return std::string();
443*6777b538SAndroid Build Coastguard Worker       }
444*6777b538SAndroid Build Coastguard Worker     }
445*6777b538SAndroid Build Coastguard Worker   }
446*6777b538SAndroid Build Coastguard Worker 
447*6777b538SAndroid Build Coastguard Worker   std::string tbs_tlv = FinishCBB(tbs_cbb.get());
448*6777b538SAndroid Build Coastguard Worker 
449*6777b538SAndroid Build Coastguard Worker   //    CertificateList  ::=  SEQUENCE  {
450*6777b538SAndroid Build Coastguard Worker   //         tbsCertList          TBSCertList,
451*6777b538SAndroid Build Coastguard Worker   //         signatureAlgorithm   AlgorithmIdentifier,
452*6777b538SAndroid Build Coastguard Worker   //         signatureValue       BIT STRING  }
453*6777b538SAndroid Build Coastguard Worker   bssl::ScopedCBB crl_cbb;
454*6777b538SAndroid Build Coastguard Worker   CBB cert_list, signature;
455*6777b538SAndroid Build Coastguard Worker   if (!CBB_init(crl_cbb.get(), 10) ||
456*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(crl_cbb.get(), &cert_list, CBS_ASN1_SEQUENCE) ||
457*6777b538SAndroid Build Coastguard Worker       !CBBAddBytes(&cert_list, tbs_tlv) ||
458*6777b538SAndroid Build Coastguard Worker       !CBBAddBytes(&cert_list, signature_algorithm_tlv) ||
459*6777b538SAndroid Build Coastguard Worker       !CBB_add_asn1(&cert_list, &signature, CBS_ASN1_BITSTRING) ||
460*6777b538SAndroid Build Coastguard Worker       !CBB_add_u8(&signature, 0 /* no unused bits */) ||
461*6777b538SAndroid Build Coastguard Worker       !std::move(signer).Run(tbs_tlv, &signature)) {
462*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
463*6777b538SAndroid Build Coastguard Worker     return std::string();
464*6777b538SAndroid Build Coastguard Worker   }
465*6777b538SAndroid Build Coastguard Worker   return FinishCBB(crl_cbb.get());
466*6777b538SAndroid Build Coastguard Worker }
467*6777b538SAndroid Build Coastguard Worker 
BuildCrl(const std::string & crl_issuer_subject,EVP_PKEY * crl_issuer_key,const std::vector<uint64_t> & revoked_serials,std::optional<bssl::SignatureAlgorithm> signature_algorithm)468*6777b538SAndroid Build Coastguard Worker std::string BuildCrl(
469*6777b538SAndroid Build Coastguard Worker     const std::string& crl_issuer_subject,
470*6777b538SAndroid Build Coastguard Worker     EVP_PKEY* crl_issuer_key,
471*6777b538SAndroid Build Coastguard Worker     const std::vector<uint64_t>& revoked_serials,
472*6777b538SAndroid Build Coastguard Worker     std::optional<bssl::SignatureAlgorithm> signature_algorithm) {
473*6777b538SAndroid Build Coastguard Worker   if (!signature_algorithm) {
474*6777b538SAndroid Build Coastguard Worker     signature_algorithm =
475*6777b538SAndroid Build Coastguard Worker         CertBuilder::DefaultSignatureAlgorithmForKey(crl_issuer_key);
476*6777b538SAndroid Build Coastguard Worker   }
477*6777b538SAndroid Build Coastguard Worker   if (!signature_algorithm) {
478*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
479*6777b538SAndroid Build Coastguard Worker     return std::string();
480*6777b538SAndroid Build Coastguard Worker   }
481*6777b538SAndroid Build Coastguard Worker   std::string signature_algorithm_tlv =
482*6777b538SAndroid Build Coastguard Worker       CertBuilder::SignatureAlgorithmToDer(*signature_algorithm);
483*6777b538SAndroid Build Coastguard Worker   if (signature_algorithm_tlv.empty()) {
484*6777b538SAndroid Build Coastguard Worker     ADD_FAILURE();
485*6777b538SAndroid Build Coastguard Worker     return std::string();
486*6777b538SAndroid Build Coastguard Worker   }
487*6777b538SAndroid Build Coastguard Worker 
488*6777b538SAndroid Build Coastguard Worker   auto signer =
489*6777b538SAndroid Build Coastguard Worker       base::BindLambdaForTesting([&](std::string tbs_tlv, CBB* signature) {
490*6777b538SAndroid Build Coastguard Worker         return CertBuilder::SignData(*signature_algorithm, tbs_tlv,
491*6777b538SAndroid Build Coastguard Worker                                      crl_issuer_key, signature);
492*6777b538SAndroid Build Coastguard Worker       });
493*6777b538SAndroid Build Coastguard Worker   return BuildCrlWithSigner(crl_issuer_subject, crl_issuer_key, revoked_serials,
494*6777b538SAndroid Build Coastguard Worker                             signature_algorithm_tlv, signer);
495*6777b538SAndroid Build Coastguard Worker }
496*6777b538SAndroid Build Coastguard Worker 
BuildCrlWithAlgorithmTlvAndDigest(const std::string & crl_issuer_subject,EVP_PKEY * crl_issuer_key,const std::vector<uint64_t> & revoked_serials,const std::string & signature_algorithm_tlv,const EVP_MD * digest)497*6777b538SAndroid Build Coastguard Worker std::string BuildCrlWithAlgorithmTlvAndDigest(
498*6777b538SAndroid Build Coastguard Worker     const std::string& crl_issuer_subject,
499*6777b538SAndroid Build Coastguard Worker     EVP_PKEY* crl_issuer_key,
500*6777b538SAndroid Build Coastguard Worker     const std::vector<uint64_t>& revoked_serials,
501*6777b538SAndroid Build Coastguard Worker     const std::string& signature_algorithm_tlv,
502*6777b538SAndroid Build Coastguard Worker     const EVP_MD* digest) {
503*6777b538SAndroid Build Coastguard Worker   auto signer =
504*6777b538SAndroid Build Coastguard Worker       base::BindLambdaForTesting([&](std::string tbs_tlv, CBB* signature) {
505*6777b538SAndroid Build Coastguard Worker         return CertBuilder::SignDataWithDigest(digest, tbs_tlv, crl_issuer_key,
506*6777b538SAndroid Build Coastguard Worker                                                signature);
507*6777b538SAndroid Build Coastguard Worker       });
508*6777b538SAndroid Build Coastguard Worker   return BuildCrlWithSigner(crl_issuer_subject, crl_issuer_key, revoked_serials,
509*6777b538SAndroid Build Coastguard Worker                             signature_algorithm_tlv, signer);
510*6777b538SAndroid Build Coastguard Worker }
511*6777b538SAndroid Build Coastguard Worker 
512*6777b538SAndroid Build Coastguard Worker }  // namespace net
513