• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "verify_signed_data.h"
6 
7 #include "fillins/openssl_util.h"
8 #include "cert_errors.h"
9 #include "signature_algorithm.h"
10 #include "signature_verify_cache.h"
11 #include "input.h"
12 #include "parse_values.h"
13 #include "parser.h"
14 #include <openssl/bytestring.h>
15 #include <openssl/digest.h>
16 #include <openssl/evp.h>
17 #include <openssl/rsa.h>
18 #include <openssl/sha.h>
19 
20 namespace bssl {
21 
22 namespace {
23 
SHA256UpdateWithLengthPrefixedData(SHA256_CTX * s_ctx,const uint8_t * data,uint64_t length)24 bool SHA256UpdateWithLengthPrefixedData(SHA256_CTX* s_ctx,
25                                         const uint8_t* data,
26                                         uint64_t length) {
27   return (SHA256_Update(s_ctx, reinterpret_cast<uint8_t*>(&length),
28                         sizeof(length)) &&
29           SHA256_Update(s_ctx, data, length));
30 }
31 
32 // Increase to make incompatible changes in the computation of the
33 // cache key.
34 constexpr uint32_t VerifyCacheKeyVersion = 1;
35 
SignatureVerifyCacheKey(std::string_view algorithm_name,const der::Input & signed_data,const der::Input & signature_value_bytes,EVP_PKEY * public_key)36 std::string SignatureVerifyCacheKey(std::string_view algorithm_name,
37                                     const der::Input& signed_data,
38                                     const der::Input& signature_value_bytes,
39                                     EVP_PKEY* public_key) {
40   SHA256_CTX s_ctx;
41   bssl::ScopedCBB public_key_cbb;
42   uint8_t digest[SHA256_DIGEST_LENGTH];
43   uint32_t version = VerifyCacheKeyVersion;
44   if (CBB_init(public_key_cbb.get(), 128) &&
45       EVP_marshal_public_key(public_key_cbb.get(), public_key) &&
46       SHA256_Init(&s_ctx) &&
47       SHA256_Update(&s_ctx, reinterpret_cast<uint8_t*>(&version),
48                     sizeof(version)) &&
49       SHA256UpdateWithLengthPrefixedData(
50           &s_ctx, reinterpret_cast<const uint8_t*>(algorithm_name.data()),
51           algorithm_name.length()) &&
52       SHA256UpdateWithLengthPrefixedData(&s_ctx, CBB_data(public_key_cbb.get()),
53                                          CBB_len(public_key_cbb.get())) &&
54       SHA256UpdateWithLengthPrefixedData(&s_ctx,
55                                          signature_value_bytes.UnsafeData(),
56                                          signature_value_bytes.Length()) &&
57       SHA256UpdateWithLengthPrefixedData(&s_ctx, signed_data.UnsafeData(),
58                                          signed_data.Length()) &&
59       SHA256_Final(digest, &s_ctx)) {
60     return std::string(reinterpret_cast<char*>(digest), sizeof(digest));
61   }
62   return std::string();
63 }
64 
65 }  // namespace
66 
67 // Parses an RSA public key or EC public key from SPKI to an EVP_PKEY. Returns
68 // true on success.
69 //
70 // This function only recognizes the "pk-rsa" (rsaEncryption) flavor of RSA
71 // public key from RFC 5912.
72 //
73 //     pk-rsa PUBLIC-KEY ::= {
74 //      IDENTIFIER rsaEncryption
75 //      KEY RSAPublicKey
76 //      PARAMS TYPE NULL ARE absent
77 //      -- Private key format not in this module --
78 //      CERT-KEY-USAGE {digitalSignature, nonRepudiation,
79 //      keyEncipherment, dataEncipherment, keyCertSign, cRLSign}
80 //     }
81 //
82 // COMPATIBILITY NOTE: RFC 5912 and RFC 3279 are in disagreement on the value
83 // of parameters for rsaEncryption. Whereas RFC 5912 says they must be absent,
84 // RFC 3279 says they must be NULL:
85 //
86 //     The rsaEncryption OID is intended to be used in the algorithm field
87 //     of a value of type AlgorithmIdentifier.  The parameters field MUST
88 //     have ASN.1 type NULL for this algorithm identifier.
89 //
90 // Following RFC 3279 in this case.
91 //
92 // In the case of parsing EC keys, RFC 5912 describes all the ECDSA
93 // signature algorithms as requiring a public key of type "pk-ec":
94 //
95 //     pk-ec PUBLIC-KEY ::= {
96 //      IDENTIFIER id-ecPublicKey
97 //      KEY ECPoint
98 //      PARAMS TYPE ECParameters ARE required
99 //      -- Private key format not in this module --
100 //      CERT-KEY-USAGE { digitalSignature, nonRepudiation, keyAgreement,
101 //                           keyCertSign, cRLSign }
102 //     }
103 //
104 // Moreover RFC 5912 stipulates what curves are allowed. The ECParameters
105 // MUST NOT use an implicitCurve or specificCurve for PKIX:
106 //
107 //     ECParameters ::= CHOICE {
108 //      namedCurve      CURVE.&id({NamedCurve})
109 //      -- implicitCurve   NULL
110 //        -- implicitCurve MUST NOT be used in PKIX
111 //      -- specifiedCurve  SpecifiedCurve
112 //        -- specifiedCurve MUST NOT be used in PKIX
113 //        -- Details for specifiedCurve can be found in [X9.62]
114 //        -- Any future additions to this CHOICE should be coordinated
115 //        -- with ANSI X.9.
116 //     }
117 //     -- If you need to be able to decode ANSI X.9 parameter structures,
118 //     -- uncomment the implicitCurve and specifiedCurve above, and also
119 //     -- uncomment the following:
120 //     --(WITH COMPONENTS {namedCurve PRESENT})
121 //
122 // The namedCurves are extensible. The ones described by RFC 5912 are:
123 //
124 //     NamedCurve CURVE ::= {
125 //     { ID secp192r1 } | { ID sect163k1 } | { ID sect163r2 } |
126 //     { ID secp224r1 } | { ID sect233k1 } | { ID sect233r1 } |
127 //     { ID secp256r1 } | { ID sect283k1 } | { ID sect283r1 } |
128 //     { ID secp384r1 } | { ID sect409k1 } | { ID sect409r1 } |
129 //     { ID secp521r1 } | { ID sect571k1 } | { ID sect571r1 },
130 //     ... -- Extensible
131 //     }
ParsePublicKey(const der::Input & public_key_spki,bssl::UniquePtr<EVP_PKEY> * public_key)132 bool ParsePublicKey(const der::Input& public_key_spki,
133                     bssl::UniquePtr<EVP_PKEY>* public_key) {
134   // Parse the SPKI to an EVP_PKEY.
135   fillins::OpenSSLErrStackTracer err_tracer;
136 
137   CBS cbs;
138   CBS_init(&cbs, public_key_spki.UnsafeData(), public_key_spki.Length());
139   public_key->reset(EVP_parse_public_key(&cbs));
140   if (!*public_key || CBS_len(&cbs) != 0) {
141     public_key->reset();
142     return false;
143   }
144   return true;
145 }
146 
VerifySignedData(SignatureAlgorithm algorithm,const der::Input & signed_data,const der::BitString & signature_value,EVP_PKEY * public_key,SignatureVerifyCache * cache)147 bool VerifySignedData(SignatureAlgorithm algorithm,
148                       const der::Input& signed_data,
149                       const der::BitString& signature_value,
150                       EVP_PKEY* public_key,
151                       SignatureVerifyCache* cache) {
152   int expected_pkey_id = 1;
153   const EVP_MD* digest = nullptr;
154   bool is_rsa_pss = false;
155   std::string_view cache_algorithm_name;
156   switch (algorithm) {
157     case SignatureAlgorithm::kRsaPkcs1Sha1:
158       expected_pkey_id = EVP_PKEY_RSA;
159       digest = EVP_sha1();
160       cache_algorithm_name = "RsaPkcs1Sha1";
161       break;
162     case SignatureAlgorithm::kRsaPkcs1Sha256:
163       expected_pkey_id = EVP_PKEY_RSA;
164       digest = EVP_sha256();
165       cache_algorithm_name = "RsaPkcs1Sha256";
166       break;
167     case SignatureAlgorithm::kRsaPkcs1Sha384:
168       expected_pkey_id = EVP_PKEY_RSA;
169       digest = EVP_sha384();
170       cache_algorithm_name = "RsaPkcs1Sha384";
171       break;
172     case SignatureAlgorithm::kRsaPkcs1Sha512:
173       expected_pkey_id = EVP_PKEY_RSA;
174       digest = EVP_sha512();
175       cache_algorithm_name = "RsaPkcs1Sha512";
176       break;
177 
178     case SignatureAlgorithm::kEcdsaSha1:
179       expected_pkey_id = EVP_PKEY_EC;
180       digest = EVP_sha1();
181       cache_algorithm_name = "EcdsaSha1";
182       break;
183     case SignatureAlgorithm::kEcdsaSha256:
184       expected_pkey_id = EVP_PKEY_EC;
185       digest = EVP_sha256();
186       cache_algorithm_name = "EcdsaSha256";
187       break;
188     case SignatureAlgorithm::kEcdsaSha384:
189       expected_pkey_id = EVP_PKEY_EC;
190       digest = EVP_sha384();
191       cache_algorithm_name = "EcdsaSha384";
192       break;
193     case SignatureAlgorithm::kEcdsaSha512:
194       expected_pkey_id = EVP_PKEY_EC;
195       digest = EVP_sha512();
196       cache_algorithm_name = "EcdsaSha512";
197       break;
198 
199     case SignatureAlgorithm::kRsaPssSha256:
200       expected_pkey_id = EVP_PKEY_RSA;
201       digest = EVP_sha256();
202       cache_algorithm_name = "RsaPssSha256";
203       is_rsa_pss = true;
204       break;
205     case SignatureAlgorithm::kRsaPssSha384:
206       expected_pkey_id = EVP_PKEY_RSA;
207       digest = EVP_sha384();
208       cache_algorithm_name = "RsaPssSha384";
209       is_rsa_pss = true;
210       break;
211     case SignatureAlgorithm::kRsaPssSha512:
212       expected_pkey_id = EVP_PKEY_RSA;
213       digest = EVP_sha512();
214       cache_algorithm_name = "RsaPssSha512";
215       is_rsa_pss = true;
216       break;
217   }
218 
219   if (expected_pkey_id != EVP_PKEY_id(public_key))
220     return false;
221 
222   // For the supported algorithms the signature value must be a whole
223   // number of bytes.
224   if (signature_value.unused_bits() != 0)
225     return false;
226   const der::Input& signature_value_bytes = signature_value.bytes();
227 
228   std::string cache_key;
229   if (cache) {
230     cache_key = SignatureVerifyCacheKey(cache_algorithm_name, signed_data,
231                                         signature_value_bytes, public_key);
232     if (!cache_key.empty()) {
233       switch (cache->Check(cache_key)) {
234         case SignatureVerifyCache::Value::kValid:
235           return true;
236         case SignatureVerifyCache::Value::kInvalid:
237           return false;
238         case SignatureVerifyCache::Value::kUnknown:
239           break;
240       }
241     }
242   }
243 
244   fillins::OpenSSLErrStackTracer err_tracer;
245 
246   bssl::ScopedEVP_MD_CTX ctx;
247   EVP_PKEY_CTX* pctx = nullptr;  // Owned by |ctx|.
248 
249   if (!EVP_DigestVerifyInit(ctx.get(), &pctx, digest, nullptr, public_key))
250     return false;
251 
252   if (is_rsa_pss) {
253     // All supported RSASSA-PSS algorithms match signing and MGF-1 digest. They
254     // also use the digest length as the salt length, which is specified with -1
255     // in OpenSSL's API.
256     if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) ||
257         !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1)) {
258       return false;
259     }
260   }
261 
262   if (!EVP_DigestVerifyUpdate(ctx.get(), signed_data.UnsafeData(),
263                               signed_data.Length())) {
264     return false;
265   }
266 
267   bool ret =
268       1 == EVP_DigestVerifyFinal(ctx.get(), signature_value_bytes.UnsafeData(),
269                                  signature_value_bytes.Length());
270   if (!cache_key.empty()) {
271     cache->Store(cache_key, ret ? SignatureVerifyCache::Value::kValid
272                                 : SignatureVerifyCache::Value::kInvalid);
273   }
274 
275   return ret;
276 }
277 
VerifySignedData(SignatureAlgorithm algorithm,const der::Input & signed_data,const der::BitString & signature_value,const der::Input & public_key_spki,SignatureVerifyCache * cache)278 bool VerifySignedData(SignatureAlgorithm algorithm,
279                       const der::Input& signed_data,
280                       const der::BitString& signature_value,
281                       const der::Input& public_key_spki,
282                       SignatureVerifyCache* cache) {
283   bssl::UniquePtr<EVP_PKEY> public_key;
284   if (!ParsePublicKey(public_key_spki, &public_key))
285     return false;
286   return VerifySignedData(algorithm, signed_data, signature_value,
287                           public_key.get(), cache);
288 }
289 
290 }  // namespace net
291