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