OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |