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 "content/child/webcrypto/crypto_data.h"
8 #include "content/child/webcrypto/nss/key_nss.h"
9 #include "content/child/webcrypto/nss/rsa_hashed_algorithm_nss.h"
10 #include "content/child/webcrypto/nss/util_nss.h"
11 #include "content/child/webcrypto/status.h"
12 #include "crypto/scoped_nss_types.h"
13 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
21 class RsaSsaImplementation
: public RsaHashedAlgorithm
{
23 RsaSsaImplementation()
24 : RsaHashedAlgorithm(CKF_SIGN
| CKF_VERIFY
,
25 blink::WebCryptoKeyUsageVerify
,
26 blink::WebCryptoKeyUsageSign
) {}
28 const char* GetJwkAlgorithm(
29 const blink::WebCryptoAlgorithmId hash
) const override
{
31 case blink::WebCryptoAlgorithmIdSha1
:
33 case blink::WebCryptoAlgorithmIdSha256
:
35 case blink::WebCryptoAlgorithmIdSha384
:
37 case blink::WebCryptoAlgorithmIdSha512
:
44 Status
Sign(const blink::WebCryptoAlgorithm
& algorithm
,
45 const blink::WebCryptoKey
& key
,
46 const CryptoData
& data
,
47 std::vector
<uint8_t>* buffer
) const override
{
48 if (key
.type() != blink::WebCryptoKeyTypePrivate
)
49 return Status::ErrorUnexpectedKeyType();
51 SECKEYPrivateKey
* private_key
= PrivateKeyNss::Cast(key
)->key();
53 const blink::WebCryptoAlgorithm
& hash
=
54 key
.algorithm().rsaHashedParams()->hash();
56 // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the
57 // inner hash of the input Web Crypto algorithm.
58 SECOidTag sign_alg_tag
;
60 case blink::WebCryptoAlgorithmIdSha1
:
61 sign_alg_tag
= SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION
;
63 case blink::WebCryptoAlgorithmIdSha256
:
64 sign_alg_tag
= SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION
;
66 case blink::WebCryptoAlgorithmIdSha384
:
67 sign_alg_tag
= SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION
;
69 case blink::WebCryptoAlgorithmIdSha512
:
70 sign_alg_tag
= SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION
;
73 return Status::ErrorUnsupported();
76 crypto::ScopedSECItem
signature_item(SECITEM_AllocItem(NULL
, NULL
, 0));
77 if (SEC_SignData(signature_item
.get(), data
.bytes(), data
.byte_length(),
78 private_key
, sign_alg_tag
) != SECSuccess
) {
79 return Status::OperationError();
82 buffer
->assign(signature_item
->data
,
83 signature_item
->data
+ signature_item
->len
);
84 return Status::Success();
87 Status
Verify(const blink::WebCryptoAlgorithm
& algorithm
,
88 const blink::WebCryptoKey
& key
,
89 const CryptoData
& signature
,
90 const CryptoData
& data
,
91 bool* signature_match
) const override
{
92 if (key
.type() != blink::WebCryptoKeyTypePublic
)
93 return Status::ErrorUnexpectedKeyType();
95 SECKEYPublicKey
* public_key
= PublicKeyNss::Cast(key
)->key();
97 const blink::WebCryptoAlgorithm
& hash
=
98 key
.algorithm().rsaHashedParams()->hash();
100 const SECItem signature_item
= MakeSECItemForBuffer(signature
);
102 SECOidTag hash_alg_tag
;
104 case blink::WebCryptoAlgorithmIdSha1
:
105 hash_alg_tag
= SEC_OID_SHA1
;
107 case blink::WebCryptoAlgorithmIdSha256
:
108 hash_alg_tag
= SEC_OID_SHA256
;
110 case blink::WebCryptoAlgorithmIdSha384
:
111 hash_alg_tag
= SEC_OID_SHA384
;
113 case blink::WebCryptoAlgorithmIdSha512
:
114 hash_alg_tag
= SEC_OID_SHA512
;
117 return Status::ErrorUnsupported();
121 SECSuccess
== VFY_VerifyDataDirect(data
.bytes(), data
.byte_length(),
122 public_key
, &signature_item
,
123 SEC_OID_PKCS1_RSA_ENCRYPTION
,
124 hash_alg_tag
, NULL
, NULL
);
125 return Status::Success();
131 AlgorithmImplementation
* CreatePlatformRsaSsaImplementation() {
132 return new RsaSsaImplementation
;
135 } // namespace webcrypto
137 } // namespace content