OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |