[email protected] | 408699c | 2013-07-17 21:23:16 | [diff] [blame] | 1 | // 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] | 3da6b21 | 2013-09-27 05:02:36 | [diff] [blame] | 5 | #include "content/renderer/webcrypto/webcrypto_impl.h" |
[email protected] | 408699c | 2013-07-17 21:23:16 | [diff] [blame] | 6 | |
[email protected] | c1b944a | 2013-10-23 06:33:21 | [diff] [blame] | 7 | #include "base/logging.h" |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 8 | #include "content/renderer/webcrypto/crypto_data.h" |
| 9 | #include "content/renderer/webcrypto/shared_crypto.h" |
[email protected] | b28852b | 2013-12-04 04:57:11 | [diff] [blame] | 10 | #include "content/renderer/webcrypto/webcrypto_util.h" |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 11 | #include "third_party/WebKit/public/platform/WebString.h" |
[email protected] | 408699c | 2013-07-17 21:23:16 | [diff] [blame] | 12 | |
| 13 | namespace content { |
| 14 | |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 15 | using webcrypto::Status; |
| 16 | |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 17 | namespace { |
| 18 | |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 19 | void CompleteWithError(const Status& status, blink::WebCryptoResult* result) { |
| 20 | DCHECK(status.IsError()); |
[email protected] | 116d8bb | 2014-02-07 08:08:45 | [diff] [blame] | 21 | if (status.HasErrorDetails()) |
| 22 | result->completeWithError(blink::WebString::fromUTF8(status.ToString())); |
| 23 | else |
| 24 | result->completeWithError(); |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 25 | } |
| 26 | |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 27 | bool IsAlgorithmAsymmetric(const blink::WebCryptoAlgorithm& algorithm) { |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 28 | // TODO(padolph): include all other asymmetric algorithms once they are |
| 29 | // defined, e.g. EC and DH. |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 30 | return (algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || |
| 31 | algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 || |
| 32 | algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep); |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 33 | } |
| 34 | |
| 35 | } // namespace |
| 36 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 37 | WebCryptoImpl::WebCryptoImpl() { webcrypto::Init(); } |
[email protected] | 7e4c36f | 2013-09-12 06:10:19 | [diff] [blame] | 38 | |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 39 | WebCryptoImpl::~WebCryptoImpl() {} |
| 40 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 41 | void 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] | 2213f25 | 2013-10-31 04:33:34 | [diff] [blame] | 46 | DCHECK(!algorithm.isNull()); |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 47 | blink::WebArrayBuffer buffer; |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 48 | Status status = webcrypto::Encrypt( |
| 49 | algorithm, key, webcrypto::CryptoData(data, data_size), &buffer); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 50 | if (status.IsError()) |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 51 | CompleteWithError(status, &result); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 52 | else |
[email protected] | a2a06c73 | 2013-09-27 10:50:54 | [diff] [blame] | 53 | result.completeWithBuffer(buffer); |
[email protected] | a2a06c73 | 2013-09-27 10:50:54 | [diff] [blame] | 54 | } |
| 55 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 56 | void 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] | 2213f25 | 2013-10-31 04:33:34 | [diff] [blame] | 61 | DCHECK(!algorithm.isNull()); |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 62 | blink::WebArrayBuffer buffer; |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 63 | Status status = webcrypto::Decrypt( |
| 64 | algorithm, key, webcrypto::CryptoData(data, data_size), &buffer); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 65 | if (status.IsError()) |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 66 | CompleteWithError(status, &result); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 67 | else |
[email protected] | 868085a9 | 2013-10-01 00:42:30 | [diff] [blame] | 68 | result.completeWithBuffer(buffer); |
[email protected] | 868085a9 | 2013-10-01 00:42:30 | [diff] [blame] | 69 | } |
| 70 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 71 | void WebCryptoImpl::digest(const blink::WebCryptoAlgorithm& algorithm, |
| 72 | const unsigned char* data, |
| 73 | unsigned int data_size, |
| 74 | blink::WebCryptoResult result) { |
[email protected] | 2213f25 | 2013-10-31 04:33:34 | [diff] [blame] | 75 | DCHECK(!algorithm.isNull()); |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 76 | blink::WebArrayBuffer buffer; |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 77 | Status status = webcrypto::Digest( |
| 78 | algorithm, webcrypto::CryptoData(data, data_size), &buffer); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 79 | if (status.IsError()) |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 80 | CompleteWithError(status, &result); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 81 | else |
[email protected] | e5b794b | 2013-08-30 01:32:54 | [diff] [blame] | 82 | result.completeWithBuffer(buffer); |
[email protected] | 408699c | 2013-07-17 21:23:16 | [diff] [blame] | 83 | } |
| 84 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 85 | void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm& algorithm, |
| 86 | bool extractable, |
| 87 | blink::WebCryptoKeyUsageMask usage_mask, |
| 88 | blink::WebCryptoResult result) { |
[email protected] | 2213f25 | 2013-10-31 04:33:34 | [diff] [blame] | 89 | DCHECK(!algorithm.isNull()); |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 90 | if (IsAlgorithmAsymmetric(algorithm)) { |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 91 | blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| 92 | blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 93 | Status status = webcrypto::GenerateKeyPair( |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 94 | algorithm, extractable, usage_mask, &public_key, &private_key); |
| 95 | if (status.IsError()) { |
| 96 | CompleteWithError(status, &result); |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 97 | } 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] | 0bfa772 | 2013-12-06 02:55:47 | [diff] [blame] | 102 | DCHECK_EQ(true, public_key.extractable()); |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 103 | 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] | dfae8ab | 2013-10-10 19:45:06 | [diff] [blame] | 108 | } else { |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 109 | blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 110 | Status status = |
| 111 | webcrypto::GenerateSecretKey(algorithm, extractable, usage_mask, &key); |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 112 | if (status.IsError()) { |
| 113 | CompleteWithError(status, &result); |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 114 | } 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] | dfae8ab | 2013-10-10 19:45:06 | [diff] [blame] | 121 | } |
| 122 | } |
| 123 | |
[email protected] | 1c879bc9 | 2013-09-18 07:45:32 | [diff] [blame] | 124 | void WebCryptoImpl::importKey( |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 125 | blink::WebCryptoKeyFormat format, |
[email protected] | 1c879bc9 | 2013-09-18 07:45:32 | [diff] [blame] | 126 | const unsigned char* key_data, |
[email protected] | d22eea96 | 2014-01-31 10:08:50 | [diff] [blame] | 127 | unsigned int key_data_size, |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 128 | const blink::WebCryptoAlgorithm& algorithm_or_null, |
[email protected] | 1c879bc9 | 2013-09-18 07:45:32 | [diff] [blame] | 129 | bool extractable, |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 130 | blink::WebCryptoKeyUsageMask usage_mask, |
| 131 | blink::WebCryptoResult result) { |
| 132 | blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 133 | 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] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 140 | 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] | 1c879bc9 | 2013-09-18 07:45:32 | [diff] [blame] | 148 | } |
| 149 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 150 | void WebCryptoImpl::exportKey(blink::WebCryptoKeyFormat format, |
| 151 | const blink::WebCryptoKey& key, |
| 152 | blink::WebCryptoResult result) { |
[email protected] | e9b2c10 | 2013-11-26 04:26:33 | [diff] [blame] | 153 | blink::WebArrayBuffer buffer; |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 154 | Status status = webcrypto::ExportKey(format, key, &buffer); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 155 | if (status.IsError()) |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 156 | CompleteWithError(status, &result); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 157 | else |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 158 | result.completeWithBuffer(buffer); |
[email protected] | e9b2c10 | 2013-11-26 04:26:33 | [diff] [blame] | 159 | } |
| 160 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 161 | void 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] | 2213f25 | 2013-10-31 04:33:34 | [diff] [blame] | 166 | DCHECK(!algorithm.isNull()); |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 167 | blink::WebArrayBuffer buffer; |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 168 | Status status = webcrypto::Sign( |
| 169 | algorithm, key, webcrypto::CryptoData(data, data_size), &buffer); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 170 | if (status.IsError()) |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 171 | CompleteWithError(status, &result); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 172 | else |
[email protected] | 1c879bc9 | 2013-09-18 07:45:32 | [diff] [blame] | 173 | result.completeWithBuffer(buffer); |
[email protected] | 1c879bc9 | 2013-09-18 07:45:32 | [diff] [blame] | 174 | } |
| 175 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 176 | void 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] | 2213f25 | 2013-10-31 04:33:34 | [diff] [blame] | 183 | DCHECK(!algorithm.isNull()); |
[email protected] | 3ed0026 | 2013-09-26 22:28:10 | [diff] [blame] | 184 | bool signature_match = false; |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 185 | 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] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 191 | if (status.IsError()) |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 192 | CompleteWithError(status, &result); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 193 | else |
[email protected] | 3ed0026 | 2013-09-26 22:28:10 | [diff] [blame] | 194 | result.completeWithBoolean(signature_match); |
[email protected] | 3ed0026 | 2013-09-26 22:28:10 | [diff] [blame] | 195 | } |
| 196 | |
[email protected] | bd48e641 | 2014-02-22 08:32:53 | [diff] [blame] | 197 | bool 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] | 408699c | 2013-07-17 21:23:16 | [diff] [blame] | 209 | } // namespace content |