2 * sslHandshakeTimeRB - measure SSL handshake timing, RingBuffer version (no
5 * Written by Doug Mitchell.
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>
13 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
19 #include <sys/param.h>
20 #include <CoreFoundation/CoreFoundation.h>
21 #include <security_utilities/devrandom.h>
23 #define DEFAULT_KC "localcert" /* default keychain */
25 /* we might make these user-tweakable */
26 #define DEFAULT_NUM_BUFS 16
27 #define DEFAULT_BUF_SIZE 1024 /* in the ring buffers */
30 static void usage(char **argv
)
32 printf("Usage: %s [option ...]\n", argv
[0]);
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");
45 SslRingBufferArgs
*clientArgs
,
46 SslRingBufferArgs
*serverArgs
,
48 CFAbsoluteTime
*totalElapsedClient
, /* RETURNED */
49 CFAbsoluteTime
*totalElapsedServer
) /* RETURNED */
51 CFAbsoluteTime elapsedClient
= 0.0;
52 CFAbsoluteTime elapsedServer
= 0.0;
54 pthread_t client_thread
= NULL
;
58 for(dex
=0; dex
<loops
; dex
++) {
60 ringBufferReset(clientArgs
->ringWrite
);
61 ringBufferReset(clientArgs
->ringRead
);
62 clientArgs
->iAmReady
= false;
63 serverArgs
->iAmReady
= false;
65 /* fire up client thread */
66 result
= pthread_create(&client_thread
, NULL
,
67 sslRbClientThread
, clientArgs
);
69 printf("***pthread_create returned %d, aborting\n", result
);
74 * And the server pseudo thread. This returns when all data has been transferred.
76 OSStatus ortn
= sslRbServerThread(serverArgs
);
77 if(*serverArgs
->abortFlag
|| ortn
) {
78 printf("***Test aborted (1).\n");
82 /* now wait for client */
83 result
= pthread_join(client_thread
, &status
);
84 if(result
|| *clientArgs
->abortFlag
) {
85 printf("***Test aborted (2).\n");
88 elapsedClient
+= (clientArgs
->startData
- clientArgs
->startHandshake
);
89 elapsedServer
+= (serverArgs
->startData
- serverArgs
->startHandshake
);
91 *totalElapsedClient
= elapsedClient
;
92 *totalElapsedServer
= elapsedServer
;
96 int main(int argc
, char **argv
)
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 */
112 CFAbsoluteTime clientFirst
;
113 CFAbsoluteTime serverFirst
;
114 CFAbsoluteTime clientTotal
;
115 CFAbsoluteTime serverTotal
;
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
;
128 while ((arg
= getopt(argc
, argv
, "l:k:x:c:v:w:aB")) != -1) {
131 loops
= atoi(optarg
);
139 cipherSuite
= TLS_RSA_WITH_AES_128_CBC_SHA
;
142 cipherSuite
= SSL_RSA_WITH_RC4_128_SHA
;
145 cipherSuite
= SSL_RSA_WITH_DES_CBC_SHA
;
148 cipherSuite
= SSL_RSA_WITH_3DES_EDE_CBC_SHA
;
151 cipherSuite
= SSL_DH_anon_WITH_RC4_128_MD5
;
152 diffieHellman
= true;
155 cipherSuite
= SSL_DHE_DSS_WITH_DES_CBC_SHA
;
156 diffieHellman
= true;
159 cipherSuite
= TLS_RSA_WITH_AES_256_CBC_SHA
;
168 prot
= kTLSProtocol1
;
171 prot
= kSSLProtocol2
;
174 prot
= kSSLProtocol3
;
181 clientAuthEnable
= true;
191 /* set up ring buffers */
192 ringBufSetup(&serverToClientRing
, "serveToClient", numBufs
, bufSize
);
193 ringBufSetup(&clientToServerRing
, "clientToServe", numBufs
, bufSize
);
195 /* get server SecIdentity */
196 idArray
= getSslCerts(kcName
,
197 CSSM_FALSE
, /* encryptOnly */
198 CSSM_FALSE
, /* completeCertChain */
199 NULL
, /* anchorFile */
201 if(idArray
== NULL
) {
202 printf("***Can't get signing cert from %s\n", kcName
);
205 idRef
= (SecIdentityRef
)CFArrayGetValueAtIndex(idArray
, 0);
206 ortn
= SecIdentityCopyCertificate(idRef
, &anchorCert
);
208 cssmPerror("SecIdentityCopyCertificate", ortn
);
211 anchorArray
= CFArrayCreate(NULL
, (const void **)&anchorCert
,
212 1, &kCFTypeArrayCallBacks
);
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
;
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
;
244 /* cold start, one loop */
245 if(doTest(&clientArgs
, &serverArgs
, 1, &clientFirst
, &serverFirst
)) {
249 /* now the real test */
250 if(doTest(&clientArgs
, &serverArgs
, loops
, &clientTotal
, &serverTotal
)) {
256 printf("SSL Protocol Version : %s\n",
257 sslGetProtocolVersionString(serverArgs
.negotiatedProt
));
258 printf("SSL Cipher : %s\n",
259 sslGetCipherSuiteString(serverArgs
.negotiatedCipher
));
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
);