blob: 076df0d4a3e14296ef9ca7f06f6207f9d6fffd60 [file] [log] [blame]
[email protected]cf5d32e52014-03-07 18:00:081// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]408699c2013-07-17 21:23:162// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]cf5d32e52014-03-07 18:00:085#include "content/child/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]cf5d32e52014-03-07 18:00:088#include "content/child/webcrypto/crypto_data.h"
9#include "content/child/webcrypto/shared_crypto.h"
[email protected]37be4cfa2014-03-20 05:39:3710#include "content/child/webcrypto/status.h"
[email protected]cf5d32e52014-03-07 18:00:0811#include "content/child/webcrypto/webcrypto_util.h"
[email protected]8238bb1c2014-02-26 15:16:2512#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
[email protected]cf5d32e52014-03-07 18:00:0813#include "third_party/WebKit/public/platform/WebString.h"
[email protected]408699c2013-07-17 21:23:1614
15namespace content {
16
[email protected]cca897482014-01-30 22:40:1917using webcrypto::Status;
18
[email protected]043cf1d32013-11-02 13:27:3019namespace {
20
[email protected]cca897482014-01-30 22:40:1921void CompleteWithError(const Status& status, blink::WebCryptoResult* result) {
22 DCHECK(status.IsError());
[email protected]116d8bb2014-02-07 08:08:4523 if (status.HasErrorDetails())
24 result->completeWithError(blink::WebString::fromUTF8(status.ToString()));
25 else
26 result->completeWithError();
[email protected]cca897482014-01-30 22:40:1927}
28
[email protected]180ef242013-11-07 06:50:4629bool IsAlgorithmAsymmetric(const blink::WebCryptoAlgorithm& algorithm) {
[email protected]043cf1d32013-11-02 13:27:3030 // TODO(padolph): include all other asymmetric algorithms once they are
31 // defined, e.g. EC and DH.
[email protected]180ef242013-11-07 06:50:4632 return (algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
33 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
34 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep);
[email protected]043cf1d32013-11-02 13:27:3035}
36
37} // namespace
38
[email protected]a60326552014-02-19 22:58:2439WebCryptoImpl::WebCryptoImpl() { webcrypto::Init(); }
[email protected]7e4c36f2013-09-12 06:10:1940
[email protected]04166f82014-02-19 06:11:0441WebCryptoImpl::~WebCryptoImpl() {}
42
[email protected]a60326552014-02-19 22:58:2443void WebCryptoImpl::encrypt(const blink::WebCryptoAlgorithm& algorithm,
44 const blink::WebCryptoKey& key,
45 const unsigned char* data,
46 unsigned int data_size,
47 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3448 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:4649 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:0450 Status status = webcrypto::Encrypt(
51 algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
[email protected]edb692e652014-01-31 05:32:5252 if (status.IsError())
[email protected]cca897482014-01-30 22:40:1953 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:5254 else
[email protected]a2a06c732013-09-27 10:50:5455 result.completeWithBuffer(buffer);
[email protected]a2a06c732013-09-27 10:50:5456}
57
[email protected]a60326552014-02-19 22:58:2458void WebCryptoImpl::decrypt(const blink::WebCryptoAlgorithm& algorithm,
59 const blink::WebCryptoKey& key,
60 const unsigned char* data,
61 unsigned int data_size,
62 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3463 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:4664 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:0465 Status status = webcrypto::Decrypt(
66 algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
[email protected]edb692e652014-01-31 05:32:5267 if (status.IsError())
[email protected]cca897482014-01-30 22:40:1968 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:5269 else
[email protected]868085a92013-10-01 00:42:3070 result.completeWithBuffer(buffer);
[email protected]868085a92013-10-01 00:42:3071}
72
[email protected]a60326552014-02-19 22:58:2473void WebCryptoImpl::digest(const blink::WebCryptoAlgorithm& algorithm,
74 const unsigned char* data,
75 unsigned int data_size,
76 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3477 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:4678 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:0479 Status status = webcrypto::Digest(
80 algorithm, webcrypto::CryptoData(data, data_size), &buffer);
[email protected]edb692e652014-01-31 05:32:5281 if (status.IsError())
[email protected]cca897482014-01-30 22:40:1982 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:5283 else
[email protected]e5b794b2013-08-30 01:32:5484 result.completeWithBuffer(buffer);
[email protected]408699c2013-07-17 21:23:1685}
86
[email protected]a60326552014-02-19 22:58:2487void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm& algorithm,
88 bool extractable,
89 blink::WebCryptoKeyUsageMask usage_mask,
90 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3491 DCHECK(!algorithm.isNull());
[email protected]043cf1d32013-11-02 13:27:3092 if (IsAlgorithmAsymmetric(algorithm)) {
[email protected]180ef242013-11-07 06:50:4693 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
94 blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
[email protected]04166f82014-02-19 06:11:0495 Status status = webcrypto::GenerateKeyPair(
[email protected]cca897482014-01-30 22:40:1996 algorithm, extractable, usage_mask, &public_key, &private_key);
97 if (status.IsError()) {
98 CompleteWithError(status, &result);
[email protected]043cf1d32013-11-02 13:27:3099 } else {
100 DCHECK(public_key.handle());
101 DCHECK(private_key.handle());
102 DCHECK_EQ(algorithm.id(), public_key.algorithm().id());
103 DCHECK_EQ(algorithm.id(), private_key.algorithm().id());
[email protected]0bfa7722013-12-06 02:55:47104 DCHECK_EQ(true, public_key.extractable());
[email protected]043cf1d32013-11-02 13:27:30105 DCHECK_EQ(extractable, private_key.extractable());
106 DCHECK_EQ(usage_mask, public_key.usages());
107 DCHECK_EQ(usage_mask, private_key.usages());
108 result.completeWithKeyPair(public_key, private_key);
109 }
[email protected]dfae8ab2013-10-10 19:45:06110 } else {
[email protected]180ef242013-11-07 06:50:46111 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
[email protected]04166f82014-02-19 06:11:04112 Status status =
113 webcrypto::GenerateSecretKey(algorithm, extractable, usage_mask, &key);
[email protected]cca897482014-01-30 22:40:19114 if (status.IsError()) {
115 CompleteWithError(status, &result);
[email protected]043cf1d32013-11-02 13:27:30116 } else {
117 DCHECK(key.handle());
118 DCHECK_EQ(algorithm.id(), key.algorithm().id());
119 DCHECK_EQ(extractable, key.extractable());
120 DCHECK_EQ(usage_mask, key.usages());
121 result.completeWithKey(key);
122 }
[email protected]dfae8ab2013-10-10 19:45:06123 }
124}
125
[email protected]c7a94682014-03-20 22:58:40126void WebCryptoImpl::importKey(blink::WebCryptoKeyFormat format,
127 const unsigned char* key_data,
128 unsigned int key_data_size,
129 const blink::WebCryptoAlgorithm& algorithm,
130 bool extractable,
131 blink::WebCryptoKeyUsageMask usage_mask,
132 blink::WebCryptoResult result) {
[email protected]180ef242013-11-07 06:50:46133 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
[email protected]04166f82014-02-19 06:11:04134 Status status =
135 webcrypto::ImportKey(format,
136 webcrypto::CryptoData(key_data, key_data_size),
[email protected]c7a94682014-03-20 22:58:40137 algorithm,
[email protected]04166f82014-02-19 06:11:04138 extractable,
139 usage_mask,
140 &key);
[email protected]cca897482014-01-30 22:40:19141 if (status.IsError()) {
142 CompleteWithError(status, &result);
143 } else {
144 DCHECK(key.handle());
145 DCHECK(!key.algorithm().isNull());
146 DCHECK_EQ(extractable, key.extractable());
147 result.completeWithKey(key);
148 }
[email protected]1c879bc92013-09-18 07:45:32149}
150
[email protected]a60326552014-02-19 22:58:24151void WebCryptoImpl::exportKey(blink::WebCryptoKeyFormat format,
152 const blink::WebCryptoKey& key,
153 blink::WebCryptoResult result) {
[email protected]e9b2c102013-11-26 04:26:33154 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:04155 Status status = webcrypto::ExportKey(format, key, &buffer);
[email protected]edb692e652014-01-31 05:32:52156 if (status.IsError())
[email protected]cca897482014-01-30 22:40:19157 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:52158 else
[email protected]cca897482014-01-30 22:40:19159 result.completeWithBuffer(buffer);
[email protected]e9b2c102013-11-26 04:26:33160}
161
[email protected]a60326552014-02-19 22:58:24162void WebCryptoImpl::sign(const blink::WebCryptoAlgorithm& algorithm,
163 const blink::WebCryptoKey& key,
164 const unsigned char* data,
165 unsigned int data_size,
166 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34167 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:46168 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:04169 Status status = webcrypto::Sign(
170 algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
[email protected]edb692e652014-01-31 05:32:52171 if (status.IsError())
[email protected]cca897482014-01-30 22:40:19172 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:52173 else
[email protected]1c879bc92013-09-18 07:45:32174 result.completeWithBuffer(buffer);
[email protected]1c879bc92013-09-18 07:45:32175}
176
[email protected]a60326552014-02-19 22:58:24177void WebCryptoImpl::verifySignature(const blink::WebCryptoAlgorithm& algorithm,
178 const blink::WebCryptoKey& key,
179 const unsigned char* signature,
180 unsigned int signature_size,
181 const unsigned char* data,
182 unsigned int data_size,
183 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34184 DCHECK(!algorithm.isNull());
[email protected]3ed00262013-09-26 22:28:10185 bool signature_match = false;
[email protected]04166f82014-02-19 06:11:04186 Status status = webcrypto::VerifySignature(
187 algorithm,
188 key,
189 webcrypto::CryptoData(signature, signature_size),
190 webcrypto::CryptoData(data, data_size),
191 &signature_match);
[email protected]edb692e652014-01-31 05:32:52192 if (status.IsError())
[email protected]cca897482014-01-30 22:40:19193 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:52194 else
[email protected]3ed00262013-09-26 22:28:10195 result.completeWithBoolean(signature_match);
[email protected]3ed00262013-09-26 22:28:10196}
197
[email protected]baa92842014-03-25 01:07:38198void WebCryptoImpl::wrapKey(blink::WebCryptoKeyFormat format,
199 const blink::WebCryptoKey& key,
200 const blink::WebCryptoKey& wrapping_key,
201 const blink::WebCryptoAlgorithm& wrap_algorithm,
202 blink::WebCryptoResult result) {
203 blink::WebArrayBuffer buffer;
204 // TODO(eroman): Use the same parameter ordering.
205 Status status = webcrypto::WrapKey(
206 format, wrapping_key, key, wrap_algorithm, &buffer);
207 if (status.IsError())
208 CompleteWithError(status, &result);
209 else
210 result.completeWithBuffer(buffer);
211}
212
213void WebCryptoImpl::unwrapKey(
214 blink::WebCryptoKeyFormat format,
215 const unsigned char* wrapped_key,
216 unsigned wrapped_key_size,
217 const blink::WebCryptoKey& wrapping_key,
218 const blink::WebCryptoAlgorithm& unwrap_algorithm,
219 const blink::WebCryptoAlgorithm& unwrapped_key_algorithm,
220 bool extractable,
221 blink::WebCryptoKeyUsageMask usages,
222 blink::WebCryptoResult result) {
223 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
224 Status status =
225 webcrypto::UnwrapKey(format,
226 webcrypto::CryptoData(wrapped_key, wrapped_key_size),
227 wrapping_key,
228 unwrap_algorithm,
229 unwrapped_key_algorithm,
230 extractable,
231 usages,
232 &key);
233 if (status.IsError())
234 CompleteWithError(status, &result);
235 else
236 result.completeWithKey(key);
237}
238
[email protected]bd48e6412014-02-22 08:32:53239bool WebCryptoImpl::digestSynchronous(
240 const blink::WebCryptoAlgorithmId algorithm_id,
241 const unsigned char* data,
242 unsigned int data_size,
243 blink::WebArrayBuffer& result) {
244 blink::WebCryptoAlgorithm algorithm =
245 blink::WebCryptoAlgorithm::adoptParamsAndCreate(algorithm_id, NULL);
246 return (webcrypto::Digest(
247 algorithm, webcrypto::CryptoData(data, data_size), &result))
248 .IsSuccess();
249}
250
[email protected]5daca0472014-03-18 20:27:08251bool WebCryptoImpl::deserializeKeyForClone(
252 const blink::WebCryptoKeyAlgorithm& algorithm,
253 blink::WebCryptoKeyType type,
254 bool extractable,
255 blink::WebCryptoKeyUsageMask usages,
256 const unsigned char* key_data,
257 unsigned key_data_size,
258 blink::WebCryptoKey& key) {
259 Status status = webcrypto::DeserializeKeyForClone(
260 algorithm,
261 type,
262 extractable,
263 usages,
264 webcrypto::CryptoData(key_data, key_data_size),
265 &key);
266 return status.IsSuccess();
267}
268
269bool WebCryptoImpl::serializeKeyForClone(
270 const blink::WebCryptoKey& key,
271 blink::WebVector<unsigned char>& key_data) {
272 Status status = webcrypto::SerializeKeyForClone(key, &key_data);
273 return status.IsSuccess();
274}
275
[email protected]408699c2013-07-17 21:23:16276} // namespace content