| 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 13 matching lines...) Expand all Loading... |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "modules/crypto/SubtleCrypto.h" | 31 #include "modules/crypto/SubtleCrypto.h" |
| 32 | 32 |
| 33 #include "bindings/core/v8/Dictionary.h" | 33 #include "bindings/core/v8/Dictionary.h" |
| 34 #include "core/dom/DOMArrayBuffer.h" |
| 35 #include "core/dom/DOMArrayBufferView.h" |
| 36 #include "core/dom/DOMArrayPiece.h" |
| 34 #include "core/dom/ExecutionContext.h" | 37 #include "core/dom/ExecutionContext.h" |
| 35 #include "modules/crypto/CryptoHistograms.h" | 38 #include "modules/crypto/CryptoHistograms.h" |
| 36 #include "modules/crypto/CryptoKey.h" | 39 #include "modules/crypto/CryptoKey.h" |
| 37 #include "modules/crypto/CryptoResultImpl.h" | 40 #include "modules/crypto/CryptoResultImpl.h" |
| 38 #include "modules/crypto/NormalizeAlgorithm.h" | 41 #include "modules/crypto/NormalizeAlgorithm.h" |
| 39 #include "platform/JSONValues.h" | 42 #include "platform/JSONValues.h" |
| 40 #include "public/platform/Platform.h" | 43 #include "public/platform/Platform.h" |
| 41 #include "public/platform/WebCrypto.h" | 44 #include "public/platform/WebCrypto.h" |
| 42 #include "public/platform/WebCryptoAlgorithm.h" | 45 #include "public/platform/WebCryptoAlgorithm.h" |
| 43 | 46 |
| 47 // TODO(eroman): Change the public blink::WebCrypto interface to allow |
| 48 // transferring ownership of data buffers instead of just taking |
| 49 // a raw pointer+length. This will avoid an extra copy. |
| 50 |
| 44 namespace blink { | 51 namespace blink { |
| 45 | 52 |
| 46 static bool parseAlgorithm(const AlgorithmIdentifier& raw, WebCryptoOperation op
, WebCryptoAlgorithm& algorithm, CryptoResult* result) | 53 static bool parseAlgorithm(const AlgorithmIdentifier& raw, WebCryptoOperation op
, WebCryptoAlgorithm& algorithm, CryptoResult* result) |
| 47 { | 54 { |
| 48 AlgorithmError error; | 55 AlgorithmError error; |
| 49 bool success = normalizeAlgorithm(raw, op, algorithm, &error); | 56 bool success = normalizeAlgorithm(raw, op, algorithm, &error); |
| 50 if (!success) | 57 if (!success) |
| 51 result->completeWithError(error.errorType, error.errorDetails); | 58 result->completeWithError(error.errorType, error.errorDetails); |
| 52 return success; | 59 return success; |
| 53 } | 60 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 81 for (unsigned i = 0; i < value.size(); ++i) | 88 for (unsigned i = 0; i < value.size(); ++i) |
| 82 jsonArray->pushString(value[i]); | 89 jsonArray->pushString(value[i]); |
| 83 destination->setArray(property, jsonArray.release()); | 90 destination->setArray(property, jsonArray.release()); |
| 84 return true; | 91 return true; |
| 85 } | 92 } |
| 86 | 93 |
| 87 // FIXME: At the time of writing this is not a part of the spec. It is based an | 94 // FIXME: At the time of writing this is not a part of the spec. It is based an |
| 88 // an unpublished editor's draft for: | 95 // an unpublished editor's draft for: |
| 89 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=24963 | 96 // https://www.w3.org/Bugs/Public/show_bug.cgi?id=24963 |
| 90 // See http://crbug.com/373917. | 97 // See http://crbug.com/373917. |
| 91 static bool copyJwkDictionaryToJson(const Dictionary& dict, CString& jsonUtf8, C
ryptoResult* result) | 98 static bool copyJwkDictionaryToJson(const Dictionary& dict, Vector<uint8_t>& jso
nUtf8, CryptoResult* result) |
| 92 { | 99 { |
| 93 RefPtr<JSONObject> jsonObject = JSONObject::create(); | 100 RefPtr<JSONObject> jsonObject = JSONObject::create(); |
| 94 | 101 |
| 95 if (!copyStringProperty("kty", dict, jsonObject.get())) { | 102 if (!copyStringProperty("kty", dict, jsonObject.get())) { |
| 96 result->completeWithError(WebCryptoErrorTypeData, "The required JWK memb
er \"kty\" was missing"); | 103 result->completeWithError(WebCryptoErrorTypeData, "The required JWK memb
er \"kty\" was missing"); |
| 97 return false; | 104 return false; |
| 98 } | 105 } |
| 99 | 106 |
| 100 copyStringProperty("use", dict, jsonObject.get()); | 107 copyStringProperty("use", dict, jsonObject.get()); |
| 101 copySequenceOfStringProperty("key_ops", dict, jsonObject.get()); | 108 copySequenceOfStringProperty("key_ops", dict, jsonObject.get()); |
| 102 copyStringProperty("alg", dict, jsonObject.get()); | 109 copyStringProperty("alg", dict, jsonObject.get()); |
| 103 | 110 |
| 104 bool ext; | 111 bool ext; |
| 105 if (DictionaryHelper::get(dict, "ext", ext)) | 112 if (DictionaryHelper::get(dict, "ext", ext)) |
| 106 jsonObject->setBoolean("ext", ext); | 113 jsonObject->setBoolean("ext", ext); |
| 107 | 114 |
| 108 const char* const propertyNames[] = { "d", "n", "e", "p", "q", "dp", "dq", "
qi", "k", "crv", "x", "y" }; | 115 const char* const propertyNames[] = { "d", "n", "e", "p", "q", "dp", "dq", "
qi", "k", "crv", "x", "y" }; |
| 109 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(propertyNames); ++i) | 116 for (unsigned i = 0; i < WTF_ARRAY_LENGTH(propertyNames); ++i) |
| 110 copyStringProperty(propertyNames[i], dict, jsonObject.get()); | 117 copyStringProperty(propertyNames[i], dict, jsonObject.get()); |
| 111 | 118 |
| 112 String json = jsonObject->toJSONString(); | 119 String json = jsonObject->toJSONString(); |
| 113 jsonUtf8 = json.utf8(); | 120 jsonUtf8.clear(); |
| 121 jsonUtf8.append(json.utf8().data(), json.utf8().length()); |
| 114 return true; | 122 return true; |
| 115 } | 123 } |
| 116 | 124 |
| 125 static Vector<uint8_t> copyBytes(const DOMArrayPiece& source) |
| 126 { |
| 127 Vector<uint8_t> result; |
| 128 result.append(reinterpret_cast<const uint8_t*>(source.data()), source.byteLe
ngth()); |
| 129 return result; |
| 130 } |
| 131 |
| 117 SubtleCrypto::SubtleCrypto() | 132 SubtleCrypto::SubtleCrypto() |
| 118 { | 133 { |
| 119 } | 134 } |
| 120 | 135 |
| 121 ScriptPromise SubtleCrypto::encrypt(ScriptState* scriptState, const AlgorithmIde
ntifier& rawAlgorithm, CryptoKey* key, const DOMArrayPiece& data) | 136 ScriptPromise SubtleCrypto::encrypt(ScriptState* scriptState, const AlgorithmIde
ntifier& rawAlgorithm, CryptoKey* key, const BufferSource& rawData) |
| 122 { | 137 { |
| 138 // Method described by: https://w3c.github.io/webcrypto/Overview.html#dfn-Su
btleCrypto-method-encrypt |
| 139 |
| 123 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 140 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 124 ScriptPromise promise = result->promise(); | 141 ScriptPromise promise = result->promise(); |
| 125 | 142 |
| 126 if (!canAccessWebCrypto(scriptState, result)) | 143 if (!canAccessWebCrypto(scriptState, result)) |
| 127 return promise; | 144 return promise; |
| 128 | 145 |
| 146 // 14.3.1.2: Let data be the result of getting a copy of the bytes held by |
| 147 // the data parameter passed to the encrypt method. |
| 148 Vector<uint8_t> data = copyBytes(rawData); |
| 149 |
| 129 WebCryptoAlgorithm algorithm; | 150 WebCryptoAlgorithm algorithm; |
| 130 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationEncrypt, algorithm, resu
lt)) | 151 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationEncrypt, algorithm, resu
lt)) |
| 131 return promise; | 152 return promise; |
| 132 | 153 |
| 133 if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageEncrypt, result)
) | 154 if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageEncrypt, result)
) |
| 134 return promise; | 155 return promise; |
| 135 | 156 |
| 136 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key-
>key()); | 157 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key-
>key()); |
| 137 Platform::current()->crypto()->encrypt(algorithm, key->key(), data.bytes(),
data.byteLength(), result->result()); | 158 Platform::current()->crypto()->encrypt(algorithm, key->key(), data.data(), d
ata.size(), result->result()); |
| 138 return promise; | 159 return promise; |
| 139 } | 160 } |
| 140 | 161 |
| 141 ScriptPromise SubtleCrypto::decrypt(ScriptState* scriptState, const AlgorithmIde
ntifier& rawAlgorithm, CryptoKey* key, const DOMArrayPiece& data) | 162 ScriptPromise SubtleCrypto::decrypt(ScriptState* scriptState, const AlgorithmIde
ntifier& rawAlgorithm, CryptoKey* key, const BufferSource& rawData) |
| 142 { | 163 { |
| 164 // Method described by: https://w3c.github.io/webcrypto/Overview.html#dfn-Su
btleCrypto-method-decrypt |
| 165 |
| 143 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 166 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 144 ScriptPromise promise = result->promise(); | 167 ScriptPromise promise = result->promise(); |
| 145 | 168 |
| 146 if (!canAccessWebCrypto(scriptState, result)) | 169 if (!canAccessWebCrypto(scriptState, result)) |
| 147 return promise; | 170 return promise; |
| 148 | 171 |
| 172 // 14.3.2.2: Let data be the result of getting a copy of the bytes held by |
| 173 // the data parameter passed to the decrypt method. |
| 174 Vector<uint8_t> data = copyBytes(rawData); |
| 175 |
| 149 WebCryptoAlgorithm algorithm; | 176 WebCryptoAlgorithm algorithm; |
| 150 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDecrypt, algorithm, resu
lt)) | 177 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDecrypt, algorithm, resu
lt)) |
| 151 return promise; | 178 return promise; |
| 152 | 179 |
| 153 if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageDecrypt, result)
) | 180 if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageDecrypt, result)
) |
| 154 return promise; | 181 return promise; |
| 155 | 182 |
| 156 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key-
>key()); | 183 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key-
>key()); |
| 157 Platform::current()->crypto()->decrypt(algorithm, key->key(), data.bytes(),
data.byteLength(), result->result()); | 184 Platform::current()->crypto()->decrypt(algorithm, key->key(), data.data(), d
ata.size(), result->result()); |
| 158 return promise; | 185 return promise; |
| 159 } | 186 } |
| 160 | 187 |
| 161 ScriptPromise SubtleCrypto::sign(ScriptState* scriptState, const AlgorithmIdenti
fier& rawAlgorithm, CryptoKey* key, const DOMArrayPiece& data) | 188 ScriptPromise SubtleCrypto::sign(ScriptState* scriptState, const AlgorithmIdenti
fier& rawAlgorithm, CryptoKey* key, const BufferSource& rawData) |
| 162 { | 189 { |
| 190 // Method described by: https://w3c.github.io/webcrypto/Overview.html#dfn-Su
btleCrypto-method-sign |
| 191 |
| 163 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 192 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 164 ScriptPromise promise = result->promise(); | 193 ScriptPromise promise = result->promise(); |
| 165 | 194 |
| 166 if (!canAccessWebCrypto(scriptState, result)) | 195 if (!canAccessWebCrypto(scriptState, result)) |
| 167 return promise; | 196 return promise; |
| 168 | 197 |
| 198 // 14.3.3.2: Let data be the result of getting a copy of the bytes held by |
| 199 // the data parameter passed to the sign method. |
| 200 Vector<uint8_t> data = copyBytes(rawData); |
| 201 |
| 169 WebCryptoAlgorithm algorithm; | 202 WebCryptoAlgorithm algorithm; |
| 170 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationSign, algorithm, result)
) | 203 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationSign, algorithm, result)
) |
| 171 return promise; | 204 return promise; |
| 172 | 205 |
| 173 if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageSign, result)) | 206 if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageSign, result)) |
| 174 return promise; | 207 return promise; |
| 175 | 208 |
| 176 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key-
>key()); | 209 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key-
>key()); |
| 177 Platform::current()->crypto()->sign(algorithm, key->key(), data.bytes(), dat
a.byteLength(), result->result()); | 210 Platform::current()->crypto()->sign(algorithm, key->key(), data.data(), data
.size(), result->result()); |
| 178 return promise; | 211 return promise; |
| 179 } | 212 } |
| 180 | 213 |
| 181 ScriptPromise SubtleCrypto::verifySignature(ScriptState* scriptState, const Algo
rithmIdentifier& rawAlgorithm, CryptoKey* key, const DOMArrayPiece& signature, c
onst DOMArrayPiece& data) | 214 ScriptPromise SubtleCrypto::verifySignature(ScriptState* scriptState, const Algo
rithmIdentifier& rawAlgorithm, CryptoKey* key, const BufferSource& rawSignature,
const BufferSource& rawData) |
| 182 { | 215 { |
| 216 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-verify |
| 217 |
| 183 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 218 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 184 ScriptPromise promise = result->promise(); | 219 ScriptPromise promise = result->promise(); |
| 185 | 220 |
| 186 if (!canAccessWebCrypto(scriptState, result)) | 221 if (!canAccessWebCrypto(scriptState, result)) |
| 187 return promise; | 222 return promise; |
| 188 | 223 |
| 224 // 14.3.4.2: Let signature be the result of getting a copy of the bytes |
| 225 // held by the signature parameter passed to the verify method. |
| 226 Vector<uint8_t> signature = copyBytes(rawSignature); |
| 227 |
| 189 WebCryptoAlgorithm algorithm; | 228 WebCryptoAlgorithm algorithm; |
| 190 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationVerify, algorithm, resul
t)) | 229 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationVerify, algorithm, resul
t)) |
| 191 return promise; | 230 return promise; |
| 192 | 231 |
| 232 // 14.3.4.5: Let data be the result of getting a copy of the bytes held by |
| 233 // the data parameter passed to the verify method. |
| 234 Vector<uint8_t> data = copyBytes(rawData); |
| 235 |
| 193 if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageVerify, result)) | 236 if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageVerify, result)) |
| 194 return promise; | 237 return promise; |
| 195 | 238 |
| 196 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key-
>key()); | 239 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key-
>key()); |
| 197 Platform::current()->crypto()->verifySignature(algorithm, key->key(), signat
ure.bytes(), signature.byteLength(), data.bytes(), data.byteLength(), result->re
sult()); | 240 Platform::current()->crypto()->verifySignature(algorithm, key->key(), signat
ure.data(), signature.size(), data.data(), data.size(), result->result()); |
| 198 return promise; | 241 return promise; |
| 199 } | 242 } |
| 200 | 243 |
| 201 ScriptPromise SubtleCrypto::digest(ScriptState* scriptState, const AlgorithmIden
tifier& rawAlgorithm, const DOMArrayPiece& data) | 244 ScriptPromise SubtleCrypto::digest(ScriptState* scriptState, const AlgorithmIden
tifier& rawAlgorithm, const BufferSource& rawData) |
| 202 { | 245 { |
| 246 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-digest |
| 247 |
| 203 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 248 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 204 ScriptPromise promise = result->promise(); | 249 ScriptPromise promise = result->promise(); |
| 205 | 250 |
| 206 if (!canAccessWebCrypto(scriptState, result)) | 251 if (!canAccessWebCrypto(scriptState, result)) |
| 207 return promise; | 252 return promise; |
| 208 | 253 |
| 254 // 14.3.5.2: Let data be the result of getting a copy of the bytes held |
| 255 // by the data parameter passed to the digest method. |
| 256 Vector<uint8_t> data = copyBytes(rawData); |
| 257 |
| 209 WebCryptoAlgorithm algorithm; | 258 WebCryptoAlgorithm algorithm; |
| 210 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDigest, algorithm, resul
t)) | 259 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDigest, algorithm, resul
t)) |
| 211 return promise; | 260 return promise; |
| 212 | 261 |
| 213 histogramAlgorithm(scriptState->getExecutionContext(), algorithm); | 262 histogramAlgorithm(scriptState->getExecutionContext(), algorithm); |
| 214 Platform::current()->crypto()->digest(algorithm, data.bytes(), data.byteLeng
th(), result->result()); | 263 Platform::current()->crypto()->digest(algorithm, data.data(), data.size(), r
esult->result()); |
| 215 return promise; | 264 return promise; |
| 216 } | 265 } |
| 217 | 266 |
| 218 ScriptPromise SubtleCrypto::generateKey(ScriptState* scriptState, const Algorith
mIdentifier& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages) | 267 ScriptPromise SubtleCrypto::generateKey(ScriptState* scriptState, const Algorith
mIdentifier& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages) |
| 219 { | 268 { |
| 220 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 269 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 221 ScriptPromise promise = result->promise(); | 270 ScriptPromise promise = result->promise(); |
| 222 | 271 |
| 223 if (!canAccessWebCrypto(scriptState, result)) | 272 if (!canAccessWebCrypto(scriptState, result)) |
| 224 return promise; | 273 return promise; |
| 225 | 274 |
| 226 WebCryptoKeyUsageMask keyUsages; | 275 WebCryptoKeyUsageMask keyUsages; |
| 227 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) | 276 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) |
| 228 return promise; | 277 return promise; |
| 229 | 278 |
| 230 WebCryptoAlgorithm algorithm; | 279 WebCryptoAlgorithm algorithm; |
| 231 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationGenerateKey, algorithm,
result)) | 280 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationGenerateKey, algorithm,
result)) |
| 232 return promise; | 281 return promise; |
| 233 | 282 |
| 234 histogramAlgorithm(scriptState->getExecutionContext(), algorithm); | 283 histogramAlgorithm(scriptState->getExecutionContext(), algorithm); |
| 235 Platform::current()->crypto()->generateKey(algorithm, extractable, keyUsages
, result->result()); | 284 Platform::current()->crypto()->generateKey(algorithm, extractable, keyUsages
, result->result()); |
| 236 return promise; | 285 return promise; |
| 237 } | 286 } |
| 238 | 287 |
| 239 ScriptPromise SubtleCrypto::importKey(ScriptState* scriptState, const String& ra
wFormat, const ArrayBufferOrArrayBufferViewOrDictionary& keyData, const Algorith
mIdentifier& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages) | 288 ScriptPromise SubtleCrypto::importKey(ScriptState* scriptState, const String& ra
wFormat, const ArrayBufferOrArrayBufferViewOrDictionary& rawKeyData, const Algor
ithmIdentifier& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsag
es) |
| 240 { | 289 { |
| 290 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-importKey |
| 291 |
| 241 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 292 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 242 ScriptPromise promise = result->promise(); | 293 ScriptPromise promise = result->promise(); |
| 243 | 294 |
| 244 if (!canAccessWebCrypto(scriptState, result)) | 295 if (!canAccessWebCrypto(scriptState, result)) |
| 245 return promise; | 296 return promise; |
| 246 | 297 |
| 247 WebCryptoKeyFormat format; | 298 WebCryptoKeyFormat format; |
| 248 if (!CryptoKey::parseFormat(rawFormat, format, result)) | 299 if (!CryptoKey::parseFormat(rawFormat, format, result)) |
| 249 return promise; | 300 return promise; |
| 250 | 301 |
| 251 if (keyData.isDictionary()) { | 302 if (rawKeyData.isDictionary()) { |
| 252 if (format != WebCryptoKeyFormatJwk) { | 303 if (format != WebCryptoKeyFormatJwk) { |
| 253 result->completeWithError(WebCryptoErrorTypeData, "Key data must be
a buffer for non-JWK formats"); | 304 result->completeWithError(WebCryptoErrorTypeData, "Key data must be
a buffer for non-JWK formats"); |
| 254 return promise; | 305 return promise; |
| 255 } | 306 } |
| 256 } else if (format == WebCryptoKeyFormatJwk) { | 307 } else if (format == WebCryptoKeyFormatJwk) { |
| 257 result->completeWithError(WebCryptoErrorTypeData, "Key data must be an o
bject for JWK import"); | 308 result->completeWithError(WebCryptoErrorTypeData, "Key data must be an o
bject for JWK import"); |
| 258 return promise; | 309 return promise; |
| 259 } | 310 } |
| 260 | 311 |
| 261 WebCryptoKeyUsageMask keyUsages; | 312 WebCryptoKeyUsageMask keyUsages; |
| 262 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) | 313 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) |
| 263 return promise; | 314 return promise; |
| 264 | 315 |
| 265 WebCryptoAlgorithm algorithm; | 316 WebCryptoAlgorithm algorithm; |
| 266 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationImportKey, algorithm, re
sult)) | 317 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationImportKey, algorithm, re
sult)) |
| 267 return promise; | 318 return promise; |
| 268 | 319 |
| 269 const unsigned char* ptr = nullptr; | 320 Vector<uint8_t> keyData; |
| 270 unsigned len = 0; | 321 if (rawKeyData.isArrayBuffer()) { |
| 271 | 322 keyData = copyBytes(rawKeyData.getAsArrayBuffer()); |
| 272 CString jsonUtf8; | 323 } else if (rawKeyData.isArrayBufferView()) { |
| 273 if (keyData.isArrayBuffer()) { | 324 keyData = copyBytes(rawKeyData.getAsArrayBufferView()); |
| 274 ptr = static_cast<const unsigned char*>(keyData.getAsArrayBuffer()->data
()); | 325 } else if (rawKeyData.isDictionary()) { |
| 275 len = keyData.getAsArrayBuffer()->byteLength(); | 326 if (!copyJwkDictionaryToJson(rawKeyData.getAsDictionary(), keyData, resu
lt)) |
| 276 } else if (keyData.isArrayBufferView()) { | |
| 277 ptr = static_cast<const unsigned char*>(keyData.getAsArrayBufferView()->
baseAddress()); | |
| 278 len = keyData.getAsArrayBufferView()->byteLength(); | |
| 279 } else if (keyData.isDictionary()) { | |
| 280 if (!copyJwkDictionaryToJson(keyData.getAsDictionary(), jsonUtf8, result
)) | |
| 281 return promise; | 327 return promise; |
| 282 ptr = reinterpret_cast<const unsigned char*>(jsonUtf8.data()); | |
| 283 len = jsonUtf8.length(); | |
| 284 } | 328 } |
| 285 histogramAlgorithm(scriptState->getExecutionContext(), algorithm); | 329 histogramAlgorithm(scriptState->getExecutionContext(), algorithm); |
| 286 Platform::current()->crypto()->importKey(format, ptr, len, algorithm, extrac
table, keyUsages, result->result()); | 330 Platform::current()->crypto()->importKey(format, keyData.data(), keyData.siz
e(), algorithm, extractable, keyUsages, result->result()); |
| 287 return promise; | 331 return promise; |
| 288 } | 332 } |
| 289 | 333 |
| 290 ScriptPromise SubtleCrypto::exportKey(ScriptState* scriptState, const String& ra
wFormat, CryptoKey* key) | 334 ScriptPromise SubtleCrypto::exportKey(ScriptState* scriptState, const String& ra
wFormat, CryptoKey* key) |
| 291 { | 335 { |
| 292 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 336 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 293 ScriptPromise promise = result->promise(); | 337 ScriptPromise promise = result->promise(); |
| 294 | 338 |
| 295 if (!canAccessWebCrypto(scriptState, result)) | 339 if (!canAccessWebCrypto(scriptState, result)) |
| 296 return promise; | 340 return promise; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 | 376 |
| 333 if (!wrappingKey->canBeUsedForAlgorithm(wrapAlgorithm, WebCryptoKeyUsageWrap
Key, result)) | 377 if (!wrappingKey->canBeUsedForAlgorithm(wrapAlgorithm, WebCryptoKeyUsageWrap
Key, result)) |
| 334 return promise; | 378 return promise; |
| 335 | 379 |
| 336 histogramAlgorithmAndKey(scriptState->getExecutionContext(), wrapAlgorithm,
wrappingKey->key()); | 380 histogramAlgorithmAndKey(scriptState->getExecutionContext(), wrapAlgorithm,
wrappingKey->key()); |
| 337 histogramKey(scriptState->getExecutionContext(), key->key()); | 381 histogramKey(scriptState->getExecutionContext(), key->key()); |
| 338 Platform::current()->crypto()->wrapKey(format, key->key(), wrappingKey->key(
), wrapAlgorithm, result->result()); | 382 Platform::current()->crypto()->wrapKey(format, key->key(), wrappingKey->key(
), wrapAlgorithm, result->result()); |
| 339 return promise; | 383 return promise; |
| 340 } | 384 } |
| 341 | 385 |
| 342 ScriptPromise SubtleCrypto::unwrapKey(ScriptState* scriptState, const String& ra
wFormat, const DOMArrayPiece& wrappedKey, CryptoKey* unwrappingKey, const Algori
thmIdentifier& rawUnwrapAlgorithm, const AlgorithmIdentifier& rawUnwrappedKeyAlg
orithm, bool extractable, const Vector<String>& rawKeyUsages) | 386 ScriptPromise SubtleCrypto::unwrapKey(ScriptState* scriptState, const String& ra
wFormat, const BufferSource& rawWrappedKey, CryptoKey* unwrappingKey, const Algo
rithmIdentifier& rawUnwrapAlgorithm, const AlgorithmIdentifier& rawUnwrappedKeyA
lgorithm, bool extractable, const Vector<String>& rawKeyUsages) |
| 343 { | 387 { |
| 388 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-unwrapKey |
| 389 |
| 344 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 390 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 345 ScriptPromise promise = result->promise(); | 391 ScriptPromise promise = result->promise(); |
| 346 | 392 |
| 347 if (!canAccessWebCrypto(scriptState, result)) | 393 if (!canAccessWebCrypto(scriptState, result)) |
| 348 return promise; | 394 return promise; |
| 349 | 395 |
| 350 WebCryptoKeyFormat format; | 396 WebCryptoKeyFormat format; |
| 351 if (!CryptoKey::parseFormat(rawFormat, format, result)) | 397 if (!CryptoKey::parseFormat(rawFormat, format, result)) |
| 352 return promise; | 398 return promise; |
| 353 | 399 |
| 354 WebCryptoKeyUsageMask keyUsages; | 400 WebCryptoKeyUsageMask keyUsages; |
| 355 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) | 401 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) |
| 356 return promise; | 402 return promise; |
| 357 | 403 |
| 404 // 14.3.12.2: Let wrappedKey be the result of getting a copy of the bytes |
| 405 // held by the wrappedKey parameter passed to the unwrapKey |
| 406 // method. |
| 407 Vector<uint8_t> wrappedKey = copyBytes(rawWrappedKey); |
| 408 |
| 358 WebCryptoAlgorithm unwrapAlgorithm; | 409 WebCryptoAlgorithm unwrapAlgorithm; |
| 359 if (!parseAlgorithm(rawUnwrapAlgorithm, WebCryptoOperationUnwrapKey, unwrapA
lgorithm, result)) | 410 if (!parseAlgorithm(rawUnwrapAlgorithm, WebCryptoOperationUnwrapKey, unwrapA
lgorithm, result)) |
| 360 return promise; | 411 return promise; |
| 361 | 412 |
| 362 WebCryptoAlgorithm unwrappedKeyAlgorithm; | 413 WebCryptoAlgorithm unwrappedKeyAlgorithm; |
| 363 if (!parseAlgorithm(rawUnwrappedKeyAlgorithm, WebCryptoOperationImportKey, u
nwrappedKeyAlgorithm, result)) | 414 if (!parseAlgorithm(rawUnwrappedKeyAlgorithm, WebCryptoOperationImportKey, u
nwrappedKeyAlgorithm, result)) |
| 364 return promise; | 415 return promise; |
| 365 | 416 |
| 366 if (!unwrappingKey->canBeUsedForAlgorithm(unwrapAlgorithm, WebCryptoKeyUsage
UnwrapKey, result)) | 417 if (!unwrappingKey->canBeUsedForAlgorithm(unwrapAlgorithm, WebCryptoKeyUsage
UnwrapKey, result)) |
| 367 return promise; | 418 return promise; |
| 368 | 419 |
| 369 histogramAlgorithmAndKey(scriptState->getExecutionContext(), unwrapAlgorithm
, unwrappingKey->key()); | 420 histogramAlgorithmAndKey(scriptState->getExecutionContext(), unwrapAlgorithm
, unwrappingKey->key()); |
| 370 histogramAlgorithm(scriptState->getExecutionContext(), unwrappedKeyAlgorithm
); | 421 histogramAlgorithm(scriptState->getExecutionContext(), unwrappedKeyAlgorithm
); |
| 371 Platform::current()->crypto()->unwrapKey(format, wrappedKey.bytes(), wrapped
Key.byteLength(), unwrappingKey->key(), unwrapAlgorithm, unwrappedKeyAlgorithm,
extractable, keyUsages, result->result()); | 422 Platform::current()->crypto()->unwrapKey(format, wrappedKey.data(), wrappedK
ey.size(), unwrappingKey->key(), unwrapAlgorithm, unwrappedKeyAlgorithm, extract
able, keyUsages, result->result()); |
| 372 return promise; | 423 return promise; |
| 373 } | 424 } |
| 374 | 425 |
| 375 ScriptPromise SubtleCrypto::deriveBits(ScriptState* scriptState, const Algorithm
Identifier& rawAlgorithm, CryptoKey* baseKey, unsigned lengthBits) | 426 ScriptPromise SubtleCrypto::deriveBits(ScriptState* scriptState, const Algorithm
Identifier& rawAlgorithm, CryptoKey* baseKey, unsigned lengthBits) |
| 376 { | 427 { |
| 377 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 428 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 378 ScriptPromise promise = result->promise(); | 429 ScriptPromise promise = result->promise(); |
| 379 | 430 |
| 380 if (!canAccessWebCrypto(scriptState, result)) | 431 if (!canAccessWebCrypto(scriptState, result)) |
| 381 return promise; | 432 return promise; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 if (!parseAlgorithm(rawDerivedKeyType, WebCryptoOperationGetKeyLength, keyLe
ngthAlgorithm, result)) | 470 if (!parseAlgorithm(rawDerivedKeyType, WebCryptoOperationGetKeyLength, keyLe
ngthAlgorithm, result)) |
| 420 return promise; | 471 return promise; |
| 421 | 472 |
| 422 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, base
Key->key()); | 473 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, base
Key->key()); |
| 423 histogramAlgorithm(scriptState->getExecutionContext(), importAlgorithm); | 474 histogramAlgorithm(scriptState->getExecutionContext(), importAlgorithm); |
| 424 Platform::current()->crypto()->deriveKey(algorithm, baseKey->key(), importAl
gorithm, keyLengthAlgorithm, extractable, keyUsages, result->result()); | 475 Platform::current()->crypto()->deriveKey(algorithm, baseKey->key(), importAl
gorithm, keyLengthAlgorithm, extractable, keyUsages, result->result()); |
| 425 return promise; | 476 return promise; |
| 426 } | 477 } |
| 427 | 478 |
| 428 } // namespace blink | 479 } // namespace blink |
| OLD | NEW |