| 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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 140 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 141 ScriptPromise promise = result->promise(); | 141 ScriptPromise promise = result->promise(); |
| 142 | 142 |
| 143 if (!canAccessWebCrypto(scriptState, result)) | 143 if (!canAccessWebCrypto(scriptState, result)) |
| 144 return promise; | 144 return promise; |
| 145 | 145 |
| 146 // 14.3.1.2: Let data be the result of getting a copy of the bytes held by | 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. | 147 // the data parameter passed to the encrypt method. |
| 148 Vector<uint8_t> data = copyBytes(rawData); | 148 Vector<uint8_t> data = copyBytes(rawData); |
| 149 | 149 |
| 150 WebCryptoAlgorithm algorithm; | 150 // 14.3.1.3: Let normalizedAlgorithm be the result of normalizing an |
| 151 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationEncrypt, algorithm, resu
lt)) | 151 // algorithm, with alg set to algorithm and op set to "encrypt". |
| 152 WebCryptoAlgorithm normalizedAlgorithm; |
| 153 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationEncrypt, normalizedAlgor
ithm, result)) |
| 152 return promise; | 154 return promise; |
| 153 | 155 |
| 154 if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageEncrypt, result)
) | 156 // 14.3.1.8: If the name member of normalizedAlgorithm is not equal to the |
| 157 // name attribute of the [[algorithm]] internal slot of key then |
| 158 // throw an InvalidAccessError. |
| 159 // |
| 160 // 14.3.1.9: If the [[usages]] internal slot of key does not contain an |
| 161 // entry that is "encrypt", then throw an InvalidAccessError. |
| 162 if (!key->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageEncryp
t, result)) |
| 155 return promise; | 163 return promise; |
| 156 | 164 |
| 157 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key-
>key()); | 165 histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgor
ithm, key->key()); |
| 158 Platform::current()->crypto()->encrypt(algorithm, key->key(), data.data(), d
ata.size(), result->result()); | 166 Platform::current()->crypto()->encrypt(normalizedAlgorithm, key->key(), data
.data(), data.size(), result->result()); |
| 159 return promise; | 167 return promise; |
| 160 } | 168 } |
| 161 | 169 |
| 162 ScriptPromise SubtleCrypto::decrypt(ScriptState* scriptState, const AlgorithmIde
ntifier& rawAlgorithm, CryptoKey* key, const BufferSource& rawData) | 170 ScriptPromise SubtleCrypto::decrypt(ScriptState* scriptState, const AlgorithmIde
ntifier& rawAlgorithm, CryptoKey* key, const BufferSource& rawData) |
| 163 { | 171 { |
| 164 // Method described by: https://w3c.github.io/webcrypto/Overview.html#dfn-Su
btleCrypto-method-decrypt | 172 // Method described by: https://w3c.github.io/webcrypto/Overview.html#dfn-Su
btleCrypto-method-decrypt |
| 165 | 173 |
| 166 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 174 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 167 ScriptPromise promise = result->promise(); | 175 ScriptPromise promise = result->promise(); |
| 168 | 176 |
| 169 if (!canAccessWebCrypto(scriptState, result)) | 177 if (!canAccessWebCrypto(scriptState, result)) |
| 170 return promise; | 178 return promise; |
| 171 | 179 |
| 172 // 14.3.2.2: Let data be the result of getting a copy of the bytes held by | 180 // 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. | 181 // the data parameter passed to the decrypt method. |
| 174 Vector<uint8_t> data = copyBytes(rawData); | 182 Vector<uint8_t> data = copyBytes(rawData); |
| 175 | 183 |
| 176 WebCryptoAlgorithm algorithm; | 184 // 14.3.2.3: Let normalizedAlgorithm be the result of normalizing an |
| 177 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDecrypt, algorithm, resu
lt)) | 185 // algorithm, with alg set to algorithm and op set to "decrypt". |
| 186 WebCryptoAlgorithm normalizedAlgorithm; |
| 187 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDecrypt, normalizedAlgor
ithm, result)) |
| 178 return promise; | 188 return promise; |
| 179 | 189 |
| 180 if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageDecrypt, result)
) | 190 // 14.3.2.8: If the name member of normalizedAlgorithm is not equal to the |
| 191 // name attribute of the [[algorithm]] internal slot of key then |
| 192 // throw an InvalidAccessError. |
| 193 // |
| 194 // 14.3.2.9: If the [[usages]] internal slot of key does not contain an |
| 195 // entry that is "decrypt", then throw an InvalidAccessError. |
| 196 if (!key->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageDecryp
t, result)) |
| 181 return promise; | 197 return promise; |
| 182 | 198 |
| 183 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key-
>key()); | 199 histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgor
ithm, key->key()); |
| 184 Platform::current()->crypto()->decrypt(algorithm, key->key(), data.data(), d
ata.size(), result->result()); | 200 Platform::current()->crypto()->decrypt(normalizedAlgorithm, key->key(), data
.data(), data.size(), result->result()); |
| 185 return promise; | 201 return promise; |
| 186 } | 202 } |
| 187 | 203 |
| 188 ScriptPromise SubtleCrypto::sign(ScriptState* scriptState, const AlgorithmIdenti
fier& rawAlgorithm, CryptoKey* key, const BufferSource& rawData) | 204 ScriptPromise SubtleCrypto::sign(ScriptState* scriptState, const AlgorithmIdenti
fier& rawAlgorithm, CryptoKey* key, const BufferSource& rawData) |
| 189 { | 205 { |
| 190 // Method described by: https://w3c.github.io/webcrypto/Overview.html#dfn-Su
btleCrypto-method-sign | 206 // Method described by: https://w3c.github.io/webcrypto/Overview.html#dfn-Su
btleCrypto-method-sign |
| 191 | 207 |
| 192 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 208 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 193 ScriptPromise promise = result->promise(); | 209 ScriptPromise promise = result->promise(); |
| 194 | 210 |
| 195 if (!canAccessWebCrypto(scriptState, result)) | 211 if (!canAccessWebCrypto(scriptState, result)) |
| 196 return promise; | 212 return promise; |
| 197 | 213 |
| 198 // 14.3.3.2: Let data be the result of getting a copy of the bytes held by | 214 // 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. | 215 // the data parameter passed to the sign method. |
| 200 Vector<uint8_t> data = copyBytes(rawData); | 216 Vector<uint8_t> data = copyBytes(rawData); |
| 201 | 217 |
| 202 WebCryptoAlgorithm algorithm; | 218 // 14.3.3.3: Let normalizedAlgorithm be the result of normalizing an |
| 203 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationSign, algorithm, result)
) | 219 // algorithm, with alg set to algorithm and op set to "sign". |
| 220 WebCryptoAlgorithm normalizedAlgorithm; |
| 221 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationSign, normalizedAlgorith
m, result)) |
| 204 return promise; | 222 return promise; |
| 205 | 223 |
| 206 if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageSign, result)) | 224 // 14.3.3.8: If the name member of normalizedAlgorithm is not equal to the |
| 225 // name attribute of the [[algorithm]] internal slot of key then |
| 226 // throw an InvalidAccessError. |
| 227 // |
| 228 // 14.3.3.9: If the [[usages]] internal slot of key does not contain an |
| 229 // entry that is "sign", then throw an InvalidAccessError. |
| 230 if (!key->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageSign,
result)) |
| 207 return promise; | 231 return promise; |
| 208 | 232 |
| 209 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key-
>key()); | 233 histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgor
ithm, key->key()); |
| 210 Platform::current()->crypto()->sign(algorithm, key->key(), data.data(), data
.size(), result->result()); | 234 Platform::current()->crypto()->sign(normalizedAlgorithm, key->key(), data.da
ta(), data.size(), result->result()); |
| 211 return promise; | 235 return promise; |
| 212 } | 236 } |
| 213 | 237 |
| 214 ScriptPromise SubtleCrypto::verifySignature(ScriptState* scriptState, const Algo
rithmIdentifier& rawAlgorithm, CryptoKey* key, const BufferSource& rawSignature,
const BufferSource& rawData) | 238 ScriptPromise SubtleCrypto::verifySignature(ScriptState* scriptState, const Algo
rithmIdentifier& rawAlgorithm, CryptoKey* key, const BufferSource& rawSignature,
const BufferSource& rawData) |
| 215 { | 239 { |
| 216 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-verify | 240 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-verify |
| 217 | 241 |
| 218 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 242 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 219 ScriptPromise promise = result->promise(); | 243 ScriptPromise promise = result->promise(); |
| 220 | 244 |
| 221 if (!canAccessWebCrypto(scriptState, result)) | 245 if (!canAccessWebCrypto(scriptState, result)) |
| 222 return promise; | 246 return promise; |
| 223 | 247 |
| 224 // 14.3.4.2: Let signature be the result of getting a copy of the bytes | 248 // 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. | 249 // held by the signature parameter passed to the verify method. |
| 226 Vector<uint8_t> signature = copyBytes(rawSignature); | 250 Vector<uint8_t> signature = copyBytes(rawSignature); |
| 227 | 251 |
| 228 WebCryptoAlgorithm algorithm; | 252 // 14.3.4.3: Let normalizedAlgorithm be the result of normalizing an |
| 229 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationVerify, algorithm, resul
t)) | 253 // algorithm, with alg set to algorithm and op set to "verify". |
| 254 WebCryptoAlgorithm normalizedAlgorithm; |
| 255 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationVerify, normalizedAlgori
thm, result)) |
| 230 return promise; | 256 return promise; |
| 231 | 257 |
| 232 // 14.3.4.5: Let data be the result of getting a copy of the bytes held by | 258 // 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. | 259 // the data parameter passed to the verify method. |
| 234 Vector<uint8_t> data = copyBytes(rawData); | 260 Vector<uint8_t> data = copyBytes(rawData); |
| 235 | 261 |
| 236 if (!key->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageVerify, result)) | 262 // 14.3.4.9: If the name member of normalizedAlgorithm is not equal to the |
| 263 // name attribute of the [[algorithm]] internal slot of key then t
hrow an |
| 264 // InvalidAccessError. |
| 265 // |
| 266 // 14.3.4.10: If the [[usages]] internal slot of key does not contain an |
| 267 // entry that is "verify", then throw an InvalidAccessError. |
| 268 if (!key->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageVerify
, result)) |
| 237 return promise; | 269 return promise; |
| 238 | 270 |
| 239 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, key-
>key()); | 271 histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgor
ithm, key->key()); |
| 240 Platform::current()->crypto()->verifySignature(algorithm, key->key(), signat
ure.data(), signature.size(), data.data(), data.size(), result->result()); | 272 Platform::current()->crypto()->verifySignature(normalizedAlgorithm, key->key
(), signature.data(), signature.size(), data.data(), data.size(), result->result
()); |
| 241 return promise; | 273 return promise; |
| 242 } | 274 } |
| 243 | 275 |
| 244 ScriptPromise SubtleCrypto::digest(ScriptState* scriptState, const AlgorithmIden
tifier& rawAlgorithm, const BufferSource& rawData) | 276 ScriptPromise SubtleCrypto::digest(ScriptState* scriptState, const AlgorithmIden
tifier& rawAlgorithm, const BufferSource& rawData) |
| 245 { | 277 { |
| 246 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-digest | 278 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-digest |
| 247 | 279 |
| 248 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 280 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 249 ScriptPromise promise = result->promise(); | 281 ScriptPromise promise = result->promise(); |
| 250 | 282 |
| 251 if (!canAccessWebCrypto(scriptState, result)) | 283 if (!canAccessWebCrypto(scriptState, result)) |
| 252 return promise; | 284 return promise; |
| 253 | 285 |
| 254 // 14.3.5.2: Let data be the result of getting a copy of the bytes held | 286 // 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. | 287 // by the data parameter passed to the digest method. |
| 256 Vector<uint8_t> data = copyBytes(rawData); | 288 Vector<uint8_t> data = copyBytes(rawData); |
| 257 | 289 |
| 258 WebCryptoAlgorithm algorithm; | 290 // 14.3.5.3: Let normalizedAlgorithm be the result of normalizing an |
| 259 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDigest, algorithm, resul
t)) | 291 // algorithm, with alg set to algorithm and op set to "digest". |
| 292 WebCryptoAlgorithm normalizedAlgorithm; |
| 293 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDigest, normalizedAlgori
thm, result)) |
| 260 return promise; | 294 return promise; |
| 261 | 295 |
| 262 histogramAlgorithm(scriptState->getExecutionContext(), algorithm); | 296 histogramAlgorithm(scriptState->getExecutionContext(), normalizedAlgorithm); |
| 263 Platform::current()->crypto()->digest(algorithm, data.data(), data.size(), r
esult->result()); | 297 Platform::current()->crypto()->digest(normalizedAlgorithm, data.data(), data
.size(), result->result()); |
| 264 return promise; | 298 return promise; |
| 265 } | 299 } |
| 266 | 300 |
| 267 ScriptPromise SubtleCrypto::generateKey(ScriptState* scriptState, const Algorith
mIdentifier& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages) | 301 ScriptPromise SubtleCrypto::generateKey(ScriptState* scriptState, const Algorith
mIdentifier& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages) |
| 268 { | 302 { |
| 303 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-generateKey |
| 304 |
| 269 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 305 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 270 ScriptPromise promise = result->promise(); | 306 ScriptPromise promise = result->promise(); |
| 271 | 307 |
| 272 if (!canAccessWebCrypto(scriptState, result)) | 308 if (!canAccessWebCrypto(scriptState, result)) |
| 273 return promise; | 309 return promise; |
| 274 | 310 |
| 275 WebCryptoKeyUsageMask keyUsages; | 311 WebCryptoKeyUsageMask keyUsages; |
| 276 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) | 312 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) |
| 277 return promise; | 313 return promise; |
| 278 | 314 |
| 279 WebCryptoAlgorithm algorithm; | 315 // 14.3.6.2: Let normalizedAlgorithm be the result of normalizing an |
| 280 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationGenerateKey, algorithm,
result)) | 316 // algorithm, with alg set to algorithm and op set to |
| 317 // "generateKey". |
| 318 WebCryptoAlgorithm normalizedAlgorithm; |
| 319 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationGenerateKey, normalizedA
lgorithm, result)) |
| 281 return promise; | 320 return promise; |
| 282 | 321 |
| 283 histogramAlgorithm(scriptState->getExecutionContext(), algorithm); | 322 // NOTE: Steps (8) and (9) disallow empty usages on secret and private |
| 284 Platform::current()->crypto()->generateKey(algorithm, extractable, keyUsages
, result->result()); | 323 // keys. This normative requirement is enforced by the platform |
| 324 // implementation in the call below. |
| 325 |
| 326 histogramAlgorithm(scriptState->getExecutionContext(), normalizedAlgorithm); |
| 327 Platform::current()->crypto()->generateKey(normalizedAlgorithm, extractable,
keyUsages, result->result()); |
| 285 return promise; | 328 return promise; |
| 286 } | 329 } |
| 287 | 330 |
| 288 ScriptPromise SubtleCrypto::importKey(ScriptState* scriptState, const String& ra
wFormat, const ArrayBufferOrArrayBufferViewOrDictionary& rawKeyData, const Algor
ithmIdentifier& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsag
es) | 331 ScriptPromise SubtleCrypto::importKey(ScriptState* scriptState, const String& ra
wFormat, const ArrayBufferOrArrayBufferViewOrDictionary& rawKeyData, const Algor
ithmIdentifier& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsag
es) |
| 289 { | 332 { |
| 290 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-importKey | 333 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-importKey |
| 291 | 334 |
| 292 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 335 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 293 ScriptPromise promise = result->promise(); | 336 ScriptPromise promise = result->promise(); |
| 294 | 337 |
| 295 if (!canAccessWebCrypto(scriptState, result)) | 338 if (!canAccessWebCrypto(scriptState, result)) |
| 296 return promise; | 339 return promise; |
| 297 | 340 |
| 298 WebCryptoKeyFormat format; | 341 WebCryptoKeyFormat format; |
| 299 if (!CryptoKey::parseFormat(rawFormat, format, result)) | 342 if (!CryptoKey::parseFormat(rawFormat, format, result)) |
| 300 return promise; | 343 return promise; |
| 301 | 344 |
| 302 if (rawKeyData.isDictionary()) { | |
| 303 if (format != WebCryptoKeyFormatJwk) { | |
| 304 result->completeWithError(WebCryptoErrorTypeData, "Key data must be
a buffer for non-JWK formats"); | |
| 305 return promise; | |
| 306 } | |
| 307 } else if (format == WebCryptoKeyFormatJwk) { | |
| 308 result->completeWithError(WebCryptoErrorTypeData, "Key data must be an o
bject for JWK import"); | |
| 309 return promise; | |
| 310 } | |
| 311 | |
| 312 WebCryptoKeyUsageMask keyUsages; | 345 WebCryptoKeyUsageMask keyUsages; |
| 313 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) | 346 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) |
| 314 return promise; | 347 return promise; |
| 315 | 348 |
| 316 WebCryptoAlgorithm algorithm; | 349 // 14.3.9.2: Let normalizedAlgorithm be the result of normalizing an |
| 317 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationImportKey, algorithm, re
sult)) | 350 // algorithm, with alg set to algorithm and op set to |
| 351 // "importKey". |
| 352 WebCryptoAlgorithm normalizedAlgorithm; |
| 353 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationImportKey, normalizedAlg
orithm, result)) |
| 318 return promise; | 354 return promise; |
| 319 | 355 |
| 356 // TODO(eroman): Match the procedure given in the spec to more |
| 357 // easily provide a normative reference. |
| 358 if (rawKeyData.isDictionary()) { |
| 359 if (format != WebCryptoKeyFormatJwk) { |
| 360 result->completeWithError(WebCryptoErrorTypeType, "Key data must be
a buffer for non-JWK formats"); |
| 361 return promise; |
| 362 } |
| 363 } else if (format == WebCryptoKeyFormatJwk) { |
| 364 result->completeWithError(WebCryptoErrorTypeType, "Key data must be an o
bject for JWK import"); |
| 365 return promise; |
| 366 } |
| 367 |
| 320 Vector<uint8_t> keyData; | 368 Vector<uint8_t> keyData; |
| 369 |
| 370 // TODO(eroman): Match the procedure given in the spec to more |
| 371 // easily provide a normative reference. |
| 321 if (rawKeyData.isArrayBuffer()) { | 372 if (rawKeyData.isArrayBuffer()) { |
| 322 keyData = copyBytes(rawKeyData.getAsArrayBuffer()); | 373 keyData = copyBytes(rawKeyData.getAsArrayBuffer()); |
| 323 } else if (rawKeyData.isArrayBufferView()) { | 374 } else if (rawKeyData.isArrayBufferView()) { |
| 324 keyData = copyBytes(rawKeyData.getAsArrayBufferView()); | 375 keyData = copyBytes(rawKeyData.getAsArrayBufferView()); |
| 325 } else if (rawKeyData.isDictionary()) { | 376 } else if (rawKeyData.isDictionary()) { |
| 326 if (!copyJwkDictionaryToJson(rawKeyData.getAsDictionary(), keyData, resu
lt)) | 377 if (!copyJwkDictionaryToJson(rawKeyData.getAsDictionary(), keyData, resu
lt)) |
| 327 return promise; | 378 return promise; |
| 328 } | 379 } |
| 329 histogramAlgorithm(scriptState->getExecutionContext(), algorithm); | 380 histogramAlgorithm(scriptState->getExecutionContext(), normalizedAlgorithm); |
| 330 Platform::current()->crypto()->importKey(format, keyData.data(), keyData.siz
e(), algorithm, extractable, keyUsages, result->result()); | 381 Platform::current()->crypto()->importKey(format, keyData.data(), keyData.siz
e(), normalizedAlgorithm, extractable, keyUsages, result->result()); |
| 331 return promise; | 382 return promise; |
| 332 } | 383 } |
| 333 | 384 |
| 334 ScriptPromise SubtleCrypto::exportKey(ScriptState* scriptState, const String& ra
wFormat, CryptoKey* key) | 385 ScriptPromise SubtleCrypto::exportKey(ScriptState* scriptState, const String& ra
wFormat, CryptoKey* key) |
| 335 { | 386 { |
| 387 // Method described by: https://w3c.github.io/webcrypto/Overview.html#dfn-Su
btleCrypto-method-exportKey |
| 388 |
| 336 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 389 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 337 ScriptPromise promise = result->promise(); | 390 ScriptPromise promise = result->promise(); |
| 338 | 391 |
| 339 if (!canAccessWebCrypto(scriptState, result)) | 392 if (!canAccessWebCrypto(scriptState, result)) |
| 340 return promise; | 393 return promise; |
| 341 | 394 |
| 342 WebCryptoKeyFormat format; | 395 WebCryptoKeyFormat format; |
| 343 if (!CryptoKey::parseFormat(rawFormat, format, result)) | 396 if (!CryptoKey::parseFormat(rawFormat, format, result)) |
| 344 return promise; | 397 return promise; |
| 345 | 398 |
| 399 // 14.3.10.6: If the [[extractable]] internal slot of key is false, then |
| 400 // throw an InvalidAccessError. |
| 346 if (!key->extractable()) { | 401 if (!key->extractable()) { |
| 347 result->completeWithError(WebCryptoErrorTypeInvalidAccess, "key is not e
xtractable"); | 402 result->completeWithError(WebCryptoErrorTypeInvalidAccess, "key is not e
xtractable"); |
| 348 return promise; | 403 return promise; |
| 349 } | 404 } |
| 350 | 405 |
| 351 histogramKey(scriptState->getExecutionContext(), key->key()); | 406 histogramKey(scriptState->getExecutionContext(), key->key()); |
| 352 Platform::current()->crypto()->exportKey(format, key->key(), result->result(
)); | 407 Platform::current()->crypto()->exportKey(format, key->key(), result->result(
)); |
| 353 return promise; | 408 return promise; |
| 354 } | 409 } |
| 355 | 410 |
| 356 ScriptPromise SubtleCrypto::wrapKey(ScriptState* scriptState, const String& rawF
ormat, CryptoKey* key, CryptoKey* wrappingKey, const AlgorithmIdentifier& rawWra
pAlgorithm) | 411 ScriptPromise SubtleCrypto::wrapKey(ScriptState* scriptState, const String& rawF
ormat, CryptoKey* key, CryptoKey* wrappingKey, const AlgorithmIdentifier& rawWra
pAlgorithm) |
| 357 { | 412 { |
| 413 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-wrapKey |
| 414 |
| 358 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 415 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 359 ScriptPromise promise = result->promise(); | 416 ScriptPromise promise = result->promise(); |
| 360 | 417 |
| 361 if (!canAccessWebCrypto(scriptState, result)) | 418 if (!canAccessWebCrypto(scriptState, result)) |
| 362 return promise; | 419 return promise; |
| 363 | 420 |
| 364 WebCryptoKeyFormat format; | 421 WebCryptoKeyFormat format; |
| 365 if (!CryptoKey::parseFormat(rawFormat, format, result)) | 422 if (!CryptoKey::parseFormat(rawFormat, format, result)) |
| 366 return promise; | 423 return promise; |
| 367 | 424 |
| 368 WebCryptoAlgorithm wrapAlgorithm; | 425 // 14.3.11.2: Let normalizedAlgorithm be the result of normalizing an |
| 369 if (!parseAlgorithm(rawWrapAlgorithm, WebCryptoOperationWrapKey, wrapAlgorit
hm, result)) | 426 // algorithm, with alg set to algorithm and op set to "wrapKey". |
| 427 // |
| 428 // 14.3.11.3: If an error occurred, let normalizedAlgorithm be the result |
| 429 // of normalizing an algorithm, with alg set to algorithm and op |
| 430 // set to "encrypt". |
| 431 WebCryptoAlgorithm normalizedAlgorithm; |
| 432 if (!parseAlgorithm(rawWrapAlgorithm, WebCryptoOperationWrapKey, normalizedA
lgorithm, result)) |
| 370 return promise; | 433 return promise; |
| 371 | 434 |
| 435 // 14.3.11.9: If the name member of normalizedAlgorithm is not equal to the |
| 436 // name attribute of the [[algorithm]] internal slot of |
| 437 // wrappingKey then throw an InvalidAccessError. |
| 438 // |
| 439 // 14.3.11.10: If the [[usages]] internal slot of wrappingKey does not |
| 440 // contain an entry that is "wrapKey", then throw an |
| 441 // InvalidAccessError. |
| 442 if (!wrappingKey->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsa
geWrapKey, result)) |
| 443 return promise; |
| 444 |
| 445 // TODO(crbug.com/628416): The error from step 11 |
| 446 // (NotSupportedError) is thrown after step 12 which does not match |
| 447 // the spec order. |
| 448 |
| 449 // 14.3.11.12: If the [[extractable]] internal slot of key is false, then |
| 450 // throw an InvalidAccessError. |
| 372 if (!key->extractable()) { | 451 if (!key->extractable()) { |
| 373 result->completeWithError(WebCryptoErrorTypeInvalidAccess, "key is not e
xtractable"); | 452 result->completeWithError(WebCryptoErrorTypeInvalidAccess, "key is not e
xtractable"); |
| 374 return promise; | 453 return promise; |
| 375 } | 454 } |
| 376 | 455 |
| 377 if (!wrappingKey->canBeUsedForAlgorithm(wrapAlgorithm, WebCryptoKeyUsageWrap
Key, result)) | 456 histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgor
ithm, wrappingKey->key()); |
| 378 return promise; | |
| 379 | |
| 380 histogramAlgorithmAndKey(scriptState->getExecutionContext(), wrapAlgorithm,
wrappingKey->key()); | |
| 381 histogramKey(scriptState->getExecutionContext(), key->key()); | 457 histogramKey(scriptState->getExecutionContext(), key->key()); |
| 382 Platform::current()->crypto()->wrapKey(format, key->key(), wrappingKey->key(
), wrapAlgorithm, result->result()); | 458 Platform::current()->crypto()->wrapKey(format, key->key(), wrappingKey->key(
), normalizedAlgorithm, result->result()); |
| 383 return promise; | 459 return promise; |
| 384 } | 460 } |
| 385 | 461 |
| 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) | 462 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) |
| 387 { | 463 { |
| 388 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-unwrapKey | 464 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-unwrapKey |
| 389 | 465 |
| 390 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 466 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 391 ScriptPromise promise = result->promise(); | 467 ScriptPromise promise = result->promise(); |
| 392 | 468 |
| 393 if (!canAccessWebCrypto(scriptState, result)) | 469 if (!canAccessWebCrypto(scriptState, result)) |
| 394 return promise; | 470 return promise; |
| 395 | 471 |
| 396 WebCryptoKeyFormat format; | 472 WebCryptoKeyFormat format; |
| 397 if (!CryptoKey::parseFormat(rawFormat, format, result)) | 473 if (!CryptoKey::parseFormat(rawFormat, format, result)) |
| 398 return promise; | 474 return promise; |
| 399 | 475 |
| 400 WebCryptoKeyUsageMask keyUsages; | 476 WebCryptoKeyUsageMask keyUsages; |
| 401 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) | 477 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) |
| 402 return promise; | 478 return promise; |
| 403 | 479 |
| 404 // 14.3.12.2: Let wrappedKey be the result of getting a copy of the bytes | 480 // 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 | 481 // held by the wrappedKey parameter passed to the unwrapKey |
| 406 // method. | 482 // method. |
| 407 Vector<uint8_t> wrappedKey = copyBytes(rawWrappedKey); | 483 Vector<uint8_t> wrappedKey = copyBytes(rawWrappedKey); |
| 408 | 484 |
| 409 WebCryptoAlgorithm unwrapAlgorithm; | 485 // 14.3.12.3: Let normalizedAlgorithm be the result of normalizing an |
| 410 if (!parseAlgorithm(rawUnwrapAlgorithm, WebCryptoOperationUnwrapKey, unwrapA
lgorithm, result)) | 486 // algorithm, with alg set to algorithm and op set to |
| 487 // "unwrapKey". |
| 488 // |
| 489 // 14.3.12.4: If an error occurred, let normalizedAlgorithm be the result |
| 490 // of normalizing an algorithm, with alg set to algorithm and op |
| 491 // set to "decrypt". |
| 492 WebCryptoAlgorithm normalizedAlgorithm; |
| 493 if (!parseAlgorithm(rawUnwrapAlgorithm, WebCryptoOperationUnwrapKey, normali
zedAlgorithm, result)) |
| 411 return promise; | 494 return promise; |
| 412 | 495 |
| 413 WebCryptoAlgorithm unwrappedKeyAlgorithm; | 496 // 14.3.12.6: Let normalizedKeyAlgorithm be the result of normalizing an |
| 414 if (!parseAlgorithm(rawUnwrappedKeyAlgorithm, WebCryptoOperationImportKey, u
nwrappedKeyAlgorithm, result)) | 497 // algorithm, with alg set to unwrappedKeyAlgorithm and op set |
| 498 // to "importKey". |
| 499 WebCryptoAlgorithm normalizedKeyAlgorithm; |
| 500 if (!parseAlgorithm(rawUnwrappedKeyAlgorithm, WebCryptoOperationImportKey, n
ormalizedKeyAlgorithm, result)) |
| 415 return promise; | 501 return promise; |
| 416 | 502 |
| 417 if (!unwrappingKey->canBeUsedForAlgorithm(unwrapAlgorithm, WebCryptoKeyUsage
UnwrapKey, result)) | 503 // 14.3.12.11: If the name member of normalizedAlgorithm is not equal to |
| 504 // the name attribute of the [[algorithm]] internal slot of |
| 505 // unwrappingKey then throw an InvalidAccessError. |
| 506 // |
| 507 // 14.3.12.12: If the [[usages]] internal slot of unwrappingKey does not |
| 508 // contain an entry that is "unwrapKey", then throw an |
| 509 // InvalidAccessError. |
| 510 if (!unwrappingKey->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyU
sageUnwrapKey, result)) |
| 418 return promise; | 511 return promise; |
| 419 | 512 |
| 420 histogramAlgorithmAndKey(scriptState->getExecutionContext(), unwrapAlgorithm
, unwrappingKey->key()); | 513 // NOTE: Step (16) disallows empty usages on secret and private keys. This |
| 421 histogramAlgorithm(scriptState->getExecutionContext(), unwrappedKeyAlgorithm
); | 514 // normative requirement is enforced by the platform implementation in the |
| 422 Platform::current()->crypto()->unwrapKey(format, wrappedKey.data(), wrappedK
ey.size(), unwrappingKey->key(), unwrapAlgorithm, unwrappedKeyAlgorithm, extract
able, keyUsages, result->result()); | 515 // call below. |
| 516 |
| 517 histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgor
ithm, unwrappingKey->key()); |
| 518 histogramAlgorithm(scriptState->getExecutionContext(), normalizedKeyAlgorith
m); |
| 519 Platform::current()->crypto()->unwrapKey(format, wrappedKey.data(), wrappedK
ey.size(), unwrappingKey->key(), normalizedAlgorithm, normalizedKeyAlgorithm, ex
tractable, keyUsages, result->result()); |
| 423 return promise; | 520 return promise; |
| 424 } | 521 } |
| 425 | 522 |
| 426 ScriptPromise SubtleCrypto::deriveBits(ScriptState* scriptState, const Algorithm
Identifier& rawAlgorithm, CryptoKey* baseKey, unsigned lengthBits) | 523 ScriptPromise SubtleCrypto::deriveBits(ScriptState* scriptState, const Algorithm
Identifier& rawAlgorithm, CryptoKey* baseKey, unsigned lengthBits) |
| 427 { | 524 { |
| 525 // Method described by: https://w3c.github.io/webcrypto/Overview.html#dfn-Su
btleCrypto-method-deriveBits |
| 526 |
| 428 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 527 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 429 ScriptPromise promise = result->promise(); | 528 ScriptPromise promise = result->promise(); |
| 430 | 529 |
| 431 if (!canAccessWebCrypto(scriptState, result)) | 530 if (!canAccessWebCrypto(scriptState, result)) |
| 432 return promise; | 531 return promise; |
| 433 | 532 |
| 434 WebCryptoAlgorithm algorithm; | 533 // 14.3.8.2: Let normalizedAlgorithm be the result of normalizing an |
| 435 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDeriveBits, algorithm, r
esult)) | 534 // algorithm, with alg set to algorithm and op set to |
| 535 // "deriveBits". |
| 536 WebCryptoAlgorithm normalizedAlgorithm; |
| 537 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDeriveBits, normalizedAl
gorithm, result)) |
| 436 return promise; | 538 return promise; |
| 437 | 539 |
| 438 if (!baseKey->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageDeriveBits,
result)) | 540 // 14.3.8.7: If the name member of normalizedAlgorithm is not equal to the |
| 541 // name attribute of the [[algorithm]] internal slot of baseKey |
| 542 // then throw an InvalidAccessError. |
| 543 // |
| 544 // 14.3.8.8: If the [[usages]] internal slot of baseKey does not contain an |
| 545 // entry that is "deriveBits", then throw an InvalidAccessError. |
| 546 if (!baseKey->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageDe
riveBits, result)) |
| 439 return promise; | 547 return promise; |
| 440 | 548 |
| 441 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, base
Key->key()); | 549 histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgor
ithm, baseKey->key()); |
| 442 Platform::current()->crypto()->deriveBits(algorithm, baseKey->key(), lengthB
its, result->result()); | 550 Platform::current()->crypto()->deriveBits(normalizedAlgorithm, baseKey->key(
), lengthBits, result->result()); |
| 443 return promise; | 551 return promise; |
| 444 } | 552 } |
| 445 | 553 |
| 446 ScriptPromise SubtleCrypto::deriveKey(ScriptState* scriptState, const AlgorithmI
dentifier& rawAlgorithm, CryptoKey* baseKey, const AlgorithmIdentifier& rawDeriv
edKeyType, bool extractable, const Vector<String>& rawKeyUsages) | 554 ScriptPromise SubtleCrypto::deriveKey(ScriptState* scriptState, const AlgorithmI
dentifier& rawAlgorithm, CryptoKey* baseKey, const AlgorithmIdentifier& rawDeriv
edKeyType, bool extractable, const Vector<String>& rawKeyUsages) |
| 447 { | 555 { |
| 556 // Method described by: https://w3c.github.io/webcrypto/Overview.html#Subtle
Crypto-method-deriveKey |
| 557 |
| 448 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); | 558 CryptoResultImpl* result = CryptoResultImpl::create(scriptState); |
| 449 ScriptPromise promise = result->promise(); | 559 ScriptPromise promise = result->promise(); |
| 450 | 560 |
| 451 if (!canAccessWebCrypto(scriptState, result)) | 561 if (!canAccessWebCrypto(scriptState, result)) |
| 452 return promise; | 562 return promise; |
| 453 | 563 |
| 454 WebCryptoKeyUsageMask keyUsages; | 564 WebCryptoKeyUsageMask keyUsages; |
| 455 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) | 565 if (!CryptoKey::parseUsageMask(rawKeyUsages, keyUsages, result)) |
| 456 return promise; | 566 return promise; |
| 457 | 567 |
| 458 WebCryptoAlgorithm algorithm; | 568 // 14.3.7.2: Let normalizedAlgorithm be the result of normalizing an |
| 459 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDeriveBits, algorithm, r
esult)) | 569 // algorithm, with alg set to algorithm and op set to |
| 570 // "deriveBits". |
| 571 WebCryptoAlgorithm normalizedAlgorithm; |
| 572 if (!parseAlgorithm(rawAlgorithm, WebCryptoOperationDeriveBits, normalizedAl
gorithm, result)) |
| 460 return promise; | 573 return promise; |
| 461 | 574 |
| 462 if (!baseKey->canBeUsedForAlgorithm(algorithm, WebCryptoKeyUsageDeriveKey, r
esult)) | 575 // 14.3.7.4: Let normalizedDerivedKeyAlgorithm be the result of normalizing |
| 576 // an algorithm, with alg set to derivedKeyType and op set to |
| 577 // "importKey". |
| 578 WebCryptoAlgorithm normalizedDerivedKeyAlgorithm; |
| 579 if (!parseAlgorithm(rawDerivedKeyType, WebCryptoOperationImportKey, normaliz
edDerivedKeyAlgorithm, result)) |
| 463 return promise; | 580 return promise; |
| 464 | 581 |
| 465 WebCryptoAlgorithm importAlgorithm; | 582 // TODO(eroman): The description in the spec needs to be updated as |
| 466 if (!parseAlgorithm(rawDerivedKeyType, WebCryptoOperationImportKey, importAl
gorithm, result)) | 583 // it doesn't describe algorithm normalization for the Get Key |
| 467 return promise; | 584 // Length parameters (https://github.com/w3c/webcrypto/issues/127) |
| 468 | 585 // For now reference step 10 which is the closest. |
| 586 // |
| 587 // 14.3.7.10: If the name member of normalizedDerivedKeyAlgorithm does not |
| 588 // identify a registered algorithm that supports the get key leng
th |
| 589 // operation, then throw a NotSupportedError. |
| 469 WebCryptoAlgorithm keyLengthAlgorithm; | 590 WebCryptoAlgorithm keyLengthAlgorithm; |
| 470 if (!parseAlgorithm(rawDerivedKeyType, WebCryptoOperationGetKeyLength, keyLe
ngthAlgorithm, result)) | 591 if (!parseAlgorithm(rawDerivedKeyType, WebCryptoOperationGetKeyLength, keyLe
ngthAlgorithm, result)) |
| 471 return promise; | 592 return promise; |
| 472 | 593 |
| 473 histogramAlgorithmAndKey(scriptState->getExecutionContext(), algorithm, base
Key->key()); | 594 // 14.3.7.11: If the name member of normalizedAlgorithm is not equal to the |
| 474 histogramAlgorithm(scriptState->getExecutionContext(), importAlgorithm); | 595 // name attribute of the [[algorithm]] internal slot of baseKey |
| 475 Platform::current()->crypto()->deriveKey(algorithm, baseKey->key(), importAl
gorithm, keyLengthAlgorithm, extractable, keyUsages, result->result()); | 596 // then throw an InvalidAccessError. |
| 597 // |
| 598 // 14.3.7.12: If the [[usages]] internal slot of baseKey does not contain |
| 599 // an entry that is "deriveKey", then throw an InvalidAccessError
. |
| 600 if (!baseKey->canBeUsedForAlgorithm(normalizedAlgorithm, WebCryptoKeyUsageDe
riveKey, result)) |
| 601 return promise; |
| 602 |
| 603 // NOTE: Step (16) disallows empty usages on secret and private keys. This |
| 604 // normative requirement is enforced by the platform implementation in the |
| 605 // call below. |
| 606 |
| 607 histogramAlgorithmAndKey(scriptState->getExecutionContext(), normalizedAlgor
ithm, baseKey->key()); |
| 608 histogramAlgorithm(scriptState->getExecutionContext(), normalizedDerivedKeyA
lgorithm); |
| 609 Platform::current()->crypto()->deriveKey(normalizedAlgorithm, baseKey->key()
, normalizedDerivedKeyAlgorithm, keyLengthAlgorithm, extractable, keyUsages, res
ult->result()); |
| 476 return promise; | 610 return promise; |
| 477 } | 611 } |
| 478 | 612 |
| 479 } // namespace blink | 613 } // namespace blink |
| OLD | NEW |