Bug 1805294 [wpt PR 37463] - WebKit export of https://bugs.webkit.org/show_bug.cgi...
[gecko.git] / dom / crypto / WebCryptoTask.h
blobf3ef0f562d2678dddb330a1d4c14efc2f7d1f32c
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_WebCryptoTask_h
8 #define mozilla_dom_WebCryptoTask_h
10 #include "ScopedNSSTypes.h"
11 #include "mozilla/dom/CryptoKey.h"
12 #include "mozilla/dom/DOMException.h"
13 #include "mozilla/dom/Promise.h"
14 #include "mozilla/dom/SubtleCryptoBinding.h"
15 #include "nsIGlobalObject.h"
17 namespace mozilla::dom {
19 class ThreadSafeWorkerRef;
21 typedef ArrayBufferViewOrArrayBuffer CryptoOperationData;
22 typedef ArrayBufferViewOrArrayBuffer KeyData;
26 The execution of a WebCryptoTask happens in several phases
28 1. Constructor
29 2. BeforeCrypto
30 3. CalculateResult -> DoCrypto
31 4. AfterCrypto
32 5. Resolve or FailWithError
33 6. Cleanup
35 If any of these steps produces an error (setting mEarlyRv), then
36 subsequent steps will not proceed. If the constructor or BeforeCrypto
37 sets mEarlyComplete to true, then we will skip step 3, saving the
38 thread overhead.
40 In general, the constructor should handle any parsing steps that
41 require JS context, and otherwise just cache information for later
42 steps to use.
44 All steps besides step 3 occur on the main thread, so they should
45 avoid blocking operations.
47 Only step 3 is guarded to ensure that NSS has not been shutdown,
48 so all NSS interactions should occur in DoCrypto
50 Cleanup should execute regardless of what else happens.
54 #define MAYBE_EARLY_FAIL(rv) \
55 if (NS_FAILED(rv)) { \
56 FailWithError(rv); \
57 return; \
60 class WebCryptoTask : public CancelableRunnable {
61 public:
62 virtual void DispatchWithPromise(Promise* aResultPromise);
64 protected:
65 static WebCryptoTask* CreateEncryptDecryptTask(
66 JSContext* aCx, const ObjectOrString& aAlgorithm, CryptoKey& aKey,
67 const CryptoOperationData& aData, bool aEncrypt);
69 static WebCryptoTask* CreateSignVerifyTask(
70 JSContext* aCx, const ObjectOrString& aAlgorithm, CryptoKey& aKey,
71 const CryptoOperationData& aSignature, const CryptoOperationData& aData,
72 bool aSign);
74 public:
75 static WebCryptoTask* CreateEncryptTask(JSContext* aCx,
76 const ObjectOrString& aAlgorithm,
77 CryptoKey& aKey,
78 const CryptoOperationData& aData) {
79 return CreateEncryptDecryptTask(aCx, aAlgorithm, aKey, aData, true);
82 static WebCryptoTask* CreateDecryptTask(JSContext* aCx,
83 const ObjectOrString& aAlgorithm,
84 CryptoKey& aKey,
85 const CryptoOperationData& aData) {
86 return CreateEncryptDecryptTask(aCx, aAlgorithm, aKey, aData, false);
89 static WebCryptoTask* CreateSignTask(JSContext* aCx,
90 const ObjectOrString& aAlgorithm,
91 CryptoKey& aKey,
92 const CryptoOperationData& aData) {
93 CryptoOperationData dummy;
94 dummy.SetAsArrayBuffer(aCx);
95 return CreateSignVerifyTask(aCx, aAlgorithm, aKey, dummy, aData, true);
98 static WebCryptoTask* CreateVerifyTask(JSContext* aCx,
99 const ObjectOrString& aAlgorithm,
100 CryptoKey& aKey,
101 const CryptoOperationData& aSignature,
102 const CryptoOperationData& aData) {
103 return CreateSignVerifyTask(aCx, aAlgorithm, aKey, aSignature, aData,
104 false);
107 static WebCryptoTask* CreateDigestTask(JSContext* aCx,
108 const ObjectOrString& aAlgorithm,
109 const CryptoOperationData& aData);
111 static WebCryptoTask* CreateImportKeyTask(
112 nsIGlobalObject* aGlobal, JSContext* aCx, const nsAString& aFormat,
113 JS::Handle<JSObject*> aKeyData, const ObjectOrString& aAlgorithm,
114 bool aExtractable, const Sequence<nsString>& aKeyUsages);
115 static WebCryptoTask* CreateExportKeyTask(const nsAString& aFormat,
116 CryptoKey& aKey);
117 static WebCryptoTask* CreateGenerateKeyTask(
118 nsIGlobalObject* aGlobal, JSContext* aCx,
119 const ObjectOrString& aAlgorithm, bool aExtractable,
120 const Sequence<nsString>& aKeyUsages);
122 static WebCryptoTask* CreateDeriveKeyTask(
123 nsIGlobalObject* aGlobal, JSContext* aCx,
124 const ObjectOrString& aAlgorithm, CryptoKey& aBaseKey,
125 const ObjectOrString& aDerivedKeyType, bool extractable,
126 const Sequence<nsString>& aKeyUsages);
127 static WebCryptoTask* CreateDeriveBitsTask(JSContext* aCx,
128 const ObjectOrString& aAlgorithm,
129 CryptoKey& aKey, uint32_t aLength);
131 static WebCryptoTask* CreateWrapKeyTask(JSContext* aCx,
132 const nsAString& aFormat,
133 CryptoKey& aKey,
134 CryptoKey& aWrappingKey,
135 const ObjectOrString& aWrapAlgorithm);
136 static WebCryptoTask* CreateUnwrapKeyTask(
137 nsIGlobalObject* aGlobal, JSContext* aCx, const nsAString& aFormat,
138 const ArrayBufferViewOrArrayBuffer& aWrappedKey,
139 CryptoKey& aUnwrappingKey, const ObjectOrString& aUnwrapAlgorithm,
140 const ObjectOrString& aUnwrappedKeyAlgorithm, bool aExtractable,
141 const Sequence<nsString>& aKeyUsages);
143 protected:
144 RefPtr<Promise> mResultPromise;
145 nsresult mEarlyRv;
146 bool mEarlyComplete;
148 WebCryptoTask();
149 virtual ~WebCryptoTask();
151 bool IsOnOriginalThread() {
152 return !mOriginalEventTarget || mOriginalEventTarget->IsOnCurrentThread();
155 // For things that need to happen on the main thread
156 // either before or after CalculateResult
157 virtual nsresult BeforeCrypto() { return NS_OK; }
158 virtual nsresult DoCrypto() { return NS_OK; }
159 virtual nsresult AfterCrypto() { return NS_OK; }
160 virtual void Resolve() {}
161 virtual void Cleanup() {}
163 void FailWithError(nsresult aRv);
165 nsresult CalculateResult();
167 void CallCallback(nsresult rv);
169 private:
170 NS_IMETHOD Run() final;
171 nsresult Cancel() final;
173 nsCOMPtr<nsISerialEventTarget> mOriginalEventTarget;
174 RefPtr<ThreadSafeWorkerRef> mWorkerRef;
175 nsresult mRv;
178 // XXX This class is declared here (unlike others) to enable reuse by WebRTC.
179 class GenerateAsymmetricKeyTask : public WebCryptoTask {
180 public:
181 GenerateAsymmetricKeyTask(nsIGlobalObject* aGlobal, JSContext* aCx,
182 const ObjectOrString& aAlgorithm, bool aExtractable,
183 const Sequence<nsString>& aKeyUsages);
185 protected:
186 UniquePLArenaPool mArena;
187 UniquePtr<CryptoKeyPair> mKeyPair;
188 nsString mAlgName;
189 CK_MECHANISM_TYPE mMechanism;
190 PK11RSAGenParams mRsaParams;
191 SECKEYDHParams mDhParams;
192 nsString mNamedCurve;
194 virtual nsresult DoCrypto() override;
195 virtual void Resolve() override;
196 virtual void Cleanup() override;
198 private:
199 UniqueSECKEYPublicKey mPublicKey;
200 UniqueSECKEYPrivateKey mPrivateKey;
203 } // namespace mozilla::dom
205 #endif // mozilla_dom_WebCryptoTask_h