1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is mozilla.org code.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2001
21 * the Initial Developer. All Rights Reserved.
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
41 #include "nsProxiedService.h"
42 #include "nsThreadUtils.h"
43 #include "nsKeygenThread.h"
44 #include "nsIObserver.h"
45 #include "nsNSSShutDown.h"
47 NS_IMPL_THREADSAFE_ISUPPORTS1(nsKeygenThread
, nsIKeygenThread
)
50 nsKeygenThread::nsKeygenThread()
53 keygenReady(PR_FALSE
),
54 statusDialogClosed(PR_FALSE
),
55 alreadyReceivedParams(PR_FALSE
),
62 isSensitive(PR_FALSE
),
69 nsKeygenThread::~nsKeygenThread()
72 PR_DestroyLock(mutex
);
76 void nsKeygenThread::SetParams(
78 PRUint32 a_keyGenMechanism
,
84 nsNSSShutDownPreventionLock locker
;
87 if (!alreadyReceivedParams
) {
88 alreadyReceivedParams
= PR_TRUE
;
90 slot
= PK11_ReferenceSlot(a_slot
);
95 keyGenMechanism
= a_keyGenMechanism
;
98 isSensitive
= a_isSensitive
;
105 nsresult
nsKeygenThread::GetParams(
106 SECKEYPrivateKey
**a_privateKey
,
107 SECKEYPublicKey
**a_publicKey
)
109 if (!a_privateKey
|| !a_publicKey
) {
110 return NS_ERROR_FAILURE
;
117 // GetParams must not be called until thread creator called
118 // Join on this thread.
119 NS_ASSERTION(keygenReady
, "logic error in nsKeygenThread::GetParams");
122 *a_privateKey
= privateKey
;
123 *a_publicKey
= publicKey
;
131 rv
= NS_ERROR_FAILURE
;
139 static void PR_CALLBACK
nsKeygenThreadRunner(void *arg
)
141 nsKeygenThread
*self
= static_cast<nsKeygenThread
*>(arg
);
145 nsresult
nsKeygenThread::StartKeyGeneration(nsIObserver
* aObserver
)
153 nsCOMPtr
<nsIObserver
> obs
;
154 NS_GetProxyForObject( NS_PROXY_TO_MAIN_THREAD
,
155 NS_GET_IID(nsIObserver
),
157 NS_PROXY_SYNC
| NS_PROXY_ALWAYS
,
158 getter_AddRefs(obs
));
162 if (iAmRunning
|| keygenReady
) {
169 iAmRunning
= PR_TRUE
;
171 threadHandle
= PR_CreateThread(PR_USER_THREAD
, nsKeygenThreadRunner
, static_cast<void*>(this),
172 PR_PRIORITY_NORMAL
, PR_LOCAL_THREAD
, PR_JOINABLE_THREAD
, 0);
174 // bool thread_started_ok = (threadHandle != nsnull);
175 // we might want to return "thread started ok" to caller in the future
176 NS_ASSERTION(threadHandle
, "Could not create nsKeygenThreadRunner thread\n");
183 nsresult
nsKeygenThread::UserCanceled(PRBool
*threadAlreadyClosedDialog
)
185 if (!threadAlreadyClosedDialog
)
188 *threadAlreadyClosedDialog
= PR_FALSE
;
196 *threadAlreadyClosedDialog
= statusDialogClosed
;
198 // User somehow closed the dialog, but we will not cancel.
199 // Bad luck, we told him not do, and user still has to wait.
200 // However, we remember that it's closed and will not close
201 // it again to avoid problems.
202 statusDialogClosed
= PR_TRUE
;
209 void nsKeygenThread::Run(void)
211 nsNSSShutDownPreventionLock locker
;
212 PRBool canGenerate
= PR_FALSE
;
216 if (alreadyReceivedParams
) {
217 canGenerate
= PR_TRUE
;
218 keygenReady
= PR_FALSE
;
224 privateKey
= PK11_GenerateKeyPair(slot
, keyGenMechanism
,
226 isPerm
, isSensitive
, wincx
);
228 // This call gave us ownership over privateKey and publicKey.
229 // But as the params structure is owner by our caller,
230 // we effectively transferred ownership to the caller.
231 // As long as key generation can't be canceled, we don't need
232 // to care for cleaning this up.
234 nsCOMPtr
<nsIObserver
> obs
;
237 keygenReady
= PR_TRUE
;
238 iAmRunning
= PR_FALSE
;
240 // forget our parameters
249 if (!statusDialogClosed
)
257 obs
->Observe(nsnull
, "keygen-finished", nsnull
);
260 void nsKeygenThread::Join()
265 PR_JoinThread(threadHandle
);
266 threadHandle
= nsnull
;