/security/manager/ssl/src/nsCertVerificationThread.cpp

http://github.com/zpao/v8monkey · C++ · 233 lines · 152 code · 43 blank · 38 comment · 18 complexity · 5a1e0c4187645a0ca923a39bcc14ed4a MD5 · raw file

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3. *
  4. * The contents of this file are subject to the Mozilla Public License Version
  5. * 1.1 (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. * http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. * for the specific language governing rights and limitations under the
  12. * License.
  13. *
  14. * The Original Code is mozilla.org code.
  15. *
  16. * The Initial Developer of the Original Code is
  17. * Red Hat, Inc.
  18. * Portions created by the Initial Developer are Copyright (C) 2006
  19. * the Initial Developer. All Rights Reserved.
  20. *
  21. * Contributor(s):
  22. * Kai Engert <kengert@redhat.com>
  23. *
  24. * Alternatively, the contents of this file may be used under the terms of
  25. * either the GNU General Public License Version 2 or later (the "GPL"), or
  26. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27. * in which case the provisions of the GPL or the LGPL are applicable instead
  28. * of those above. If you wish to allow use of your version of this file only
  29. * under the terms of either the GPL or the LGPL, and not to allow others to
  30. * use your version of this file under the terms of the MPL, indicate your
  31. * decision by deleting the provisions above and replace them with the notice
  32. * and other provisions required by the GPL or the LGPL. If you do not delete
  33. * the provisions above, a recipient may use your version of this file under
  34. * the terms of any one of the MPL, the GPL or the LGPL.
  35. *
  36. * ***** END LICENSE BLOCK ***** */
  37. #include "nsMemory.h"
  38. #include "nsAutoPtr.h"
  39. #include "nsCertVerificationThread.h"
  40. #include "nsThreadUtils.h"
  41. using namespace mozilla;
  42. nsCertVerificationThread *nsCertVerificationThread::verification_thread_singleton;
  43. NS_IMPL_THREADSAFE_ISUPPORTS1(nsCertVerificationResult, nsICertVerificationResult)
  44. namespace {
  45. class DispatchCertVerificationResult : public nsRunnable
  46. {
  47. public:
  48. DispatchCertVerificationResult(nsICertVerificationListener* aListener,
  49. nsIX509Cert3* aCert,
  50. nsICertVerificationResult* aResult)
  51. : mListener(aListener)
  52. , mCert(aCert)
  53. , mResult(aResult)
  54. { }
  55. NS_IMETHOD Run() {
  56. mListener->Notify(mCert, mResult);
  57. return NS_OK;
  58. }
  59. private:
  60. nsCOMPtr<nsICertVerificationListener> mListener;
  61. nsCOMPtr<nsIX509Cert3> mCert;
  62. nsCOMPtr<nsICertVerificationResult> mResult;
  63. };
  64. } // anonymous namespace
  65. void nsCertVerificationJob::Run()
  66. {
  67. if (!mListener || !mCert)
  68. return;
  69. PRUint32 verified;
  70. PRUint32 count;
  71. PRUnichar **usages;
  72. nsCOMPtr<nsICertVerificationResult> ires;
  73. nsRefPtr<nsCertVerificationResult> vres = new nsCertVerificationResult;
  74. if (vres)
  75. {
  76. nsresult rv = mCert->GetUsagesArray(false, // do not ignore OCSP
  77. &verified,
  78. &count,
  79. &usages);
  80. vres->mRV = rv;
  81. if (NS_SUCCEEDED(rv))
  82. {
  83. vres->mVerified = verified;
  84. vres->mCount = count;
  85. vres->mUsages = usages;
  86. }
  87. ires = vres;
  88. }
  89. nsCOMPtr<nsIX509Cert3> c3 = do_QueryInterface(mCert);
  90. nsCOMPtr<nsIRunnable> r = new DispatchCertVerificationResult(mListener, c3, ires);
  91. NS_DispatchToMainThread(r);
  92. }
  93. void nsSMimeVerificationJob::Run()
  94. {
  95. if (!mMessage || !mListener)
  96. return;
  97. nsresult rv;
  98. if (digest_data)
  99. rv = mMessage->VerifyDetachedSignature(digest_data, digest_len);
  100. else
  101. rv = mMessage->VerifySignature();
  102. nsCOMPtr<nsICMSMessage2> m2 = do_QueryInterface(mMessage);
  103. mListener->Notify(m2, rv);
  104. }
  105. nsCertVerificationThread::nsCertVerificationThread()
  106. : mJobQ(nsnull)
  107. {
  108. NS_ASSERTION(!verification_thread_singleton,
  109. "nsCertVerificationThread is a singleton, caller attempts"
  110. " to create another instance!");
  111. verification_thread_singleton = this;
  112. }
  113. nsCertVerificationThread::~nsCertVerificationThread()
  114. {
  115. verification_thread_singleton = nsnull;
  116. }
  117. nsresult nsCertVerificationThread::addJob(nsBaseVerificationJob *aJob)
  118. {
  119. if (!aJob || !verification_thread_singleton)
  120. return NS_ERROR_FAILURE;
  121. if (!verification_thread_singleton->mThreadHandle)
  122. return NS_ERROR_OUT_OF_MEMORY;
  123. MutexAutoLock threadLock(verification_thread_singleton->mMutex);
  124. verification_thread_singleton->mJobQ.Push(aJob);
  125. verification_thread_singleton->mCond.NotifyAll();
  126. return NS_OK;
  127. }
  128. void nsCertVerificationThread::Run(void)
  129. {
  130. while (true) {
  131. nsBaseVerificationJob *job = nsnull;
  132. {
  133. MutexAutoLock threadLock(verification_thread_singleton->mMutex);
  134. while (!exitRequested(threadLock) &&
  135. 0 == verification_thread_singleton->mJobQ.GetSize()) {
  136. // no work to do ? let's wait a moment
  137. mCond.Wait();
  138. }
  139. if (exitRequested(threadLock))
  140. break;
  141. job = static_cast<nsBaseVerificationJob*>(mJobQ.PopFront());
  142. }
  143. if (job)
  144. {
  145. job->Run();
  146. delete job;
  147. }
  148. }
  149. {
  150. MutexAutoLock threadLock(verification_thread_singleton->mMutex);
  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. nsCertVerificationResult::nsCertVerificationResult()
  160. : mRV(0),
  161. mVerified(0),
  162. mCount(0),
  163. mUsages(0)
  164. {
  165. }
  166. nsCertVerificationResult::~nsCertVerificationResult()
  167. {
  168. if (mUsages)
  169. {
  170. NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(mCount, mUsages);
  171. }
  172. }
  173. NS_IMETHODIMP
  174. nsCertVerificationResult::GetUsagesArrayResult(PRUint32 *aVerified,
  175. PRUint32 *aCount,
  176. PRUnichar ***aUsages)
  177. {
  178. if (NS_FAILED(mRV))
  179. return mRV;
  180. // transfer ownership
  181. *aVerified = mVerified;
  182. *aCount = mCount;
  183. *aUsages = mUsages;
  184. mVerified = 0;
  185. mCount = 0;
  186. mUsages = 0;
  187. nsresult rv = mRV;
  188. mRV = NS_ERROR_FAILURE; // this object works only once...
  189. return rv;
  190. }