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