| 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 |