blob: 2269030d0a3a3eaf4d1f445a42b8ed909b3f4490 [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]1c879bc92013-09-18 07:45:328#include "base/memory/scoped_ptr.h"
[email protected]e5b794b2013-08-30 01:32:549#include "third_party/WebKit/public/platform/WebArrayBuffer.h"
[email protected]1c879bc92013-09-18 07:45:3210#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h"
11#include "third_party/WebKit/public/platform/WebCryptoKey.h"
[email protected]408699c2013-07-17 21:23:1612
13namespace content {
14
[email protected]043cf1d32013-11-02 13:27:3015namespace {
16
[email protected]180ef242013-11-07 06:50:4617bool IsAlgorithmAsymmetric(const blink::WebCryptoAlgorithm& algorithm) {
[email protected]043cf1d32013-11-02 13:27:3018 // TODO(padolph): include all other asymmetric algorithms once they are
19 // defined, e.g. EC and DH.
[email protected]180ef242013-11-07 06:50:4620 return (algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 ||
21 algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 ||
22 algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep);
[email protected]043cf1d32013-11-02 13:27:3023}
24
25} // namespace
26
[email protected]7e4c36f2013-09-12 06:10:1927WebCryptoImpl::WebCryptoImpl() {
28 Init();
29}
30
[email protected]c1b944a2013-10-23 06:33:2131// static
32// TODO(eroman): This works by re-allocating a new buffer. It would be better if
33// the WebArrayBuffer could just be truncated instead.
34void WebCryptoImpl::ShrinkBuffer(
[email protected]180ef242013-11-07 06:50:4635 blink::WebArrayBuffer* buffer,
[email protected]c1b944a2013-10-23 06:33:2136 unsigned new_size) {
37 DCHECK_LE(new_size, buffer->byteLength());
38
39 if (new_size == buffer->byteLength())
40 return;
41
[email protected]180ef242013-11-07 06:50:4642 blink::WebArrayBuffer new_buffer =
43 blink::WebArrayBuffer::create(new_size, 1);
[email protected]c1b944a2013-10-23 06:33:2144 DCHECK(!new_buffer.isNull());
45 memcpy(new_buffer.data(), buffer->data(), new_size);
46 *buffer = new_buffer;
47}
48
[email protected]a2a06c732013-09-27 10:50:5449void WebCryptoImpl::encrypt(
[email protected]180ef242013-11-07 06:50:4650 const blink::WebCryptoAlgorithm& algorithm,
51 const blink::WebCryptoKey& key,
[email protected]a2a06c732013-09-27 10:50:5452 const unsigned char* data,
53 unsigned data_size,
[email protected]180ef242013-11-07 06:50:4654 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3455 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:4656 blink::WebArrayBuffer buffer;
[email protected]a2a06c732013-09-27 10:50:5457 if (!EncryptInternal(algorithm, key, data, data_size, &buffer)) {
58 result.completeWithError();
59 } else {
60 result.completeWithBuffer(buffer);
61 }
62}
63
[email protected]868085a92013-10-01 00:42:3064void WebCryptoImpl::decrypt(
[email protected]180ef242013-11-07 06:50:4665 const blink::WebCryptoAlgorithm& algorithm,
66 const blink::WebCryptoKey& key,
[email protected]868085a92013-10-01 00:42:3067 const unsigned char* data,
68 unsigned data_size,
[email protected]180ef242013-11-07 06:50:4669 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3470 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:4671 blink::WebArrayBuffer buffer;
[email protected]868085a92013-10-01 00:42:3072 if (!DecryptInternal(algorithm, key, data, data_size, &buffer)) {
73 result.completeWithError();
74 } else {
75 result.completeWithBuffer(buffer);
76 }
77}
78
[email protected]e5b794b2013-08-30 01:32:5479void WebCryptoImpl::digest(
[email protected]180ef242013-11-07 06:50:4680 const blink::WebCryptoAlgorithm& algorithm,
[email protected]e5b794b2013-08-30 01:32:5481 const unsigned char* data,
[email protected]ed80a092013-09-10 16:36:3882 unsigned data_size,
[email protected]180ef242013-11-07 06:50:4683 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3484 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:4685 blink::WebArrayBuffer buffer;
[email protected]ed80a092013-09-10 16:36:3886 if (!DigestInternal(algorithm, data, data_size, &buffer)) {
[email protected]e5b794b2013-08-30 01:32:5487 result.completeWithError();
88 } else {
89 result.completeWithBuffer(buffer);
[email protected]408699c2013-07-17 21:23:1690 }
91}
92
[email protected]dfae8ab2013-10-10 19:45:0693void WebCryptoImpl::generateKey(
[email protected]180ef242013-11-07 06:50:4694 const blink::WebCryptoAlgorithm& algorithm,
[email protected]2213f252013-10-31 04:33:3495 bool extractable,
[email protected]180ef242013-11-07 06:50:4696 blink::WebCryptoKeyUsageMask usage_mask,
97 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:3498 DCHECK(!algorithm.isNull());
[email protected]043cf1d32013-11-02 13:27:3099 if (IsAlgorithmAsymmetric(algorithm)) {
[email protected]180ef242013-11-07 06:50:46100 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
101 blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
[email protected]043cf1d32013-11-02 13:27:30102 if (!GenerateKeyPairInternal(
103 algorithm, extractable, usage_mask, &public_key, &private_key)) {
104 result.completeWithError();
105 } else {
106 DCHECK(public_key.handle());
107 DCHECK(private_key.handle());
108 DCHECK_EQ(algorithm.id(), public_key.algorithm().id());
109 DCHECK_EQ(algorithm.id(), private_key.algorithm().id());
110 // TODO(padolph): The public key should probably always be extractable,
111 // regardless of the input 'extractable' parameter, but that is not called
112 // out in the Web Crypto API spec.
113 // See https://www.w3.org/Bugs/Public/show_bug.cgi?id=23695
114 DCHECK_EQ(extractable, public_key.extractable());
115 DCHECK_EQ(extractable, private_key.extractable());
116 DCHECK_EQ(usage_mask, public_key.usages());
117 DCHECK_EQ(usage_mask, private_key.usages());
118 result.completeWithKeyPair(public_key, private_key);
119 }
[email protected]dfae8ab2013-10-10 19:45:06120 } else {
[email protected]180ef242013-11-07 06:50:46121 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
[email protected]043cf1d32013-11-02 13:27:30122 if (!GenerateKeyInternal(algorithm, extractable, usage_mask, &key)) {
123 result.completeWithError();
124 } else {
125 DCHECK(key.handle());
126 DCHECK_EQ(algorithm.id(), key.algorithm().id());
127 DCHECK_EQ(extractable, key.extractable());
128 DCHECK_EQ(usage_mask, key.usages());
129 result.completeWithKey(key);
130 }
[email protected]dfae8ab2013-10-10 19:45:06131 }
132}
133
[email protected]1c879bc92013-09-18 07:45:32134void WebCryptoImpl::importKey(
[email protected]180ef242013-11-07 06:50:46135 blink::WebCryptoKeyFormat format,
[email protected]1c879bc92013-09-18 07:45:32136 const unsigned char* key_data,
137 unsigned key_data_size,
[email protected]180ef242013-11-07 06:50:46138 const blink::WebCryptoAlgorithm& algorithm_or_null,
[email protected]1c879bc92013-09-18 07:45:32139 bool extractable,
[email protected]180ef242013-11-07 06:50:46140 blink::WebCryptoKeyUsageMask usage_mask,
141 blink::WebCryptoResult result) {
142 blink::WebCryptoKey key = blink::WebCryptoKey::createNull();
[email protected]1c879bc92013-09-18 07:45:32143 if (!ImportKeyInternal(format,
144 key_data,
145 key_data_size,
[email protected]2213f252013-10-31 04:33:34146 algorithm_or_null,
147 extractable,
[email protected]1c879bc92013-09-18 07:45:32148 usage_mask,
[email protected]2213f252013-10-31 04:33:34149 &key)) {
[email protected]1c879bc92013-09-18 07:45:32150 result.completeWithError();
151 return;
152 }
[email protected]2213f252013-10-31 04:33:34153 DCHECK(key.handle());
154 DCHECK(!key.algorithm().isNull());
155 DCHECK_EQ(extractable, key.extractable());
[email protected]1c879bc92013-09-18 07:45:32156 result.completeWithKey(key);
157}
158
159void WebCryptoImpl::sign(
[email protected]180ef242013-11-07 06:50:46160 const blink::WebCryptoAlgorithm& algorithm,
161 const blink::WebCryptoKey& key,
[email protected]1c879bc92013-09-18 07:45:32162 const unsigned char* data,
163 unsigned data_size,
[email protected]180ef242013-11-07 06:50:46164 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34165 DCHECK(!algorithm.isNull());
[email protected]180ef242013-11-07 06:50:46166 blink::WebArrayBuffer buffer;
[email protected]1c879bc92013-09-18 07:45:32167 if (!SignInternal(algorithm, key, data, data_size, &buffer)) {
168 result.completeWithError();
169 } else {
170 result.completeWithBuffer(buffer);
171 }
172}
173
[email protected]3ed00262013-09-26 22:28:10174void WebCryptoImpl::verifySignature(
[email protected]180ef242013-11-07 06:50:46175 const blink::WebCryptoAlgorithm& algorithm,
176 const blink::WebCryptoKey& key,
[email protected]3ed00262013-09-26 22:28:10177 const unsigned char* signature,
178 unsigned signature_size,
179 const unsigned char* data,
180 unsigned data_size,
[email protected]180ef242013-11-07 06:50:46181 blink::WebCryptoResult result) {
[email protected]2213f252013-10-31 04:33:34182 DCHECK(!algorithm.isNull());
[email protected]3ed00262013-09-26 22:28:10183 bool signature_match = false;
184 if (!VerifySignatureInternal(algorithm,
185 key,
186 signature,
187 signature_size,
188 data,
189 data_size,
190 &signature_match)) {
191 result.completeWithError();
192 } else {
193 result.completeWithBoolean(signature_match);
194 }
195}
196
[email protected]408699c2013-07-17 21:23:16197} // namespace content