blob: 8a5691f79cfa96dfaf078d5dcb8a7ab050919e7d [file] [log] [blame]
[email protected]408699c2013-07-17 21:23:161// Copyright (c) 2013 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.
4
[email protected]3da6b212013-09-27 05:02:365#include "content/renderer/webcrypto/webcrypto_impl.h"
[email protected]408699c2013-07-17 21:23:166
[email protected]c1b944a2013-10-23 06:33:217#include "base/logging.h"
[email protected]04166f82014-02-19 06:11:048#include "content/renderer/webcrypto/crypto_data.h"
9#include "content/renderer/webcrypto/shared_crypto.h"
[email protected]b28852b2013-12-04 04:57:1110#include "content/renderer/webcrypto/webcrypto_util.h"
[email protected]cca897482014-01-30 22:40:1911#include "third_party/WebKit/public/platform/WebString.h"
[email protected]8238bb1c2014-02-26 15:16:2512#ifdef WEBCRYPTO_HAS_KEY_ALGORITHM
13#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
14#endif
[email protected]408699c2013-07-17 21:23:1615
16namespace content {
17
[email protected]cca897482014-01-30 22:40:1918using webcrypto::Status;
19
[email protected]043cf1d32013-11-02 13:27:3020namespace {
21
[email protected]cca897482014-01-30 22:40:1922void CompleteWithError(const Status& status, blink::WebCryptoResult* result) {
23 DCHECK(status.IsError());
[email protected]116d8bb2014-02-07 08:08:4524 if (status.HasErrorDetails())
25 result->completeWithError(blink::WebString::fromUTF8(status.ToString()));
26 else
27 result->completeWithError();
[email protected]cca897482014-01-30 22:40:1928}
29
[email protected]180ef242013-11-07 06:50:4630bool IsAlgorithmAsymmetric(const blink::WebCryptoAlgorithm& algorithm) {
[email protected]043cf1d32013-11-02 13:27:3031 // TODO(padolph): include all other asymmetric algorithms once they are
32 // defined, e.g. EC and DH.
[email protected]180ef242013-11-07 06:50:4633 return (algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
34 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
35 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep);
[email protected]043cf1d32013-11-02 13:27:3036}
37
38} // namespace
39
[email protected]a60326552014-02-19 22:58:2440WebCryptoImpl::WebCryptoImpl() { webcrypto::Init(); }
[email protected]7e4c36f2013-09-12 06:10:1941
[email protected]04166f82014-02-19 06:11:0442WebCryptoImpl::~WebCryptoImpl() {}
43
[email protected]a60326552014-02-19 22:58:2444void WebCryptoImpl::encrypt(const blink::WebCryptoAlgorithm& algorithm,
45 const blink::WebCryptoKey& key,
46 const unsigned char* data,
47 unsigned int data_size,
48 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3449 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:4650 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:0451 Status status = webcrypto::Encrypt(
52 algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
[email protected]edb692e652014-01-31 05:32:5253 if (status.IsError())
[email protected]cca897482014-01-30 22:40:1954 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:5255 else
[email protected]a2a06c732013-09-27 10:50:5456 result.completeWithBuffer(buffer);
[email protected]a2a06c732013-09-27 10:50:5457}
58
[email protected]a60326552014-02-19 22:58:2459void WebCryptoImpl::decrypt(const blink::WebCryptoAlgorithm& algorithm,
60 const blink::WebCryptoKey& key,
61 const unsigned char* data,
62 unsigned int data_size,
63 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3464 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:4665 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:0466 Status status = webcrypto::Decrypt(
67 algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
[email protected]edb692e652014-01-31 05:32:5268 if (status.IsError())
[email protected]cca897482014-01-30 22:40:1969 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:5270 else
[email protected]868085a92013-10-01 00:42:3071 result.completeWithBuffer(buffer);
[email protected]868085a92013-10-01 00:42:3072}
73
[email protected]a60326552014-02-19 22:58:2474void WebCryptoImpl::digest(const blink::WebCryptoAlgorithm& algorithm,
75 const unsigned char* data,
76 unsigned int data_size,
77 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3478 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:4679 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:0480 Status status = webcrypto::Digest(
81 algorithm, webcrypto::CryptoData(data, data_size), &buffer);
[email protected]edb692e652014-01-31 05:32:5282 if (status.IsError())
[email protected]cca897482014-01-30 22:40:1983 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:5284 else
[email protected]e5b794b2013-08-30 01:32:5485 result.completeWithBuffer(buffer);
[email protected]408699c2013-07-17 21:23:1686}
87
[email protected]a60326552014-02-19 22:58:2488void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm& algorithm,
89 bool extractable,
90 blink::WebCryptoKeyUsageMask usage_mask,
91 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3492 DCHECK(!algorithm.isNull());
[email protected]043cf1d32013-11-02 13:27:3093 if (IsAlgorithmAsymmetric(algorithm)) {
[email protected]180ef242013-11-07 06:50:4694 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
95 blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
[email protected]04166f82014-02-19 06:11:0496 Status status = webcrypto::GenerateKeyPair(
[email protected]cca897482014-01-30 22:40:1997 algorithm, extractable, usage_mask, &public_key, &private_key);
98 if (status.IsError()) {
99 CompleteWithError(status, &result);
[email protected]043cf1d32013-11-02 13:27:30100 } else {
101 DCHECK(public_key.handle());
102 DCHECK(private_key.handle());
103 DCHECK_EQ(algorithm.id(), public_key.algorithm().id());
104 DCHECK_EQ(algorithm.id(), private_key.algorithm().id());
[email protected]0bfa7722013-12-06 02:55:47105 DCHECK_EQ(true, public_key.extractable());
[email protected]043cf1d32013-11-02 13:27:30106 DCHECK_EQ(extractable, private_key.extractable());
107 DCHECK_EQ(usage_mask, public_key.usages());
108 DCHECK_EQ(usage_mask, private_key.usages());
109 result.completeWithKeyPair(public_key, private_key);
110 }
[email protected]dfae8ab2013-10-10 19:45:06111 } else {
[email protected]180ef242013-11-07 06:50:46112 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
[email protected]04166f82014-02-19 06:11:04113 Status status =
114 webcrypto::GenerateSecretKey(algorithm, extractable, usage_mask, &key);
[email protected]cca897482014-01-30 22:40:19115 if (status.IsError()) {
116 CompleteWithError(status, &result);
[email protected]043cf1d32013-11-02 13:27:30117 } else {
118 DCHECK(key.handle());
119 DCHECK_EQ(algorithm.id(), key.algorithm().id());
120 DCHECK_EQ(extractable, key.extractable());
121 DCHECK_EQ(usage_mask, key.usages());
122 result.completeWithKey(key);
123 }
[email protected]dfae8ab2013-10-10 19:45:06124 }
125}
126
[email protected]1c879bc92013-09-18 07:45:32127void WebCryptoImpl::importKey(
[email protected]180ef242013-11-07 06:50:46128 blink::WebCryptoKeyFormat format,
[email protected]1c879bc92013-09-18 07:45:32129 const unsigned char* key_data,
[email protected]d22eea962014-01-31 10:08:50130 unsigned int key_data_size,
[email protected]180ef242013-11-07 06:50:46131 const blink::WebCryptoAlgorithm& algorithm_or_null,
[email protected]1c879bc92013-09-18 07:45:32132 bool extractable,
[email protected]180ef242013-11-07 06:50:46133 blink::WebCryptoKeyUsageMask usage_mask,
134 blink::WebCryptoResult result) {
135 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
[email protected]04166f82014-02-19 06:11:04136 Status status =
137 webcrypto::ImportKey(format,
138 webcrypto::CryptoData(key_data, key_data_size),
139 algorithm_or_null,
140 extractable,
141 usage_mask,
142 &key);
[email protected]cca897482014-01-30 22:40:19143 if (status.IsError()) {
144 CompleteWithError(status, &result);
145 } else {
146 DCHECK(key.handle());
147 DCHECK(!key.algorithm().isNull());
148 DCHECK_EQ(extractable, key.extractable());
149 result.completeWithKey(key);
150 }
[email protected]1c879bc92013-09-18 07:45:32151}
152
[email protected]a60326552014-02-19 22:58:24153void WebCryptoImpl::exportKey(blink::WebCryptoKeyFormat format,
154 const blink::WebCryptoKey& key,
155 blink::WebCryptoResult result) {
[email protected]e9b2c102013-11-26 04:26:33156 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:04157 Status status = webcrypto::ExportKey(format, key, &buffer);
[email protected]edb692e652014-01-31 05:32:52158 if (status.IsError())
[email protected]cca897482014-01-30 22:40:19159 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:52160 else
[email protected]cca897482014-01-30 22:40:19161 result.completeWithBuffer(buffer);
[email protected]e9b2c102013-11-26 04:26:33162}
163
[email protected]a60326552014-02-19 22:58:24164void WebCryptoImpl::sign(const blink::WebCryptoAlgorithm& algorithm,
165 const blink::WebCryptoKey& key,
166 const unsigned char* data,
167 unsigned int data_size,
168 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34169 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:46170 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:04171 Status status = webcrypto::Sign(
172 algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
[email protected]edb692e652014-01-31 05:32:52173 if (status.IsError())
[email protected]cca897482014-01-30 22:40:19174 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:52175 else
[email protected]1c879bc92013-09-18 07:45:32176 result.completeWithBuffer(buffer);
[email protected]1c879bc92013-09-18 07:45:32177}
178
[email protected]a60326552014-02-19 22:58:24179void WebCryptoImpl::verifySignature(const blink::WebCryptoAlgorithm& algorithm,
180 const blink::WebCryptoKey& key,
181 const unsigned char* signature,
182 unsigned int signature_size,
183 const unsigned char* data,
184 unsigned int data_size,
185 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34186 DCHECK(!algorithm.isNull());
[email protected]3ed00262013-09-26 22:28:10187 bool signature_match = false;
[email protected]04166f82014-02-19 06:11:04188 Status status = webcrypto::VerifySignature(
189 algorithm,
190 key,
191 webcrypto::CryptoData(signature, signature_size),
192 webcrypto::CryptoData(data, data_size),
193 &signature_match);
[email protected]edb692e652014-01-31 05:32:52194 if (status.IsError())
[email protected]cca897482014-01-30 22:40:19195 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:52196 else
[email protected]3ed00262013-09-26 22:28:10197 result.completeWithBoolean(signature_match);
[email protected]3ed00262013-09-26 22:28:10198}
199
[email protected]bd48e6412014-02-22 08:32:53200bool WebCryptoImpl::digestSynchronous(
201 const blink::WebCryptoAlgorithmId algorithm_id,
202 const unsigned char* data,
203 unsigned int data_size,
204 blink::WebArrayBuffer& result) {
205 blink::WebCryptoAlgorithm algorithm =
206 blink::WebCryptoAlgorithm::adoptParamsAndCreate(algorithm_id, NULL);
207 return (webcrypto::Digest(
208 algorithm, webcrypto::CryptoData(data, data_size), &result))
209 .IsSuccess();
210}
211
[email protected]408699c2013-07-17 21:23:16212} // namespace content