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

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

Issue 19885002: WebCrypto: Add interfaces for importKey(). (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 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 | Annotate | Revision Log
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 13 matching lines...) Expand all
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31 #include "config.h" 31 #include "config.h"
32 #include "modules/crypto/SubtleCrypto.h" 32 #include "modules/crypto/SubtleCrypto.h"
33 33
34 #include "V8Key.h" // NOTE: This must appear before ScriptPromiseResolver to def ine toV8()
35 #include "bindings/v8/ScriptPromiseResolver.h"
34 #include "core/dom/ExceptionCode.h" 36 #include "core/dom/ExceptionCode.h"
35 #include "modules/crypto/CryptoOperation.h" 37 #include "modules/crypto/CryptoOperation.h"
38 #include "modules/crypto/Key.h"
36 #include "modules/crypto/NormalizeAlgorithm.h" 39 #include "modules/crypto/NormalizeAlgorithm.h"
37 #include "public/platform/Platform.h" 40 #include "public/platform/Platform.h"
38 #include "public/platform/WebArrayBuffer.h" // FIXME: temporary 41 #include "public/platform/WebArrayBuffer.h" // FIXME: temporary
39 #include "public/platform/WebCrypto.h" 42 #include "public/platform/WebCrypto.h"
43 #include "public/platform/WebCryptoAlgorithmParams.h"
40 #include "wtf/ArrayBuffer.h" 44 #include "wtf/ArrayBuffer.h"
41 #include "wtf/ArrayBufferView.h" 45 #include "wtf/ArrayBufferView.h"
42 #include "wtf/SHA1.h" // FIXME: temporary 46 #include "wtf/SHA1.h" // FIXME: temporary
43 47
44 48
45 namespace WebCore { 49 namespace WebCore {
46 50
47 namespace { 51 namespace {
48 52
49 // FIXME: The following are temporary implementations of what *should* go on the 53 // FIXME: The following are temporary implementations of what *should* go on the
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 memcpy(buffer.data(), hash.data(), hash.size()); 98 memcpy(buffer.data(), hash.data(), hash.size());
95 99
96 m_result->completeWithArrayBuffer(buffer); 100 m_result->completeWithArrayBuffer(buffer);
97 delete this; 101 delete this;
98 } 102 }
99 103
100 private: 104 private:
101 SHA1 m_sha1; 105 SHA1 m_sha1;
102 }; 106 };
103 107
104 class MockPlatformCrypto : public WebKit::WebCrypto { 108 class MockPlatformCrypto : public WebKit::WebCrypto {
abarth-chromium 2013/07/20 06:32:00 It would be better if these mock implementations w
eroman 2013/07/22 17:02:06 Thanks Adam. I am trying to wrap my head around h
105 public: 109 public:
106 virtual void digest(const WebKit::WebCryptoAlgorithm& algorithm, WebKit::Web CryptoOperationResult* result) OVERRIDE 110 virtual void digest(const WebKit::WebCryptoAlgorithm& algorithm, WebKit::Web CryptoOperationResult* result) OVERRIDE
107 { 111 {
108 if (algorithm.id() == WebKit::WebCryptoAlgorithmIdSha1) { 112 if (algorithm.id() == WebKit::WebCryptoAlgorithmIdSha1) {
109 result->initializationSucceded(new MockSha1Operation(result)); 113 result->initializationSucceded(new MockSha1Operation(result));
110 } else { 114 } else {
111 // Don't fail synchronously, since existing layout tests rely on 115 // Don't fail synchronously, since existing layout tests rely on
112 // digest for testing algorithm normalization. 116 // digest for testing algorithm normalization.
113 result->initializationSucceded(new DummyOperation(result)); 117 result->initializationSucceded(new DummyOperation(result));
114 } 118 }
115 } 119 }
120
121 virtual void importKey(WebKit::WebCryptoKeyFormat, const unsigned char* keyD ata, size_t keyDataSize, const WebKit::WebCryptoAlgorithm& algorithm, bool extra ctable, WebKit::WebCryptoKeyUsageMask usages, WebKit::WebCryptoKeyOperationResul t* result)
122 {
123 String keyDataString(keyData, keyDataSize);
124
125 WebKit::WebCryptoKeyType type;
126 if (keyDataString == "reject") {
127 result->completeWithError();
128 } else if (keyDataString == "throw") {
129 result->initializationFailed();
130 } else {
131 if (keyDataString == "public") {
132 type = WebKit::WebCryptoKeyTypePublic;
133 } else if (keyDataString == "private") {
134 type = WebKit::WebCryptoKeyTypePrivate;
135 }
136 result->completeWithKey(WebKit::WebCryptoKey::create(0, type, extrac table, algorithm, usages));
137 }
138 }
116 }; 139 };
117 140
118 WebKit::WebCrypto* mockPlatformCrypto() 141 WebKit::WebCrypto* mockPlatformCrypto()
119 { 142 {
120 DEFINE_STATIC_LOCAL(MockPlatformCrypto, crypto, ()); 143 DEFINE_STATIC_LOCAL(MockPlatformCrypto, crypto, ());
121 return &crypto; 144 return &crypto;
122 } 145 }
123 146
124 PassRefPtr<CryptoOperation> doDummyOperation(const Dictionary& rawAlgorithm, Alg orithmOperation operationType, ExceptionCode& ec) 147 PassRefPtr<CryptoOperation> doDummyOperation(const Dictionary& rawAlgorithm, Alg orithmOperation operationType, ExceptionCode& ec)
125 { 148 {
126 WebKit::WebCryptoAlgorithm algorithm; 149 WebKit::WebCryptoAlgorithm algorithm;
127 if (!normalizeAlgorithm(rawAlgorithm, operationType, algorithm, ec)) 150 if (!normalizeAlgorithm(rawAlgorithm, operationType, algorithm, ec))
128 return 0; 151 return 0;
129 152
130 RefPtr<CryptoOperation> op = CryptoOperation::create(algorithm, &ec); 153 RefPtr<CryptoOperation> op = CryptoOperation::create(algorithm, &ec);
131 op->initializationSucceded(new DummyOperation(op.get())); 154 op->initializationSucceded(new DummyOperation(op.get()));
132 return op.release(); 155 return op.release();
133 } 156 }
134 //------------------------------------------------------------------------------ 157 //------------------------------------------------------------------------------
158 //
159 //
160 class KeyOperation : public WebKit::WebCryptoKeyOperationResult {
161 public:
162 KeyOperation(ScriptPromiseResolver* resolver, ExceptionCode* ec)
163 : m_state(Initializing)
164 , m_impl(0)
165 , m_promiseResolver(resolver)
166 , m_exceptionCode(ec)
167 {
168 }
169
170 ~KeyOperation();
171
172 // Implementation of WebKit::WebCryptoKeyOperationResult.
173 virtual void initializationFailed() OVERRIDE;
174 virtual void initializationSucceeded(WebKit::WebCryptoKeyOperation*) OVERRID E;
175 virtual void completeWithError() OVERRIDE;
176 virtual void completeWithKey(const WebKit::WebCryptoKey&) OVERRIDE;
177
178 private:
179 enum State {
180 Initializing,
181 InProgress,
182 Done,
183 };
184
185 State m_state;
186 WebKit::WebCryptoKeyOperation* m_impl;
187 ExceptionCode* m_exceptionCode;
188 RefPtr<ScriptPromiseResolver> m_promiseResolver;
189 };
190
191 KeyOperation::~KeyOperation()
192 {
193 // Abort any inprogress operation.
194 switch (m_state) {
195 case Initializing:
196 ASSERT_NOT_REACHED();
197 break;
198 case InProgress:
199 // This will cause m_impl to be deleted.
200 m_state = Done;
201 m_impl->abort();
202 m_impl = 0;
203 case Done:
204 ASSERT(!m_impl);
205 break;
206 }
207 }
208
209 void KeyOperation::initializationFailed()
210 {
211 ASSERT(m_state == Initializing);
212
213 *m_exceptionCode = NotSupportedError;
214
215 m_exceptionCode = 0;
216 m_state = Done;
217 delete this;
218 }
219
220 void KeyOperation::initializationSucceeded(WebKit::WebCryptoKeyOperation* operat ionImpl)
221 {
222 ASSERT(m_state == Initializing);
223 ASSERT(operationImpl);
224 ASSERT(!m_impl);
225
226 m_exceptionCode = 0;
227 m_impl = operationImpl;
228 m_state = InProgress;
229 }
230
231 void KeyOperation::completeWithError()
232 {
233 ASSERT(m_state == Initializing || m_state == InProgress);
234
235 m_exceptionCode = 0;
236 m_impl = 0;
237 m_state = Done;
238
239 m_promiseResolver->reject(ScriptValue::createNull());
240 delete this;
241 }
242
243 void KeyOperation::completeWithKey(const WebKit::WebCryptoKey& key)
244 {
245 ASSERT(m_state == Initializing || m_state == InProgress);
246
247 m_exceptionCode = 0;
248 m_impl = 0;
249 m_state = Done;
250
251 m_promiseResolver->fulfill(Key::create(key));
252 delete this;
253 }
135 254
136 } // namespace 255 } // namespace
137 256
138 SubtleCrypto::SubtleCrypto() 257 SubtleCrypto::SubtleCrypto()
139 { 258 {
140 ScriptWrappable::init(this); 259 ScriptWrappable::init(this);
141 } 260 }
142 261
143 PassRefPtr<CryptoOperation> SubtleCrypto::encrypt(const Dictionary& rawAlgorithm , ExceptionCode& ec) 262 PassRefPtr<CryptoOperation> SubtleCrypto::encrypt(const Dictionary& rawAlgorithm , ExceptionCode& ec)
144 { 263 {
(...skipping 25 matching lines...) Expand all
170 289
171 WebKit::WebCryptoAlgorithm algorithm; 290 WebKit::WebCryptoAlgorithm algorithm;
172 if (!normalizeAlgorithm(rawAlgorithm, Digest, algorithm, ec)) 291 if (!normalizeAlgorithm(rawAlgorithm, Digest, algorithm, ec))
173 return 0; 292 return 0;
174 293
175 RefPtr<CryptoOperation> op = CryptoOperation::create(algorithm, &ec); 294 RefPtr<CryptoOperation> op = CryptoOperation::create(algorithm, &ec);
176 platformCrypto->digest(algorithm, op.get()); 295 platformCrypto->digest(algorithm, op.get());
177 return op.release(); 296 return op.release();
178 } 297 }
179 298
299 ScriptObject SubtleCrypto::importKey(const String& rawFormat, ArrayBufferView* k eyData, const Dictionary& rawAlgorithm, bool extractable, const Vector<String>& rawKeyUsages, ExceptionCode& ec)
300 {
301 WebKit::WebCrypto* platformCrypto = mockPlatformCrypto();
302 if (!platformCrypto) {
303 ec = NotSupportedError;
304 return ScriptObject();
305 }
306
307 WebKit::WebCryptoKeyUsageMask keyUsages;
308 if (!Key::parseUsageMask(rawKeyUsages, keyUsages)) {
309 ec = TypeError;
310 return ScriptObject();
311 }
312
313 WebKit::WebCryptoKeyFormat format;
314 if (!Key::parseFormat(rawFormat, format)) {
315 ec = TypeError;
316 return ScriptObject();
317 }
318
319 WebKit::WebCryptoAlgorithm algorithm;
320 if (!normalizeAlgorithmForImportKey(rawAlgorithm, algorithm, ec))
321 return ScriptObject();
322
323 const unsigned char* keyDataBytes = static_cast<unsigned char*>(keyData->bas eAddress());
324
325 RefPtr<ScriptPromiseResolver> promiseResolver = ScriptPromiseResolver::creat e();
326
327 // The |op| object is deleted upon completion of the underlying operation
328 // (i.e. when platformCrypto->importKey() notifies completion).
329 //
330 // FIXME: KeyOperation is never aborted. It should probably be aborted when
331 // the SubtleCrypto object that started it gets deleted. The concern being
332 // if the operation eventually does complete, the ScriptPromiseResolver
333 // might no longer be valid because the context it belonged to got torn
334 // down.
335 KeyOperation* op = new KeyOperation(promiseResolver.get(), &ec);
336 platformCrypto->importKey(format, keyDataBytes, keyData->byteLength(), algor ithm, extractable, keyUsages, op);
337 return promiseResolver->promise();
338 }
339
180 } // namespace WebCore 340 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698