[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] | 8238bb1c | 2014-02-26 15:16:25 | [diff] [blame^] | 12 | #ifdef WEBCRYPTO_HAS_KEY_ALGORITHM |
| 13 | #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
| 14 | #endif |
[email protected] | 408699c | 2013-07-17 21:23:16 | [diff] [blame] | 15 | |
| 16 | namespace content { |
| 17 | |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 18 | using webcrypto::Status; |
| 19 | |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 20 | namespace { |
| 21 | |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 22 | void CompleteWithError(const Status& status, blink::WebCryptoResult* result) { |
| 23 | DCHECK(status.IsError()); |
[email protected] | 116d8bb | 2014-02-07 08:08:45 | [diff] [blame] | 24 | if (status.HasErrorDetails()) |
| 25 | result->completeWithError(blink::WebString::fromUTF8(status.ToString())); |
| 26 | else |
| 27 | result->completeWithError(); |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 28 | } |
| 29 | |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 30 | bool IsAlgorithmAsymmetric(const blink::WebCryptoAlgorithm& algorithm) { |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 31 | // TODO(padolph): include all other asymmetric algorithms once they are |
| 32 | // defined, e.g. EC and DH. |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 33 | return (algorithm.id() == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || |
| 34 | algorithm.id() == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 || |
| 35 | algorithm.id() == blink::WebCryptoAlgorithmIdRsaOaep); |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 36 | } |
| 37 | |
| 38 | } // namespace |
| 39 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 40 | WebCryptoImpl::WebCryptoImpl() { webcrypto::Init(); } |
[email protected] | 7e4c36f | 2013-09-12 06:10:19 | [diff] [blame] | 41 | |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 42 | WebCryptoImpl::~WebCryptoImpl() {} |
| 43 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 44 | void 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] | 2213f25 | 2013-10-31 04:33:34 | [diff] [blame] | 49 | DCHECK(!algorithm.isNull()); |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 50 | blink::WebArrayBuffer buffer; |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 51 | Status status = webcrypto::Encrypt( |
| 52 | algorithm, key, webcrypto::CryptoData(data, data_size), &buffer); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 53 | if (status.IsError()) |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 54 | CompleteWithError(status, &result); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 55 | else |
[email protected] | a2a06c73 | 2013-09-27 10:50:54 | [diff] [blame] | 56 | result.completeWithBuffer(buffer); |
[email protected] | a2a06c73 | 2013-09-27 10:50:54 | [diff] [blame] | 57 | } |
| 58 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 59 | void 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] | 2213f25 | 2013-10-31 04:33:34 | [diff] [blame] | 64 | DCHECK(!algorithm.isNull()); |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 65 | blink::WebArrayBuffer buffer; |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 66 | Status status = webcrypto::Decrypt( |
| 67 | algorithm, key, webcrypto::CryptoData(data, data_size), &buffer); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 68 | if (status.IsError()) |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 69 | CompleteWithError(status, &result); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 70 | else |
[email protected] | 868085a9 | 2013-10-01 00:42:30 | [diff] [blame] | 71 | result.completeWithBuffer(buffer); |
[email protected] | 868085a9 | 2013-10-01 00:42:30 | [diff] [blame] | 72 | } |
| 73 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 74 | void WebCryptoImpl::digest(const blink::WebCryptoAlgorithm& algorithm, |
| 75 | const unsigned char* data, |
| 76 | unsigned int data_size, |
| 77 | blink::WebCryptoResult result) { |
[email protected] | 2213f25 | 2013-10-31 04:33:34 | [diff] [blame] | 78 | DCHECK(!algorithm.isNull()); |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 79 | blink::WebArrayBuffer buffer; |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 80 | Status status = webcrypto::Digest( |
| 81 | algorithm, webcrypto::CryptoData(data, data_size), &buffer); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 82 | if (status.IsError()) |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 83 | CompleteWithError(status, &result); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 84 | else |
[email protected] | e5b794b | 2013-08-30 01:32:54 | [diff] [blame] | 85 | result.completeWithBuffer(buffer); |
[email protected] | 408699c | 2013-07-17 21:23:16 | [diff] [blame] | 86 | } |
| 87 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 88 | void WebCryptoImpl::generateKey(const blink::WebCryptoAlgorithm& algorithm, |
| 89 | bool extractable, |
| 90 | blink::WebCryptoKeyUsageMask usage_mask, |
| 91 | blink::WebCryptoResult result) { |
[email protected] | 2213f25 | 2013-10-31 04:33:34 | [diff] [blame] | 92 | DCHECK(!algorithm.isNull()); |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 93 | if (IsAlgorithmAsymmetric(algorithm)) { |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 94 | blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| 95 | blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 96 | Status status = webcrypto::GenerateKeyPair( |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 97 | algorithm, extractable, usage_mask, &public_key, &private_key); |
| 98 | if (status.IsError()) { |
| 99 | CompleteWithError(status, &result); |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 100 | } 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] | 0bfa772 | 2013-12-06 02:55:47 | [diff] [blame] | 105 | DCHECK_EQ(true, public_key.extractable()); |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 106 | 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] | dfae8ab | 2013-10-10 19:45:06 | [diff] [blame] | 111 | } else { |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 112 | blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 113 | Status status = |
| 114 | webcrypto::GenerateSecretKey(algorithm, extractable, usage_mask, &key); |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 115 | if (status.IsError()) { |
| 116 | CompleteWithError(status, &result); |
[email protected] | 043cf1d3 | 2013-11-02 13:27:30 | [diff] [blame] | 117 | } 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] | dfae8ab | 2013-10-10 19:45:06 | [diff] [blame] | 124 | } |
| 125 | } |
| 126 | |
[email protected] | 1c879bc9 | 2013-09-18 07:45:32 | [diff] [blame] | 127 | void WebCryptoImpl::importKey( |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 128 | blink::WebCryptoKeyFormat format, |
[email protected] | 1c879bc9 | 2013-09-18 07:45:32 | [diff] [blame] | 129 | const unsigned char* key_data, |
[email protected] | d22eea96 | 2014-01-31 10:08:50 | [diff] [blame] | 130 | unsigned int key_data_size, |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 131 | const blink::WebCryptoAlgorithm& algorithm_or_null, |
[email protected] | 1c879bc9 | 2013-09-18 07:45:32 | [diff] [blame] | 132 | bool extractable, |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 133 | blink::WebCryptoKeyUsageMask usage_mask, |
| 134 | blink::WebCryptoResult result) { |
| 135 | blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 136 | 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] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 143 | 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] | 1c879bc9 | 2013-09-18 07:45:32 | [diff] [blame] | 151 | } |
| 152 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 153 | void WebCryptoImpl::exportKey(blink::WebCryptoKeyFormat format, |
| 154 | const blink::WebCryptoKey& key, |
| 155 | blink::WebCryptoResult result) { |
[email protected] | e9b2c10 | 2013-11-26 04:26:33 | [diff] [blame] | 156 | blink::WebArrayBuffer buffer; |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 157 | Status status = webcrypto::ExportKey(format, key, &buffer); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 158 | if (status.IsError()) |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 159 | CompleteWithError(status, &result); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 160 | else |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 161 | result.completeWithBuffer(buffer); |
[email protected] | e9b2c10 | 2013-11-26 04:26:33 | [diff] [blame] | 162 | } |
| 163 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 164 | void 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] | 2213f25 | 2013-10-31 04:33:34 | [diff] [blame] | 169 | DCHECK(!algorithm.isNull()); |
[email protected] | 180ef24 | 2013-11-07 06:50:46 | [diff] [blame] | 170 | blink::WebArrayBuffer buffer; |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 171 | Status status = webcrypto::Sign( |
| 172 | algorithm, key, webcrypto::CryptoData(data, data_size), &buffer); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 173 | if (status.IsError()) |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 174 | CompleteWithError(status, &result); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 175 | else |
[email protected] | 1c879bc9 | 2013-09-18 07:45:32 | [diff] [blame] | 176 | result.completeWithBuffer(buffer); |
[email protected] | 1c879bc9 | 2013-09-18 07:45:32 | [diff] [blame] | 177 | } |
| 178 | |
[email protected] | a6032655 | 2014-02-19 22:58:24 | [diff] [blame] | 179 | void 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] | 2213f25 | 2013-10-31 04:33:34 | [diff] [blame] | 186 | DCHECK(!algorithm.isNull()); |
[email protected] | 3ed0026 | 2013-09-26 22:28:10 | [diff] [blame] | 187 | bool signature_match = false; |
[email protected] | 04166f8 | 2014-02-19 06:11:04 | [diff] [blame] | 188 | 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] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 194 | if (status.IsError()) |
[email protected] | cca89748 | 2014-01-30 22:40:19 | [diff] [blame] | 195 | CompleteWithError(status, &result); |
[email protected] | edb692e65 | 2014-01-31 05:32:52 | [diff] [blame] | 196 | else |
[email protected] | 3ed0026 | 2013-09-26 22:28:10 | [diff] [blame] | 197 | result.completeWithBoolean(signature_match); |
[email protected] | 3ed0026 | 2013-09-26 22:28:10 | [diff] [blame] | 198 | } |
| 199 | |
[email protected] | bd48e641 | 2014-02-22 08:32:53 | [diff] [blame] | 200 | bool 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] | 408699c | 2013-07-17 21:23:16 | [diff] [blame] | 212 | } // namespace content |