| 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 29 matching lines...) Expand all Loading... |
| 40 #include "modules/crypto/Key.h" | 40 #include "modules/crypto/Key.h" |
| 41 #include "modules/crypto/KeyPair.h" | 41 #include "modules/crypto/KeyPair.h" |
| 42 #include "modules/crypto/NormalizeAlgorithm.h" | 42 #include "modules/crypto/NormalizeAlgorithm.h" |
| 43 #include "public/platform/Platform.h" | 43 #include "public/platform/Platform.h" |
| 44 #include "public/platform/WebArrayBuffer.h" | 44 #include "public/platform/WebArrayBuffer.h" |
| 45 #include "public/platform/WebCryptoAlgorithm.h" | 45 #include "public/platform/WebCryptoAlgorithm.h" |
| 46 #include "wtf/ArrayBufferView.h" | 46 #include "wtf/ArrayBufferView.h" |
| 47 | 47 |
| 48 namespace WebCore { | 48 namespace WebCore { |
| 49 | 49 |
| 50 namespace { | |
| 51 | |
| 52 class WeakResolver : public ScriptPromiseResolverWithContext { | |
| 53 public: | |
| 54 static WeakPtr<ScriptPromiseResolverWithContext> create(ScriptState* scriptS
tate) | |
| 55 { | |
| 56 RefPtr<WeakResolver> p = adoptRef(new WeakResolver(scriptState)); | |
| 57 p->suspendIfNeeded(); | |
| 58 return p->m_weakPtrFactory.createWeakPtr(); | |
| 59 } | |
| 60 | |
| 61 private: | |
| 62 explicit WeakResolver(ScriptState* scriptState) | |
| 63 : ScriptPromiseResolverWithContext(scriptState, ScriptPromiseResolverWit
hContext::KeepAliveWhilePending) | |
| 64 , m_weakPtrFactory(this) { } | |
| 65 WeakPtrFactory<ScriptPromiseResolverWithContext> m_weakPtrFactory; | |
| 66 }; | |
| 67 | |
| 68 } // namespace | |
| 69 | |
| 70 ExceptionCode webCryptoErrorToExceptionCode(blink::WebCryptoErrorType errorType) | 50 ExceptionCode webCryptoErrorToExceptionCode(blink::WebCryptoErrorType errorType) |
| 71 { | 51 { |
| 72 switch (errorType) { | 52 switch (errorType) { |
| 73 case blink::WebCryptoErrorTypeNotSupported: | 53 case blink::WebCryptoErrorTypeNotSupported: |
| 74 return NotSupportedError; | 54 return NotSupportedError; |
| 75 case blink::WebCryptoErrorTypeSyntax: | 55 case blink::WebCryptoErrorTypeSyntax: |
| 76 return SyntaxError; | 56 return SyntaxError; |
| 77 case blink::WebCryptoErrorTypeInvalidState: | 57 case blink::WebCryptoErrorTypeInvalidState: |
| 78 return InvalidStateError; | 58 return InvalidStateError; |
| 79 case blink::WebCryptoErrorTypeInvalidAccess: | 59 case blink::WebCryptoErrorTypeInvalidAccess: |
| 80 return InvalidAccessError; | 60 return InvalidAccessError; |
| 81 case blink::WebCryptoErrorTypeUnknown: | 61 case blink::WebCryptoErrorTypeUnknown: |
| 82 return UnknownError; | 62 return UnknownError; |
| 83 case blink::WebCryptoErrorTypeData: | 63 case blink::WebCryptoErrorTypeData: |
| 84 return DataError; | 64 return DataError; |
| 85 case blink::WebCryptoErrorTypeOperation: | 65 case blink::WebCryptoErrorTypeOperation: |
| 86 return OperationError; | 66 return OperationError; |
| 87 case blink::WebCryptoErrorTypeType: | 67 case blink::WebCryptoErrorTypeType: |
| 88 // FIXME: This should construct a TypeError instead. For now do | 68 // FIXME: This should construct a TypeError instead. For now do |
| 89 // something to facilitate refactor, but this will need to be | 69 // something to facilitate refactor, but this will need to be |
| 90 // revisited. | 70 // revisited. |
| 91 return DataError; | 71 return DataError; |
| 92 } | 72 } |
| 93 | 73 |
| 94 ASSERT_NOT_REACHED(); | 74 ASSERT_NOT_REACHED(); |
| 95 return 0; | 75 return 0; |
| 96 } | 76 } |
| 97 | 77 |
| 98 CryptoResultImpl::~CryptoResultImpl() | 78 // The PromiseState class contains all the state which is tied to an |
| 99 { | 79 // ExecutionContext. Whereas CryptoResultImpl can be deleted from any thread, |
| 100 } | 80 // PromiseState is not thread safe and must only be accessed and deleted from |
| 81 // the blink thread. |
| 82 // |
| 83 // This is achieved by making CryptoResultImpl hold a WeakPtr to the PromiseStat
e. |
| 84 // The PromiseState deletes itself after being notified of completion. |
| 85 // Additionally the PromiseState is deleted when the ExecutionContext is |
| 86 // destroyed (necessary to avoid leaks when dealing with WebWorker threads, |
| 87 // which may die before the operation is completed). |
| 88 class CryptoResultImpl::PromiseState FINAL { |
| 89 public: |
| 90 static WeakPtr<PromiseState> create(ScriptState* scriptState) |
| 91 { |
| 92 PromiseState* promiseState = new PromiseState(scriptState); |
| 93 return promiseState->m_weakFactory.createWeakPtr(); |
| 94 } |
| 101 | 95 |
| 102 PassRefPtr<CryptoResultImpl> CryptoResultImpl::create(ScriptState* scriptState) | 96 void contextDestroyed() |
| 103 { | 97 { |
| 104 return adoptRef(new CryptoResultImpl(scriptState)); | 98 delete this; |
| 105 } | 99 } |
| 106 | 100 |
| 107 void CryptoResultImpl::completeWithError(blink::WebCryptoErrorType errorType, co
nst blink::WebString& errorDetails) | 101 ScriptPromise promise() |
| 108 { | 102 { |
| 109 if (m_resolver) | 103 return m_promiseResolver->promise(); |
| 110 m_resolver->reject(DOMException::create(webCryptoErrorToExceptionCode(er
rorType), errorDetails)); | 104 } |
| 111 } | |
| 112 | 105 |
| 113 void CryptoResultImpl::completeWithBuffer(const blink::WebArrayBuffer& buffer) | 106 void completeWithError(blink::WebCryptoErrorType errorType, const blink::Web
String& errorDetails) |
| 114 { | 107 { |
| 115 if (m_resolver) | 108 m_promiseResolver->reject(DOMException::create(webCryptoErrorToException
Code(errorType), errorDetails)); |
| 116 m_resolver->resolve(PassRefPtr<ArrayBuffer>(buffer)); | 109 delete this; |
| 117 } | 110 } |
| 118 | 111 |
| 119 void CryptoResultImpl::completeWithJson(const char* utf8Data, unsigned length) | 112 void completeWithBuffer(const blink::WebArrayBuffer& buffer) |
| 120 { | 113 { |
| 121 if (m_resolver) { | 114 m_promiseResolver->resolve(PassRefPtr<ArrayBuffer>(buffer)); |
| 122 ScriptPromiseResolverWithContext* resolver = m_resolver.get(); | 115 delete this; |
| 123 ScriptState* scriptState = resolver->scriptState(); | 116 } |
| 117 |
| 118 void completeWithJson(const char* utf8Data, unsigned length) |
| 119 { |
| 120 ScriptState* scriptState = m_promiseResolver->scriptState(); |
| 124 ScriptState::Scope scope(scriptState); | 121 ScriptState::Scope scope(scriptState); |
| 125 | 122 |
| 126 v8::Handle<v8::String> jsonString = v8::String::NewFromUtf8(scriptState-
>isolate(), utf8Data, v8::String::kInternalizedString, length); | 123 v8::Handle<v8::String> jsonString = v8::String::NewFromUtf8(scriptState-
>isolate(), utf8Data, v8::String::kInternalizedString, length); |
| 127 | 124 |
| 128 v8::TryCatch exceptionCatcher; | 125 v8::TryCatch exceptionCatcher; |
| 129 v8::Handle<v8::Value> jsonDictionary = v8::JSON::Parse(jsonString); | 126 v8::Handle<v8::Value> jsonDictionary = v8::JSON::Parse(jsonString); |
| 130 if (exceptionCatcher.HasCaught() || jsonDictionary.IsEmpty()) { | 127 if (exceptionCatcher.HasCaught() || jsonDictionary.IsEmpty()) { |
| 131 ASSERT_NOT_REACHED(); | 128 ASSERT_NOT_REACHED(); |
| 132 resolver->reject(DOMException::create(OperationError, "Failed inflat
ing JWK JSON to object")); | 129 m_promiseResolver->reject(DOMException::create(OperationError, "Fail
ed inflating JWK JSON to object")); |
| 133 } else { | 130 } else { |
| 134 resolver->resolve(jsonDictionary); | 131 m_promiseResolver->resolve(jsonDictionary); |
| 135 } | 132 } |
| 133 delete this; |
| 136 } | 134 } |
| 135 |
| 136 void completeWithBoolean(bool b) |
| 137 { |
| 138 m_promiseResolver->resolve(b); |
| 139 delete this; |
| 140 } |
| 141 |
| 142 void completeWithKey(const blink::WebCryptoKey& key) |
| 143 { |
| 144 m_promiseResolver->resolve(Key::create(key)); |
| 145 delete this; |
| 146 } |
| 147 |
| 148 void completeWithKeyPair(const blink::WebCryptoKey& publicKey, const blink::
WebCryptoKey& privateKey) |
| 149 { |
| 150 m_promiseResolver->resolve(KeyPair::create(publicKey, privateKey)); |
| 151 delete this; |
| 152 } |
| 153 |
| 154 private: |
| 155 // This subclass of ScriptPromiseResolverWithContext is to be notified |
| 156 // when the context was destroyed. |
| 157 class PromiseResolver FINAL : public ScriptPromiseResolverWithContext { |
| 158 public: |
| 159 static PassRefPtr<PromiseResolver> create(ScriptState* scriptState, Prom
iseState* promiseState) |
| 160 { |
| 161 RefPtr<PromiseResolver> resolver = adoptRef(new PromiseResolver(scri
ptState, promiseState)); |
| 162 resolver->suspendIfNeeded(); |
| 163 return resolver.release(); |
| 164 } |
| 165 |
| 166 virtual void contextDestroyed() OVERRIDE |
| 167 { |
| 168 ScriptPromiseResolverWithContext::contextDestroyed(); |
| 169 m_promiseState->contextDestroyed(); |
| 170 } |
| 171 |
| 172 private: |
| 173 explicit PromiseResolver(ScriptState* scriptState, PromiseState* promise
State) |
| 174 : ScriptPromiseResolverWithContext(scriptState) |
| 175 , m_promiseState(promiseState) |
| 176 { |
| 177 } |
| 178 |
| 179 PromiseState* m_promiseState; |
| 180 }; |
| 181 |
| 182 explicit PromiseState(ScriptState* scriptState) |
| 183 : m_weakFactory(this) |
| 184 , m_promiseResolver(PromiseResolver::create(scriptState, this)) |
| 185 { |
| 186 } |
| 187 |
| 188 WeakPtrFactory<PromiseState> m_weakFactory; |
| 189 RefPtr<PromiseResolver> m_promiseResolver; |
| 190 }; |
| 191 |
| 192 CryptoResultImpl::~CryptoResultImpl() |
| 193 { |
| 194 } |
| 195 |
| 196 PassRefPtr<CryptoResultImpl> CryptoResultImpl::create(ScriptState* scriptState) |
| 197 { |
| 198 return adoptRef(new CryptoResultImpl(scriptState)); |
| 199 } |
| 200 |
| 201 void CryptoResultImpl::completeWithError(blink::WebCryptoErrorType errorType, co
nst blink::WebString& errorDetails) |
| 202 { |
| 203 if (m_promiseState) |
| 204 m_promiseState->completeWithError(errorType, errorDetails); |
| 205 } |
| 206 |
| 207 void CryptoResultImpl::completeWithBuffer(const blink::WebArrayBuffer& buffer) |
| 208 { |
| 209 if (m_promiseState) |
| 210 m_promiseState->completeWithBuffer(buffer); |
| 211 } |
| 212 |
| 213 void CryptoResultImpl::completeWithJson(const char* utf8Data, unsigned length) |
| 214 { |
| 215 if (m_promiseState) |
| 216 m_promiseState->completeWithJson(utf8Data, length); |
| 137 } | 217 } |
| 138 | 218 |
| 139 void CryptoResultImpl::completeWithBoolean(bool b) | 219 void CryptoResultImpl::completeWithBoolean(bool b) |
| 140 { | 220 { |
| 141 if (m_resolver) | 221 if (m_promiseState) |
| 142 m_resolver->resolve(b); | 222 m_promiseState->completeWithBoolean(b); |
| 143 } | 223 } |
| 144 | 224 |
| 145 void CryptoResultImpl::completeWithKey(const blink::WebCryptoKey& key) | 225 void CryptoResultImpl::completeWithKey(const blink::WebCryptoKey& key) |
| 146 { | 226 { |
| 147 if (m_resolver) | 227 if (m_promiseState) |
| 148 m_resolver->resolve(Key::create(key)); | 228 m_promiseState->completeWithKey(key); |
| 149 } | 229 } |
| 150 | 230 |
| 151 void CryptoResultImpl::completeWithKeyPair(const blink::WebCryptoKey& publicKey,
const blink::WebCryptoKey& privateKey) | 231 void CryptoResultImpl::completeWithKeyPair(const blink::WebCryptoKey& publicKey,
const blink::WebCryptoKey& privateKey) |
| 152 { | 232 { |
| 153 if (m_resolver) | 233 if (m_promiseState) |
| 154 m_resolver->resolve(KeyPair::create(publicKey, privateKey)); | 234 m_promiseState->completeWithKeyPair(publicKey, privateKey); |
| 155 } | 235 } |
| 156 | 236 |
| 157 CryptoResultImpl::CryptoResultImpl(ScriptState* scriptState) | 237 CryptoResultImpl::CryptoResultImpl(ScriptState* scriptState) |
| 158 : m_resolver(WeakResolver::create(scriptState)) | 238 : m_promiseState(PromiseState::create(scriptState)) |
| 159 { | 239 { |
| 160 } | 240 } |
| 161 | 241 |
| 162 ScriptPromise CryptoResultImpl::promise() | 242 ScriptPromise CryptoResultImpl::promise() |
| 163 { | 243 { |
| 164 return m_resolver->promise(); | 244 return m_promiseState->promise(); |
| 165 } | 245 } |
| 166 | 246 |
| 167 } // namespace WebCore | 247 } // namespace WebCore |
| OLD | NEW |