summaryrefslogtreecommitdiff
path: root/chromium/net/cert/internal/signature_policy.cc
blob: b98cb7ae0524aa58f2213798312308198e10c34c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Copyright 2015 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/signature_policy.h"

#include "base/logging.h"
#include "net/cert/internal/cert_error_params.h"
#include "net/cert/internal/cert_errors.h"
#include "third_party/boringssl/src/include/openssl/obj.h"

namespace net {

namespace {

DEFINE_CERT_ERROR_ID(kUnacceptableCurveForEcdsa,
                     "Only P-256, P-384, P-521 are supported for ECDSA");
DEFINE_CERT_ERROR_ID(kRsaModulusTooSmall, "RSA modulus too small");

bool IsModulusSizeGreaterOrEqual(size_t modulus_length_bits,
                                 size_t min_length_bits,
                                 CertErrors* errors) {
  if (modulus_length_bits < min_length_bits) {
    errors->AddError(kRsaModulusTooSmall,
                     CreateCertErrorParams2SizeT("actual", modulus_length_bits,
                                                 "minimum", min_length_bits));
    return false;
  }
  return true;
}

// Whitelist of default permitted signature digest algorithms.
WARN_UNUSED_RESULT bool IsAcceptableDigest(DigestAlgorithm digest) {
  switch (digest) {
    case DigestAlgorithm::Md2:
    case DigestAlgorithm::Md4:
    case DigestAlgorithm::Md5:
      return false;

    case DigestAlgorithm::Sha1:
    case DigestAlgorithm::Sha256:
    case DigestAlgorithm::Sha384:
    case DigestAlgorithm::Sha512:
      return true;
  }

  return false;
}

}  // namespace

bool SignaturePolicy::IsAcceptableSignatureAlgorithm(
    const SignatureAlgorithm& algorithm,
    CertErrors* errors) const {
  // Whitelist default permitted signature algorithms to:
  //
  //    RSA PKCS#1 v1.5
  //    RSASSA-PSS
  //    ECDSA
  //
  // When used with digest algorithms:
  //
  //    SHA1
  //    SHA256
  //    SHA384
  //    SHA512
  switch (algorithm.algorithm()) {
    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 SignaturePolicy::IsAcceptableCurveForEcdsa(int curve_nid,
                                                CertErrors* errors) const {
  // Whitelist default permitted named curves.
  switch (curve_nid) {
    case NID_X9_62_prime256v1:
    case NID_secp384r1:
    case NID_secp521r1:
      return true;
  }

  errors->AddError(kUnacceptableCurveForEcdsa);
  return false;
}

bool SignaturePolicy::IsAcceptableModulusLengthForRsa(
    size_t modulus_length_bits,
    CertErrors* errors) const {
  return IsModulusSizeGreaterOrEqual(modulus_length_bits, 2048, errors);
}

SimpleSignaturePolicy::SimpleSignaturePolicy(size_t min_rsa_modulus_length_bits)
    : min_rsa_modulus_length_bits_(min_rsa_modulus_length_bits) {}

bool SimpleSignaturePolicy::IsAcceptableModulusLengthForRsa(
    size_t modulus_length_bits,
    CertErrors* errors) const {
  return IsModulusSizeGreaterOrEqual(modulus_length_bits,
                                     min_rsa_modulus_length_bits_, errors);
}

}  // namespace net