security/manager/ssl/src/nsCertVerificationThread.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:634c860be6d9
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #include "nsCertVerificationThread.h"
6 #include "nsThreadUtils.h"
7 #include "nsProxyRelease.h"
8
9 using namespace mozilla;
10
11 nsCertVerificationThread *nsCertVerificationThread::verification_thread_singleton;
12
13 NS_IMPL_ISUPPORTS(nsCertVerificationResult, nsICertVerificationResult)
14
15 namespace {
16 class DispatchCertVerificationResult : public nsRunnable
17 {
18 public:
19 DispatchCertVerificationResult(const nsMainThreadPtrHandle<nsICertVerificationListener>& aListener,
20 nsIX509Cert3* aCert,
21 nsICertVerificationResult* aResult)
22 : mListener(aListener)
23 , mCert(aCert)
24 , mResult(aResult)
25 { }
26
27 NS_IMETHOD Run() {
28 mListener->Notify(mCert, mResult);
29 return NS_OK;
30 }
31
32 private:
33 nsMainThreadPtrHandle<nsICertVerificationListener> mListener;
34 nsCOMPtr<nsIX509Cert3> mCert;
35 nsCOMPtr<nsICertVerificationResult> mResult;
36 };
37 } // anonymous namespace
38
39 void nsCertVerificationJob::Run()
40 {
41 if (!mListener || !mCert)
42 return;
43
44 uint32_t verified;
45 uint32_t count;
46 char16_t **usages;
47
48 nsCOMPtr<nsICertVerificationResult> ires;
49 RefPtr<nsCertVerificationResult> vres(new nsCertVerificationResult);
50 if (vres)
51 {
52 nsresult rv = mCert->GetUsagesArray(false, // do not ignore OCSP
53 &verified,
54 &count,
55 &usages);
56 vres->mRV = rv;
57 if (NS_SUCCEEDED(rv))
58 {
59 vres->mVerified = verified;
60 vres->mCount = count;
61 vres->mUsages = usages;
62 }
63
64 ires = vres;
65 }
66
67 nsCOMPtr<nsIX509Cert3> c3 = do_QueryInterface(mCert);
68 nsCOMPtr<nsIRunnable> r = new DispatchCertVerificationResult(mListener, c3, ires);
69 NS_DispatchToMainThread(r);
70 }
71
72 void nsSMimeVerificationJob::Run()
73 {
74 if (!mMessage || !mListener)
75 return;
76
77 nsresult rv;
78
79 if (digest_data)
80 rv = mMessage->VerifyDetachedSignature(digest_data, digest_len);
81 else
82 rv = mMessage->VerifySignature();
83
84 nsCOMPtr<nsICMSMessage2> m2 = do_QueryInterface(mMessage);
85 mListener->Notify(m2, rv);
86 }
87
88 nsCertVerificationThread::nsCertVerificationThread()
89 : mJobQ(nullptr)
90 {
91 NS_ASSERTION(!verification_thread_singleton,
92 "nsCertVerificationThread is a singleton, caller attempts"
93 " to create another instance!");
94
95 verification_thread_singleton = this;
96 }
97
98 nsCertVerificationThread::~nsCertVerificationThread()
99 {
100 verification_thread_singleton = nullptr;
101 }
102
103 nsresult nsCertVerificationThread::addJob(nsBaseVerificationJob *aJob)
104 {
105 if (!aJob || !verification_thread_singleton)
106 return NS_ERROR_FAILURE;
107
108 if (!verification_thread_singleton->mThreadHandle)
109 return NS_ERROR_OUT_OF_MEMORY;
110
111 MutexAutoLock threadLock(verification_thread_singleton->mMutex);
112
113 verification_thread_singleton->mJobQ.Push(aJob);
114 verification_thread_singleton->mCond.NotifyAll();
115
116 return NS_OK;
117 }
118
119 void nsCertVerificationThread::Run(void)
120 {
121 while (true) {
122
123 nsBaseVerificationJob *job = nullptr;
124
125 {
126 MutexAutoLock threadLock(verification_thread_singleton->mMutex);
127
128 while (!exitRequested(threadLock) &&
129 0 == verification_thread_singleton->mJobQ.GetSize()) {
130 // no work to do ? let's wait a moment
131
132 mCond.Wait();
133 }
134
135 if (exitRequested(threadLock))
136 break;
137
138 job = static_cast<nsBaseVerificationJob*>(mJobQ.PopFront());
139 }
140
141 if (job)
142 {
143 job->Run();
144 delete job;
145 }
146 }
147
148 {
149 MutexAutoLock threadLock(verification_thread_singleton->mMutex);
150
151 while (verification_thread_singleton->mJobQ.GetSize()) {
152 nsCertVerificationJob *job =
153 static_cast<nsCertVerificationJob*>(mJobQ.PopFront());
154 delete job;
155 }
156 postStoppedEventToMainThread(threadLock);
157 }
158 }
159
160 nsCertVerificationResult::nsCertVerificationResult()
161 : mRV(NS_OK),
162 mVerified(0),
163 mCount(0),
164 mUsages(0)
165 {
166 }
167
168 nsCertVerificationResult::~nsCertVerificationResult()
169 {
170 if (mUsages)
171 {
172 NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mCount, mUsages);
173 }
174 }
175
176 NS_IMETHODIMP
177 nsCertVerificationResult::GetUsagesArrayResult(uint32_t *aVerified,
178 uint32_t *aCount,
179 char16_t ***aUsages)
180 {
181 if (NS_FAILED(mRV))
182 return mRV;
183
184 // transfer ownership
185
186 *aVerified = mVerified;
187 *aCount = mCount;
188 *aUsages = mUsages;
189
190 mVerified = 0;
191 mCount = 0;
192 mUsages = 0;
193
194 nsresult rv = mRV;
195
196 mRV = NS_ERROR_FAILURE; // this object works only once...
197
198 return rv;
199 }

mercurial