| 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/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 Loading... |
| 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 Loading... |
| 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()); |
| 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 Loading... |
| 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 |
| OLD | NEW |