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