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

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

Issue 2159313002: Miscelaneous updates to WebCrypto to match latest spec. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: spelling fix cal --> call Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/LayoutTests/crypto/subtle/importKey-badParameters-expected.txt ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/crypto/subtle/importKey-badParameters-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698