1 // Copyright 2014 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.
7 #include "components/webcrypto/crypto_data.h"
8 #include "components/webcrypto/nss/key_nss.h"
9 #include "components/webcrypto/nss/rsa_hashed_algorithm_nss.h"
10 #include "components/webcrypto/nss/util_nss.h"
11 #include "components/webcrypto/status.h"
12 #include "crypto/scoped_nss_types.h"
13 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
19 class RsaSsaImplementation
: public RsaHashedAlgorithm
{
21 RsaSsaImplementation()
22 : RsaHashedAlgorithm(CKF_SIGN
| CKF_VERIFY
,
23 blink::WebCryptoKeyUsageVerify
,
24 blink::WebCryptoKeyUsageSign
) {}
26 const char* GetJwkAlgorithm(
27 const blink::WebCryptoAlgorithmId hash
) const override
{
29 case blink::WebCryptoAlgorithmIdSha1
:
31 case blink::WebCryptoAlgorithmIdSha256
:
33 case blink::WebCryptoAlgorithmIdSha384
:
35 case blink::WebCryptoAlgorithmIdSha512
:
42 Status
Sign(const blink::WebCryptoAlgorithm
& algorithm
,
43 const blink::WebCryptoKey
& key
,
44 const CryptoData
& data
,
45 std::vector
<uint8_t>* buffer
) const override
{
46 if (key
.type() != blink::WebCryptoKeyTypePrivate
)
47 return Status::ErrorUnexpectedKeyType();
49 SECKEYPrivateKey
* private_key
= PrivateKeyNss::Cast(key
)->key();
51 const blink::WebCryptoAlgorithm
& hash
=
52 key
.algorithm().rsaHashedParams()->hash();
54 // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the
55 // inner hash of the input Web Crypto algorithm.
56 SECOidTag sign_alg_tag
;
58 case blink::WebCryptoAlgorithmIdSha1
:
59 sign_alg_tag
= SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION
;
61 case blink::WebCryptoAlgorithmIdSha256
:
62 sign_alg_tag
= SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION
;
64 case blink::WebCryptoAlgorithmIdSha384
:
65 sign_alg_tag
= SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION
;
67 case blink::WebCryptoAlgorithmIdSha512
:
68 sign_alg_tag
= SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION
;
71 return Status::ErrorUnsupported();
74 crypto::ScopedSECItem
signature_item(SECITEM_AllocItem(NULL
, NULL
, 0));
75 if (SEC_SignData(signature_item
.get(), data
.bytes(), data
.byte_length(),
76 private_key
, sign_alg_tag
) != SECSuccess
) {
77 return Status::OperationError();
80 buffer
->assign(signature_item
->data
,
81 signature_item
->data
+ signature_item
->len
);
82 return Status::Success();
85 Status
Verify(const blink::WebCryptoAlgorithm
& algorithm
,
86 const blink::WebCryptoKey
& key
,
87 const CryptoData
& signature
,
88 const CryptoData
& data
,
89 bool* signature_match
) const override
{
90 if (key
.type() != blink::WebCryptoKeyTypePublic
)
91 return Status::ErrorUnexpectedKeyType();
93 SECKEYPublicKey
* public_key
= PublicKeyNss::Cast(key
)->key();
95 const blink::WebCryptoAlgorithm
& hash
=
96 key
.algorithm().rsaHashedParams()->hash();
98 const SECItem signature_item
= MakeSECItemForBuffer(signature
);
100 SECOidTag hash_alg_tag
;
102 case blink::WebCryptoAlgorithmIdSha1
:
103 hash_alg_tag
= SEC_OID_SHA1
;
105 case blink::WebCryptoAlgorithmIdSha256
:
106 hash_alg_tag
= SEC_OID_SHA256
;
108 case blink::WebCryptoAlgorithmIdSha384
:
109 hash_alg_tag
= SEC_OID_SHA384
;
111 case blink::WebCryptoAlgorithmIdSha512
:
112 hash_alg_tag
= SEC_OID_SHA512
;
115 return Status::ErrorUnsupported();
119 SECSuccess
== VFY_VerifyDataDirect(data
.bytes(), data
.byte_length(),
120 public_key
, &signature_item
,
121 SEC_OID_PKCS1_RSA_ENCRYPTION
,
122 hash_alg_tag
, NULL
, NULL
);
123 return Status::Success();
129 AlgorithmImplementation
* CreatePlatformRsaSsaImplementation() {
130 return new RsaSsaImplementation
;
133 } // namespace webcrypto