xref: /aosp_15_r20/external/cronet/third_party/boringssl/src/pki/verify_signed_data.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "verify_signed_data.h"
6 
7 #include <openssl/bytestring.h>
8 #include <openssl/digest.h>
9 #include <openssl/err.h>
10 #include <openssl/evp.h>
11 #include <openssl/pki/signature_verify_cache.h>
12 #include <openssl/rsa.h>
13 #include <openssl/sha.h>
14 
15 #include "cert_errors.h"
16 #include "input.h"
17 #include "parse_values.h"
18 #include "parser.h"
19 #include "signature_algorithm.h"
20 
21 namespace bssl {
22 
23 namespace {
24 
SHA256UpdateWithLengthPrefixedData(SHA256_CTX * s_ctx,const uint8_t * data,uint64_t length)25 bool SHA256UpdateWithLengthPrefixedData(SHA256_CTX *s_ctx, const uint8_t *data,
26                                         uint64_t length) {
27   return (SHA256_Update(s_ctx, reinterpret_cast<uint8_t *>(&length),
28                         sizeof(length)) &&
29           SHA256_Update(s_ctx, data, length));
30 }
31 
32 // Increase to make incompatible changes in the computation of the
33 // cache key.
34 constexpr uint32_t VerifyCacheKeyVersion = 1;
35 
SignatureVerifyCacheKey(std::string_view algorithm_name,der::Input signed_data,der::Input signature_value_bytes,EVP_PKEY * public_key)36 std::string SignatureVerifyCacheKey(std::string_view algorithm_name,
37                                     der::Input signed_data,
38                                     der::Input signature_value_bytes,
39                                     EVP_PKEY *public_key) {
40   SHA256_CTX s_ctx;
41   bssl::ScopedCBB public_key_cbb;
42   uint8_t digest[SHA256_DIGEST_LENGTH];
43   uint32_t version = VerifyCacheKeyVersion;
44   if (CBB_init(public_key_cbb.get(), 128) &&
45       EVP_marshal_public_key(public_key_cbb.get(), public_key) &&
46       SHA256_Init(&s_ctx) &&
47       SHA256_Update(&s_ctx, reinterpret_cast<uint8_t *>(&version),
48                     sizeof(version)) &&
49       SHA256UpdateWithLengthPrefixedData(
50           &s_ctx, reinterpret_cast<const uint8_t *>(algorithm_name.data()),
51           algorithm_name.length()) &&
52       SHA256UpdateWithLengthPrefixedData(&s_ctx, CBB_data(public_key_cbb.get()),
53                                          CBB_len(public_key_cbb.get())) &&
54       SHA256UpdateWithLengthPrefixedData(&s_ctx, signature_value_bytes.data(),
55                                          signature_value_bytes.size()) &&
56       SHA256UpdateWithLengthPrefixedData(&s_ctx, signed_data.data(),
57                                          signed_data.size()) &&
58       SHA256_Final(digest, &s_ctx)) {
59     return std::string(reinterpret_cast<char *>(digest), sizeof(digest));
60   }
61   return std::string();
62 }
63 
64 // Place an instance of this class on the call stack to automatically clear
65 // the OpenSSL error stack on function exit.
66 // TODO(crbug.com/boringssl/38): Remove this when the library is more robust to
67 // leaving things in the error queue.
68 class OpenSSLErrStackTracer {
69  public:
~OpenSSLErrStackTracer()70   ~OpenSSLErrStackTracer() { ERR_clear_error(); };
71 };
72 
73 }  // namespace
74 
75 // Parses an RSA public key or EC public key from SPKI to an EVP_PKEY. Returns
76 // true on success.
77 //
78 // This function only recognizes the "pk-rsa" (rsaEncryption) flavor of RSA
79 // public key from RFC 5912.
80 //
81 //     pk-rsa PUBLIC-KEY ::= {
82 //      IDENTIFIER rsaEncryption
83 //      KEY RSAPublicKey
84 //      PARAMS TYPE NULL ARE absent
85 //      -- Private key format not in this module --
86 //      CERT-KEY-USAGE {digitalSignature, nonRepudiation,
87 //      keyEncipherment, dataEncipherment, keyCertSign, cRLSign}
88 //     }
89 //
90 // COMPATIBILITY NOTE: RFC 5912 and RFC 3279 are in disagreement on the value
91 // of parameters for rsaEncryption. Whereas RFC 5912 says they must be absent,
92 // RFC 3279 says they must be NULL:
93 //
94 //     The rsaEncryption OID is intended to be used in the algorithm field
95 //     of a value of type AlgorithmIdentifier.  The parameters field MUST
96 //     have ASN.1 type NULL for this algorithm identifier.
97 //
98 // Following RFC 3279 in this case.
99 //
100 // In the case of parsing EC keys, RFC 5912 describes all the ECDSA
101 // signature algorithms as requiring a public key of type "pk-ec":
102 //
103 //     pk-ec PUBLIC-KEY ::= {
104 //      IDENTIFIER id-ecPublicKey
105 //      KEY ECPoint
106 //      PARAMS TYPE ECParameters ARE required
107 //      -- Private key format not in this module --
108 //      CERT-KEY-USAGE { digitalSignature, nonRepudiation, keyAgreement,
109 //                           keyCertSign, cRLSign }
110 //     }
111 //
112 // Moreover RFC 5912 stipulates what curves are allowed. The ECParameters
113 // MUST NOT use an implicitCurve or specificCurve for PKIX:
114 //
115 //     ECParameters ::= CHOICE {
116 //      namedCurve      CURVE.&id({NamedCurve})
117 //      -- implicitCurve   NULL
118 //        -- implicitCurve MUST NOT be used in PKIX
119 //      -- specifiedCurve  SpecifiedCurve
120 //        -- specifiedCurve MUST NOT be used in PKIX
121 //        -- Details for specifiedCurve can be found in [X9.62]
122 //        -- Any future additions to this CHOICE should be coordinated
123 //        -- with ANSI X.9.
124 //     }
125 //     -- If you need to be able to decode ANSI X.9 parameter structures,
126 //     -- uncomment the implicitCurve and specifiedCurve above, and also
127 //     -- uncomment the following:
128 //     --(WITH COMPONENTS {namedCurve PRESENT})
129 //
130 // The namedCurves are extensible. The ones described by RFC 5912 are:
131 //
132 //     NamedCurve CURVE ::= {
133 //     { ID secp192r1 } | { ID sect163k1 } | { ID sect163r2 } |
134 //     { ID secp224r1 } | { ID sect233k1 } | { ID sect233r1 } |
135 //     { ID secp256r1 } | { ID sect283k1 } | { ID sect283r1 } |
136 //     { ID secp384r1 } | { ID sect409k1 } | { ID sect409r1 } |
137 //     { ID secp521r1 } | { ID sect571k1 } | { ID sect571r1 },
138 //     ... -- Extensible
139 //     }
ParsePublicKey(der::Input public_key_spki,bssl::UniquePtr<EVP_PKEY> * public_key)140 bool ParsePublicKey(der::Input public_key_spki,
141                     bssl::UniquePtr<EVP_PKEY> *public_key) {
142   // Parse the SPKI to an EVP_PKEY.
143   OpenSSLErrStackTracer err_tracer;
144 
145   CBS cbs;
146   CBS_init(&cbs, public_key_spki.data(), public_key_spki.size());
147   public_key->reset(EVP_parse_public_key(&cbs));
148   if (!*public_key || CBS_len(&cbs) != 0) {
149     public_key->reset();
150     return false;
151   }
152   return true;
153 }
154 
VerifySignedData(SignatureAlgorithm algorithm,der::Input signed_data,const der::BitString & signature_value,EVP_PKEY * public_key,SignatureVerifyCache * cache)155 bool VerifySignedData(SignatureAlgorithm algorithm, der::Input signed_data,
156                       const der::BitString &signature_value,
157                       EVP_PKEY *public_key, SignatureVerifyCache *cache) {
158   int expected_pkey_id = 1;
159   const EVP_MD *digest = nullptr;
160   bool is_rsa_pss = false;
161   std::string_view cache_algorithm_name;
162   switch (algorithm) {
163     case SignatureAlgorithm::kRsaPkcs1Sha1:
164       expected_pkey_id = EVP_PKEY_RSA;
165       digest = EVP_sha1();
166       cache_algorithm_name = "RsaPkcs1Sha1";
167       break;
168     case SignatureAlgorithm::kRsaPkcs1Sha256:
169       expected_pkey_id = EVP_PKEY_RSA;
170       digest = EVP_sha256();
171       cache_algorithm_name = "RsaPkcs1Sha256";
172       break;
173     case SignatureAlgorithm::kRsaPkcs1Sha384:
174       expected_pkey_id = EVP_PKEY_RSA;
175       digest = EVP_sha384();
176       cache_algorithm_name = "RsaPkcs1Sha384";
177       break;
178     case SignatureAlgorithm::kRsaPkcs1Sha512:
179       expected_pkey_id = EVP_PKEY_RSA;
180       digest = EVP_sha512();
181       cache_algorithm_name = "RsaPkcs1Sha512";
182       break;
183 
184     case SignatureAlgorithm::kEcdsaSha1:
185       expected_pkey_id = EVP_PKEY_EC;
186       digest = EVP_sha1();
187       cache_algorithm_name = "EcdsaSha1";
188       break;
189     case SignatureAlgorithm::kEcdsaSha256:
190       expected_pkey_id = EVP_PKEY_EC;
191       digest = EVP_sha256();
192       cache_algorithm_name = "EcdsaSha256";
193       break;
194     case SignatureAlgorithm::kEcdsaSha384:
195       expected_pkey_id = EVP_PKEY_EC;
196       digest = EVP_sha384();
197       cache_algorithm_name = "EcdsaSha384";
198       break;
199     case SignatureAlgorithm::kEcdsaSha512:
200       expected_pkey_id = EVP_PKEY_EC;
201       digest = EVP_sha512();
202       cache_algorithm_name = "EcdsaSha512";
203       break;
204 
205     case SignatureAlgorithm::kRsaPssSha256:
206       expected_pkey_id = EVP_PKEY_RSA;
207       digest = EVP_sha256();
208       cache_algorithm_name = "RsaPssSha256";
209       is_rsa_pss = true;
210       break;
211     case SignatureAlgorithm::kRsaPssSha384:
212       expected_pkey_id = EVP_PKEY_RSA;
213       digest = EVP_sha384();
214       cache_algorithm_name = "RsaPssSha384";
215       is_rsa_pss = true;
216       break;
217     case SignatureAlgorithm::kRsaPssSha512:
218       expected_pkey_id = EVP_PKEY_RSA;
219       digest = EVP_sha512();
220       cache_algorithm_name = "RsaPssSha512";
221       is_rsa_pss = true;
222       break;
223   }
224 
225   if (expected_pkey_id != EVP_PKEY_id(public_key)) {
226     return false;
227   }
228 
229   // For the supported algorithms the signature value must be a whole
230   // number of bytes.
231   if (signature_value.unused_bits() != 0) {
232     return false;
233   }
234   der::Input signature_value_bytes = signature_value.bytes();
235 
236   std::string cache_key;
237   if (cache) {
238     cache_key = SignatureVerifyCacheKey(cache_algorithm_name, signed_data,
239                                         signature_value_bytes, public_key);
240     if (!cache_key.empty()) {
241       switch (cache->Check(cache_key)) {
242         case SignatureVerifyCache::Value::kValid:
243           return true;
244         case SignatureVerifyCache::Value::kInvalid:
245           return false;
246         case SignatureVerifyCache::Value::kUnknown:
247           break;
248       }
249     }
250   }
251 
252   OpenSSLErrStackTracer err_tracer;
253 
254   bssl::ScopedEVP_MD_CTX ctx;
255   EVP_PKEY_CTX *pctx = nullptr;  // Owned by |ctx|.
256 
257   if (!EVP_DigestVerifyInit(ctx.get(), &pctx, digest, nullptr, public_key)) {
258     return false;
259   }
260 
261   if (is_rsa_pss) {
262     // All supported RSASSA-PSS algorithms match signing and MGF-1 digest. They
263     // also use the digest length as the salt length, which is specified with -1
264     // in OpenSSL's API.
265     if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
266         !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) {
267       return false;
268     }
269   }
270 
271   bool ret = 1 == EVP_DigestVerify(ctx.get(), signature_value_bytes.data(),
272                                    signature_value_bytes.size(),
273                                    signed_data.data(), signed_data.size());
274   if (!cache_key.empty()) {
275     cache->Store(cache_key, ret ? SignatureVerifyCache::Value::kValid
276                                 : SignatureVerifyCache::Value::kInvalid);
277   }
278 
279   return ret;
280 }
281 
VerifySignedData(SignatureAlgorithm algorithm,der::Input signed_data,const der::BitString & signature_value,der::Input public_key_spki,SignatureVerifyCache * cache)282 bool VerifySignedData(SignatureAlgorithm algorithm, der::Input signed_data,
283                       const der::BitString &signature_value,
284                       der::Input public_key_spki, SignatureVerifyCache *cache) {
285   bssl::UniquePtr<EVP_PKEY> public_key;
286   if (!ParsePublicKey(public_key_spki, &public_key)) {
287     return false;
288   }
289   return VerifySignedData(algorithm, signed_data, signature_value,
290                           public_key.get(), cache);
291 }
292 
293 }  // namespace bssl
294