1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/cert/internal/signature_algorithm.h"
7 #include "base/numerics/safe_math.h"
8 #include "net/der/input.h"
9 #include "net/der/parse_values.h"
10 #include "net/der/parser.h"
18 // sha1WithRSAEncryption OBJECT IDENTIFIER ::= {
19 // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
22 // In dotted notation: 1.2.840.113549.1.1.5
23 const uint8_t kOidSha1WithRsaEncryption
[] =
24 {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05};
26 // sha1WithRSASignature is a deprecated equivalent of
27 // sha1WithRSAEncryption.
29 // It originates from the NIST Open Systems Environment (OSE)
30 // Implementor's Workshop (OIW).
32 // It is supported for compatibility with Microsoft's certificate APIs and
33 // tools, particularly makecert.exe, which default(ed/s) to this OID for SHA-1.
35 // See also: https://bugzilla.mozilla.org/show_bug.cgi?id=1042479
37 // In dotted notation: 1.3.14.3.2.29
38 const uint8_t kOidSha1WithRsaSignature
[] = {0x2b, 0x0e, 0x03, 0x02, 0x1d};
42 // pkcs-1 OBJECT IDENTIFIER ::=
43 // { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
47 // sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
49 // In dotted notation: 1.2.840.113549.1.1.11
50 const uint8_t kOidSha256WithRsaEncryption
[] =
51 {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b};
55 // sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
57 // In dotted notation: 1.2.840.113549.1.1.11
58 const uint8_t kOidSha384WithRsaEncryption
[] =
59 {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c};
63 // sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
65 // In dotted notation: 1.2.840.113549.1.1.13
66 const uint8_t kOidSha512WithRsaEncryption
[] =
67 {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d};
71 // ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
72 // iso(1) member-body(2) us(840) ansi-X9-62(10045)
75 // In dotted notation: 1.2.840.10045.4.1
76 const uint8_t kOidEcdsaWithSha1
[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01};
80 // ecdsa-with-SHA256 OBJECT IDENTIFIER ::= {
81 // iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
82 // ecdsa-with-SHA2(3) 2 }
84 // In dotted notation: 1.2.840.10045.4.3.2
85 const uint8_t kOidEcdsaWithSha256
[] =
86 {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02};
90 // ecdsa-with-SHA384 OBJECT IDENTIFIER ::= {
91 // iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
92 // ecdsa-with-SHA2(3) 3 }
94 // In dotted notation: 1.2.840.10045.4.3.3
95 const uint8_t kOidEcdsaWithSha384
[] =
96 {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03};
100 // ecdsa-with-SHA512 OBJECT IDENTIFIER ::= {
101 // iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
102 // ecdsa-with-SHA2(3) 4 }
104 // In dotted notation: 1.2.840.10045.4.3.4
105 const uint8_t kOidEcdsaWithSha512
[] =
106 {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04};
110 // id-RSASSA-PSS OBJECT IDENTIFIER ::= { pkcs-1 10 }
112 // In dotted notation: 1.2.840.113549.1.1.10
113 const uint8_t kOidRsaSsaPss
[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
114 0x0d, 0x01, 0x01, 0x0a};
118 // id-sha1 OBJECT IDENTIFIER ::= {
119 // iso(1) identified-organization(3) oiw(14) secsig(3)
122 // In dotted notation: 1.3.14.3.2.26
123 const uint8_t kOidSha1
[] = {0x2B, 0x0E, 0x03, 0x02, 0x1A};
127 // id-sha256 OBJECT IDENTIFIER ::=
128 // { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
129 // csor(3) nistAlgorithms(4) hashalgs(2) 1 }
131 // In dotted notation: 2.16.840.1.101.3.4.2.1
132 const uint8_t kOidSha256
[] = {0x60, 0x86, 0x48, 0x01, 0x65,
133 0x03, 0x04, 0x02, 0x01};
137 // id-sha384 OBJECT IDENTIFIER ::=
138 // { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
139 // csor(3) nistAlgorithms(4) hashalgs(2) 2 }
141 // In dotted notation: 2.16.840.1.101.3.4.2.2
142 const uint8_t kOidSha384
[] = {0x60, 0x86, 0x48, 0x01, 0x65,
143 0x03, 0x04, 0x02, 0x02};
147 // id-sha512 OBJECT IDENTIFIER ::=
148 // { joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101)
149 // csor(3) nistAlgorithms(4) hashalgs(2) 3 }
151 // In dotted notation: 2.16.840.1.101.3.4.2.3
152 const uint8_t kOidSha512
[] = {0x60, 0x86, 0x48, 0x01, 0x65,
153 0x03, 0x04, 0x02, 0x03};
157 // id-mgf1 OBJECT IDENTIFIER ::= { pkcs-1 8 }
159 // In dotted notation: 1.2.840.113549.1.1.8
160 const uint8_t kOidMgf1
[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
161 0x0d, 0x01, 0x01, 0x08};
163 // RFC 5280 section 4.1.1.2 defines signatureAlgorithm as:
165 // AlgorithmIdentifier ::= SEQUENCE {
166 // algorithm OBJECT IDENTIFIER,
167 // parameters ANY DEFINED BY algorithm OPTIONAL }
168 WARN_UNUSED_RESULT
bool ParseAlgorithmIdentifier(const der::Input
& input
,
169 der::Input
* algorithm
,
170 der::Input
* parameters
) {
171 der::Parser
parser(input
);
173 der::Parser algorithm_identifier_parser
;
174 if (!parser
.ReadSequence(&algorithm_identifier_parser
))
177 // There shouldn't be anything after the sequence. This is by definition,
178 // as the input to this function is expected to be a single
179 // AlgorithmIdentifier.
180 if (parser
.HasMore())
183 if (!algorithm_identifier_parser
.ReadTag(der::kOid
, algorithm
))
186 // Read the optional parameters to a der::Input. The parameters can be at
187 // most one TLV (for instance NULL or a sequence).
189 // Note that nothing is allowed after the single optional "parameters" TLV.
190 // This is because RFC 5912's notation for AlgorithmIdentifier doesn't
191 // explicitly list an extension point after "parameters".
192 *parameters
= der::Input();
193 if (algorithm_identifier_parser
.HasMore() &&
194 !algorithm_identifier_parser
.ReadRawTLV(parameters
)) {
197 return !algorithm_identifier_parser
.HasMore();
200 // Returns true if |input| is empty.
201 WARN_UNUSED_RESULT
bool IsEmpty(const der::Input
& input
) {
202 return input
.Length() == 0;
205 // Returns true if the entirety of the input is a NULL value.
206 WARN_UNUSED_RESULT
bool IsNull(const der::Input
& input
) {
207 der::Parser
parser(input
);
208 der::Input null_value
;
209 if (!parser
.ReadTag(der::kNull
, &null_value
))
212 // NULL values are TLV encoded; the value is expected to be empty.
213 if (!IsEmpty(null_value
))
216 // By definition of this function, the entire input must be a NULL.
217 return !parser
.HasMore();
220 // Parses an RSA PKCS#1 v1.5 signature algorithm given the DER-encoded
221 // "parameters" from the parsed AlgorithmIdentifier, and the hash algorithm
222 // that was implied by the AlgorithmIdentifier's OID.
224 // Returns a nullptr on failure.
226 // RFC 5912 requires that the parameters for RSA PKCS#1 v1.5 algorithms be NULL
227 // ("PARAMS TYPE NULL ARE required"):
229 // sa-rsaWithSHA1 SIGNATURE-ALGORITHM ::= {
230 // IDENTIFIER sha1WithRSAEncryption
231 // PARAMS TYPE NULL ARE required
232 // HASHES { mda-sha1 }
233 // PUBLIC-KEYS { pk-rsa }
234 // SMIME-CAPS {IDENTIFIED BY sha1WithRSAEncryption }
237 // sa-sha256WithRSAEncryption SIGNATURE-ALGORITHM ::= {
238 // IDENTIFIER sha256WithRSAEncryption
239 // PARAMS TYPE NULL ARE required
240 // HASHES { mda-sha256 }
241 // PUBLIC-KEYS { pk-rsa }
242 // SMIME-CAPS { IDENTIFIED BY sha256WithRSAEncryption }
245 // sa-sha384WithRSAEncryption SIGNATURE-ALGORITHM ::= {
246 // IDENTIFIER sha384WithRSAEncryption
247 // PARAMS TYPE NULL ARE required
248 // HASHES { mda-sha384 }
249 // PUBLIC-KEYS { pk-rsa }
250 // SMIME-CAPS { IDENTIFIED BY sha384WithRSAEncryption }
253 // sa-sha512WithRSAEncryption SIGNATURE-ALGORITHM ::= {
254 // IDENTIFIER sha512WithRSAEncryption
255 // PARAMS TYPE NULL ARE required
256 // HASHES { mda-sha512 }
257 // PUBLIC-KEYS { pk-rsa }
258 // SMIME-CAPS { IDENTIFIED BY sha512WithRSAEncryption }
260 scoped_ptr
<SignatureAlgorithm
> ParseRsaPkcs1(DigestAlgorithm digest
,
261 const der::Input
& params
) {
265 return SignatureAlgorithm::CreateRsaPkcs1(digest
);
268 // Parses an ECDSA signature algorithm given the DER-encoded "parameters" from
269 // the parsed AlgorithmIdentifier, and the hash algorithm that was implied by
270 // the AlgorithmIdentifier's OID.
272 // On failure returns a nullptr.
274 // RFC 5912 requires that the parameters for ECDSA algorithms be absent
275 // ("PARAMS TYPE NULL ARE absent"):
277 // sa-ecdsaWithSHA1 SIGNATURE-ALGORITHM ::= {
278 // IDENTIFIER ecdsa-with-SHA1
279 // VALUE ECDSA-Sig-Value
280 // PARAMS TYPE NULL ARE absent
281 // HASHES { mda-sha1 }
282 // PUBLIC-KEYS { pk-ec }
283 // SMIME-CAPS {IDENTIFIED BY ecdsa-with-SHA1 }
286 // sa-ecdsaWithSHA256 SIGNATURE-ALGORITHM ::= {
287 // IDENTIFIER ecdsa-with-SHA256
288 // VALUE ECDSA-Sig-Value
289 // PARAMS TYPE NULL ARE absent
290 // HASHES { mda-sha256 }
291 // PUBLIC-KEYS { pk-ec }
292 // SMIME-CAPS { IDENTIFIED BY ecdsa-with-SHA256 }
295 // sa-ecdsaWithSHA384 SIGNATURE-ALGORITHM ::= {
296 // IDENTIFIER ecdsa-with-SHA384
297 // VALUE ECDSA-Sig-Value
298 // PARAMS TYPE NULL ARE absent
299 // HASHES { mda-sha384 }
300 // PUBLIC-KEYS { pk-ec }
301 // SMIME-CAPS { IDENTIFIED BY ecdsa-with-SHA384 }
304 // sa-ecdsaWithSHA512 SIGNATURE-ALGORITHM ::= {
305 // IDENTIFIER ecdsa-with-SHA512
306 // VALUE ECDSA-Sig-Value
307 // PARAMS TYPE NULL ARE absent
308 // HASHES { mda-sha512 }
309 // PUBLIC-KEYS { pk-ec }
310 // SMIME-CAPS { IDENTIFIED BY ecdsa-with-SHA512 }
312 scoped_ptr
<SignatureAlgorithm
> ParseEcdsa(DigestAlgorithm digest
,
313 const der::Input
& params
) {
314 if (!IsEmpty(params
))
317 return SignatureAlgorithm::CreateEcdsa(digest
);
320 // Parses a HashAlgorithm as defined by RFC 5912:
322 // HashAlgorithm ::= AlgorithmIdentifier{DIGEST-ALGORITHM,
325 // HashAlgorithms DIGEST-ALGORITHM ::= {
326 // { IDENTIFIER id-sha1 PARAMS TYPE NULL ARE preferredPresent } |
327 // { IDENTIFIER id-sha224 PARAMS TYPE NULL ARE preferredPresent } |
328 // { IDENTIFIER id-sha256 PARAMS TYPE NULL ARE preferredPresent } |
329 // { IDENTIFIER id-sha384 PARAMS TYPE NULL ARE preferredPresent } |
330 // { IDENTIFIER id-sha512 PARAMS TYPE NULL ARE preferredPresent }
332 WARN_UNUSED_RESULT
bool ParseHashAlgorithm(const der::Input input
,
333 DigestAlgorithm
* out
) {
336 if (!ParseAlgorithmIdentifier(input
, &oid
, ¶ms
))
339 DigestAlgorithm hash
;
341 if (oid
.Equals(der::Input(kOidSha1
))) {
342 hash
= DigestAlgorithm::Sha1
;
343 } else if (oid
.Equals(der::Input(kOidSha256
))) {
344 hash
= DigestAlgorithm::Sha256
;
345 } else if (oid
.Equals(der::Input(kOidSha384
))) {
346 hash
= DigestAlgorithm::Sha384
;
347 } else if (oid
.Equals(der::Input(kOidSha512
))) {
348 hash
= DigestAlgorithm::Sha512
;
350 // Unsupported digest algorithm.
354 // From RFC 5912: "PARAMS TYPE NULL ARE preferredPresent". Which is to say
355 // the can either be absent, or NULL.
356 if (!IsEmpty(params
) && !IsNull(params
))
363 // Parses a MaskGenAlgorithm as defined by RFC 5912:
365 // MaskGenAlgorithm ::= AlgorithmIdentifier{ALGORITHM,
366 // {PKCS1MGFAlgorithms}}
368 // mgf1SHA1 MaskGenAlgorithm ::= {
369 // algorithm id-mgf1,
370 // parameters HashAlgorithm : sha1Identifier
374 // -- Define the set of mask generation functions
376 // -- If the identifier is id-mgf1, any of the listed hash
377 // -- algorithms may be used.
380 // PKCS1MGFAlgorithms ALGORITHM ::= {
381 // { IDENTIFIER id-mgf1 PARAMS TYPE HashAlgorithm ARE required },
385 // Note that the possible mask gen algorithms is extensible. However at present
386 // the only function supported is MGF1, as that is the singular mask gen
387 // function defined by RFC 4055 / RFC 5912.
388 WARN_UNUSED_RESULT
bool ParseMaskGenAlgorithm(const der::Input input
,
389 DigestAlgorithm
* mgf1_hash
) {
392 if (!ParseAlgorithmIdentifier(input
, &oid
, ¶ms
))
395 // MGF1 is the only supported mask generation algorithm.
396 if (!oid
.Equals(der::Input(kOidMgf1
)))
399 return ParseHashAlgorithm(params
, mgf1_hash
);
402 // Consumes an optional, explicitly-tagged INTEGER from |parser|, using the
403 // indicated context-specific class number. Values greater than 32-bits will be
406 // Returns true on success and sets |*present| to true if the field was present.
407 WARN_UNUSED_RESULT
bool ReadOptionalContextSpecificUint32(der::Parser
* parser
,
408 uint8_t class_number
,
414 // Read the context specific value.
415 if (!parser
->ReadOptionalTag(der::ContextSpecificConstructed(class_number
),
416 &value
, &has_value
)) {
421 // Parse the integer contained in it.
422 der::Parser
number_parser(value
);
423 uint64_t uint64_value
;
425 if (!number_parser
.ReadUint64(&uint64_value
))
427 if (number_parser
.HasMore())
430 // Cast the number to a uint32_t
431 base::CheckedNumeric
<uint32_t> casted(uint64_value
);
432 if (!casted
.IsValid())
434 *out
= casted
.ValueOrDie();
437 *present
= has_value
;
441 // Parses the parameters for an RSASSA-PSS signature algorithm, as defined by
444 // sa-rsaSSA-PSS SIGNATURE-ALGORITHM ::= {
445 // IDENTIFIER id-RSASSA-PSS
446 // PARAMS TYPE RSASSA-PSS-params ARE required
447 // HASHES { mda-sha1 | mda-sha224 | mda-sha256 | mda-sha384
449 // PUBLIC-KEYS { pk-rsa | pk-rsaSSA-PSS }
450 // SMIME-CAPS { IDENTIFIED BY id-RSASSA-PSS }
453 // RSASSA-PSS-params ::= SEQUENCE {
454 // hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier,
455 // maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
456 // saltLength [2] INTEGER DEFAULT 20,
457 // trailerField [3] INTEGER DEFAULT 1
460 // Which is to say the parameters MUST be present, and of type
461 // RSASSA-PSS-params.
462 scoped_ptr
<SignatureAlgorithm
> ParseRsaPss(const der::Input
& params
) {
463 der::Parser
parser(params
);
464 der::Parser params_parser
;
465 if (!parser
.ReadSequence(¶ms_parser
))
468 // There shouldn't be anything after the sequence (by definition the
469 // parameters is a single sequence).
470 if (parser
.HasMore())
477 // hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier,
478 DigestAlgorithm hash
= DigestAlgorithm::Sha1
;
479 if (!params_parser
.ReadOptionalTag(der::ContextSpecificConstructed(0), &field
,
483 if (has_field
&& !ParseHashAlgorithm(field
, &hash
))
487 // maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1,
488 DigestAlgorithm mgf1_hash
= DigestAlgorithm::Sha1
;
489 if (!params_parser
.ReadOptionalTag(der::ContextSpecificConstructed(1), &field
,
493 if (has_field
&& !ParseMaskGenAlgorithm(field
, &mgf1_hash
))
497 // saltLength [2] INTEGER DEFAULT 20,
498 uint32_t salt_length
= 20u;
499 if (!ReadOptionalContextSpecificUint32(¶ms_parser
, 2, &salt_length
,
505 // trailerField [3] INTEGER DEFAULT 1
506 uint32_t trailer_field
= 1u;
507 if (!ReadOptionalContextSpecificUint32(¶ms_parser
, 3, &trailer_field
,
512 // RFC 4055 says that the trailer field must be 1:
514 // The trailerField field is an integer. It provides
515 // compatibility with IEEE Std 1363a-2004 [P1363A]. The value
516 // MUST be 1, which represents the trailer field with hexadecimal
517 // value 0xBC. Other trailer fields, including the trailer field
518 // composed of HashID concatenated with 0xCC that is specified in
519 // IEEE Std 1363a, are not supported. Implementations that
520 // perform signature generation MUST omit the trailerField field,
521 // indicating that the default trailer field value was used.
522 // Implementations that perform signature validation MUST
523 // recognize both a present trailerField field with value 1 and an
524 // absent trailerField field.
525 if (trailer_field
!= 1)
528 // There must not be any unconsumed data left. (RFC 5912 does not explicitly
529 // include an extensibility point for RSASSA-PSS-params)
530 if (params_parser
.HasMore())
533 return SignatureAlgorithm::CreateRsaPss(hash
, mgf1_hash
, salt_length
);
538 RsaPssParameters::RsaPssParameters(DigestAlgorithm mgf1_hash
,
539 uint32_t salt_length
)
540 : mgf1_hash_(mgf1_hash
), salt_length_(salt_length
) {
543 bool RsaPssParameters::Equals(const RsaPssParameters
* other
) const {
544 return mgf1_hash_
== other
->mgf1_hash_
&& salt_length_
== other
->salt_length_
;
547 SignatureAlgorithm::~SignatureAlgorithm() {
550 scoped_ptr
<SignatureAlgorithm
> SignatureAlgorithm::CreateFromDer(
551 const der::Input
& algorithm_identifier
) {
554 if (!ParseAlgorithmIdentifier(algorithm_identifier
, &oid
, ¶ms
))
557 // TODO(eroman): Each OID is tested for equality in order, which is not
558 // particularly efficient.
560 if (oid
.Equals(der::Input(kOidSha1WithRsaEncryption
)))
561 return ParseRsaPkcs1(DigestAlgorithm::Sha1
, params
);
563 if (oid
.Equals(der::Input(kOidSha256WithRsaEncryption
)))
564 return ParseRsaPkcs1(DigestAlgorithm::Sha256
, params
);
566 if (oid
.Equals(der::Input(kOidSha384WithRsaEncryption
)))
567 return ParseRsaPkcs1(DigestAlgorithm::Sha384
, params
);
569 if (oid
.Equals(der::Input(kOidSha512WithRsaEncryption
)))
570 return ParseRsaPkcs1(DigestAlgorithm::Sha512
, params
);
572 if (oid
.Equals(der::Input(kOidEcdsaWithSha1
)))
573 return ParseEcdsa(DigestAlgorithm::Sha1
, params
);
575 if (oid
.Equals(der::Input(kOidEcdsaWithSha256
)))
576 return ParseEcdsa(DigestAlgorithm::Sha256
, params
);
578 if (oid
.Equals(der::Input(kOidEcdsaWithSha384
)))
579 return ParseEcdsa(DigestAlgorithm::Sha384
, params
);
581 if (oid
.Equals(der::Input(kOidEcdsaWithSha512
)))
582 return ParseEcdsa(DigestAlgorithm::Sha512
, params
);
584 if (oid
.Equals(der::Input(kOidRsaSsaPss
)))
585 return ParseRsaPss(params
);
587 if (oid
.Equals(der::Input(kOidSha1WithRsaSignature
)))
588 return ParseRsaPkcs1(DigestAlgorithm::Sha1
, params
);
590 return nullptr; // Unsupported OID.
593 scoped_ptr
<SignatureAlgorithm
> SignatureAlgorithm::CreateRsaPkcs1(
594 DigestAlgorithm digest
) {
595 return make_scoped_ptr(
596 new SignatureAlgorithm(SignatureAlgorithmId::RsaPkcs1
, digest
, nullptr));
599 scoped_ptr
<SignatureAlgorithm
> SignatureAlgorithm::CreateEcdsa(
600 DigestAlgorithm digest
) {
601 return make_scoped_ptr(
602 new SignatureAlgorithm(SignatureAlgorithmId::Ecdsa
, digest
, nullptr));
605 scoped_ptr
<SignatureAlgorithm
> SignatureAlgorithm::CreateRsaPss(
606 DigestAlgorithm digest
,
607 DigestAlgorithm mgf1_hash
,
608 uint32_t salt_length
) {
609 return make_scoped_ptr(new SignatureAlgorithm(
610 SignatureAlgorithmId::RsaPss
, digest
,
611 make_scoped_ptr(new RsaPssParameters(mgf1_hash
, salt_length
))));
614 bool SignatureAlgorithm::Equals(const SignatureAlgorithm
& other
) const {
615 if (algorithm_
!= other
.algorithm_
)
618 if (digest_
!= other
.digest_
)
621 // Check that the parameters are equal.
622 switch (algorithm_
) {
623 case SignatureAlgorithmId::RsaPss
: {
624 const RsaPssParameters
* params1
= ParamsForRsaPss();
625 const RsaPssParameters
* params2
= other
.ParamsForRsaPss();
626 if (!params1
|| !params2
|| !params1
->Equals(params2
))
631 // There shouldn't be any parameters.
632 case SignatureAlgorithmId::RsaPkcs1
:
633 case SignatureAlgorithmId::Ecdsa
:
634 if (params_
|| other
.params_
)
642 const RsaPssParameters
* SignatureAlgorithm::ParamsForRsaPss() const {
643 if (algorithm_
== SignatureAlgorithmId::RsaPss
)
644 return static_cast<RsaPssParameters
*>(params_
.get());
648 SignatureAlgorithm::SignatureAlgorithm(
649 SignatureAlgorithmId algorithm
,
650 DigestAlgorithm digest
,
651 scoped_ptr
<SignatureAlgorithmParameters
> params
)
652 : algorithm_(algorithm
), digest_(digest
), params_(params
.Pass()) {