| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "net/cert/internal/simple_path_builder_delegate.h" |
| |
| #include "base/logging.h" |
| #include "net/cert/internal/cert_error_params.h" |
| #include "net/cert/internal/cert_errors.h" |
| #include "net/cert/internal/signature_algorithm.h" |
| #include "net/cert/internal/verify_signed_data.h" |
| #include "third_party/boringssl/src/include/openssl/bn.h" |
| #include "third_party/boringssl/src/include/openssl/bytestring.h" |
| #include "third_party/boringssl/src/include/openssl/digest.h" |
| #include "third_party/boringssl/src/include/openssl/ec.h" |
| #include "third_party/boringssl/src/include/openssl/ec_key.h" |
| #include "third_party/boringssl/src/include/openssl/evp.h" |
| #include "third_party/boringssl/src/include/openssl/nid.h" |
| #include "third_party/boringssl/src/include/openssl/rsa.h" |
| |
| namespace net { |
| |
| DEFINE_CERT_ERROR_ID(SimplePathBuilderDelegate::kRsaModulusTooSmall, |
| "RSA modulus too small"); |
| |
| namespace { |
| |
| DEFINE_CERT_ERROR_ID(kUnacceptableCurveForEcdsa, |
| "Only P-256, P-384, P-521 are supported for ECDSA"); |
| |
| bool IsAcceptableCurveForEcdsa(int curve_nid) { |
| // Whitelist default permitted named curves. |
| switch (curve_nid) { |
| case NID_X9_62_prime256v1: |
| case NID_secp384r1: |
| case NID_secp521r1: |
| return true; |
| } |
| |
| return false; |
| } |
| |
| } // namespace |
| |
| SimplePathBuilderDelegate::SimplePathBuilderDelegate( |
| size_t min_rsa_modulus_length_bits, |
| DigestPolicy digest_policy) |
| : min_rsa_modulus_length_bits_(min_rsa_modulus_length_bits), |
| digest_policy_(digest_policy) {} |
| |
| void SimplePathBuilderDelegate::CheckPathAfterVerification( |
| CertPathBuilderResultPath* path) { |
| // Do nothing - consider all candidate paths valid. |
| } |
| |
| bool SimplePathBuilderDelegate::IsSignatureAlgorithmAcceptable( |
| const SignatureAlgorithm& algorithm, |
| CertErrors* errors) { |
| // Whitelist default permitted signature algorithms to: |
| // |
| // RSA PKCS#1 v1.5 |
| // RSASSA-PSS |
| // ECDSA |
| switch (algorithm.algorithm()) { |
| case SignatureAlgorithmId::Dsa: |
| return false; |
| case SignatureAlgorithmId::Ecdsa: |
| case SignatureAlgorithmId::RsaPkcs1: |
| return IsAcceptableDigest(algorithm.digest()); |
| case SignatureAlgorithmId::RsaPss: |
| return IsAcceptableDigest(algorithm.digest()) && |
| IsAcceptableDigest(algorithm.ParamsForRsaPss()->mgf1_hash()); |
| } |
| |
| return false; |
| } |
| |
| bool SimplePathBuilderDelegate::IsPublicKeyAcceptable(EVP_PKEY* public_key, |
| CertErrors* errors) { |
| int pkey_id = EVP_PKEY_id(public_key); |
| if (pkey_id == EVP_PKEY_RSA) { |
| // Extract the modulus length from the key. |
| RSA* rsa = EVP_PKEY_get0_RSA(public_key); |
| if (!rsa) |
| return false; |
| unsigned int modulus_length_bits = BN_num_bits(rsa->n); |
| |
| if (modulus_length_bits < min_rsa_modulus_length_bits_) { |
| errors->AddError( |
| kRsaModulusTooSmall, |
| CreateCertErrorParams2SizeT("actual", modulus_length_bits, "minimum", |
| min_rsa_modulus_length_bits_)); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| if (pkey_id == EVP_PKEY_EC) { |
| // Extract the curve name. |
| EC_KEY* ec = EVP_PKEY_get0_EC_KEY(public_key); |
| if (!ec) |
| return false; // Unexpected. |
| int curve_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); |
| |
| if (!IsAcceptableCurveForEcdsa(curve_nid)) { |
| errors->AddError(kUnacceptableCurveForEcdsa); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| // Unexpected key type. |
| return false; |
| } |
| |
| // Restricted signature digest algorithms to: |
| // |
| // SHA1 (if digest_policy_ == kWeakAllowSha1) |
| // SHA256 |
| // SHA384 |
| // SHA512 |
| bool SimplePathBuilderDelegate::IsAcceptableDigest( |
| DigestAlgorithm digest) const { |
| switch (digest) { |
| case DigestAlgorithm::Md2: |
| case DigestAlgorithm::Md4: |
| case DigestAlgorithm::Md5: |
| return false; |
| |
| case DigestAlgorithm::Sha1: |
| return digest_policy_ == |
| SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1; |
| case DigestAlgorithm::Sha256: |
| case DigestAlgorithm::Sha384: |
| case DigestAlgorithm::Sha512: |
| return true; |
| } |
| |
| return false; |
| } |
| |
| } // namespace net |