• 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 "net/cert/pki/signature_algorithm.h"
6 
7 #include "net/der/input.h"
8 #include "net/der/parse_values.h"
9 #include "net/der/parser.h"
10 #include "third_party/boringssl/src/include/openssl/bytestring.h"
11 #include "third_party/boringssl/src/include/openssl/digest.h"
12 
13 namespace net {
14 
15 namespace {
16 
17 // From RFC 5912:
18 //
19 //     sha1WithRSAEncryption OBJECT IDENTIFIER ::= {
20 //      iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
21 //      pkcs-1(1) 5 }
22 //
23 // In dotted notation: 1.2.840.113549.1.1.5
24 const uint8_t kOidSha1WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
25                                              0x0d, 0x01, 0x01, 0x05};
26 
27 // sha1WithRSASignature is a deprecated equivalent of
28 // sha1WithRSAEncryption.
29 //
30 // It originates from the NIST Open Systems Environment (OSE)
31 // Implementor's Workshop (OIW).
32 //
33 // It is supported for compatibility with Microsoft's certificate APIs and
34 // tools, particularly makecert.exe, which default(ed/s) to this OID for SHA-1.
35 //
36 // See also: https://bugzilla.mozilla.org/show_bug.cgi?id=1042479
37 //
38 // In dotted notation: 1.3.14.3.2.29
39 const uint8_t kOidSha1WithRsaSignature[] = {0x2b, 0x0e, 0x03, 0x02, 0x1d};
40 
41 // From RFC 5912:
42 //
43 //     pkcs-1  OBJECT IDENTIFIER  ::=
44 //         { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
45 
46 // From RFC 5912:
47 //
48 //     sha256WithRSAEncryption  OBJECT IDENTIFIER  ::=  { pkcs-1 11 }
49 //
50 // In dotted notation: 1.2.840.113549.1.1.11
51 const uint8_t kOidSha256WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
52                                                0x0d, 0x01, 0x01, 0x0b};
53 
54 // From RFC 5912:
55 //
56 //     sha384WithRSAEncryption  OBJECT IDENTIFIER  ::=  { pkcs-1 12 }
57 //
58 // In dotted notation: 1.2.840.113549.1.1.11
59 const uint8_t kOidSha384WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
60                                                0x0d, 0x01, 0x01, 0x0c};
61 
62 // From RFC 5912:
63 //
64 //     sha512WithRSAEncryption  OBJECT IDENTIFIER  ::=  { pkcs-1 13 }
65 //
66 // In dotted notation: 1.2.840.113549.1.1.13
67 const uint8_t kOidSha512WithRsaEncryption[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
68                                                0x0d, 0x01, 0x01, 0x0d};
69 
70 // From RFC 5912:
71 //
72 //     ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
73 //      iso(1) member-body(2) us(840) ansi-X9-62(10045)
74 //      signatures(4) 1 }
75 //
76 // In dotted notation: 1.2.840.10045.4.1
77 const uint8_t kOidEcdsaWithSha1[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01};
78 
79 // From RFC 5912:
80 //
81 //     ecdsa-with-SHA256 OBJECT IDENTIFIER ::= {
82 //      iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
83 //      ecdsa-with-SHA2(3) 2 }
84 //
85 // In dotted notation: 1.2.840.10045.4.3.2
86 const uint8_t kOidEcdsaWithSha256[] = {0x2a, 0x86, 0x48, 0xce,
87                                        0x3d, 0x04, 0x03, 0x02};
88 
89 // From RFC 5912:
90 //
91 //     ecdsa-with-SHA384 OBJECT IDENTIFIER ::= {
92 //      iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
93 //      ecdsa-with-SHA2(3) 3 }
94 //
95 // In dotted notation: 1.2.840.10045.4.3.3
96 const uint8_t kOidEcdsaWithSha384[] = {0x2a, 0x86, 0x48, 0xce,
97                                        0x3d, 0x04, 0x03, 0x03};
98 
99 // From RFC 5912:
100 //
101 //     ecdsa-with-SHA512 OBJECT IDENTIFIER ::= {
102 //      iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
103 //      ecdsa-with-SHA2(3) 4 }
104 //
105 // In dotted notation: 1.2.840.10045.4.3.4
106 const uint8_t kOidEcdsaWithSha512[] = {0x2a, 0x86, 0x48, 0xce,
107                                        0x3d, 0x04, 0x03, 0x04};
108 
109 // From RFC 5912:
110 //
111 //     id-RSASSA-PSS  OBJECT IDENTIFIER  ::=  { pkcs-1 10 }
112 //
113 // In dotted notation: 1.2.840.113549.1.1.10
114 const uint8_t kOidRsaSsaPss[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
115                                  0x0d, 0x01, 0x01, 0x0a};
116 
117 // From RFC 5912:
118 //
119 //     id-mgf1  OBJECT IDENTIFIER  ::=  { pkcs-1 8 }
120 //
121 // In dotted notation: 1.2.840.113549.1.1.8
122 const uint8_t kOidMgf1[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
123                             0x0d, 0x01, 0x01, 0x08};
124 
125 // Returns true if |input| is empty.
IsEmpty(const der::Input & input)126 [[nodiscard]] bool IsEmpty(const der::Input& input) {
127   return input.Length() == 0;
128 }
129 
130 // Returns true if the entirety of the input is a NULL value.
IsNull(const der::Input & input)131 [[nodiscard]] bool IsNull(const der::Input& input) {
132   der::Parser parser(input);
133   der::Input null_value;
134   if (!parser.ReadTag(der::kNull, &null_value))
135     return false;
136 
137   // NULL values are TLV encoded; the value is expected to be empty.
138   if (!IsEmpty(null_value))
139     return false;
140 
141   // By definition of this function, the entire input must be a NULL.
142   return !parser.HasMore();
143 }
144 
IsNullOrEmpty(const der::Input & input)145 [[nodiscard]] bool IsNullOrEmpty(const der::Input& input) {
146   return IsNull(input) || IsEmpty(input);
147 }
148 
149 // Parses a MaskGenAlgorithm as defined by RFC 5912:
150 //
151 //     MaskGenAlgorithm ::= AlgorithmIdentifier{ALGORITHM,
152 //                             {PKCS1MGFAlgorithms}}
153 //
154 //     mgf1SHA1 MaskGenAlgorithm ::= {
155 //         algorithm id-mgf1,
156 //         parameters HashAlgorithm : sha1Identifier
157 //     }
158 //
159 //     --
160 //     --  Define the set of mask generation functions
161 //     --
162 //     --  If the identifier is id-mgf1, any of the listed hash
163 //     --    algorithms may be used.
164 //     --
165 //
166 //     PKCS1MGFAlgorithms ALGORITHM ::= {
167 //         { IDENTIFIER id-mgf1 PARAMS TYPE HashAlgorithm ARE required },
168 //         ...
169 //     }
170 //
171 // Note that the possible mask gen algorithms is extensible. However at present
172 // the only function supported is MGF1, as that is the singular mask gen
173 // function defined by RFC 4055 / RFC 5912.
ParseMaskGenAlgorithm(const der::Input input,DigestAlgorithm * mgf1_hash)174 [[nodiscard]] bool ParseMaskGenAlgorithm(const der::Input input,
175                                          DigestAlgorithm* mgf1_hash) {
176   der::Input oid;
177   der::Input params;
178   if (!ParseAlgorithmIdentifier(input, &oid, &params))
179     return false;
180 
181   // MGF1 is the only supported mask generation algorithm.
182   if (oid != der::Input(kOidMgf1))
183     return false;
184 
185   return ParseHashAlgorithm(params, mgf1_hash);
186 }
187 
188 // Parses the parameters for an RSASSA-PSS signature algorithm, as defined by
189 // RFC 5912:
190 //
191 //     sa-rsaSSA-PSS SIGNATURE-ALGORITHM ::= {
192 //         IDENTIFIER id-RSASSA-PSS
193 //         PARAMS TYPE RSASSA-PSS-params ARE required
194 //         HASHES { mda-sha1 | mda-sha224 | mda-sha256 | mda-sha384
195 //                      | mda-sha512 }
196 //         PUBLIC-KEYS { pk-rsa | pk-rsaSSA-PSS }
197 //         SMIME-CAPS { IDENTIFIED BY id-RSASSA-PSS }
198 //     }
199 //
200 //     RSASSA-PSS-params  ::=  SEQUENCE  {
201 //         hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier,
202 //         maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
203 //         saltLength        [2] INTEGER DEFAULT 20,
204 //         trailerField      [3] INTEGER DEFAULT 1
205 //     }
206 //
207 // Which is to say the parameters MUST be present, and of type
208 // RSASSA-PSS-params. Additionally, we only support the RSA-PSS parameter
209 // combinations representable by TLS 1.3 (RFC 8446).
210 //
211 // Note also that DER encoding (ITU-T X.690 section 11.5) prohibits
212 // specifying default values explicitly. The parameter should instead be
213 // omitted to indicate a default value.
ParseRsaPss(const der::Input & params)214 absl::optional<SignatureAlgorithm> ParseRsaPss(const der::Input& params) {
215   der::Parser parser(params);
216   der::Parser params_parser;
217   if (!parser.ReadSequence(&params_parser)) {
218     return absl::nullopt;
219   }
220 
221   // There shouldn't be anything after the sequence (by definition the
222   // parameters is a single sequence).
223   if (parser.HasMore()) {
224     return absl::nullopt;
225   }
226 
227   // The default values for hashAlgorithm, maskGenAlgorithm, and saltLength
228   // correspond to SHA-1, which we do not support with RSA-PSS, so treat them as
229   // required fields. Explicitly-specified defaults will be rejected later, when
230   // we limit combinations. Additionally, as the trailerField is required to be
231   // the default, we simply ignore it and reject it as any other trailing data.
232   //
233   //     hashAlgorithm     [0] HashAlgorithm DEFAULT sha1Identifier,
234   //     maskGenAlgorithm  [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
235   //     saltLength        [2] INTEGER DEFAULT 20,
236   //     trailerField      [3] INTEGER DEFAULT 1
237   der::Input field;
238   DigestAlgorithm hash, mgf1_hash;
239   der::Parser salt_length_parser;
240   uint64_t salt_length;
241   if (!params_parser.ReadTag(der::ContextSpecificConstructed(0), &field) ||
242       !ParseHashAlgorithm(field, &hash) ||
243       !params_parser.ReadTag(der::ContextSpecificConstructed(1), &field) ||
244       !ParseMaskGenAlgorithm(field, &mgf1_hash) ||
245       !params_parser.ReadConstructed(der::ContextSpecificConstructed(2),
246                                      &salt_length_parser) ||
247       !salt_length_parser.ReadUint64(&salt_length) ||
248       salt_length_parser.HasMore() || params_parser.HasMore()) {
249     return absl::nullopt;
250   }
251 
252   // Only combinations of RSASSA-PSS-params specified by TLS 1.3 (RFC 8446) are
253   // supported.
254   if (hash != mgf1_hash) {
255     return absl::nullopt;  // TLS 1.3 always matches MGF-1 and message hash.
256   }
257   if (hash == DigestAlgorithm::Sha256 && salt_length == 32) {
258     return SignatureAlgorithm::kRsaPssSha256;
259   }
260   if (hash == DigestAlgorithm::Sha384 && salt_length == 48) {
261     return SignatureAlgorithm::kRsaPssSha384;
262   }
263   if (hash == DigestAlgorithm::Sha512 && salt_length == 64) {
264     return SignatureAlgorithm::kRsaPssSha512;
265   }
266 
267   return absl::nullopt;
268 }
269 
270 }  // namespace
271 
ParseAlgorithmIdentifier(const der::Input & input,der::Input * algorithm,der::Input * parameters)272 [[nodiscard]] bool ParseAlgorithmIdentifier(const der::Input& input,
273                                             der::Input* algorithm,
274                                             der::Input* parameters) {
275   der::Parser parser(input);
276 
277   der::Parser algorithm_identifier_parser;
278   if (!parser.ReadSequence(&algorithm_identifier_parser))
279     return false;
280 
281   // There shouldn't be anything after the sequence. This is by definition,
282   // as the input to this function is expected to be a single
283   // AlgorithmIdentifier.
284   if (parser.HasMore())
285     return false;
286 
287   if (!algorithm_identifier_parser.ReadTag(der::kOid, algorithm))
288     return false;
289 
290   // Read the optional parameters to a der::Input. The parameters can be at
291   // most one TLV (for instance NULL or a sequence).
292   //
293   // Note that nothing is allowed after the single optional "parameters" TLV.
294   // This is because RFC 5912's notation for AlgorithmIdentifier doesn't
295   // explicitly list an extension point after "parameters".
296   *parameters = der::Input();
297   if (algorithm_identifier_parser.HasMore() &&
298       !algorithm_identifier_parser.ReadRawTLV(parameters)) {
299     return false;
300   }
301   return !algorithm_identifier_parser.HasMore();
302 }
303 
ParseHashAlgorithm(const der::Input & input,DigestAlgorithm * out)304 [[nodiscard]] bool ParseHashAlgorithm(const der::Input& input,
305                                       DigestAlgorithm* out) {
306   CBS cbs;
307   CBS_init(&cbs, input.UnsafeData(), input.Length());
308   const EVP_MD* md = EVP_parse_digest_algorithm(&cbs);
309 
310   if (md == EVP_sha1()) {
311     *out = DigestAlgorithm::Sha1;
312   } else if (md == EVP_sha256()) {
313     *out = DigestAlgorithm::Sha256;
314   } else if (md == EVP_sha384()) {
315     *out = DigestAlgorithm::Sha384;
316   } else if (md == EVP_sha512()) {
317     *out = DigestAlgorithm::Sha512;
318   } else {
319     // TODO(eroman): Support MD2, MD4, MD5 for completeness?
320     // Unsupported digest algorithm.
321     return false;
322   }
323 
324   return true;
325 }
326 
ParseSignatureAlgorithm(const der::Input & algorithm_identifier)327 absl::optional<SignatureAlgorithm> ParseSignatureAlgorithm(
328     const der::Input& algorithm_identifier) {
329   der::Input oid;
330   der::Input params;
331   if (!ParseAlgorithmIdentifier(algorithm_identifier, &oid, &params)) {
332     return absl::nullopt;
333   }
334 
335   // TODO(eroman): Each OID is tested for equality in order, which is not
336   // particularly efficient.
337 
338   // RFC 5912 requires that the parameters for RSA PKCS#1 v1.5 algorithms be
339   // NULL ("PARAMS TYPE NULL ARE required"), however an empty parameter is also
340   // allowed for compatibility with non-compliant OCSP responders.
341   //
342   // TODO(svaldez): Add warning about non-strict parsing.
343   if (oid == der::Input(kOidSha1WithRsaEncryption) && IsNullOrEmpty(params)) {
344     return SignatureAlgorithm::kRsaPkcs1Sha1;
345   }
346   if (oid == der::Input(kOidSha256WithRsaEncryption) && IsNullOrEmpty(params)) {
347     return SignatureAlgorithm::kRsaPkcs1Sha256;
348   }
349   if (oid == der::Input(kOidSha384WithRsaEncryption) && IsNullOrEmpty(params)) {
350     return SignatureAlgorithm::kRsaPkcs1Sha384;
351   }
352   if (oid == der::Input(kOidSha512WithRsaEncryption) && IsNullOrEmpty(params)) {
353     return SignatureAlgorithm::kRsaPkcs1Sha512;
354   }
355   if (oid == der::Input(kOidSha1WithRsaSignature) && IsNullOrEmpty(params)) {
356     return SignatureAlgorithm::kRsaPkcs1Sha1;
357   }
358 
359   // RFC 5912 requires that the parameters for ECDSA algorithms be absent
360   // ("PARAMS TYPE NULL ARE absent"):
361   if (oid == der::Input(kOidEcdsaWithSha1) && IsEmpty(params)) {
362     return SignatureAlgorithm::kEcdsaSha1;
363   }
364   if (oid == der::Input(kOidEcdsaWithSha256) && IsEmpty(params)) {
365     return SignatureAlgorithm::kEcdsaSha256;
366   }
367   if (oid == der::Input(kOidEcdsaWithSha384) && IsEmpty(params)) {
368     return SignatureAlgorithm::kEcdsaSha384;
369   }
370   if (oid == der::Input(kOidEcdsaWithSha512) && IsEmpty(params)) {
371     return SignatureAlgorithm::kEcdsaSha512;
372   }
373 
374   if (oid == der::Input(kOidRsaSsaPss)) {
375     return ParseRsaPss(params);
376   }
377 
378   // Unknown signature algorithm.
379   return absl::nullopt;
380 }
381 
GetTlsServerEndpointDigestAlgorithm(SignatureAlgorithm alg)382 absl::optional<DigestAlgorithm> GetTlsServerEndpointDigestAlgorithm(
383     SignatureAlgorithm alg) {
384   // See RFC 5929, section 4.1. RFC 5929 breaks the signature algorithm
385   // abstraction by trying to extract individual digest algorithms. (While
386   // common, this is not a universal property of signature algorithms.) We
387   // implement this within the library, so callers do not need to condition over
388   // all algorithms.
389   switch (alg) {
390     // If the single digest algorithm is SHA-1, use SHA-256.
391     case SignatureAlgorithm::kRsaPkcs1Sha1:
392     case SignatureAlgorithm::kEcdsaSha1:
393       return DigestAlgorithm::Sha256;
394 
395     case SignatureAlgorithm::kRsaPkcs1Sha256:
396     case SignatureAlgorithm::kEcdsaSha256:
397       return DigestAlgorithm::Sha256;
398 
399     case SignatureAlgorithm::kRsaPkcs1Sha384:
400     case SignatureAlgorithm::kEcdsaSha384:
401       return DigestAlgorithm::Sha384;
402 
403     case SignatureAlgorithm::kRsaPkcs1Sha512:
404     case SignatureAlgorithm::kEcdsaSha512:
405       return DigestAlgorithm::Sha512;
406 
407     // It is ambiguous whether hash-matching RSASSA-PSS instantiations count as
408     // using one or multiple digests, but the corresponding digest is the only
409     // reasonable interpretation.
410     case SignatureAlgorithm::kRsaPssSha256:
411       return DigestAlgorithm::Sha256;
412     case SignatureAlgorithm::kRsaPssSha384:
413       return DigestAlgorithm::Sha384;
414     case SignatureAlgorithm::kRsaPssSha512:
415       return DigestAlgorithm::Sha512;
416   }
417   return absl::nullopt;
418 }
419 
420 }  // namespace net
421