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