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 28 matching lines...) Expand all Loading... |
39 #include "modules/crypto/NormalizeAlgorithm.h" | 39 #include "modules/crypto/NormalizeAlgorithm.h" |
40 #include "public/platform/Platform.h" | 40 #include "public/platform/Platform.h" |
41 #include "public/platform/WebCrypto.h" | 41 #include "public/platform/WebCrypto.h" |
42 #include "public/platform/WebCryptoAlgorithm.h" | 42 #include "public/platform/WebCryptoAlgorithm.h" |
43 #include "wtf/ArrayBufferView.h" | 43 #include "wtf/ArrayBufferView.h" |
44 | 44 |
45 namespace WebCore { | 45 namespace WebCore { |
46 | 46 |
47 namespace { | 47 namespace { |
48 | 48 |
| 49 bool parseAlgorithm(const Dictionary& rawAlgorithm, AlgorithmOperation operation
Type, blink::WebCryptoAlgorithm &algorithm, ExceptionState& exceptionState, Cryp
toResult* result) |
| 50 { |
| 51 String errorDetails; |
| 52 if (parseAlgorithm(rawAlgorithm, operationType, algorithm, errorDetails, exc
eptionState)) |
| 53 return true; |
| 54 |
| 55 if (!exceptionState.hadException()) |
| 56 result->completeWithError(errorDetails); |
| 57 |
| 58 return false; |
| 59 } |
| 60 |
49 ScriptPromise startCryptoOperation(const Dictionary& rawAlgorithm, Key* key, Alg
orithmOperation operationType, ArrayBufferView* signature, ArrayBufferView* data
Buffer, ExceptionState& exceptionState) | 61 ScriptPromise startCryptoOperation(const Dictionary& rawAlgorithm, Key* key, Alg
orithmOperation operationType, ArrayBufferView* signature, ArrayBufferView* data
Buffer, ExceptionState& exceptionState) |
50 { | 62 { |
51 bool requiresKey = operationType != Digest; | 63 bool requiresKey = operationType != Digest; |
52 | 64 |
53 // Seems like the generated bindings should take care of these however it | 65 // Seems like the generated bindings should take care of these however it |
54 // currently doesn't. See also http://crbugh.com/264520 | 66 // currently doesn't. See also http://crbugh.com/264520 |
55 if (requiresKey && !key) { | 67 if (requiresKey && !key) { |
56 exceptionState.throwTypeError("Invalid key argument"); | 68 exceptionState.throwTypeError("Invalid key argument"); |
57 return ScriptPromise(); | 69 return ScriptPromise(); |
58 } | 70 } |
59 if (operationType == Verify && !signature) { | 71 if (operationType == Verify && !signature) { |
60 exceptionState.throwTypeError("Invalid signature argument"); | 72 exceptionState.throwTypeError("Invalid signature argument"); |
61 return ScriptPromise(); | 73 return ScriptPromise(); |
62 } | 74 } |
63 if (!dataBuffer) { | 75 if (!dataBuffer) { |
64 exceptionState.throwTypeError("Invalid dataBuffer argument"); | 76 exceptionState.throwTypeError("Invalid dataBuffer argument"); |
65 return ScriptPromise(); | 77 return ScriptPromise(); |
66 } | 78 } |
67 | 79 |
| 80 ScriptPromise promise = ScriptPromise::createPending(); |
| 81 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); |
| 82 |
68 blink::WebCryptoAlgorithm algorithm; | 83 blink::WebCryptoAlgorithm algorithm; |
69 if (!normalizeAlgorithm(rawAlgorithm, operationType, algorithm, exceptionSta
te)) | 84 if (!parseAlgorithm(rawAlgorithm, operationType, algorithm, exceptionState,
result.get())) |
70 return ScriptPromise(); | 85 return promise; |
71 | 86 |
72 if (requiresKey && !key->canBeUsedForAlgorithm(algorithm, operationType, exc
eptionState)) | 87 String errorDetails; |
73 return ScriptPromise(); | 88 if (requiresKey && !key->canBeUsedForAlgorithm(algorithm, operationType, err
orDetails)) { |
| 89 result->completeWithError(errorDetails); |
| 90 return promise; |
| 91 } |
74 | 92 |
75 const unsigned char* data = static_cast<const unsigned char*>(dataBuffer->ba
seAddress()); | 93 const unsigned char* data = static_cast<const unsigned char*>(dataBuffer->ba
seAddress()); |
76 unsigned dataSize = dataBuffer->byteLength(); | 94 unsigned dataSize = dataBuffer->byteLength(); |
77 | 95 |
78 ScriptPromise promise = ScriptPromise::createPending(); | |
79 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); | |
80 | |
81 switch (operationType) { | 96 switch (operationType) { |
82 case Encrypt: | 97 case Encrypt: |
83 blink::Platform::current()->crypto()->encrypt(algorithm, key->key(), dat
a, dataSize, result->result()); | 98 blink::Platform::current()->crypto()->encrypt(algorithm, key->key(), dat
a, dataSize, result->result()); |
84 break; | 99 break; |
85 case Decrypt: | 100 case Decrypt: |
86 blink::Platform::current()->crypto()->decrypt(algorithm, key->key(), dat
a, dataSize, result->result()); | 101 blink::Platform::current()->crypto()->decrypt(algorithm, key->key(), dat
a, dataSize, result->result()); |
87 break; | 102 break; |
88 case Sign: | 103 case Sign: |
89 blink::Platform::current()->crypto()->sign(algorithm, key->key(), data,
dataSize, result->result()); | 104 blink::Platform::current()->crypto()->sign(algorithm, key->key(), data,
dataSize, result->result()); |
90 break; | 105 break; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 { | 148 { |
134 return startCryptoOperation(rawAlgorithm, 0, Digest, 0, data, exceptionState
); | 149 return startCryptoOperation(rawAlgorithm, 0, Digest, 0, data, exceptionState
); |
135 } | 150 } |
136 | 151 |
137 ScriptPromise SubtleCrypto::generateKey(const Dictionary& rawAlgorithm, bool ext
ractable, const Vector<String>& rawKeyUsages, ExceptionState& exceptionState) | 152 ScriptPromise SubtleCrypto::generateKey(const Dictionary& rawAlgorithm, bool ext
ractable, const Vector<String>& rawKeyUsages, ExceptionState& exceptionState) |
138 { | 153 { |
139 blink::WebCryptoKeyUsageMask keyUsages; | 154 blink::WebCryptoKeyUsageMask keyUsages; |
140 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, exceptionState)) | 155 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, exceptionState)) |
141 return ScriptPromise(); | 156 return ScriptPromise(); |
142 | 157 |
143 blink::WebCryptoAlgorithm algorithm; | |
144 if (!normalizeAlgorithm(rawAlgorithm, GenerateKey, algorithm, exceptionState
)) | |
145 return ScriptPromise(); | |
146 | |
147 ScriptPromise promise = ScriptPromise::createPending(); | 158 ScriptPromise promise = ScriptPromise::createPending(); |
148 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); | 159 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); |
| 160 |
| 161 blink::WebCryptoAlgorithm algorithm; |
| 162 if (!parseAlgorithm(rawAlgorithm, GenerateKey, algorithm, exceptionState, re
sult.get())) |
| 163 return promise; |
| 164 |
149 blink::Platform::current()->crypto()->generateKey(algorithm, extractable, ke
yUsages, result->result()); | 165 blink::Platform::current()->crypto()->generateKey(algorithm, extractable, ke
yUsages, result->result()); |
150 return promise; | 166 return promise; |
151 } | 167 } |
152 | 168 |
153 ScriptPromise SubtleCrypto::importKey(const String& rawFormat, ArrayBufferView*
keyData, const Dictionary& rawAlgorithm, bool extractable, const Vector<String>&
rawKeyUsages, ExceptionState& exceptionState) | 169 ScriptPromise SubtleCrypto::importKey(const String& rawFormat, ArrayBufferView*
keyData, const Dictionary& rawAlgorithm, bool extractable, const Vector<String>&
rawKeyUsages, ExceptionState& exceptionState) |
154 { | 170 { |
155 blink::WebCryptoKeyFormat format; | 171 blink::WebCryptoKeyFormat format; |
156 if (!Key::parseFormat(rawFormat, format, exceptionState)) | 172 if (!Key::parseFormat(rawFormat, format, exceptionState)) |
157 return ScriptPromise(); | 173 return ScriptPromise(); |
158 | 174 |
159 if (!keyData) { | 175 if (!keyData) { |
160 exceptionState.throwTypeError("Invalid keyData argument"); | 176 exceptionState.throwTypeError("Invalid keyData argument"); |
161 return ScriptPromise(); | 177 return ScriptPromise(); |
162 } | 178 } |
163 | 179 |
164 blink::WebCryptoKeyUsageMask keyUsages; | 180 blink::WebCryptoKeyUsageMask keyUsages; |
165 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, exceptionState)) | 181 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, exceptionState)) |
166 return ScriptPromise(); | 182 return ScriptPromise(); |
167 | 183 |
| 184 ScriptPromise promise = ScriptPromise::createPending(); |
| 185 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); |
| 186 |
168 // The algorithm is optional. | 187 // The algorithm is optional. |
169 blink::WebCryptoAlgorithm algorithm; | 188 blink::WebCryptoAlgorithm algorithm; |
170 if (!rawAlgorithm.isUndefinedOrNull() && !normalizeAlgorithm(rawAlgorithm, I
mportKey, algorithm, exceptionState)) | 189 if (!rawAlgorithm.isUndefinedOrNull() && !parseAlgorithm(rawAlgorithm, Impor
tKey, algorithm, exceptionState, result.get())) |
171 return ScriptPromise(); | 190 return promise; |
172 | 191 |
173 const unsigned char* keyDataBytes = static_cast<unsigned char*>(keyData->bas
eAddress()); | 192 const unsigned char* keyDataBytes = static_cast<unsigned char*>(keyData->bas
eAddress()); |
174 | 193 |
175 ScriptPromise promise = ScriptPromise::createPending(); | |
176 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); | |
177 blink::Platform::current()->crypto()->importKey(format, keyDataBytes, keyDat
a->byteLength(), algorithm, extractable, keyUsages, result->result()); | 194 blink::Platform::current()->crypto()->importKey(format, keyDataBytes, keyDat
a->byteLength(), algorithm, extractable, keyUsages, result->result()); |
178 return promise; | 195 return promise; |
179 } | 196 } |
180 | 197 |
181 ScriptPromise SubtleCrypto::exportKey(const String& rawFormat, Key* key, Excepti
onState& exceptionState) | 198 ScriptPromise SubtleCrypto::exportKey(const String& rawFormat, Key* key, Excepti
onState& exceptionState) |
182 { | 199 { |
183 blink::WebCryptoKeyFormat format; | 200 blink::WebCryptoKeyFormat format; |
184 if (!Key::parseFormat(rawFormat, format, exceptionState)) | 201 if (!Key::parseFormat(rawFormat, format, exceptionState)) |
185 return ScriptPromise(); | 202 return ScriptPromise(); |
186 | 203 |
187 if (!key) { | 204 if (!key) { |
188 exceptionState.throwTypeError("Invalid key argument"); | 205 exceptionState.throwTypeError("Invalid key argument"); |
189 return ScriptPromise(); | 206 return ScriptPromise(); |
190 } | 207 } |
191 | 208 |
192 if (!key->extractable()) { | |
193 exceptionState.throwDOMException(NotSupportedError, "key is not extracta
ble"); | |
194 return ScriptPromise(); | |
195 } | |
196 | |
197 ScriptPromise promise = ScriptPromise::createPending(); | 209 ScriptPromise promise = ScriptPromise::createPending(); |
198 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); | 210 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); |
| 211 |
| 212 if (!key->extractable()) { |
| 213 result->completeWithError("key is not extractable"); |
| 214 return promise; |
| 215 } |
| 216 |
199 blink::Platform::current()->crypto()->exportKey(format, key->key(), result->
result()); | 217 blink::Platform::current()->crypto()->exportKey(format, key->key(), result->
result()); |
200 return promise; | 218 return promise; |
201 } | 219 } |
202 | 220 |
203 ScriptPromise SubtleCrypto::wrapKey(const String& rawFormat, Key* key, Key* wrap
pingKey, const Dictionary& rawWrapAlgorithm, ExceptionState& exceptionState) | 221 ScriptPromise SubtleCrypto::wrapKey(const String& rawFormat, Key* key, Key* wrap
pingKey, const Dictionary& rawWrapAlgorithm, ExceptionState& exceptionState) |
204 { | 222 { |
205 blink::WebCryptoKeyFormat format; | 223 blink::WebCryptoKeyFormat format; |
206 if (!Key::parseFormat(rawFormat, format, exceptionState)) | 224 if (!Key::parseFormat(rawFormat, format, exceptionState)) |
207 return ScriptPromise(); | 225 return ScriptPromise(); |
208 | 226 |
209 if (!key) { | 227 if (!key) { |
210 exceptionState.throwTypeError("Invalid key argument"); | 228 exceptionState.throwTypeError("Invalid key argument"); |
211 return ScriptPromise(); | 229 return ScriptPromise(); |
212 } | 230 } |
213 | 231 |
214 if (!wrappingKey) { | 232 if (!wrappingKey) { |
215 exceptionState.throwTypeError("Invalid wrappingKey argument"); | 233 exceptionState.throwTypeError("Invalid wrappingKey argument"); |
216 return ScriptPromise(); | 234 return ScriptPromise(); |
217 } | 235 } |
218 | 236 |
| 237 ScriptPromise promise = ScriptPromise::createPending(); |
| 238 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); |
| 239 |
219 blink::WebCryptoAlgorithm wrapAlgorithm; | 240 blink::WebCryptoAlgorithm wrapAlgorithm; |
220 if (!normalizeAlgorithm(rawWrapAlgorithm, WrapKey, wrapAlgorithm, exceptionS
tate)) | 241 if (!parseAlgorithm(rawWrapAlgorithm, WrapKey, wrapAlgorithm, exceptionState
, result.get())) |
221 return ScriptPromise(); | 242 return promise; |
222 | 243 |
223 if (!key->extractable()) { | 244 if (!key->extractable()) { |
224 exceptionState.throwDOMException(NotSupportedError, "key is not extracta
ble"); | 245 result->completeWithError("key is not extractable"); |
225 return ScriptPromise(); | 246 return promise; |
226 } | 247 } |
227 | 248 |
228 if (!wrappingKey->canBeUsedForAlgorithm(wrapAlgorithm, WrapKey, exceptionSta
te)) | 249 String errorDetails; |
229 return ScriptPromise(); | 250 if (!wrappingKey->canBeUsedForAlgorithm(wrapAlgorithm, WrapKey, errorDetails
)) { |
| 251 result->completeWithError(errorDetails); |
| 252 return promise; |
| 253 } |
230 | 254 |
231 ScriptPromise promise = ScriptPromise::createPending(); | |
232 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); | |
233 blink::Platform::current()->crypto()->wrapKey(format, key->key(), wrappingKe
y->key(), wrapAlgorithm, result->result()); | 255 blink::Platform::current()->crypto()->wrapKey(format, key->key(), wrappingKe
y->key(), wrapAlgorithm, result->result()); |
234 return promise; | 256 return promise; |
235 } | 257 } |
236 | 258 |
237 ScriptPromise SubtleCrypto::unwrapKey(const String& rawFormat, ArrayBufferView*
wrappedKey, Key* unwrappingKey, const Dictionary& rawUnwrapAlgorithm, const Dict
ionary& rawUnwrappedKeyAlgorithm, bool extractable, const Vector<String>& rawKey
Usages, ExceptionState& exceptionState) | 259 ScriptPromise SubtleCrypto::unwrapKey(const String& rawFormat, ArrayBufferView*
wrappedKey, Key* unwrappingKey, const Dictionary& rawUnwrapAlgorithm, const Dict
ionary& rawUnwrappedKeyAlgorithm, bool extractable, const Vector<String>& rawKey
Usages, ExceptionState& exceptionState) |
238 { | 260 { |
239 blink::WebCryptoKeyFormat format; | 261 blink::WebCryptoKeyFormat format; |
240 if (!Key::parseFormat(rawFormat, format, exceptionState)) | 262 if (!Key::parseFormat(rawFormat, format, exceptionState)) |
241 return ScriptPromise(); | 263 return ScriptPromise(); |
242 | 264 |
243 if (!wrappedKey) { | 265 if (!wrappedKey) { |
244 exceptionState.throwTypeError("Invalid wrappedKey argument"); | 266 exceptionState.throwTypeError("Invalid wrappedKey argument"); |
245 return ScriptPromise(); | 267 return ScriptPromise(); |
246 } | 268 } |
247 | 269 |
248 if (!unwrappingKey) { | 270 if (!unwrappingKey) { |
249 exceptionState.throwTypeError("Invalid unwrappingKey argument"); | 271 exceptionState.throwTypeError("Invalid unwrappingKey argument"); |
250 return ScriptPromise(); | 272 return ScriptPromise(); |
251 } | 273 } |
252 | 274 |
253 blink::WebCryptoAlgorithm unwrapAlgorithm; | |
254 if (!normalizeAlgorithm(rawUnwrapAlgorithm, UnwrapKey, unwrapAlgorithm, exce
ptionState)) | |
255 return ScriptPromise(); | |
256 | |
257 // The unwrappedKeyAlgorithm is optional. | |
258 blink::WebCryptoAlgorithm unwrappedKeyAlgorithm; | |
259 if (!rawUnwrappedKeyAlgorithm.isUndefinedOrNull() && !normalizeAlgorithm(raw
UnwrappedKeyAlgorithm, ImportKey, unwrappedKeyAlgorithm, exceptionState)) | |
260 return ScriptPromise(); | |
261 | |
262 blink::WebCryptoKeyUsageMask keyUsages; | 275 blink::WebCryptoKeyUsageMask keyUsages; |
263 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, exceptionState)) | 276 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, exceptionState)) |
264 return ScriptPromise(); | 277 return ScriptPromise(); |
265 | 278 |
266 if (!unwrappingKey->canBeUsedForAlgorithm(unwrapAlgorithm, UnwrapKey, except
ionState)) | 279 ScriptPromise promise = ScriptPromise::createPending(); |
267 return ScriptPromise(); | 280 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); |
| 281 |
| 282 blink::WebCryptoAlgorithm unwrapAlgorithm; |
| 283 if (!parseAlgorithm(rawUnwrapAlgorithm, UnwrapKey, unwrapAlgorithm, exceptio
nState, result.get())) |
| 284 return promise; |
| 285 |
| 286 // The unwrappedKeyAlgorithm is optional. |
| 287 blink::WebCryptoAlgorithm unwrappedKeyAlgorithm; |
| 288 if (!rawUnwrappedKeyAlgorithm.isUndefinedOrNull() && !parseAlgorithm(rawUnwr
appedKeyAlgorithm, ImportKey, unwrappedKeyAlgorithm, exceptionState, result.get(
))) |
| 289 return promise; |
| 290 |
| 291 String errorDetails; |
| 292 if (!unwrappingKey->canBeUsedForAlgorithm(unwrapAlgorithm, UnwrapKey, errorD
etails)) { |
| 293 result->completeWithError(errorDetails); |
| 294 return promise; |
| 295 } |
268 | 296 |
269 const unsigned char* wrappedKeyData = static_cast<const unsigned char*>(wrap
pedKey->baseAddress()); | 297 const unsigned char* wrappedKeyData = static_cast<const unsigned char*>(wrap
pedKey->baseAddress()); |
270 unsigned wrappedKeyDataSize = wrappedKey->byteLength(); | 298 unsigned wrappedKeyDataSize = wrappedKey->byteLength(); |
271 | 299 |
272 ScriptPromise promise = ScriptPromise::createPending(); | |
273 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(promise); | |
274 blink::Platform::current()->crypto()->unwrapKey(format, wrappedKeyData, wrap
pedKeyDataSize, unwrappingKey->key(), unwrapAlgorithm, unwrappedKeyAlgorithm, ex
tractable, keyUsages, result->result()); | 300 blink::Platform::current()->crypto()->unwrapKey(format, wrappedKeyData, wrap
pedKeyDataSize, unwrappingKey->key(), unwrapAlgorithm, unwrappedKeyAlgorithm, ex
tractable, keyUsages, result->result()); |
275 return promise; | 301 return promise; |
276 } | 302 } |
277 | 303 |
278 | 304 |
279 } // namespace WebCore | 305 } // namespace WebCore |
OLD | NEW |