Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: Source/modules/crypto/SubtleCrypto.cpp

Issue 336173002: [webcrypto] Require importKey() for JWK to provide data as a Javascript object rather than a JSON a… (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Update additional tests Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/modules/crypto/SubtleCrypto.h ('k') | Source/modules/crypto/SubtleCrypto.idl » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 18 matching lines...) Expand all
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "modules/crypto/SubtleCrypto.h" 32 #include "modules/crypto/SubtleCrypto.h"
33 33
34 #include "bindings/v8/Dictionary.h" 34 #include "bindings/v8/Dictionary.h"
35 #include "core/dom/ExecutionContext.h" 35 #include "core/dom/ExecutionContext.h"
36 #include "modules/crypto/CryptoResultImpl.h" 36 #include "modules/crypto/CryptoResultImpl.h"
37 #include "modules/crypto/Key.h" 37 #include "modules/crypto/Key.h"
38 #include "modules/crypto/NormalizeAlgorithm.h" 38 #include "modules/crypto/NormalizeAlgorithm.h"
39 #include "platform/JSONValues.h"
39 #include "public/platform/Platform.h" 40 #include "public/platform/Platform.h"
40 #include "public/platform/WebCrypto.h" 41 #include "public/platform/WebCrypto.h"
41 #include "public/platform/WebCryptoAlgorithm.h" 42 #include "public/platform/WebCryptoAlgorithm.h"
42 #include "wtf/ArrayBufferView.h" 43 #include "wtf/ArrayBufferView.h"
43 44
44 namespace WebCore { 45 namespace WebCore {
45 46
46 // Seems like the generated bindings should take care of these however it 47 // Seems like the generated bindings should take care of these however it
47 // currently doesn't. See also http://crbug.com/264520 48 // currently doesn't. See also http://crbug.com/264520
48 static bool ensureNotNull(const ArrayPiece& x, const char* paramName, CryptoResu lt* result) 49 static bool ensureNotNull(const ArrayPiece& x, const char* paramName, CryptoResu lt* result)
49 { 50 {
50 if (x.isNull()) { 51 if (x.isNull()) {
51 String message = String("Invalid ") + paramName + String(" argument"); 52 String message = String("Invalid ") + paramName + String(" argument");
52 result->completeWithError(blink::WebCryptoErrorTypeType, blink::WebStrin g(message)); 53 result->completeWithError(blink::WebCryptoErrorTypeType, blink::WebStrin g(message));
53 return false; 54 return false;
54 } 55 }
55 return true; 56 return true;
56 } 57 }
57 58
58 static bool ensureNotNull(Key* key, const char* paramName, CryptoResult* result) 59 static bool ensureNotNull(Key* key, const char* paramName, CryptoResult* result)
59 { 60 {
60 if (!key) { 61 if (!key) {
61 String message = String("Invalid ") + paramName + String(" argument"); 62 String message = String("Invalid ") + paramName + String(" argument");
62 result->completeWithError(blink::WebCryptoErrorTypeType, blink::WebStrin g(message)); 63 result->completeWithError(blink::WebCryptoErrorTypeType, blink::WebStrin g(message));
63 return false; 64 return false;
64 } 65 }
65 return true; 66 return true;
66 } 67 }
67 68
68 bool parseAlgorithm(const Dictionary& raw, blink::WebCryptoOperation op, blink:: WebCryptoAlgorithm& algorithm, CryptoResult* result) 69 static bool parseAlgorithm(const Dictionary& raw, blink::WebCryptoOperation op, blink::WebCryptoAlgorithm& algorithm, CryptoResult* result)
69 { 70 {
70 AlgorithmError error; 71 AlgorithmError error;
71 bool success = normalizeAlgorithm(raw, op, algorithm, &error); 72 bool success = normalizeAlgorithm(raw, op, algorithm, &error);
72 if (!success) 73 if (!success)
73 result->completeWithError(error.errorType, error.errorDetails); 74 result->completeWithError(error.errorType, error.errorDetails);
74 return success; 75 return success;
75 } 76 }
76 77
77 static bool canAccessWebCrypto(ScriptState* scriptState, CryptoResult* result) 78 static bool canAccessWebCrypto(ScriptState* scriptState, CryptoResult* result)
78 { 79 {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 blink::Platform::current()->crypto()->digest(algorithm, data, dataSize, result->result()); 130 blink::Platform::current()->crypto()->digest(algorithm, data, dataSize, result->result());
130 break; 131 break;
131 default: 132 default:
132 ASSERT_NOT_REACHED(); 133 ASSERT_NOT_REACHED();
133 return ScriptPromise(); 134 return ScriptPromise();
134 } 135 }
135 136
136 return promise; 137 return promise;
137 } 138 }
138 139
140 static bool copyStringProperty(const char* property, const Dictionary& source, J SONObject* destination)
141 {
142 String value;
143 if (!source.get(property, value))
144 return false;
145 destination->setString(property, value);
146 return true;
147 }
148
149 static bool copySequenceOfStringProperty(const char* property, const Dictionary& source, JSONObject* destination)
150 {
151 Vector<String> value;
152 if (!source.get(property, value))
153 return false;
154 RefPtr<JSONArray> jsonArray = JSONArray::create();
155 for (unsigned i = 0; i < value.size(); ++i)
156 jsonArray->pushString(value[i]);
157 destination->setArray(property, jsonArray.release());
158 return true;
159 }
160
161 // FIXME: At the time of writing this is not a part of the spec. It is based an
162 // an unpublished editor's draft for:
163 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=24963
164 // See http://crbug.com/373917.
165 static bool copyJwkDictionaryToJson(const Dictionary& dict, CString& jsonUtf8, C ryptoResult* result)
166 {
167 RefPtr<JSONObject> jsonObject = JSONObject::create();
168
169 if (!copyStringProperty("kty", dict, jsonObject.get())) {
170 result->completeWithError(blink::WebCryptoErrorTypeData, "The required J WK property \"kty\" was missing");
171 return false;
172 }
173
174 copyStringProperty("use", dict, jsonObject.get());
175 copySequenceOfStringProperty("key_ops", dict, jsonObject.get());
176 copyStringProperty("alg", dict, jsonObject.get());
177
178 bool ext;
179 if (dict.get("ext", ext))
180 jsonObject->setBoolean("ext", ext);
181
182 const char* const propertyNames[] = { "d", "n", "e", "p", "q", "dp", "dq", " qi", "k" };
183 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(propertyNames); ++i)
184 copyStringProperty(propertyNames[i], dict, jsonObject.get());
185
186 String json = jsonObject->toJSONString();
187 jsonUtf8 = json.utf8();
188 return true;
189 }
190
139 SubtleCrypto::SubtleCrypto() 191 SubtleCrypto::SubtleCrypto()
140 { 192 {
141 ScriptWrappable::init(this); 193 ScriptWrappable::init(this);
142 } 194 }
143 195
144 ScriptPromise SubtleCrypto::encrypt(ScriptState* scriptState, const Dictionary& rawAlgorithm, Key* key, const ArrayPiece& data) 196 ScriptPromise SubtleCrypto::encrypt(ScriptState* scriptState, const Dictionary& rawAlgorithm, Key* key, const ArrayPiece& data)
145 { 197 {
146 return startCryptoOperation(scriptState, rawAlgorithm, key, blink::WebCrypto OperationEncrypt, ArrayPiece(), data); 198 return startCryptoOperation(scriptState, rawAlgorithm, key, blink::WebCrypto OperationEncrypt, ArrayPiece(), data);
147 } 199 }
148 200
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 if (!canAccessWebCrypto(scriptState, result.get())) 246 if (!canAccessWebCrypto(scriptState, result.get()))
195 return promise; 247 return promise;
196 248
197 if (!ensureNotNull(keyData, "keyData", result.get())) 249 if (!ensureNotNull(keyData, "keyData", result.get()))
198 return promise; 250 return promise;
199 251
200 blink::WebCryptoKeyFormat format; 252 blink::WebCryptoKeyFormat format;
201 if (!Key::parseFormat(rawFormat, format, result.get())) 253 if (!Key::parseFormat(rawFormat, format, result.get()))
202 return promise; 254 return promise;
203 255
256 if (format == blink::WebCryptoKeyFormatJwk) {
257 result->completeWithError(blink::WebCryptoErrorTypeData, "Key data must be an object for JWK import");
258 return promise;
259 }
260
204 blink::WebCryptoKeyUsageMask keyUsages; 261 blink::WebCryptoKeyUsageMask keyUsages;
205 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get())) 262 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get()))
206 return promise; 263 return promise;
207 264
208 blink::WebCryptoAlgorithm algorithm; 265 blink::WebCryptoAlgorithm algorithm;
209 if (!parseAlgorithm(rawAlgorithm, blink::WebCryptoOperationImportKey, algori thm, result.get())) 266 if (!parseAlgorithm(rawAlgorithm, blink::WebCryptoOperationImportKey, algori thm, result.get()))
210 return promise; 267 return promise;
211 268
212 blink::Platform::current()->crypto()->importKey(format, keyData.bytes(), key Data.byteLength(), algorithm, extractable, keyUsages, result->result()); 269 blink::Platform::current()->crypto()->importKey(format, keyData.bytes(), key Data.byteLength(), algorithm, extractable, keyUsages, result->result());
213 return promise; 270 return promise;
214 } 271 }
215 272
273 ScriptPromise SubtleCrypto::importKey(ScriptState* scriptState, const String& ra wFormat, const Dictionary& keyData, const Dictionary& rawAlgorithm, bool extract able, const Vector<String>& rawKeyUsages)
274 {
275 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(scriptState);
276 ScriptPromise promise = result->promise();
277
278 if (!canAccessWebCrypto(scriptState, result.get()))
279 return promise;
280
281 blink::WebCryptoKeyFormat format;
282 if (!Key::parseFormat(rawFormat, format, result.get()))
283 return promise;
284
285 blink::WebCryptoKeyUsageMask keyUsages;
286 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get()))
287 return promise;
288
289 if (format != blink::WebCryptoKeyFormatJwk) {
290 result->completeWithError(blink::WebCryptoErrorTypeData, "Key data must be a buffer for non-JWK formats");
291 return promise;
292 }
293
294 blink::WebCryptoAlgorithm algorithm;
295 if (!parseAlgorithm(rawAlgorithm, blink::WebCryptoOperationImportKey, algori thm, result.get()))
296 return promise;
297
298 CString jsonUtf8;
299 if (!copyJwkDictionaryToJson(keyData, jsonUtf8, result.get()))
300 return promise;
301
302 blink::Platform::current()->crypto()->importKey(format, reinterpret_cast<con st unsigned char*>(jsonUtf8.data()), jsonUtf8.length(), algorithm, extractable, keyUsages, result->result());
303 return promise;
304 }
305
216 ScriptPromise SubtleCrypto::exportKey(ScriptState* scriptState, const String& ra wFormat, Key* key) 306 ScriptPromise SubtleCrypto::exportKey(ScriptState* scriptState, const String& ra wFormat, Key* key)
217 { 307 {
218 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(scriptState); 308 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(scriptState);
219 ScriptPromise promise = result->promise(); 309 ScriptPromise promise = result->promise();
220 310
221 if (!canAccessWebCrypto(scriptState, result.get())) 311 if (!canAccessWebCrypto(scriptState, result.get()))
222 return promise; 312 return promise;
223 313
224 if (!ensureNotNull(key, "key", result.get())) 314 if (!ensureNotNull(key, "key", result.get()))
225 return promise; 315 return promise;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 return promise; 391 return promise;
302 392
303 if (!unwrappingKey->canBeUsedForAlgorithm(unwrapAlgorithm, blink::WebCryptoO perationUnwrapKey, result.get())) 393 if (!unwrappingKey->canBeUsedForAlgorithm(unwrapAlgorithm, blink::WebCryptoO perationUnwrapKey, result.get()))
304 return promise; 394 return promise;
305 395
306 blink::Platform::current()->crypto()->unwrapKey(format, wrappedKey.bytes(), wrappedKey.byteLength(), unwrappingKey->key(), unwrapAlgorithm, unwrappedKeyAlgo rithm, extractable, keyUsages, result->result()); 396 blink::Platform::current()->crypto()->unwrapKey(format, wrappedKey.bytes(), wrappedKey.byteLength(), unwrappingKey->key(), unwrapAlgorithm, unwrappedKeyAlgo rithm, extractable, keyUsages, result->result());
307 return promise; 397 return promise;
308 } 398 }
309 399
310 } // namespace WebCore 400 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/modules/crypto/SubtleCrypto.h ('k') | Source/modules/crypto/SubtleCrypto.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698