]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/sslHandshakeTimeRB/sslHandshakeTimeRB.cpp
Security-57031.30.12.tar.gz
[apple/security.git] / SecurityTests / clxutils / sslHandshakeTimeRB / sslHandshakeTimeRB.cpp
1 /*
2 * sslHandshakeTimeRB - measure SSL handshake timing, RingBuffer version (no
3 * socket I/O).
4 *
5 * Written by Doug Mitchell.
6 */
7 #include <Security/SecureTransport.h>
8 #include <clAppUtils/sslAppUtils.h>
9 #include <utilLib/common.h>
10 #include <clAppUtils/ringBufferIo.h>
11 #include <clAppUtils/sslRingBufferThreads.h>
12
13 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <time.h>
18 #include <ctype.h>
19 #include <sys/param.h>
20 #include <CoreFoundation/CoreFoundation.h>
21 #include <security_utilities/devrandom.h>
22
23 #define DEFAULT_KC "localcert" /* default keychain */
24
25 /* we might make these user-tweakable */
26 #define DEFAULT_NUM_BUFS 16
27 #define DEFAULT_BUF_SIZE 1024 /* in the ring buffers */
28 #define LOOPS_DEF 20
29
30 static void usage(char **argv)
31 {
32 printf("Usage: %s [option ...]\n", argv[0]);
33 printf("Options:\n");
34 printf(" -l loops (default= %d)\n", LOOPS_DEF);
35 printf(" -k keychain (default = %s)\n", DEFAULT_KC);
36 printf(" -c cipher (default = RSA/AES128\n");
37 printf(" ciphers: a=RSA/AES128; r=RSA/RC4; d=RSA/DES; D=RSA/3DES;\n");
38 printf(" h=DHA/RC4; H=DH/DSS/DES; A=AES256\n");
39 printf(" -v version (t|2|3; default = t(TLS1)\n");
40 printf(" -a (enable client authentication)\n");
41 exit(1);
42 }
43
44 static int doTest(
45 SslRingBufferArgs *clientArgs,
46 SslRingBufferArgs *serverArgs,
47 unsigned loops,
48 CFAbsoluteTime *totalElapsedClient, /* RETURNED */
49 CFAbsoluteTime *totalElapsedServer) /* RETURNED */
50 {
51 CFAbsoluteTime elapsedClient = 0.0;
52 CFAbsoluteTime elapsedServer = 0.0;
53 int result;
54 pthread_t client_thread = NULL;
55 unsigned dex;
56 void *status;
57
58 for(dex=0; dex<loops; dex++) {
59
60 ringBufferReset(clientArgs->ringWrite);
61 ringBufferReset(clientArgs->ringRead);
62 clientArgs->iAmReady = false;
63 serverArgs->iAmReady = false;
64
65 /* fire up client thread */
66 result = pthread_create(&client_thread, NULL,
67 sslRbClientThread, clientArgs);
68 if(result) {
69 printf("***pthread_create returned %d, aborting\n", result);
70 return -1;
71 }
72
73 /*
74 * And the server pseudo thread. This returns when all data has been transferred.
75 */
76 OSStatus ortn = sslRbServerThread(serverArgs);
77 if(*serverArgs->abortFlag || ortn) {
78 printf("***Test aborted (1).\n");
79 return -1;
80 }
81
82 /* now wait for client */
83 result = pthread_join(client_thread, &status);
84 if(result || *clientArgs->abortFlag) {
85 printf("***Test aborted (2).\n");
86 return -1;
87 }
88 elapsedClient += (clientArgs->startData - clientArgs->startHandshake);
89 elapsedServer += (serverArgs->startData - serverArgs->startHandshake);
90 }
91 *totalElapsedClient = elapsedClient;
92 *totalElapsedServer = elapsedServer;
93 return 0;
94 }
95
96 int main(int argc, char **argv)
97 {
98 RingBuffer serverToClientRing;
99 RingBuffer clientToServerRing;
100 unsigned numBufs = DEFAULT_NUM_BUFS;
101 unsigned bufSize = DEFAULT_BUF_SIZE;
102 CFArrayRef idArray; /* for SSLSetCertificate */
103 CFArrayRef anchorArray; /* trusted roots */
104 SslRingBufferArgs clientArgs;
105 SslRingBufferArgs serverArgs;
106 SecKeychainRef kcRef = NULL;
107 SecCertificateRef anchorCert = NULL;
108 SecIdentityRef idRef = NULL;
109 bool abortFlag = false;
110 bool diffieHellman = true; /* FIXME needs work */
111 OSStatus ortn;
112 CFAbsoluteTime clientFirst;
113 CFAbsoluteTime serverFirst;
114 CFAbsoluteTime clientTotal;
115 CFAbsoluteTime serverTotal;
116
117 /* user-spec'd variables */
118 char *kcName = DEFAULT_KC;
119 SSLCipherSuite cipherSuite = TLS_RSA_WITH_AES_128_CBC_SHA;
120 SSLProtocol prot = kTLSProtocol1;
121 bool clientAuthEnable = false;
122 unsigned loops = LOOPS_DEF;
123
124 extern int optind;
125 extern char *optarg;
126 int arg;
127 optind = 1;
128 while ((arg = getopt(argc, argv, "l:k:x:c:v:w:aB")) != -1) {
129 switch (arg) {
130 case 'l':
131 loops = atoi(optarg);
132 break;
133 case 'k':
134 kcName = optarg;
135 break;
136 case 'c':
137 switch(optarg[0]) {
138 case 'a':
139 cipherSuite = TLS_RSA_WITH_AES_128_CBC_SHA;
140 break;
141 case 'r':
142 cipherSuite = SSL_RSA_WITH_RC4_128_SHA;
143 break;
144 case 'd':
145 cipherSuite = SSL_RSA_WITH_DES_CBC_SHA;
146 break;
147 case 'D':
148 cipherSuite = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
149 break;
150 case 'h':
151 cipherSuite = SSL_DH_anon_WITH_RC4_128_MD5;
152 diffieHellman = true;
153 break;
154 case 'H':
155 cipherSuite = SSL_DHE_DSS_WITH_DES_CBC_SHA;
156 diffieHellman = true;
157 break;
158 case 'A':
159 cipherSuite = TLS_RSA_WITH_AES_256_CBC_SHA;
160 break;
161 default:
162 usage(argv);
163 }
164 break;
165 case 'v':
166 switch(optarg[0]) {
167 case 't':
168 prot = kTLSProtocol1;
169 break;
170 case '2':
171 prot = kSSLProtocol2;
172 break;
173 case '3':
174 prot = kSSLProtocol3;
175 break;
176 default:
177 usage(argv);
178 }
179 break;
180 case 'a':
181 clientAuthEnable = true;
182 break;
183 default:
184 usage(argv);
185 }
186 }
187 if(optind != argc) {
188 usage(argv);
189 }
190
191 /* set up ring buffers */
192 ringBufSetup(&serverToClientRing, "serveToClient", numBufs, bufSize);
193 ringBufSetup(&clientToServerRing, "clientToServe", numBufs, bufSize);
194
195 /* get server SecIdentity */
196 idArray = getSslCerts(kcName,
197 CSSM_FALSE, /* encryptOnly */
198 CSSM_FALSE, /* completeCertChain */
199 NULL, /* anchorFile */
200 &kcRef);
201 if(idArray == NULL) {
202 printf("***Can't get signing cert from %s\n", kcName);
203 exit(1);
204 }
205 idRef = (SecIdentityRef)CFArrayGetValueAtIndex(idArray, 0);
206 ortn = SecIdentityCopyCertificate(idRef, &anchorCert);
207 if(ortn) {
208 cssmPerror("SecIdentityCopyCertificate", ortn);
209 exit(1);
210 }
211 anchorArray = CFArrayCreate(NULL, (const void **)&anchorCert,
212 1, &kCFTypeArrayCallBacks);
213
214 CFRelease(kcRef);
215
216 /* set up server side */
217 memset(&serverArgs, 0, sizeof(serverArgs));
218 serverArgs.idArray = idArray;
219 serverArgs.trustedRoots = anchorArray;
220 serverArgs.xferSize = 0;
221 serverArgs.xferBuf = NULL;
222 serverArgs.chunkSize = 0;
223 serverArgs.cipherSuite = cipherSuite;
224 serverArgs.prot = prot;
225 serverArgs.ringWrite = &serverToClientRing;
226 serverArgs.ringRead = &clientToServerRing;
227 serverArgs.goFlag = &clientArgs.iAmReady;
228 serverArgs.abortFlag = &abortFlag;
229
230 /* set up client side */
231 memset(&clientArgs, 0, sizeof(clientArgs));
232 clientArgs.idArray = NULL; /* until we do client auth */
233 clientArgs.trustedRoots = anchorArray;
234 clientArgs.xferSize = 0;
235 clientArgs.xferBuf = NULL;
236 clientArgs.chunkSize = 0;
237 clientArgs.cipherSuite = cipherSuite;
238 clientArgs.prot = prot;
239 clientArgs.ringWrite = &clientToServerRing;
240 clientArgs.ringRead = &serverToClientRing;
241 clientArgs.goFlag = &serverArgs.iAmReady;
242 clientArgs.abortFlag = &abortFlag;
243
244 /* cold start, one loop */
245 if(doTest(&clientArgs, &serverArgs, 1, &clientFirst, &serverFirst)) {
246 exit(1);
247 }
248
249 /* now the real test */
250 if(doTest(&clientArgs, &serverArgs, loops, &clientTotal, &serverTotal)) {
251 exit(1);
252 }
253
254 printf("\n");
255
256 printf("SSL Protocol Version : %s\n",
257 sslGetProtocolVersionString(serverArgs.negotiatedProt));
258 printf("SSL Cipher : %s\n",
259 sslGetCipherSuiteString(serverArgs.negotiatedCipher));
260
261 printf("Client Handshake 1st : %f ms\n", clientFirst * 1000.0);
262 printf("Server Handshake 1st : %f ms\n", serverFirst * 1000.0);
263 printf("Client Handshake : %f s in %u loops\n", clientTotal, loops);
264 printf(" %f ms per handshake\n",
265 (clientTotal * 1000.0) / loops);
266 printf("Server Handshake : %f s in %u loops\n", serverTotal, loops);
267 printf(" %f ms per handshake\n",
268 (serverTotal * 1000.0) / loops);
269
270 return 0;
271 }
272
273
274