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, ¶ms))
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(¶ms_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, ¶ms)) {
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