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 20 matching lines...) Expand all Loading... |
31 #include "config.h" | 31 #include "config.h" |
32 #include "modules/crypto/SubtleCrypto.h" | 32 #include "modules/crypto/SubtleCrypto.h" |
33 | 33 |
34 #include "bindings/v8/Dictionary.h" | 34 #include "bindings/v8/Dictionary.h" |
35 #include "modules/crypto/CryptoResultImpl.h" | 35 #include "modules/crypto/CryptoResultImpl.h" |
36 #include "modules/crypto/Key.h" | 36 #include "modules/crypto/Key.h" |
37 #include "modules/crypto/NormalizeAlgorithm.h" | 37 #include "modules/crypto/NormalizeAlgorithm.h" |
38 #include "public/platform/Platform.h" | 38 #include "public/platform/Platform.h" |
39 #include "public/platform/WebCrypto.h" | 39 #include "public/platform/WebCrypto.h" |
40 #include "public/platform/WebCryptoAlgorithm.h" | 40 #include "public/platform/WebCryptoAlgorithm.h" |
| 41 #include "public/platform/WebCryptoAlgorithmOperation.h" |
41 #include "wtf/ArrayBufferView.h" | 42 #include "wtf/ArrayBufferView.h" |
42 | 43 |
43 namespace WebCore { | 44 namespace WebCore { |
44 | 45 |
45 namespace { | 46 namespace { |
46 | 47 |
47 // Seems like the generated bindings should take care of these however it | 48 // Seems like the generated bindings should take care of these however it |
48 // currently doesn't. See also http://crbug.com/264520 | 49 // currently doesn't. See also http://crbug.com/264520 |
49 bool ensureNotNull(const ArrayPiece& x, const char* paramName, CryptoResult* res
ult) | 50 bool ensureNotNull(const ArrayPiece& x, const char* paramName, CryptoResult* res
ult) |
50 { | 51 { |
51 if (x.isNull()) { | 52 if (x.isNull()) { |
52 String message = String("Invalid ") + paramName + String(" argument"); | 53 String message = String("Invalid ") + paramName + String(" argument"); |
53 result->completeWithError(blink::WebCryptoErrorTypeType, blink::WebStrin
g(message)); | 54 result->completeWithError(blink::WebCryptoErrorTypeType, blink::WebStrin
g(message)); |
54 return false; | 55 return false; |
55 } | 56 } |
56 return true; | 57 return true; |
57 } | 58 } |
58 | 59 |
59 bool ensureNotNull(Key* key, const char* paramName, CryptoResult* result) | 60 bool ensureNotNull(Key* key, const char* paramName, CryptoResult* result) |
60 { | 61 { |
61 if (!key) { | 62 if (!key) { |
62 String message = String("Invalid ") + paramName + String(" argument"); | 63 String message = String("Invalid ") + paramName + String(" argument"); |
63 result->completeWithError(blink::WebCryptoErrorTypeType, blink::WebStrin
g(message)); | 64 result->completeWithError(blink::WebCryptoErrorTypeType, blink::WebStrin
g(message)); |
64 return false; | 65 return false; |
65 } | 66 } |
66 return true; | 67 return true; |
67 } | 68 } |
68 | 69 |
69 ScriptPromise startCryptoOperation(const Dictionary& rawAlgorithm, Key* key, Alg
orithmOperation operationType, const ArrayPiece& signature, const ArrayPiece& da
taBuffer) | 70 bool parseAlgorithm(const Dictionary& raw, blink::AlgorithmOperation op, blink::
WebCryptoAlgorithm& algorithm, CryptoResult* result) |
| 71 { |
| 72 AlgorithmError error; |
| 73 bool success = normalizeAlgorithm(raw, op, algorithm, &error); |
| 74 if (!success) |
| 75 result->completeWithError(error.errorType, error.errorDetails); |
| 76 return success; |
| 77 } |
| 78 |
| 79 ScriptPromise startCryptoOperation(const Dictionary& rawAlgorithm, Key* key, bli
nk::AlgorithmOperation operationType, const ArrayPiece& signature, const ArrayPi
ece& dataBuffer) |
70 { | 80 { |
71 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(); | 81 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(); |
72 ScriptPromise promise = result->promise(); | 82 ScriptPromise promise = result->promise(); |
73 | 83 |
74 bool requiresKey = operationType != Digest; | 84 bool requiresKey = operationType != blink::Digest; |
75 | 85 |
76 if (requiresKey && !ensureNotNull(key, "key", result.get())) | 86 if (requiresKey && !ensureNotNull(key, "key", result.get())) |
77 return promise; | 87 return promise; |
78 if (operationType == Verify && !ensureNotNull(signature, "signature", result
.get())) | 88 if (operationType == blink::Verify && !ensureNotNull(signature, "signature",
result.get())) |
79 return promise; | 89 return promise; |
80 if (!ensureNotNull(dataBuffer, "dataBuffer", result.get())) | 90 if (!ensureNotNull(dataBuffer, "dataBuffer", result.get())) |
81 return promise; | 91 return promise; |
82 | 92 |
83 blink::WebCryptoAlgorithm algorithm; | 93 blink::WebCryptoAlgorithm algorithm; |
84 if (!parseAlgorithm(rawAlgorithm, operationType, algorithm, result.get())) | 94 if (!parseAlgorithm(rawAlgorithm, operationType, algorithm, result.get())) |
85 return promise; | 95 return promise; |
86 | 96 |
87 if (requiresKey && !key->canBeUsedForAlgorithm(algorithm, operationType, res
ult.get())) | 97 if (requiresKey && !key->canBeUsedForAlgorithm(algorithm, operationType, res
ult.get())) |
88 return promise; | 98 return promise; |
89 | 99 |
90 const unsigned char* data = dataBuffer.bytes(); | 100 const unsigned char* data = dataBuffer.bytes(); |
91 unsigned dataSize = dataBuffer.byteLength(); | 101 unsigned dataSize = dataBuffer.byteLength(); |
92 | 102 |
93 switch (operationType) { | 103 switch (operationType) { |
94 case Encrypt: | 104 case blink::Encrypt: |
95 blink::Platform::current()->crypto()->encrypt(algorithm, key->key(), dat
a, dataSize, result->result()); | 105 blink::Platform::current()->crypto()->encrypt(algorithm, key->key(), dat
a, dataSize, result->result()); |
96 break; | 106 break; |
97 case Decrypt: | 107 case blink::Decrypt: |
98 blink::Platform::current()->crypto()->decrypt(algorithm, key->key(), dat
a, dataSize, result->result()); | 108 blink::Platform::current()->crypto()->decrypt(algorithm, key->key(), dat
a, dataSize, result->result()); |
99 break; | 109 break; |
100 case Sign: | 110 case blink::Sign: |
101 blink::Platform::current()->crypto()->sign(algorithm, key->key(), data,
dataSize, result->result()); | 111 blink::Platform::current()->crypto()->sign(algorithm, key->key(), data,
dataSize, result->result()); |
102 break; | 112 break; |
103 case Verify: | 113 case blink::Verify: |
104 blink::Platform::current()->crypto()->verifySignature(algorithm, key->ke
y(), signature.bytes(), signature.byteLength(), data, dataSize, result->result()
); | 114 blink::Platform::current()->crypto()->verifySignature(algorithm, key->ke
y(), signature.bytes(), signature.byteLength(), data, dataSize, result->result()
); |
105 break; | 115 break; |
106 case Digest: | 116 case blink::Digest: |
107 blink::Platform::current()->crypto()->digest(algorithm, data, dataSize,
result->result()); | 117 blink::Platform::current()->crypto()->digest(algorithm, data, dataSize,
result->result()); |
108 break; | 118 break; |
109 default: | 119 default: |
110 ASSERT_NOT_REACHED(); | 120 ASSERT_NOT_REACHED(); |
111 return ScriptPromise(); | 121 return ScriptPromise(); |
112 } | 122 } |
113 | 123 |
114 return promise; | 124 return promise; |
115 } | 125 } |
116 | 126 |
117 } // namespace | 127 } // namespace |
118 | 128 |
119 SubtleCrypto::SubtleCrypto() | 129 SubtleCrypto::SubtleCrypto() |
120 { | 130 { |
121 ScriptWrappable::init(this); | 131 ScriptWrappable::init(this); |
122 } | 132 } |
123 | 133 |
124 ScriptPromise SubtleCrypto::encrypt(const Dictionary& rawAlgorithm, Key* key, co
nst ArrayPiece& data) | 134 ScriptPromise SubtleCrypto::encrypt(const Dictionary& rawAlgorithm, Key* key, co
nst ArrayPiece& data) |
125 { | 135 { |
126 return startCryptoOperation(rawAlgorithm, key, Encrypt, ArrayPiece(), data); | 136 return startCryptoOperation(rawAlgorithm, key, blink::Encrypt, ArrayPiece(),
data); |
127 } | 137 } |
128 | 138 |
129 ScriptPromise SubtleCrypto::decrypt(const Dictionary& rawAlgorithm, Key* key, co
nst ArrayPiece& data) | 139 ScriptPromise SubtleCrypto::decrypt(const Dictionary& rawAlgorithm, Key* key, co
nst ArrayPiece& data) |
130 { | 140 { |
131 return startCryptoOperation(rawAlgorithm, key, Decrypt, ArrayPiece(), data); | 141 return startCryptoOperation(rawAlgorithm, key, blink::Decrypt, ArrayPiece(),
data); |
132 } | 142 } |
133 | 143 |
134 ScriptPromise SubtleCrypto::sign(const Dictionary& rawAlgorithm, Key* key, const
ArrayPiece& data) | 144 ScriptPromise SubtleCrypto::sign(const Dictionary& rawAlgorithm, Key* key, const
ArrayPiece& data) |
135 { | 145 { |
136 return startCryptoOperation(rawAlgorithm, key, Sign, ArrayPiece(), data); | 146 return startCryptoOperation(rawAlgorithm, key, blink::Sign, ArrayPiece(), da
ta); |
137 } | 147 } |
138 | 148 |
139 ScriptPromise SubtleCrypto::verifySignature(const Dictionary& rawAlgorithm, Key*
key, const ArrayPiece& signature, const ArrayPiece& data) | 149 ScriptPromise SubtleCrypto::verifySignature(const Dictionary& rawAlgorithm, Key*
key, const ArrayPiece& signature, const ArrayPiece& data) |
140 { | 150 { |
141 return startCryptoOperation(rawAlgorithm, key, Verify, signature, data); | 151 return startCryptoOperation(rawAlgorithm, key, blink::Verify, signature, dat
a); |
142 } | 152 } |
143 | 153 |
144 ScriptPromise SubtleCrypto::digest(const Dictionary& rawAlgorithm, const ArrayPi
ece& data) | 154 ScriptPromise SubtleCrypto::digest(const Dictionary& rawAlgorithm, const ArrayPi
ece& data) |
145 { | 155 { |
146 return startCryptoOperation(rawAlgorithm, 0, Digest, ArrayPiece(), data); | 156 return startCryptoOperation(rawAlgorithm, 0, blink::Digest, ArrayPiece(), da
ta); |
147 } | 157 } |
148 | 158 |
149 ScriptPromise SubtleCrypto::generateKey(const Dictionary& rawAlgorithm, bool ext
ractable, const Vector<String>& rawKeyUsages) | 159 ScriptPromise SubtleCrypto::generateKey(const Dictionary& rawAlgorithm, bool ext
ractable, const Vector<String>& rawKeyUsages) |
150 { | 160 { |
151 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(); | 161 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(); |
152 ScriptPromise promise = result->promise(); | 162 ScriptPromise promise = result->promise(); |
153 | 163 |
154 blink::WebCryptoKeyUsageMask keyUsages; | 164 blink::WebCryptoKeyUsageMask keyUsages; |
155 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get())) | 165 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get())) |
156 return promise; | 166 return promise; |
157 | 167 |
158 blink::WebCryptoAlgorithm algorithm; | 168 blink::WebCryptoAlgorithm algorithm; |
159 if (!parseAlgorithm(rawAlgorithm, GenerateKey, algorithm, result.get())) | 169 if (!parseAlgorithm(rawAlgorithm, blink::GenerateKey, algorithm, result.get(
))) |
160 return promise; | 170 return promise; |
161 | 171 |
162 blink::Platform::current()->crypto()->generateKey(algorithm, extractable, ke
yUsages, result->result()); | 172 blink::Platform::current()->crypto()->generateKey(algorithm, extractable, ke
yUsages, result->result()); |
163 return promise; | 173 return promise; |
164 } | 174 } |
165 | 175 |
166 ScriptPromise SubtleCrypto::importKey(const String& rawFormat, const ArrayPiece&
keyData, const Dictionary& rawAlgorithm, bool extractable, const Vector<String>
& rawKeyUsages) | 176 ScriptPromise SubtleCrypto::importKey(const String& rawFormat, const ArrayPiece&
keyData, const Dictionary& rawAlgorithm, bool extractable, const Vector<String>
& rawKeyUsages) |
167 { | 177 { |
168 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(); | 178 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(); |
169 ScriptPromise promise = result->promise(); | 179 ScriptPromise promise = result->promise(); |
170 | 180 |
171 if (!ensureNotNull(keyData, "keyData", result.get())) | 181 if (!ensureNotNull(keyData, "keyData", result.get())) |
172 return promise; | 182 return promise; |
173 | 183 |
174 blink::WebCryptoKeyFormat format; | 184 blink::WebCryptoKeyFormat format; |
175 if (!Key::parseFormat(rawFormat, format, result.get())) | 185 if (!Key::parseFormat(rawFormat, format, result.get())) |
176 return promise; | 186 return promise; |
177 | 187 |
178 blink::WebCryptoKeyUsageMask keyUsages; | 188 blink::WebCryptoKeyUsageMask keyUsages; |
179 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get())) | 189 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get())) |
180 return promise; | 190 return promise; |
181 | 191 |
182 blink::WebCryptoAlgorithm algorithm; | 192 blink::WebCryptoAlgorithm algorithm; |
183 if (!parseAlgorithm(rawAlgorithm, ImportKey, algorithm, result.get())) | 193 if (!parseAlgorithm(rawAlgorithm, blink::ImportKey, algorithm, result.get())
) |
184 return promise; | 194 return promise; |
185 | 195 |
186 blink::Platform::current()->crypto()->importKey(format, keyData.bytes(), key
Data.byteLength(), algorithm, extractable, keyUsages, result->result()); | 196 blink::Platform::current()->crypto()->importKey(format, keyData.bytes(), key
Data.byteLength(), algorithm, extractable, keyUsages, result->result()); |
187 return promise; | 197 return promise; |
188 } | 198 } |
189 | 199 |
190 ScriptPromise SubtleCrypto::exportKey(const String& rawFormat, Key* key) | 200 ScriptPromise SubtleCrypto::exportKey(const String& rawFormat, Key* key) |
191 { | 201 { |
192 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(); | 202 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(); |
193 ScriptPromise promise = result->promise(); | 203 ScriptPromise promise = result->promise(); |
(...skipping 23 matching lines...) Expand all Loading... |
217 return promise; | 227 return promise; |
218 | 228 |
219 if (!ensureNotNull(wrappingKey, "wrappingKey", result.get())) | 229 if (!ensureNotNull(wrappingKey, "wrappingKey", result.get())) |
220 return promise; | 230 return promise; |
221 | 231 |
222 blink::WebCryptoKeyFormat format; | 232 blink::WebCryptoKeyFormat format; |
223 if (!Key::parseFormat(rawFormat, format, result.get())) | 233 if (!Key::parseFormat(rawFormat, format, result.get())) |
224 return promise; | 234 return promise; |
225 | 235 |
226 blink::WebCryptoAlgorithm wrapAlgorithm; | 236 blink::WebCryptoAlgorithm wrapAlgorithm; |
227 if (!parseAlgorithm(rawWrapAlgorithm, WrapKey, wrapAlgorithm, result.get())) | 237 if (!parseAlgorithm(rawWrapAlgorithm, blink::WrapKey, wrapAlgorithm, result.
get())) |
228 return promise; | 238 return promise; |
229 | 239 |
230 if (!key->extractable()) { | 240 if (!key->extractable()) { |
231 result->completeWithError(blink::WebCryptoErrorTypeInvalidAccess, "key i
s not extractable"); | 241 result->completeWithError(blink::WebCryptoErrorTypeInvalidAccess, "key i
s not extractable"); |
232 return promise; | 242 return promise; |
233 } | 243 } |
234 | 244 |
235 if (!wrappingKey->canBeUsedForAlgorithm(wrapAlgorithm, WrapKey, result.get()
)) | 245 if (!wrappingKey->canBeUsedForAlgorithm(wrapAlgorithm, blink::WrapKey, resul
t.get())) |
236 return promise; | 246 return promise; |
237 | 247 |
238 blink::Platform::current()->crypto()->wrapKey(format, key->key(), wrappingKe
y->key(), wrapAlgorithm, result->result()); | 248 blink::Platform::current()->crypto()->wrapKey(format, key->key(), wrappingKe
y->key(), wrapAlgorithm, result->result()); |
239 return promise; | 249 return promise; |
240 } | 250 } |
241 | 251 |
242 ScriptPromise SubtleCrypto::unwrapKey(const String& rawFormat, const ArrayPiece&
wrappedKey, Key* unwrappingKey, const Dictionary& rawUnwrapAlgorithm, const Dic
tionary& rawUnwrappedKeyAlgorithm, bool extractable, const Vector<String>& rawKe
yUsages) | 252 ScriptPromise SubtleCrypto::unwrapKey(const String& rawFormat, const ArrayPiece&
wrappedKey, Key* unwrappingKey, const Dictionary& rawUnwrapAlgorithm, const Dic
tionary& rawUnwrappedKeyAlgorithm, bool extractable, const Vector<String>& rawKe
yUsages) |
243 { | 253 { |
244 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(); | 254 RefPtr<CryptoResultImpl> result = CryptoResultImpl::create(); |
245 ScriptPromise promise = result->promise(); | 255 ScriptPromise promise = result->promise(); |
246 | 256 |
247 if (!ensureNotNull(wrappedKey, "wrappedKey", result.get())) | 257 if (!ensureNotNull(wrappedKey, "wrappedKey", result.get())) |
248 return promise; | 258 return promise; |
249 if (!ensureNotNull(unwrappingKey, "unwrappingKey", result.get())) | 259 if (!ensureNotNull(unwrappingKey, "unwrappingKey", result.get())) |
250 return promise; | 260 return promise; |
251 | 261 |
252 blink::WebCryptoKeyFormat format; | 262 blink::WebCryptoKeyFormat format; |
253 if (!Key::parseFormat(rawFormat, format, result.get())) | 263 if (!Key::parseFormat(rawFormat, format, result.get())) |
254 return promise; | 264 return promise; |
255 | 265 |
256 blink::WebCryptoKeyUsageMask keyUsages; | 266 blink::WebCryptoKeyUsageMask keyUsages; |
257 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get())) | 267 if (!Key::parseUsageMask(rawKeyUsages, keyUsages, result.get())) |
258 return promise; | 268 return promise; |
259 | 269 |
260 blink::WebCryptoAlgorithm unwrapAlgorithm; | 270 blink::WebCryptoAlgorithm unwrapAlgorithm; |
261 if (!parseAlgorithm(rawUnwrapAlgorithm, UnwrapKey, unwrapAlgorithm, result.g
et())) | 271 if (!parseAlgorithm(rawUnwrapAlgorithm, blink::UnwrapKey, unwrapAlgorithm, r
esult.get())) |
262 return promise; | 272 return promise; |
263 | 273 |
264 blink::WebCryptoAlgorithm unwrappedKeyAlgorithm; | 274 blink::WebCryptoAlgorithm unwrappedKeyAlgorithm; |
265 if (!parseAlgorithm(rawUnwrappedKeyAlgorithm, ImportKey, unwrappedKeyAlgorit
hm, result.get())) | 275 if (!parseAlgorithm(rawUnwrappedKeyAlgorithm, blink::ImportKey, unwrappedKey
Algorithm, result.get())) |
266 return promise; | 276 return promise; |
267 | 277 |
268 if (!unwrappingKey->canBeUsedForAlgorithm(unwrapAlgorithm, UnwrapKey, result
.get())) | 278 if (!unwrappingKey->canBeUsedForAlgorithm(unwrapAlgorithm, blink::UnwrapKey,
result.get())) |
269 return promise; | 279 return promise; |
270 | 280 |
271 blink::Platform::current()->crypto()->unwrapKey(format, wrappedKey.bytes(),
wrappedKey.byteLength(), unwrappingKey->key(), unwrapAlgorithm, unwrappedKeyAlgo
rithm, extractable, keyUsages, result->result()); | 281 blink::Platform::current()->crypto()->unwrapKey(format, wrappedKey.bytes(),
wrappedKey.byteLength(), unwrappingKey->key(), unwrapAlgorithm, unwrappedKeyAlgo
rithm, extractable, keyUsages, result->result()); |
272 return promise; | 282 return promise; |
273 } | 283 } |
274 | 284 |
275 } // namespace WebCore | 285 } // namespace WebCore |
OLD | NEW |