Removing uses of X11 native key events.
[chromium-blink-merge.git] / content / child / webcrypto / algorithm_dispatch.cc
blob758f5e9da1bc61f87b8355878858df390c08398c
1 // Copyright 2014 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.
5 #include "content/child/webcrypto/algorithm_dispatch.h"
7 #include "base/logging.h"
8 #include "content/child/webcrypto/algorithm_implementation.h"
9 #include "content/child/webcrypto/algorithm_registry.h"
10 #include "content/child/webcrypto/crypto_data.h"
11 #include "content/child/webcrypto/platform_crypto.h"
12 #include "content/child/webcrypto/status.h"
13 #include "content/child/webcrypto/webcrypto_util.h"
14 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
16 namespace content {
18 namespace webcrypto {
20 namespace {
22 Status DecryptDontCheckKeyUsage(const blink::WebCryptoAlgorithm& algorithm,
23 const blink::WebCryptoKey& key,
24 const CryptoData& data,
25 std::vector<uint8_t>* buffer) {
26 if (algorithm.id() != key.algorithm().id())
27 return Status::ErrorUnexpected();
29 const AlgorithmImplementation* impl = NULL;
30 Status status = GetAlgorithmImplementation(algorithm.id(), &impl);
31 if (status.IsError())
32 return status;
34 return impl->Decrypt(algorithm, key, data, buffer);
37 Status EncryptDontCheckUsage(const blink::WebCryptoAlgorithm& algorithm,
38 const blink::WebCryptoKey& key,
39 const CryptoData& data,
40 std::vector<uint8_t>* buffer) {
41 if (algorithm.id() != key.algorithm().id())
42 return Status::ErrorUnexpected();
44 const AlgorithmImplementation* impl = NULL;
45 Status status = GetAlgorithmImplementation(algorithm.id(), &impl);
46 if (status.IsError())
47 return status;
49 return impl->Encrypt(algorithm, key, data, buffer);
52 Status ExportKeyDontCheckExtractability(blink::WebCryptoKeyFormat format,
53 const blink::WebCryptoKey& key,
54 std::vector<uint8_t>* buffer) {
55 const AlgorithmImplementation* impl = NULL;
56 Status status = GetAlgorithmImplementation(key.algorithm().id(), &impl);
57 if (status.IsError())
58 return status;
60 switch (format) {
61 case blink::WebCryptoKeyFormatRaw:
62 return impl->ExportKeyRaw(key, buffer);
63 case blink::WebCryptoKeyFormatSpki:
64 return impl->ExportKeySpki(key, buffer);
65 case blink::WebCryptoKeyFormatPkcs8:
66 return impl->ExportKeyPkcs8(key, buffer);
67 case blink::WebCryptoKeyFormatJwk:
68 return impl->ExportKeyJwk(key, buffer);
69 default:
70 return Status::ErrorUnsupported();
74 } // namespace
76 Status Encrypt(const blink::WebCryptoAlgorithm& algorithm,
77 const blink::WebCryptoKey& key,
78 const CryptoData& data,
79 std::vector<uint8_t>* buffer) {
80 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageEncrypt))
81 return Status::ErrorUnexpected();
82 return EncryptDontCheckUsage(algorithm, key, data, buffer);
85 Status Decrypt(const blink::WebCryptoAlgorithm& algorithm,
86 const blink::WebCryptoKey& key,
87 const CryptoData& data,
88 std::vector<uint8_t>* buffer) {
89 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageDecrypt))
90 return Status::ErrorUnexpected();
91 return DecryptDontCheckKeyUsage(algorithm, key, data, buffer);
94 Status Digest(const blink::WebCryptoAlgorithm& algorithm,
95 const CryptoData& data,
96 std::vector<uint8_t>* buffer) {
97 const AlgorithmImplementation* impl = NULL;
98 Status status = GetAlgorithmImplementation(algorithm.id(), &impl);
99 if (status.IsError())
100 return status;
102 return impl->Digest(algorithm, data, buffer);
105 Status GenerateSecretKey(const blink::WebCryptoAlgorithm& algorithm,
106 bool extractable,
107 blink::WebCryptoKeyUsageMask usage_mask,
108 blink::WebCryptoKey* key) {
109 const AlgorithmImplementation* impl = NULL;
110 Status status = GetAlgorithmImplementation(algorithm.id(), &impl);
111 if (status.IsError())
112 return status;
114 status = impl->VerifyKeyUsagesBeforeGenerateKey(usage_mask);
115 if (status.IsError())
116 return status;
118 return impl->GenerateSecretKey(algorithm, extractable, usage_mask, key);
121 Status GenerateKeyPair(const blink::WebCryptoAlgorithm& algorithm,
122 bool extractable,
123 blink::WebCryptoKeyUsageMask combined_usage_mask,
124 blink::WebCryptoKey* public_key,
125 blink::WebCryptoKey* private_key) {
126 const AlgorithmImplementation* impl = NULL;
127 Status status = GetAlgorithmImplementation(algorithm.id(), &impl);
128 if (status.IsError())
129 return status;
131 blink::WebCryptoKeyUsageMask public_usage_mask;
132 blink::WebCryptoKeyUsageMask private_usage_mask;
133 status = impl->VerifyKeyUsagesBeforeGenerateKeyPair(
134 combined_usage_mask, &public_usage_mask, &private_usage_mask);
135 if (status.IsError())
136 return status;
138 return impl->GenerateKeyPair(algorithm,
139 extractable,
140 public_usage_mask,
141 private_usage_mask,
142 public_key,
143 private_key);
146 // Note that this function may be called from the target Blink thread.
147 Status ImportKey(blink::WebCryptoKeyFormat format,
148 const CryptoData& key_data,
149 const blink::WebCryptoAlgorithm& algorithm,
150 bool extractable,
151 blink::WebCryptoKeyUsageMask usage_mask,
152 blink::WebCryptoKey* key) {
153 const AlgorithmImplementation* impl = NULL;
154 Status status = GetAlgorithmImplementation(algorithm.id(), &impl);
155 if (status.IsError())
156 return status;
158 status = impl->VerifyKeyUsagesBeforeImportKey(format, usage_mask);
159 if (status.IsError())
160 return status;
162 switch (format) {
163 case blink::WebCryptoKeyFormatRaw:
164 return impl->ImportKeyRaw(
165 key_data, algorithm, extractable, usage_mask, key);
166 case blink::WebCryptoKeyFormatSpki:
167 return impl->ImportKeySpki(
168 key_data, algorithm, extractable, usage_mask, key);
169 case blink::WebCryptoKeyFormatPkcs8:
170 return impl->ImportKeyPkcs8(
171 key_data, algorithm, extractable, usage_mask, key);
172 case blink::WebCryptoKeyFormatJwk:
173 return impl->ImportKeyJwk(
174 key_data, algorithm, extractable, usage_mask, key);
175 default:
176 return Status::ErrorUnsupported();
180 Status ExportKey(blink::WebCryptoKeyFormat format,
181 const blink::WebCryptoKey& key,
182 std::vector<uint8_t>* buffer) {
183 if (!key.extractable())
184 return Status::ErrorKeyNotExtractable();
185 return ExportKeyDontCheckExtractability(format, key, buffer);
188 Status Sign(const blink::WebCryptoAlgorithm& algorithm,
189 const blink::WebCryptoKey& key,
190 const CryptoData& data,
191 std::vector<uint8_t>* buffer) {
192 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageSign))
193 return Status::ErrorUnexpected();
194 if (algorithm.id() != key.algorithm().id())
195 return Status::ErrorUnexpected();
197 const AlgorithmImplementation* impl = NULL;
198 Status status = GetAlgorithmImplementation(algorithm.id(), &impl);
199 if (status.IsError())
200 return status;
202 return impl->Sign(algorithm, key, data, buffer);
205 Status Verify(const blink::WebCryptoAlgorithm& algorithm,
206 const blink::WebCryptoKey& key,
207 const CryptoData& signature,
208 const CryptoData& data,
209 bool* signature_match) {
210 if (!KeyUsageAllows(key, blink::WebCryptoKeyUsageVerify))
211 return Status::ErrorUnexpected();
212 if (algorithm.id() != key.algorithm().id())
213 return Status::ErrorUnexpected();
215 const AlgorithmImplementation* impl = NULL;
216 Status status = GetAlgorithmImplementation(algorithm.id(), &impl);
217 if (status.IsError())
218 return status;
220 return impl->Verify(algorithm, key, signature, data, signature_match);
223 Status WrapKey(blink::WebCryptoKeyFormat format,
224 const blink::WebCryptoKey& key_to_wrap,
225 const blink::WebCryptoKey& wrapping_key,
226 const blink::WebCryptoAlgorithm& wrapping_algorithm,
227 std::vector<uint8_t>* buffer) {
228 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageWrapKey))
229 return Status::ErrorUnexpected();
231 std::vector<uint8_t> exported_data;
232 Status status = ExportKey(format, key_to_wrap, &exported_data);
233 if (status.IsError())
234 return status;
235 return EncryptDontCheckUsage(
236 wrapping_algorithm, wrapping_key, CryptoData(exported_data), buffer);
239 Status UnwrapKey(blink::WebCryptoKeyFormat format,
240 const CryptoData& wrapped_key_data,
241 const blink::WebCryptoKey& wrapping_key,
242 const blink::WebCryptoAlgorithm& wrapping_algorithm,
243 const blink::WebCryptoAlgorithm& algorithm,
244 bool extractable,
245 blink::WebCryptoKeyUsageMask usage_mask,
246 blink::WebCryptoKey* key) {
247 if (!KeyUsageAllows(wrapping_key, blink::WebCryptoKeyUsageUnwrapKey))
248 return Status::ErrorUnexpected();
249 if (wrapping_algorithm.id() != wrapping_key.algorithm().id())
250 return Status::ErrorUnexpected();
252 // Fail fast if the import is doomed to fail.
253 const AlgorithmImplementation* import_impl = NULL;
254 Status status = GetAlgorithmImplementation(algorithm.id(), &import_impl);
255 if (status.IsError())
256 return status;
258 status = import_impl->VerifyKeyUsagesBeforeImportKey(format, usage_mask);
259 if (status.IsError())
260 return status;
262 std::vector<uint8_t> buffer;
263 status = DecryptDontCheckKeyUsage(
264 wrapping_algorithm, wrapping_key, wrapped_key_data, &buffer);
265 if (status.IsError())
266 return status;
268 // NOTE that returning the details of ImportKey() failures may leak
269 // information about the plaintext of the encrypted key (for instance the JWK
270 // key_ops). As long as the ImportKey error messages don't describe actual
271 // key bytes however this should be OK. For more discussion see
272 // http://crubg.com/372040
273 return ImportKey(
274 format, CryptoData(buffer), algorithm, extractable, usage_mask, key);
277 scoped_ptr<blink::WebCryptoDigestor> CreateDigestor(
278 blink::WebCryptoAlgorithmId algorithm) {
279 PlatformInit();
280 return CreatePlatformDigestor(algorithm);
283 } // namespace webcrypto
285 } // namespace content