Wed, 31 Dec 2014 07:16:47 +0100
Revert simplistic fix pending revisit of Mozilla integration attempt.
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 * libpkixBuildThreads.c
6 *
7 * libpkix Builder Performance Evaluation application (multi-threaded)
8 *
9 */
11 #include <stdio.h>
12 #include <string.h>
14 #include "secutil.h"
16 #include "nspr.h"
17 #include "prtypes.h"
18 #include "prtime.h"
19 #include "prlong.h"
21 #include "pk11func.h"
22 #include "secasn1.h"
23 #include "cert.h"
24 #include "cryptohi.h"
25 #include "secoid.h"
26 #include "certdb.h"
27 #include "nss.h"
29 #include "pkix.h"
30 #include "pkix_tools.h"
31 #include "pkix_pl_cert.h"
33 #include "testutil.h"
34 #include "testutil_nss.h"
36 static void *plContext = NULL;
38 #undef pkixTempResult
39 #define PERF_DECREF(obj) \
40 { \
41 PKIX_Error *pkixTempResult = NULL; \
42 if (obj){ \
43 pkixTempResult = PKIX_PL_Object_DecRef \
44 ((PKIX_PL_Object *)(obj), plContext); \
45 obj = NULL; \
46 } \
47 }
49 static void finish(char* message, int code);
51 typedef struct ThreadDataStr tData;
53 struct ThreadDataStr {
54 CERTCertificate* anchor;
55 char* eecertName;
56 PRIntervalTime duration;
57 CERTCertDBHandle *handle;
58 PRUint32 iterations;
59 };
61 #define PKIX_LOGGER_ON 1
63 #ifdef PKIX_LOGGER_ON
65 char *logLevels[] = {
66 "None",
67 "Fatal Error",
68 "Error",
69 "Warning",
70 "Debug",
71 "Trace"
72 };
74 static PKIX_Error *loggerCallback(
75 PKIX_Logger *logger,
76 PKIX_PL_String *message,
77 PKIX_UInt32 logLevel,
78 PKIX_ERRORCLASS logComponent,
79 void *plContext)
80 {
81 char *msg = NULL;
82 static int callCount = 0;
84 msg = PKIX_String2ASCII(message, plContext);
85 printf("Logging %s (%s): %s\n",
86 logLevels[logLevel],
87 PKIX_ERRORCLASSNAMES[logComponent],
88 msg);
89 PR_Free((void *)msg);
91 return(NULL);
92 }
94 #endif /* PKIX_LOGGER_ON */
96 static void ThreadEntry(void* data)
97 {
98 tData* tdata = (tData*) data;
99 PRIntervalTime duration = tdata->duration;
100 PRIntervalTime start = PR_IntervalNow();
102 PKIX_List *anchors = NULL;
103 PKIX_ProcessingParams *procParams = NULL;
104 PKIX_BuildResult *buildResult = NULL;
105 CERTCertificate* nsseecert;
106 PKIX_PL_Cert *eeCert = NULL;
107 PKIX_CertStore *certStore = NULL;
108 PKIX_List *certStores = NULL;
109 PKIX_ComCertSelParams *certSelParams = NULL;
110 PKIX_CertSelector *certSelector = NULL;
111 PKIX_PL_Date *nowDate = NULL;
112 void *state = NULL; /* only relevant with non-blocking I/O */
113 void *nbioContext = NULL; /* only relevant with non-blocking I/O */
115 PR_ASSERT(duration);
116 if (!duration){
117 return;
118 }
120 do {
122 /* libpkix code */
124 /* keep more update time, testing cache */
125 PKIX_PL_Date_Create_UTCTime(NULL, &nowDate, plContext);
127 /* CertUsage is 0x10 and no NSS arena */
128 /* We haven't determined how we obtain the value of wincx */
130 nsseecert = CERT_FindCertByNicknameOrEmailAddr(tdata->handle,
131 tdata->eecertName);
132 if (!nsseecert) finish("Unable to find eecert.\n", 1);
134 pkix_pl_Cert_CreateWithNSSCert
135 (nsseecert, &eeCert, plContext);
137 PKIX_List_Create(&anchors, plContext);
139 /*
140 * This code is retired.
141 * pkix_pl_Cert_CreateWithNSSCert
142 * (tdata->anchor, &anchorCert, NULL);
143 * PKIX_TrustAnchor_CreateWithCert(anchorCert, &anchor, NULL);
144 * PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, NULL);
145 */
147 PKIX_ProcessingParams_Create(anchors, &procParams, plContext);
149 PKIX_ProcessingParams_SetRevocationEnabled
150 (procParams, PKIX_TRUE, plContext);
152 PKIX_ProcessingParams_SetDate
153 (procParams, nowDate, plContext);
155 /* create CertSelector with target certificate in params */
157 PKIX_ComCertSelParams_Create(&certSelParams, plContext);
159 PKIX_ComCertSelParams_SetCertificate
160 (certSelParams, eeCert, plContext);
162 PKIX_CertSelector_Create
163 (NULL, NULL, &certSelector, plContext);
165 PKIX_CertSelector_SetCommonCertSelectorParams
166 (certSelector, certSelParams, plContext);
168 PKIX_ProcessingParams_SetTargetCertConstraints
169 (procParams, certSelector, plContext);
171 PKIX_PL_Pk11CertStore_Create(&certStore, plContext);
173 PKIX_List_Create(&certStores, plContext);
174 PKIX_List_AppendItem
175 (certStores, (PKIX_PL_Object *)certStore, plContext);
176 PKIX_ProcessingParams_SetCertStores
177 (procParams, certStores, plContext);
179 PKIX_BuildChain
180 (procParams,
181 &nbioContext,
182 &state,
183 &buildResult,
184 NULL,
185 plContext);
187 /*
188 * As long as we use only CertStores with blocking I/O, we
189 * know we must be done at this point.
190 */
192 if (!buildResult){
193 (void) fprintf(stderr, "libpkix BuildChain failed.\n");
194 PORT_Assert(0);
195 return;
196 }
198 tdata->iterations ++;
200 PERF_DECREF(nowDate);
201 PERF_DECREF(anchors);
202 PERF_DECREF(procParams);
203 PERF_DECREF(buildResult);
204 PERF_DECREF(certStore);
205 PERF_DECREF(certStores);
206 PERF_DECREF(certSelParams);
207 PERF_DECREF(certSelector);
208 PERF_DECREF(eeCert);
210 } while ((PR_IntervalNow() - start) < duration);
213 }
215 static void
216 Test(
217 CERTCertificate* anchor,
218 char* eecertName,
219 PRIntervalTime duration,
220 CERTCertDBHandle *handle,
221 PRUint32 threads)
222 {
223 tData data;
224 tData** alldata;
225 PRIntervalTime starttime, endtime, elapsed;
226 PRUint32 msecs;
227 float total = 0;
228 PRThread** pthreads = NULL;
229 PRUint32 i = 0;
231 data.duration = duration;
232 data.anchor = anchor;
233 data.eecertName = eecertName;
234 data.handle = handle;
236 data.iterations = 0;
238 starttime = PR_IntervalNow();
239 pthreads = (PRThread**)PR_Malloc(threads*sizeof (PRThread*));
240 alldata = (tData**)PR_Malloc(threads*sizeof (tData*));
241 for (i = 0; i < threads; i++){
242 alldata[i] = (tData*)PR_Malloc(sizeof (tData));
243 *alldata[i] = data;
244 pthreads[i] =
245 PR_CreateThread(PR_USER_THREAD,
246 ThreadEntry,
247 (void*) alldata[i],
248 PR_PRIORITY_NORMAL,
249 PR_GLOBAL_THREAD,
250 PR_JOINABLE_THREAD,
251 0);
252 }
254 for (i = 0; i < threads; i++) {
255 tData* args = alldata[i];
256 PR_JoinThread(pthreads[i]);
257 total += args->iterations;
258 PR_Free((void*)args);
259 }
261 PR_Free((void*) pthreads);
262 PR_Free((void*) alldata);
263 endtime = PR_IntervalNow();
265 endtime = PR_IntervalNow();
266 elapsed = endtime - starttime;
267 msecs = PR_IntervalToMilliseconds(elapsed);
268 total /= msecs;
269 total *= 1000;
270 (void) fprintf(stdout, "%f operations per second.\n", total);
271 }
274 static void finish(char* message, int code)
275 {
276 (void) printf(message);
277 exit(code);
278 }
280 static void usage(char* progname)
281 {
282 (void) printf("Usage : %s <-d certStoreDirectory> <duration> <threads> "
283 "<anchorNickname> <eecertNickname>\n\n", progname);
284 finish("", 0);
285 }
287 int
288 libpkix_buildthreads(int argc, char** argv)
289 {
290 CERTCertDBHandle *handle = NULL;
291 CERTCertificate* eecert = NULL;
292 PRIntervalTime duration = PR_SecondsToInterval(1);
293 PRUint32 threads = 1;
294 PKIX_UInt32 actualMinorVersion;
295 PKIX_UInt32 j = 0;
296 PKIX_Logger *logger = NULL;
297 void *wincx = NULL;
299 /* if (argc != 5) -- when TrustAnchor used to be on command line */
300 if (argc != 4)
301 {
302 usage(argv[0]);
303 }
304 if (atoi(argv[1]) > 0)
305 {
306 duration = PR_SecondsToInterval(atoi(argv[1]));
307 }
308 if (atoi(argv[2]) > 0)
309 {
310 threads = atoi(argv[2]);
311 }
313 PKIX_PL_NssContext_Create(certificateUsageEmailSigner, PKIX_FALSE,
314 NULL, &plContext);
316 handle = CERT_GetDefaultCertDB();
317 PR_ASSERT(handle);
319 #ifdef PKIX_LOGGER_ON
321 /* set logger to log trace and up */
322 PKIX_SetLoggers(NULL, plContext);
323 PKIX_Logger_Create(loggerCallback, NULL, &logger, plContext);
324 PKIX_Logger_SetMaxLoggingLevel
325 (logger, PKIX_LOGGER_LEVEL_WARNING, plContext);
326 PKIX_AddLogger(logger, plContext);
328 #endif /* PKIX_LOGGER_ON */
330 /*
331 * This code is retired
332 * anchor = CERT_FindCertByNicknameOrEmailAddr(handle, argv[3]);
333 * if (!anchor) finish("Unable to find anchor.\n", 1);
334 *
335 * eecert = CERT_FindCertByNicknameOrEmailAddr(handle, argv[4]);
337 * if (!eecert) finish("Unable to find eecert.\n", 1);
338 *
339 * Test(anchor, eecert, duration, threads);
340 */
342 Test(NULL, argv[3], duration, handle, threads);
344 PERF_DECREF(logger);
346 PKIX_Shutdown(plContext);
348 return (0);
349 }