Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(376)

Side by Side Diff: net/cert/internal/verify_signed_data.cc

Issue 2400033005: Use BoringSSL scopers in //net. (Closed)
Patch Set: avoid some unnecessary refcount-bumping Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/cert/internal/verify_signed_data.h" 5 #include "net/cert/internal/verify_signed_data.h"
6 6
7 #include <openssl/bn.h>
7 #include <openssl/bytestring.h> 8 #include <openssl/bytestring.h>
8 #include <openssl/digest.h> 9 #include <openssl/digest.h>
9 #include <openssl/ec.h> 10 #include <openssl/ec.h>
10 #include <openssl/ec_key.h> 11 #include <openssl/ec_key.h>
11 #include <openssl/evp.h> 12 #include <openssl/evp.h>
12 #include <openssl/rsa.h> 13 #include <openssl/rsa.h>
13 14
14 #include "base/compiler_specific.h" 15 #include "base/compiler_specific.h"
15 #include "base/logging.h" 16 #include "base/logging.h"
16 #include "crypto/openssl_util.h" 17 #include "crypto/openssl_util.h"
17 #include "crypto/scoped_openssl_types.h"
18 #include "net/cert/internal/cert_errors.h" 18 #include "net/cert/internal/cert_errors.h"
19 #include "net/cert/internal/signature_algorithm.h" 19 #include "net/cert/internal/signature_algorithm.h"
20 #include "net/cert/internal/signature_policy.h" 20 #include "net/cert/internal/signature_policy.h"
21 #include "net/der/input.h" 21 #include "net/der/input.h"
22 #include "net/der/parse_values.h" 22 #include "net/der/parse_values.h"
23 #include "net/der/parser.h" 23 #include "net/der/parser.h"
24 24
25 namespace net { 25 namespace net {
26 26
27 namespace { 27 namespace {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1_hash) && 74 EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1_hash) &&
75 EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, 75 EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx,
76 salt_length_bytes_int.ValueOrDie()); 76 salt_length_bytes_int.ValueOrDie());
77 } 77 }
78 78
79 // TODO(eroman): This function is not strict enough. It accepts BER, other RSA 79 // TODO(eroman): This function is not strict enough. It accepts BER, other RSA
80 // OIDs, and does not check id-rsaEncryption parameters. 80 // OIDs, and does not check id-rsaEncryption parameters.
81 // See https://crbug.com/522228 and https://crbug.com/522232 81 // See https://crbug.com/522228 and https://crbug.com/522232
82 WARN_UNUSED_RESULT bool ImportPkeyFromSpki(const der::Input& spki, 82 WARN_UNUSED_RESULT bool ImportPkeyFromSpki(const der::Input& spki,
83 int expected_pkey_id, 83 int expected_pkey_id,
84 crypto::ScopedEVP_PKEY* pkey) { 84 bssl::UniquePtr<EVP_PKEY>* pkey) {
85 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 85 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
86 86
87 CBS cbs; 87 CBS cbs;
88 CBS_init(&cbs, spki.UnsafeData(), spki.Length()); 88 CBS_init(&cbs, spki.UnsafeData(), spki.Length());
89 pkey->reset(EVP_parse_public_key(&cbs)); 89 pkey->reset(EVP_parse_public_key(&cbs));
90 if (!*pkey || CBS_len(&cbs) != 0 || 90 if (!*pkey || CBS_len(&cbs) != 0 ||
91 EVP_PKEY_id(pkey->get()) != expected_pkey_id) { 91 EVP_PKEY_id(pkey->get()) != expected_pkey_id) {
92 pkey->reset(); 92 pkey->reset();
93 return false; 93 return false;
94 } 94 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 // COMPATIBILITY NOTE: RFC 5912 and RFC 3279 are in disagreement on the value 146 // COMPATIBILITY NOTE: RFC 5912 and RFC 3279 are in disagreement on the value
147 // of parameters for rsaEncryption. Whereas RFC 5912 says they must be absent, 147 // of parameters for rsaEncryption. Whereas RFC 5912 says they must be absent,
148 // RFC 3279 says they must be NULL: 148 // RFC 3279 says they must be NULL:
149 // 149 //
150 // The rsaEncryption OID is intended to be used in the algorithm field 150 // The rsaEncryption OID is intended to be used in the algorithm field
151 // of a value of type AlgorithmIdentifier. The parameters field MUST 151 // of a value of type AlgorithmIdentifier. The parameters field MUST
152 // have ASN.1 type NULL for this algorithm identifier. 152 // have ASN.1 type NULL for this algorithm identifier.
153 // 153 //
154 // Following RFC 3279 in this case. 154 // Following RFC 3279 in this case.
155 WARN_UNUSED_RESULT bool ParseRsaKeyFromSpki(const der::Input& public_key_spki, 155 WARN_UNUSED_RESULT bool ParseRsaKeyFromSpki(const der::Input& public_key_spki,
156 crypto::ScopedEVP_PKEY* pkey, 156 bssl::UniquePtr<EVP_PKEY>* pkey,
157 const SignaturePolicy* policy, 157 const SignaturePolicy* policy,
158 CertErrors* errors) { 158 CertErrors* errors) {
159 // TODO(crbug.com/634443): Add more specific errors. 159 // TODO(crbug.com/634443): Add more specific errors.
160 if (!ImportPkeyFromSpki(public_key_spki, EVP_PKEY_RSA, pkey)) 160 if (!ImportPkeyFromSpki(public_key_spki, EVP_PKEY_RSA, pkey))
161 return false; 161 return false;
162 162
163 // Extract the modulus length from the key. 163 // Extract the modulus length from the key.
164 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey->get())); 164 RSA* rsa = EVP_PKEY_get0_RSA(pkey->get());
eroman 2016/10/10 22:45:55 Thanks for removing the spurious refcounts in this
165 if (!rsa) 165 if (!rsa)
166 return false; 166 return false;
167 unsigned int modulus_length_bits = BN_num_bits(rsa->n); 167 unsigned int modulus_length_bits = BN_num_bits(rsa->n);
168 168
169 if (!policy->IsAcceptableModulusLengthForRsa(modulus_length_bits, errors)) { 169 if (!policy->IsAcceptableModulusLengthForRsa(modulus_length_bits, errors)) {
170 errors->AddError(kUnacceptableRsaModulusLength); 170 errors->AddError(kUnacceptableRsaModulusLength);
171 return false; 171 return false;
172 } 172 }
173 173
174 return true; 174 return true;
175 } 175 }
176 176
177 // Does signature verification using either RSA or ECDSA. 177 // Does signature verification using either RSA or ECDSA.
178 WARN_UNUSED_RESULT bool DoVerify(const SignatureAlgorithm& algorithm, 178 WARN_UNUSED_RESULT bool DoVerify(const SignatureAlgorithm& algorithm,
179 const der::Input& signed_data, 179 const der::Input& signed_data,
180 const der::BitString& signature_value, 180 const der::BitString& signature_value,
181 EVP_PKEY* public_key) { 181 EVP_PKEY* public_key) {
182 DCHECK(algorithm.algorithm() == SignatureAlgorithmId::RsaPkcs1 || 182 DCHECK(algorithm.algorithm() == SignatureAlgorithmId::RsaPkcs1 ||
183 algorithm.algorithm() == SignatureAlgorithmId::RsaPss || 183 algorithm.algorithm() == SignatureAlgorithmId::RsaPss ||
184 algorithm.algorithm() == SignatureAlgorithmId::Ecdsa); 184 algorithm.algorithm() == SignatureAlgorithmId::Ecdsa);
185 185
186 // For the supported algorithms the signature value must be a whole 186 // For the supported algorithms the signature value must be a whole
187 // number of bytes. 187 // number of bytes.
188 if (signature_value.unused_bits() != 0) 188 if (signature_value.unused_bits() != 0)
189 return false; 189 return false;
190 const der::Input& signature_value_bytes = signature_value.bytes(); 190 const der::Input& signature_value_bytes = signature_value.bytes();
191 191
192 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); 192 crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE);
193 193
194 crypto::ScopedEVP_MD_CTX ctx(EVP_MD_CTX_create()); 194 bssl::ScopedEVP_MD_CTX ctx;
195 EVP_PKEY_CTX* pctx = nullptr; // Owned by |ctx|. 195 EVP_PKEY_CTX* pctx = nullptr; // Owned by |ctx|.
196 196
197 const EVP_MD* digest; 197 const EVP_MD* digest;
198 if (!GetDigest(algorithm.digest(), &digest)) 198 if (!GetDigest(algorithm.digest(), &digest))
199 return false; 199 return false;
200 200
201 if (!EVP_DigestVerifyInit(ctx.get(), &pctx, digest, nullptr, public_key)) 201 if (!EVP_DigestVerifyInit(ctx.get(), &pctx, digest, nullptr, public_key))
202 return false; 202 return false;
203 203
204 // Set the RSASSA-PSS specific options. 204 // Set the RSASSA-PSS specific options.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 // 255 //
256 // NamedCurve CURVE ::= { 256 // NamedCurve CURVE ::= {
257 // { ID secp192r1 } | { ID sect163k1 } | { ID sect163r2 } | 257 // { ID secp192r1 } | { ID sect163k1 } | { ID sect163r2 } |
258 // { ID secp224r1 } | { ID sect233k1 } | { ID sect233r1 } | 258 // { ID secp224r1 } | { ID sect233k1 } | { ID sect233r1 } |
259 // { ID secp256r1 } | { ID sect283k1 } | { ID sect283r1 } | 259 // { ID secp256r1 } | { ID sect283k1 } | { ID sect283r1 } |
260 // { ID secp384r1 } | { ID sect409k1 } | { ID sect409r1 } | 260 // { ID secp384r1 } | { ID sect409k1 } | { ID sect409r1 } |
261 // { ID secp521r1 } | { ID sect571k1 } | { ID sect571r1 }, 261 // { ID secp521r1 } | { ID sect571k1 } | { ID sect571r1 },
262 // ... -- Extensible 262 // ... -- Extensible
263 // } 263 // }
264 WARN_UNUSED_RESULT bool ParseEcKeyFromSpki(const der::Input& public_key_spki, 264 WARN_UNUSED_RESULT bool ParseEcKeyFromSpki(const der::Input& public_key_spki,
265 crypto::ScopedEVP_PKEY* pkey, 265 bssl::UniquePtr<EVP_PKEY>* pkey,
266 const SignaturePolicy* policy, 266 const SignaturePolicy* policy,
267 CertErrors* errors) { 267 CertErrors* errors) {
268 // TODO(crbug.com/634443): Add more specific errors. 268 // TODO(crbug.com/634443): Add more specific errors.
269 if (!ImportPkeyFromSpki(public_key_spki, EVP_PKEY_EC, pkey)) 269 if (!ImportPkeyFromSpki(public_key_spki, EVP_PKEY_EC, pkey))
270 return false; 270 return false;
271 271
272 // Extract the curve name. 272 // Extract the curve name.
273 crypto::ScopedEC_KEY ec(EVP_PKEY_get1_EC_KEY(pkey->get())); 273 EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey->get());
274 if (!ec.get()) 274 if (!ec)
275 return false; // Unexpected. 275 return false; // Unexpected.
276 int curve_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec.get())); 276 int curve_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec));
277 277
278 if (!policy->IsAcceptableCurveForEcdsa(curve_nid, errors)) { 278 if (!policy->IsAcceptableCurveForEcdsa(curve_nid, errors)) {
279 errors->AddError(kUnacceptableEcdsaCurve); 279 errors->AddError(kUnacceptableEcdsaCurve);
280 return false; 280 return false;
281 } 281 }
282 282
283 return true; 283 return true;
284 } 284 }
285 285
286 } // namespace 286 } // namespace
287 287
288 bool VerifySignedData(const SignatureAlgorithm& signature_algorithm, 288 bool VerifySignedData(const SignatureAlgorithm& signature_algorithm,
289 const der::Input& signed_data, 289 const der::Input& signed_data,
290 const der::BitString& signature_value, 290 const der::BitString& signature_value,
291 const der::Input& public_key_spki, 291 const der::Input& public_key_spki,
292 const SignaturePolicy* policy, 292 const SignaturePolicy* policy,
293 CertErrors* errors) { 293 CertErrors* errors) {
294 if (!policy->IsAcceptableSignatureAlgorithm(signature_algorithm, errors)) { 294 if (!policy->IsAcceptableSignatureAlgorithm(signature_algorithm, errors)) {
295 errors->AddError(kUnacceptableSignatureAlgorithm); 295 errors->AddError(kUnacceptableSignatureAlgorithm);
296 return false; 296 return false;
297 } 297 }
298 298
299 crypto::ScopedEVP_PKEY public_key; 299 bssl::UniquePtr<EVP_PKEY> public_key;
300 300
301 // Parse the SPKI to an EVP_PKEY appropriate for the signature algorithm. 301 // Parse the SPKI to an EVP_PKEY appropriate for the signature algorithm.
302 switch (signature_algorithm.algorithm()) { 302 switch (signature_algorithm.algorithm()) {
303 case SignatureAlgorithmId::RsaPkcs1: 303 case SignatureAlgorithmId::RsaPkcs1:
304 case SignatureAlgorithmId::RsaPss: 304 case SignatureAlgorithmId::RsaPss:
305 if (!ParseRsaKeyFromSpki(public_key_spki, &public_key, policy, errors)) 305 if (!ParseRsaKeyFromSpki(public_key_spki, &public_key, policy, errors))
306 return false; 306 return false;
307 break; 307 break;
308 case SignatureAlgorithmId::Ecdsa: 308 case SignatureAlgorithmId::Ecdsa:
309 if (!ParseEcKeyFromSpki(public_key_spki, &public_key, policy, errors)) 309 if (!ParseEcKeyFromSpki(public_key_spki, &public_key, policy, errors))
310 return false; 310 return false;
311 break; 311 break;
312 } 312 }
313 313
314 if (!DoVerify(signature_algorithm, signed_data, signature_value, 314 if (!DoVerify(signature_algorithm, signed_data, signature_value,
315 public_key.get())) { 315 public_key.get())) {
316 errors->AddError(kSignatureVerificationFailed); 316 errors->AddError(kSignatureVerificationFailed);
317 return false; 317 return false;
318 } 318 }
319 319
320 return true; 320 return true;
321 } 321 }
322 322
323 } // namespace net 323 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698