1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/cmd/libpkix/perf/libpkix_buildthreads.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,349 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +/* 1.8 + * libpkixBuildThreads.c 1.9 + * 1.10 + * libpkix Builder Performance Evaluation application (multi-threaded) 1.11 + * 1.12 + */ 1.13 + 1.14 +#include <stdio.h> 1.15 +#include <string.h> 1.16 + 1.17 +#include "secutil.h" 1.18 + 1.19 +#include "nspr.h" 1.20 +#include "prtypes.h" 1.21 +#include "prtime.h" 1.22 +#include "prlong.h" 1.23 + 1.24 +#include "pk11func.h" 1.25 +#include "secasn1.h" 1.26 +#include "cert.h" 1.27 +#include "cryptohi.h" 1.28 +#include "secoid.h" 1.29 +#include "certdb.h" 1.30 +#include "nss.h" 1.31 + 1.32 +#include "pkix.h" 1.33 +#include "pkix_tools.h" 1.34 +#include "pkix_pl_cert.h" 1.35 + 1.36 +#include "testutil.h" 1.37 +#include "testutil_nss.h" 1.38 + 1.39 +static void *plContext = NULL; 1.40 + 1.41 +#undef pkixTempResult 1.42 +#define PERF_DECREF(obj) \ 1.43 + { \ 1.44 + PKIX_Error *pkixTempResult = NULL; \ 1.45 + if (obj){ \ 1.46 + pkixTempResult = PKIX_PL_Object_DecRef \ 1.47 + ((PKIX_PL_Object *)(obj), plContext); \ 1.48 + obj = NULL; \ 1.49 + } \ 1.50 + } 1.51 + 1.52 +static void finish(char* message, int code); 1.53 + 1.54 +typedef struct ThreadDataStr tData; 1.55 + 1.56 +struct ThreadDataStr { 1.57 + CERTCertificate* anchor; 1.58 + char* eecertName; 1.59 + PRIntervalTime duration; 1.60 + CERTCertDBHandle *handle; 1.61 + PRUint32 iterations; 1.62 +}; 1.63 + 1.64 +#define PKIX_LOGGER_ON 1 1.65 + 1.66 +#ifdef PKIX_LOGGER_ON 1.67 + 1.68 +char *logLevels[] = { 1.69 + "None", 1.70 + "Fatal Error", 1.71 + "Error", 1.72 + "Warning", 1.73 + "Debug", 1.74 + "Trace" 1.75 +}; 1.76 + 1.77 +static PKIX_Error *loggerCallback( 1.78 + PKIX_Logger *logger, 1.79 + PKIX_PL_String *message, 1.80 + PKIX_UInt32 logLevel, 1.81 + PKIX_ERRORCLASS logComponent, 1.82 + void *plContext) 1.83 +{ 1.84 + char *msg = NULL; 1.85 + static int callCount = 0; 1.86 + 1.87 + msg = PKIX_String2ASCII(message, plContext); 1.88 + printf("Logging %s (%s): %s\n", 1.89 + logLevels[logLevel], 1.90 + PKIX_ERRORCLASSNAMES[logComponent], 1.91 + msg); 1.92 + PR_Free((void *)msg); 1.93 + 1.94 + return(NULL); 1.95 +} 1.96 + 1.97 +#endif /* PKIX_LOGGER_ON */ 1.98 + 1.99 +static void ThreadEntry(void* data) 1.100 +{ 1.101 + tData* tdata = (tData*) data; 1.102 + PRIntervalTime duration = tdata->duration; 1.103 + PRIntervalTime start = PR_IntervalNow(); 1.104 + 1.105 + PKIX_List *anchors = NULL; 1.106 + PKIX_ProcessingParams *procParams = NULL; 1.107 + PKIX_BuildResult *buildResult = NULL; 1.108 + CERTCertificate* nsseecert; 1.109 + PKIX_PL_Cert *eeCert = NULL; 1.110 + PKIX_CertStore *certStore = NULL; 1.111 + PKIX_List *certStores = NULL; 1.112 + PKIX_ComCertSelParams *certSelParams = NULL; 1.113 + PKIX_CertSelector *certSelector = NULL; 1.114 + PKIX_PL_Date *nowDate = NULL; 1.115 + void *state = NULL; /* only relevant with non-blocking I/O */ 1.116 + void *nbioContext = NULL; /* only relevant with non-blocking I/O */ 1.117 + 1.118 + PR_ASSERT(duration); 1.119 + if (!duration){ 1.120 + return; 1.121 + } 1.122 + 1.123 + do { 1.124 + 1.125 + /* libpkix code */ 1.126 + 1.127 + /* keep more update time, testing cache */ 1.128 + PKIX_PL_Date_Create_UTCTime(NULL, &nowDate, plContext); 1.129 + 1.130 + /* CertUsage is 0x10 and no NSS arena */ 1.131 + /* We haven't determined how we obtain the value of wincx */ 1.132 + 1.133 + nsseecert = CERT_FindCertByNicknameOrEmailAddr(tdata->handle, 1.134 + tdata->eecertName); 1.135 + if (!nsseecert) finish("Unable to find eecert.\n", 1); 1.136 + 1.137 + pkix_pl_Cert_CreateWithNSSCert 1.138 + (nsseecert, &eeCert, plContext); 1.139 + 1.140 + PKIX_List_Create(&anchors, plContext); 1.141 + 1.142 + /* 1.143 + * This code is retired. 1.144 + * pkix_pl_Cert_CreateWithNSSCert 1.145 + * (tdata->anchor, &anchorCert, NULL); 1.146 + * PKIX_TrustAnchor_CreateWithCert(anchorCert, &anchor, NULL); 1.147 + * PKIX_List_AppendItem(anchors, (PKIX_PL_Object *)anchor, NULL); 1.148 + */ 1.149 + 1.150 + PKIX_ProcessingParams_Create(anchors, &procParams, plContext); 1.151 + 1.152 + PKIX_ProcessingParams_SetRevocationEnabled 1.153 + (procParams, PKIX_TRUE, plContext); 1.154 + 1.155 + PKIX_ProcessingParams_SetDate 1.156 + (procParams, nowDate, plContext); 1.157 + 1.158 + /* create CertSelector with target certificate in params */ 1.159 + 1.160 + PKIX_ComCertSelParams_Create(&certSelParams, plContext); 1.161 + 1.162 + PKIX_ComCertSelParams_SetCertificate 1.163 + (certSelParams, eeCert, plContext); 1.164 + 1.165 + PKIX_CertSelector_Create 1.166 + (NULL, NULL, &certSelector, plContext); 1.167 + 1.168 + PKIX_CertSelector_SetCommonCertSelectorParams 1.169 + (certSelector, certSelParams, plContext); 1.170 + 1.171 + PKIX_ProcessingParams_SetTargetCertConstraints 1.172 + (procParams, certSelector, plContext); 1.173 + 1.174 + PKIX_PL_Pk11CertStore_Create(&certStore, plContext); 1.175 + 1.176 + PKIX_List_Create(&certStores, plContext); 1.177 + PKIX_List_AppendItem 1.178 + (certStores, (PKIX_PL_Object *)certStore, plContext); 1.179 + PKIX_ProcessingParams_SetCertStores 1.180 + (procParams, certStores, plContext); 1.181 + 1.182 + PKIX_BuildChain 1.183 + (procParams, 1.184 + &nbioContext, 1.185 + &state, 1.186 + &buildResult, 1.187 + NULL, 1.188 + plContext); 1.189 + 1.190 + /* 1.191 + * As long as we use only CertStores with blocking I/O, we 1.192 + * know we must be done at this point. 1.193 + */ 1.194 + 1.195 + if (!buildResult){ 1.196 + (void) fprintf(stderr, "libpkix BuildChain failed.\n"); 1.197 + PORT_Assert(0); 1.198 + return; 1.199 + } 1.200 + 1.201 + tdata->iterations ++; 1.202 + 1.203 + PERF_DECREF(nowDate); 1.204 + PERF_DECREF(anchors); 1.205 + PERF_DECREF(procParams); 1.206 + PERF_DECREF(buildResult); 1.207 + PERF_DECREF(certStore); 1.208 + PERF_DECREF(certStores); 1.209 + PERF_DECREF(certSelParams); 1.210 + PERF_DECREF(certSelector); 1.211 + PERF_DECREF(eeCert); 1.212 + 1.213 + } while ((PR_IntervalNow() - start) < duration); 1.214 + 1.215 + 1.216 +} 1.217 + 1.218 +static void 1.219 +Test( 1.220 + CERTCertificate* anchor, 1.221 + char* eecertName, 1.222 + PRIntervalTime duration, 1.223 + CERTCertDBHandle *handle, 1.224 + PRUint32 threads) 1.225 +{ 1.226 + tData data; 1.227 + tData** alldata; 1.228 + PRIntervalTime starttime, endtime, elapsed; 1.229 + PRUint32 msecs; 1.230 + float total = 0; 1.231 + PRThread** pthreads = NULL; 1.232 + PRUint32 i = 0; 1.233 + 1.234 + data.duration = duration; 1.235 + data.anchor = anchor; 1.236 + data.eecertName = eecertName; 1.237 + data.handle = handle; 1.238 + 1.239 + data.iterations = 0; 1.240 + 1.241 + starttime = PR_IntervalNow(); 1.242 + pthreads = (PRThread**)PR_Malloc(threads*sizeof (PRThread*)); 1.243 + alldata = (tData**)PR_Malloc(threads*sizeof (tData*)); 1.244 + for (i = 0; i < threads; i++){ 1.245 + alldata[i] = (tData*)PR_Malloc(sizeof (tData)); 1.246 + *alldata[i] = data; 1.247 + pthreads[i] = 1.248 + PR_CreateThread(PR_USER_THREAD, 1.249 + ThreadEntry, 1.250 + (void*) alldata[i], 1.251 + PR_PRIORITY_NORMAL, 1.252 + PR_GLOBAL_THREAD, 1.253 + PR_JOINABLE_THREAD, 1.254 + 0); 1.255 + } 1.256 + 1.257 + for (i = 0; i < threads; i++) { 1.258 + tData* args = alldata[i]; 1.259 + PR_JoinThread(pthreads[i]); 1.260 + total += args->iterations; 1.261 + PR_Free((void*)args); 1.262 + } 1.263 + 1.264 + PR_Free((void*) pthreads); 1.265 + PR_Free((void*) alldata); 1.266 + endtime = PR_IntervalNow(); 1.267 + 1.268 + endtime = PR_IntervalNow(); 1.269 + elapsed = endtime - starttime; 1.270 + msecs = PR_IntervalToMilliseconds(elapsed); 1.271 + total /= msecs; 1.272 + total *= 1000; 1.273 + (void) fprintf(stdout, "%f operations per second.\n", total); 1.274 +} 1.275 + 1.276 + 1.277 +static void finish(char* message, int code) 1.278 +{ 1.279 + (void) printf(message); 1.280 + exit(code); 1.281 +} 1.282 + 1.283 +static void usage(char* progname) 1.284 +{ 1.285 + (void) printf("Usage : %s <-d certStoreDirectory> <duration> <threads> " 1.286 + "<anchorNickname> <eecertNickname>\n\n", progname); 1.287 + finish("", 0); 1.288 +} 1.289 + 1.290 +int 1.291 +libpkix_buildthreads(int argc, char** argv) 1.292 +{ 1.293 + CERTCertDBHandle *handle = NULL; 1.294 + CERTCertificate* eecert = NULL; 1.295 + PRIntervalTime duration = PR_SecondsToInterval(1); 1.296 + PRUint32 threads = 1; 1.297 + PKIX_UInt32 actualMinorVersion; 1.298 + PKIX_UInt32 j = 0; 1.299 + PKIX_Logger *logger = NULL; 1.300 + void *wincx = NULL; 1.301 + 1.302 + /* if (argc != 5) -- when TrustAnchor used to be on command line */ 1.303 + if (argc != 4) 1.304 + { 1.305 + usage(argv[0]); 1.306 + } 1.307 + if (atoi(argv[1]) > 0) 1.308 + { 1.309 + duration = PR_SecondsToInterval(atoi(argv[1])); 1.310 + } 1.311 + if (atoi(argv[2]) > 0) 1.312 + { 1.313 + threads = atoi(argv[2]); 1.314 + } 1.315 + 1.316 + PKIX_PL_NssContext_Create(certificateUsageEmailSigner, PKIX_FALSE, 1.317 + NULL, &plContext); 1.318 + 1.319 + handle = CERT_GetDefaultCertDB(); 1.320 + PR_ASSERT(handle); 1.321 + 1.322 +#ifdef PKIX_LOGGER_ON 1.323 + 1.324 + /* set logger to log trace and up */ 1.325 + PKIX_SetLoggers(NULL, plContext); 1.326 + PKIX_Logger_Create(loggerCallback, NULL, &logger, plContext); 1.327 + PKIX_Logger_SetMaxLoggingLevel 1.328 + (logger, PKIX_LOGGER_LEVEL_WARNING, plContext); 1.329 + PKIX_AddLogger(logger, plContext); 1.330 + 1.331 +#endif /* PKIX_LOGGER_ON */ 1.332 + 1.333 + /* 1.334 + * This code is retired 1.335 + * anchor = CERT_FindCertByNicknameOrEmailAddr(handle, argv[3]); 1.336 + * if (!anchor) finish("Unable to find anchor.\n", 1); 1.337 + * 1.338 + * eecert = CERT_FindCertByNicknameOrEmailAddr(handle, argv[4]); 1.339 + 1.340 + * if (!eecert) finish("Unable to find eecert.\n", 1); 1.341 + * 1.342 + * Test(anchor, eecert, duration, threads); 1.343 + */ 1.344 + 1.345 + Test(NULL, argv[3], duration, handle, threads); 1.346 + 1.347 + PERF_DECREF(logger); 1.348 + 1.349 + PKIX_Shutdown(plContext); 1.350 + 1.351 + return (0); 1.352 +}