blob: 3eddb7f7d6d6b11acc0982f3001b4fd2a785413d [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]408699c2013-07-17 21:23:1612
13namespace content {
14
[email protected]cca897482014-01-30 22:40:1915using webcrypto::Status;
16
[email protected]043cf1d32013-11-02 13:27:3017namespace {
18
[email protected]cca897482014-01-30 22:40:1919void CompleteWithError(const Status& status, blink::WebCryptoResult* result) {
20 DCHECK(status.IsError());
[email protected]116d8bb2014-02-07 08:08:4521 if (status.HasErrorDetails())
22 result->completeWithError(blink::WebString::fromUTF8(status.ToString()));
23 else
24 result->completeWithError();
[email protected]cca897482014-01-30 22:40:1925}
26
[email protected]180ef242013-11-07 06:50:4627bool IsAlgorithmAsymmetric(const blink::WebCryptoAlgorithm& algorithm) {
[email protected]043cf1d32013-11-02 13:27:3028 // TODO(padolph): include all other asymmetric algorithms once they are
29 // defined, e.g. EC and DH.
[email protected]180ef242013-11-07 06:50:4630 return (algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
31 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
32 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep);
[email protected]043cf1d32013-11-02 13:27:3033}
34
35} // namespace
36
[email protected]a60326552014-02-19 22:58:2437WebCryptoImpl::WebCryptoImpl() { webcrypto::Init(); }
[email protected]7e4c36f2013-09-12 06:10:1938
[email protected]04166f82014-02-19 06:11:0439WebCryptoImpl::~WebCryptoImpl() {}
40
[email protected]a60326552014-02-19 22:58:2441void WebCryptoImpl::encrypt(const blink::WebCryptoAlgorithm& algorithm,
42 const blink::WebCryptoKey& key,
43 const unsigned char* data,
44 unsigned int data_size,
45 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3446 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:4647 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:0448 Status status = webcrypto::Encrypt(
49 algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
[email protected]edb692e652014-01-31 05:32:5250 if (status.IsError())
[email protected]cca897482014-01-30 22:40:1951 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:5252 else
[email protected]a2a06c732013-09-27 10:50:5453 result.completeWithBuffer(buffer);
[email protected]a2a06c732013-09-27 10:50:5454}
55
[email protected]a60326552014-02-19 22:58:2456void WebCryptoImpl::decrypt(const blink::WebCryptoAlgorithm& algorithm,
57 const blink::WebCryptoKey& key,
58 const unsigned char* data,
59 unsigned int data_size,
60 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3461 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:4662 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:0463 Status status = webcrypto::Decrypt(
64 algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
[email protected]edb692e652014-01-31 05:32:5265 if (status.IsError())
[email protected]cca897482014-01-30 22:40:1966 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:5267 else
[email protected]868085a92013-10-01 00:42:3068 result.completeWithBuffer(buffer);
[email protected]868085a92013-10-01 00:42:3069}
70
[email protected]a60326552014-02-19 22:58:2471void WebCryptoImpl::digest(const blink::WebCryptoAlgorithm& algorithm,
72 const unsigned char* data,
73 unsigned int data_size,
74 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3475 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:4676 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:0477 Status status = webcrypto::Digest(
78 algorithm, webcrypto::CryptoData(data, data_size), &buffer);
[email protected]edb692e652014-01-31 05:32:5279 if (status.IsError())
[email protected]cca897482014-01-30 22:40:1980 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:5281 else
[email protected]e5b794b2013-08-30 01:32:5482 result.completeWithBuffer(buffer);
[email protected]408699c2013-07-17 21:23:1683}
84
[email protected]a60326552014-02-19 22:58:2485void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm& algorithm,
86 bool extractable,
87 blink::WebCryptoKeyUsageMask usage_mask,
88 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3489 DCHECK(!algorithm.isNull());
[email protected]043cf1d32013-11-02 13:27:3090 if (IsAlgorithmAsymmetric(algorithm)) {
[email protected]180ef242013-11-07 06:50:4691 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
92 blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
[email protected]04166f82014-02-19 06:11:0493 Status status = webcrypto::GenerateKeyPair(
[email protected]cca897482014-01-30 22:40:1994 algorithm, extractable, usage_mask, &public_key, &private_key);
95 if (status.IsError()) {
96 CompleteWithError(status, &result);
[email protected]043cf1d32013-11-02 13:27:3097 } else {
98 DCHECK(public_key.handle());
99 DCHECK(private_key.handle());
100 DCHECK_EQ(algorithm.id(), public_key.algorithm().id());
101 DCHECK_EQ(algorithm.id(), private_key.algorithm().id());
[email protected]0bfa7722013-12-06 02:55:47102 DCHECK_EQ(true, public_key.extractable());
[email protected]043cf1d32013-11-02 13:27:30103 DCHECK_EQ(extractable, private_key.extractable());
104 DCHECK_EQ(usage_mask, public_key.usages());
105 DCHECK_EQ(usage_mask, private_key.usages());
106 result.completeWithKeyPair(public_key, private_key);
107 }
[email protected]dfae8ab2013-10-10 19:45:06108 } else {
[email protected]180ef242013-11-07 06:50:46109 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
[email protected]04166f82014-02-19 06:11:04110 Status status =
111 webcrypto::GenerateSecretKey(algorithm, extractable, usage_mask, &key);
[email protected]cca897482014-01-30 22:40:19112 if (status.IsError()) {
113 CompleteWithError(status, &result);
[email protected]043cf1d32013-11-02 13:27:30114 } else {
115 DCHECK(key.handle());
116 DCHECK_EQ(algorithm.id(), key.algorithm().id());
117 DCHECK_EQ(extractable, key.extractable());
118 DCHECK_EQ(usage_mask, key.usages());
119 result.completeWithKey(key);
120 }
[email protected]dfae8ab2013-10-10 19:45:06121 }
122}
123
[email protected]1c879bc92013-09-18 07:45:32124void WebCryptoImpl::importKey(
[email protected]180ef242013-11-07 06:50:46125 blink::WebCryptoKeyFormat format,
[email protected]1c879bc92013-09-18 07:45:32126 const unsigned char* key_data,
[email protected]d22eea962014-01-31 10:08:50127 unsigned int key_data_size,
[email protected]180ef242013-11-07 06:50:46128 const blink::WebCryptoAlgorithm& algorithm_or_null,
[email protected]1c879bc92013-09-18 07:45:32129 bool extractable,
[email protected]180ef242013-11-07 06:50:46130 blink::WebCryptoKeyUsageMask usage_mask,
131 blink::WebCryptoResult result) {
132 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
[email protected]04166f82014-02-19 06:11:04133 Status status =
134 webcrypto::ImportKey(format,
135 webcrypto::CryptoData(key_data, key_data_size),
136 algorithm_or_null,
137 extractable,
138 usage_mask,
139 &key);
[email protected]cca897482014-01-30 22:40:19140 if (status.IsError()) {
141 CompleteWithError(status, &result);
142 } else {
143 DCHECK(key.handle());
144 DCHECK(!key.algorithm().isNull());
145 DCHECK_EQ(extractable, key.extractable());
146 result.completeWithKey(key);
147 }
[email protected]1c879bc92013-09-18 07:45:32148}
149
[email protected]a60326552014-02-19 22:58:24150void WebCryptoImpl::exportKey(blink::WebCryptoKeyFormat format,
151 const blink::WebCryptoKey& key,
152 blink::WebCryptoResult result) {
[email protected]e9b2c102013-11-26 04:26:33153 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:04154 Status status = webcrypto::ExportKey(format, key, &buffer);
[email protected]edb692e652014-01-31 05:32:52155 if (status.IsError())
[email protected]cca897482014-01-30 22:40:19156 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:52157 else
[email protected]cca897482014-01-30 22:40:19158 result.completeWithBuffer(buffer);
[email protected]e9b2c102013-11-26 04:26:33159}
160
[email protected]a60326552014-02-19 22:58:24161void WebCryptoImpl::sign(const blink::WebCryptoAlgorithm& algorithm,
162 const blink::WebCryptoKey& key,
163 const unsigned char* data,
164 unsigned int data_size,
165 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34166 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:46167 blink::WebArrayBuffer buffer;
[email protected]04166f82014-02-19 06:11:04168 Status status = webcrypto::Sign(
169 algorithm, key, webcrypto::CryptoData(data, data_size), &buffer);
[email protected]edb692e652014-01-31 05:32:52170 if (status.IsError())
[email protected]cca897482014-01-30 22:40:19171 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:52172 else
[email protected]1c879bc92013-09-18 07:45:32173 result.completeWithBuffer(buffer);
[email protected]1c879bc92013-09-18 07:45:32174}
175
[email protected]a60326552014-02-19 22:58:24176void WebCryptoImpl::verifySignature(const blink::WebCryptoAlgorithm& algorithm,
177 const blink::WebCryptoKey& key,
178 const unsigned char* signature,
179 unsigned int signature_size,
180 const unsigned char* data,
181 unsigned int data_size,
182 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34183 DCHECK(!algorithm.isNull());
[email protected]3ed00262013-09-26 22:28:10184 bool signature_match = false;
[email protected]04166f82014-02-19 06:11:04185 Status status = webcrypto::VerifySignature(
186 algorithm,
187 key,
188 webcrypto::CryptoData(signature, signature_size),
189 webcrypto::CryptoData(data, data_size),
190 &signature_match);
[email protected]edb692e652014-01-31 05:32:52191 if (status.IsError())
[email protected]cca897482014-01-30 22:40:19192 CompleteWithError(status, &result);
[email protected]edb692e652014-01-31 05:32:52193 else
[email protected]3ed00262013-09-26 22:28:10194 result.completeWithBoolean(signature_match);
[email protected]3ed00262013-09-26 22:28:10195}
196
[email protected]bd48e6412014-02-22 08:32:53197bool WebCryptoImpl::digestSynchronous(
198 const blink::WebCryptoAlgorithmId algorithm_id,
199 const unsigned char* data,
200 unsigned int data_size,
201 blink::WebArrayBuffer& result) {
202 blink::WebCryptoAlgorithm algorithm =
203 blink::WebCryptoAlgorithm::adoptParamsAndCreate(algorithm_id, NULL);
204 return (webcrypto::Digest(
205 algorithm, webcrypto::CryptoData(data, data_size), &result))
206 .IsSuccess();
207}
208
[email protected]408699c2013-07-17 21:23:16209} // namespace content