Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/dom/WebCryptoTask.h
Line
Count
Source (jump to first uncovered line)
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/. */
6
7
#ifndef mozilla_dom_WebCryptoTask_h
8
#define mozilla_dom_WebCryptoTask_h
9
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"
16
17
namespace mozilla {
18
namespace dom {
19
20
class ThreadSafeWorkerRef;
21
22
typedef ArrayBufferViewOrArrayBuffer CryptoOperationData;
23
typedef ArrayBufferViewOrArrayBuffer KeyData;
24
25
/*
26
27
The execution of a WebCryptoTask happens in several phases
28
29
1. Constructor
30
2. BeforeCrypto
31
3. CalculateResult -> DoCrypto
32
4. AfterCrypto
33
5. Resolve or FailWithError
34
6. Cleanup
35
36
If any of these steps produces an error (setting mEarlyRv), then
37
subsequent steps will not proceed.  If the constructor or BeforeCrypto
38
sets mEarlyComplete to true, then we will skip step 3, saving the
39
thread overhead.
40
41
In general, the constructor should handle any parsing steps that
42
require JS context, and otherwise just cache information for later
43
steps to use.
44
45
All steps besides step 3 occur on the main thread, so they should
46
avoid blocking operations.
47
48
Only step 3 is guarded to ensure that NSS has not been shutdown,
49
so all NSS interactions should occur in DoCrypto
50
51
Cleanup should execute regardless of what else happens.
52
53
*/
54
55
0
#define MAYBE_EARLY_FAIL(rv) \
56
0
if (NS_FAILED(rv)) { \
57
0
  FailWithError(rv); \
58
0
  return; \
59
0
}
60
61
class WebCryptoTask : public CancelableRunnable
62
{
63
public:
64
  virtual void DispatchWithPromise(Promise* aResultPromise);
65
66
protected:
67
  static WebCryptoTask* CreateEncryptDecryptTask(JSContext* aCx,
68
                           const ObjectOrString& aAlgorithm,
69
                           CryptoKey& aKey,
70
                           const CryptoOperationData& aData,
71
                           bool aEncrypt);
72
73
  static WebCryptoTask* CreateSignVerifyTask(JSContext* aCx,
74
                          const ObjectOrString& aAlgorithm,
75
                          CryptoKey& aKey,
76
                          const CryptoOperationData& aSignature,
77
                          const CryptoOperationData& aData,
78
                          bool aSign);
79
80
public:
81
  static WebCryptoTask* CreateEncryptTask(JSContext* aCx,
82
                          const ObjectOrString& aAlgorithm,
83
                          CryptoKey& aKey,
84
                          const CryptoOperationData& aData)
85
0
  {
86
0
    return CreateEncryptDecryptTask(aCx, aAlgorithm, aKey, aData, true);
87
0
  }
88
89
  static WebCryptoTask* CreateDecryptTask(JSContext* aCx,
90
                          const ObjectOrString& aAlgorithm,
91
                          CryptoKey& aKey,
92
                          const CryptoOperationData& aData)
93
0
  {
94
0
    return CreateEncryptDecryptTask(aCx, aAlgorithm, aKey, aData, false);
95
0
  }
96
97
  static WebCryptoTask* CreateSignTask(JSContext* aCx,
98
                          const ObjectOrString& aAlgorithm,
99
                          CryptoKey& aKey,
100
                          const CryptoOperationData& aData)
101
0
  {
102
0
    CryptoOperationData dummy;
103
0
    dummy.SetAsArrayBuffer(aCx);
104
0
    return CreateSignVerifyTask(aCx, aAlgorithm, aKey, dummy, aData, true);
105
0
  }
106
107
  static WebCryptoTask* CreateVerifyTask(JSContext* aCx,
108
                          const ObjectOrString& aAlgorithm,
109
                          CryptoKey& aKey,
110
                          const CryptoOperationData& aSignature,
111
                          const CryptoOperationData& aData)
112
0
  {
113
0
    return CreateSignVerifyTask(aCx, aAlgorithm, aKey, aSignature, aData, false);
114
0
  }
115
116
  static WebCryptoTask* CreateDigestTask(JSContext* aCx,
117
                          const ObjectOrString& aAlgorithm,
118
                          const CryptoOperationData& aData);
119
120
  static WebCryptoTask* CreateImportKeyTask(nsIGlobalObject* aGlobal,
121
                          JSContext* aCx,
122
                          const nsAString& aFormat,
123
                          JS::Handle<JSObject*> aKeyData,
124
                          const ObjectOrString& aAlgorithm,
125
                          bool aExtractable,
126
                          const Sequence<nsString>& aKeyUsages);
127
  static WebCryptoTask* CreateExportKeyTask(const nsAString& aFormat,
128
                          CryptoKey& aKey);
129
  static WebCryptoTask* CreateGenerateKeyTask(nsIGlobalObject* aGlobal,
130
                          JSContext* aCx,
131
                          const ObjectOrString& aAlgorithm,
132
                          bool aExtractable,
133
                          const Sequence<nsString>& aKeyUsages);
134
135
  static WebCryptoTask* CreateDeriveKeyTask(nsIGlobalObject* aGlobal,
136
                          JSContext* aCx,
137
                          const ObjectOrString& aAlgorithm,
138
                          CryptoKey& aBaseKey,
139
                          const ObjectOrString& aDerivedKeyType,
140
                          bool extractable,
141
                          const Sequence<nsString>& aKeyUsages);
142
  static WebCryptoTask* CreateDeriveBitsTask(JSContext* aCx,
143
                          const ObjectOrString& aAlgorithm,
144
                          CryptoKey& aKey,
145
                          uint32_t aLength);
146
147
  static WebCryptoTask* CreateWrapKeyTask(JSContext* aCx,
148
                          const nsAString& aFormat,
149
                          CryptoKey& aKey,
150
                          CryptoKey& aWrappingKey,
151
                          const ObjectOrString& aWrapAlgorithm);
152
  static WebCryptoTask* CreateUnwrapKeyTask(nsIGlobalObject* aGlobal,
153
                          JSContext* aCx,
154
                          const nsAString& aFormat,
155
                          const ArrayBufferViewOrArrayBuffer& aWrappedKey,
156
                          CryptoKey& aUnwrappingKey,
157
                          const ObjectOrString& aUnwrapAlgorithm,
158
                          const ObjectOrString& aUnwrappedKeyAlgorithm,
159
                          bool aExtractable,
160
                          const Sequence<nsString>& aKeyUsages);
161
162
protected:
163
  RefPtr<Promise> mResultPromise;
164
  nsresult mEarlyRv;
165
  bool mEarlyComplete;
166
167
  WebCryptoTask();
168
  virtual ~WebCryptoTask();
169
170
0
  bool IsOnOriginalThread() {
171
0
    return !mOriginalEventTarget || mOriginalEventTarget->IsOnCurrentThread();
172
0
  }
173
174
  // For things that need to happen on the main thread
175
  // either before or after CalculateResult
176
0
  virtual nsresult BeforeCrypto() { return NS_OK; }
177
0
  virtual nsresult DoCrypto() { return NS_OK; }
178
0
  virtual nsresult AfterCrypto() { return NS_OK; }
179
0
  virtual void Resolve() {}
180
0
  virtual void Cleanup() {}
181
182
  void FailWithError(nsresult aRv);
183
184
  nsresult CalculateResult();
185
186
  void CallCallback(nsresult rv);
187
188
private:
189
  NS_IMETHOD Run() final;
190
  nsresult Cancel() final;
191
192
  nsCOMPtr<nsISerialEventTarget> mOriginalEventTarget;
193
  RefPtr<ThreadSafeWorkerRef> mWorkerRef;
194
  nsresult mRv;
195
};
196
197
// XXX This class is declared here (unlike others) to enable reuse by WebRTC.
198
class GenerateAsymmetricKeyTask : public WebCryptoTask
199
{
200
public:
201
  GenerateAsymmetricKeyTask(nsIGlobalObject* aGlobal, JSContext* aCx,
202
                            const ObjectOrString& aAlgorithm, bool aExtractable,
203
                            const Sequence<nsString>& aKeyUsages);
204
protected:
205
  UniquePLArenaPool mArena;
206
  UniquePtr<CryptoKeyPair> mKeyPair;
207
  nsString mAlgName;
208
  CK_MECHANISM_TYPE mMechanism;
209
  PK11RSAGenParams mRsaParams;
210
  SECKEYDHParams mDhParams;
211
  nsString mNamedCurve;
212
213
  virtual nsresult DoCrypto() override;
214
  virtual void Resolve() override;
215
  virtual void Cleanup() override;
216
217
private:
218
  UniqueSECKEYPublicKey mPublicKey;
219
  UniqueSECKEYPrivateKey mPrivateKey;
220
};
221
222
} // namespace dom
223
} // namespace mozilla
224
225
#endif // mozilla_dom_WebCryptoTask_h