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

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

Issue 2289363004: Add error information to VerifySignedData(). (Closed)
Patch Set: checkpoint Created 4 years, 3 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/bytestring.h> 7 #include <openssl/bytestring.h>
8 #include <openssl/digest.h> 8 #include <openssl/digest.h>
9 #include <openssl/ec.h> 9 #include <openssl/ec.h>
10 #include <openssl/ec_key.h> 10 #include <openssl/ec_key.h>
11 #include <openssl/evp.h> 11 #include <openssl/evp.h>
12 #include <openssl/rsa.h> 12 #include <openssl/rsa.h>
13 13
14 #include "base/compiler_specific.h" 14 #include "base/compiler_specific.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "crypto/openssl_util.h" 16 #include "crypto/openssl_util.h"
17 #include "crypto/scoped_openssl_types.h" 17 #include "crypto/scoped_openssl_types.h"
18 #include "net/cert/internal/cert_errors.h"
18 #include "net/cert/internal/signature_algorithm.h" 19 #include "net/cert/internal/signature_algorithm.h"
19 #include "net/cert/internal/signature_policy.h" 20 #include "net/cert/internal/signature_policy.h"
20 #include "net/der/input.h" 21 #include "net/der/input.h"
21 #include "net/der/parse_values.h" 22 #include "net/der/parse_values.h"
22 #include "net/der/parser.h" 23 #include "net/der/parser.h"
23 24
24 namespace net { 25 namespace net {
25 26
26 namespace { 27 namespace {
27 28
29 DEFINE_CERT_ERROR_TYPE(kUnacceptableSignatureAlgorithm,
30 "Unacceptable signature algorithm");
31 DEFINE_CERT_ERROR_TYPE(kUnacceptableRsaModulusLength,
32 "Unacceptable modulus length for RSA key");
33 DEFINE_CERT_ERROR_TYPE(kUnacceptableEcdsaCurve,
34 "Unacceptable curve for ECDSA key");
35 DEFINE_CERT_ERROR_TYPE(kSignatureVerificationFailed,
36 "Signature verification failed");
37
28 // Converts a DigestAlgorithm to an equivalent EVP_MD*. 38 // Converts a DigestAlgorithm to an equivalent EVP_MD*.
29 WARN_UNUSED_RESULT bool GetDigest(DigestAlgorithm digest, const EVP_MD** out) { 39 WARN_UNUSED_RESULT bool GetDigest(DigestAlgorithm digest, const EVP_MD** out) {
30 *out = nullptr; 40 *out = nullptr;
31 41
32 switch (digest) { 42 switch (digest) {
33 case DigestAlgorithm::Sha1: 43 case DigestAlgorithm::Sha1:
34 *out = EVP_sha1(); 44 *out = EVP_sha1();
35 break; 45 break;
36 case DigestAlgorithm::Sha256: 46 case DigestAlgorithm::Sha256:
37 *out = EVP_sha256(); 47 *out = EVP_sha256();
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 // 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,
138 // RFC 3279 says they must be NULL: 148 // RFC 3279 says they must be NULL:
139 // 149 //
140 // 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
141 // of a value of type AlgorithmIdentifier. The parameters field MUST 151 // of a value of type AlgorithmIdentifier. The parameters field MUST
142 // have ASN.1 type NULL for this algorithm identifier. 152 // have ASN.1 type NULL for this algorithm identifier.
143 // 153 //
144 // Following RFC 3279 in this case. 154 // Following RFC 3279 in this case.
145 WARN_UNUSED_RESULT bool ParseRsaKeyFromSpki(const der::Input& public_key_spki, 155 WARN_UNUSED_RESULT bool ParseRsaKeyFromSpki(const der::Input& public_key_spki,
146 crypto::ScopedEVP_PKEY* pkey, 156 crypto::ScopedEVP_PKEY* pkey,
147 const SignaturePolicy* policy) { 157 const SignaturePolicy* policy,
158 CertErrors* errors) {
159 // TODO(crbug.com/634443): Add more specific errors.
148 if (!ImportPkeyFromSpki(public_key_spki, EVP_PKEY_RSA, pkey)) 160 if (!ImportPkeyFromSpki(public_key_spki, EVP_PKEY_RSA, pkey))
149 return false; 161 return false;
150 162
151 // Extract the modulus length from the key. 163 // Extract the modulus length from the key.
152 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey->get())); 164 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey->get()));
153 if (!rsa) 165 if (!rsa)
154 return false; 166 return false;
155 unsigned int modulus_length_bits = BN_num_bits(rsa->n); 167 unsigned int modulus_length_bits = BN_num_bits(rsa->n);
156 168
157 return policy->IsAcceptableModulusLengthForRsa(modulus_length_bits); 169 if (!policy->IsAcceptableModulusLengthForRsa(modulus_length_bits, errors)) {
170 errors->Add(kUnacceptableRsaModulusLength);
171 return false;
172 }
173
174 return true;
158 } 175 }
159 176
160 // Does signature verification using either RSA or ECDSA. 177 // Does signature verification using either RSA or ECDSA.
161 WARN_UNUSED_RESULT bool DoVerify(const SignatureAlgorithm& algorithm, 178 WARN_UNUSED_RESULT bool DoVerify(const SignatureAlgorithm& algorithm,
162 const der::Input& signed_data, 179 const der::Input& signed_data,
163 const der::BitString& signature_value, 180 const der::BitString& signature_value,
164 EVP_PKEY* public_key) { 181 EVP_PKEY* public_key) {
165 DCHECK(algorithm.algorithm() == SignatureAlgorithmId::RsaPkcs1 || 182 DCHECK(algorithm.algorithm() == SignatureAlgorithmId::RsaPkcs1 ||
166 algorithm.algorithm() == SignatureAlgorithmId::RsaPss || 183 algorithm.algorithm() == SignatureAlgorithmId::RsaPss ||
167 algorithm.algorithm() == SignatureAlgorithmId::Ecdsa); 184 algorithm.algorithm() == SignatureAlgorithmId::Ecdsa);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 // NamedCurve CURVE ::= { 256 // NamedCurve CURVE ::= {
240 // { ID secp192r1 } | { ID sect163k1 } | { ID sect163r2 } | 257 // { ID secp192r1 } | { ID sect163k1 } | { ID sect163r2 } |
241 // { ID secp224r1 } | { ID sect233k1 } | { ID sect233r1 } | 258 // { ID secp224r1 } | { ID sect233k1 } | { ID sect233r1 } |
242 // { ID secp256r1 } | { ID sect283k1 } | { ID sect283r1 } | 259 // { ID secp256r1 } | { ID sect283k1 } | { ID sect283r1 } |
243 // { ID secp384r1 } | { ID sect409k1 } | { ID sect409r1 } | 260 // { ID secp384r1 } | { ID sect409k1 } | { ID sect409r1 } |
244 // { ID secp521r1 } | { ID sect571k1 } | { ID sect571r1 }, 261 // { ID secp521r1 } | { ID sect571k1 } | { ID sect571r1 },
245 // ... -- Extensible 262 // ... -- Extensible
246 // } 263 // }
247 WARN_UNUSED_RESULT bool ParseEcKeyFromSpki(const der::Input& public_key_spki, 264 WARN_UNUSED_RESULT bool ParseEcKeyFromSpki(const der::Input& public_key_spki,
248 crypto::ScopedEVP_PKEY* pkey, 265 crypto::ScopedEVP_PKEY* pkey,
249 const SignaturePolicy* policy) { 266 const SignaturePolicy* policy,
267 CertErrors* errors) {
268 // TODO(crbug.com/634443): Add more specific errors.
250 if (!ImportPkeyFromSpki(public_key_spki, EVP_PKEY_EC, pkey)) 269 if (!ImportPkeyFromSpki(public_key_spki, EVP_PKEY_EC, pkey))
251 return false; 270 return false;
252 271
253 // Extract the curve name. 272 // Extract the curve name.
254 crypto::ScopedEC_KEY ec(EVP_PKEY_get1_EC_KEY(pkey->get())); 273 crypto::ScopedEC_KEY ec(EVP_PKEY_get1_EC_KEY(pkey->get()));
255 if (!ec.get()) 274 if (!ec.get())
256 return false; // Unexpected. 275 return false; // Unexpected.
257 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.get()));
258 277
259 return policy->IsAcceptableCurveForEcdsa(curve_nid); 278 if (!policy->IsAcceptableCurveForEcdsa(curve_nid, errors)) {
279 errors->Add(kUnacceptableEcdsaCurve);
280 return false;
281 }
282
283 return true;
260 } 284 }
261 285
262 } // namespace 286 } // namespace
263 287
264 bool VerifySignedData(const SignatureAlgorithm& signature_algorithm, 288 bool VerifySignedData(const SignatureAlgorithm& signature_algorithm,
265 const der::Input& signed_data, 289 const der::Input& signed_data,
266 const der::BitString& signature_value, 290 const der::BitString& signature_value,
267 const der::Input& public_key_spki, 291 const der::Input& public_key_spki,
268 const SignaturePolicy* policy) { 292 const SignaturePolicy* policy,
269 if (!policy->IsAcceptableSignatureAlgorithm(signature_algorithm)) 293 CertErrors* errors) {
294 if (!policy->IsAcceptableSignatureAlgorithm(signature_algorithm, errors)) {
295 errors->Add(kUnacceptableSignatureAlgorithm);
270 return false; 296 return false;
297 }
271 298
272 crypto::ScopedEVP_PKEY public_key; 299 crypto::ScopedEVP_PKEY public_key;
273 300
274 // 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.
275 switch (signature_algorithm.algorithm()) { 302 switch (signature_algorithm.algorithm()) {
276 case SignatureAlgorithmId::RsaPkcs1: 303 case SignatureAlgorithmId::RsaPkcs1:
277 case SignatureAlgorithmId::RsaPss: 304 case SignatureAlgorithmId::RsaPss:
278 if (!ParseRsaKeyFromSpki(public_key_spki, &public_key, policy)) 305 if (!ParseRsaKeyFromSpki(public_key_spki, &public_key, policy, errors))
279 return false; 306 return false;
280 break; 307 break;
281 case SignatureAlgorithmId::Ecdsa: 308 case SignatureAlgorithmId::Ecdsa:
282 if (!ParseEcKeyFromSpki(public_key_spki, &public_key, policy)) 309 if (!ParseEcKeyFromSpki(public_key_spki, &public_key, policy, errors))
283 return false; 310 return false;
284 break; 311 break;
285 } 312 }
286 313
287 return DoVerify(signature_algorithm, signed_data, signature_value, 314 if (!DoVerify(signature_algorithm, signed_data, signature_value,
288 public_key.get()); 315 public_key.get())) {
316 errors->Add(kSignatureVerificationFailed);
317 return false;
318 }
319
320 return true;
289 } 321 }
290 322
291 } // namespace net 323 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698