2 * Measure performance of SecureTransport - setup and sustained data
3 * throughput. Single process version, no sockets - all data transfer
4 * between client and server is via local memory shared between two
7 * Written by Doug Mitchell.
9 #include <Security/SecureTransport.h>
10 #include <clAppUtils/sslAppUtils.h>
11 #include <utilLib/fileIo.h>
12 #include <utilLib/common.h>
13 #include <clAppUtils/ringBufferIo.h>
14 #include <clAppUtils/sslRingBufferThreads.h>
16 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
22 #include <sys/param.h>
23 #include <CoreFoundation/CoreFoundation.h>
24 #include <security_utilities/devrandom.h>
26 #define DEFAULT_KC "localcert" /* default keychain */
27 #define DEFAULT_XFER (1024 * 1024 * 20) /* total xfer size in bytes */
29 /* we might make these user-tweakable */
30 #define DEFAULT_NUM_BUFS 16
31 #define DEFAULT_BUF_SIZE 2048 /* in the ring buffers */
32 #define DEFAULT_CHUNK 1024 /* bytes to write per SSLWrite() */
34 static void usage(char **argv
)
36 printf("Usage: %s [option ...]\n", argv
[0]);
38 printf(" -k keychain (default = %s)\n", DEFAULT_KC
);
39 printf(" -x transferSize (default=%d; 0=forever)\n", DEFAULT_XFER
);
40 printf(" -c cipher (default = RSA/AES128\n");
41 printf(" ciphers: a=RSA/AES128; r=RSA/RC4; d=RSA/DES; D=RSA/3DES;\n");
42 printf(" h=DHA/RC4; H=DH/DSS/DES; A=AES256\n");
43 printf(" -v version (t|2|3; default = t(TLS1)\n");
44 printf(" -w password (unlock server keychain with password)\n");
45 printf(" -a (enable client authentication)\n");
46 printf(" -p (pause on error)\n");
47 printf(" -m (pause for malloc debug)\n");
51 int main(int argc
, char **argv
)
53 RingBuffer serverToClientRing
;
54 RingBuffer clientToServerRing
;
55 unsigned numBufs
= DEFAULT_NUM_BUFS
;
56 unsigned bufSize
= DEFAULT_BUF_SIZE
;
57 unsigned chunkSize
= DEFAULT_CHUNK
;
58 unsigned char clientBuf
[DEFAULT_CHUNK
];
59 unsigned char serverBuf
[DEFAULT_CHUNK
];
60 CFArrayRef idArray
; /* for SSLSetCertificate */
61 CFArrayRef anchorArray
; /* trusted roots */
62 SslRingBufferArgs clientArgs
;
63 SslRingBufferArgs serverArgs
;
64 SecKeychainRef kcRef
= NULL
;
65 SecCertificateRef anchorCert
= NULL
;
66 SecIdentityRef idRef
= NULL
;
67 bool abortFlag
= false;
68 pthread_t client_thread
= NULL
;
70 bool diffieHellman
= true; /* FIXME needs work */
73 /* user-spec'd variables */
74 char *kcName
= DEFAULT_KC
;
75 unsigned xferSize
= DEFAULT_XFER
;
76 SSLCipherSuite cipherSuite
= TLS_RSA_WITH_AES_128_CBC_SHA
;
77 SSLProtocol prot
= kTLSProtocol1
;
79 bool clientAuthEnable
= false;
80 bool pauseOnError
= false;
81 bool runForever
= false;
82 bool mallocPause
= false;
90 while ((arg
= getopt(argc
, argv
, "k:x:c:v:w:aBpm")) != -1) {
97 unsigned xsize
= atoi(optarg
);
100 /* and leave xferSize alone */
110 cipherSuite
= TLS_RSA_WITH_AES_128_CBC_SHA
;
113 cipherSuite
= SSL_RSA_WITH_RC4_128_SHA
;
116 cipherSuite
= SSL_RSA_WITH_DES_CBC_SHA
;
119 cipherSuite
= SSL_RSA_WITH_3DES_EDE_CBC_SHA
;
122 cipherSuite
= SSL_DH_anon_WITH_RC4_128_MD5
;
123 diffieHellman
= true;
126 cipherSuite
= SSL_DHE_DSS_WITH_DES_CBC_SHA
;
127 diffieHellman
= true;
130 cipherSuite
= TLS_RSA_WITH_AES_256_CBC_SHA
;
139 prot
= kTLSProtocol1
;
142 prot
= kSSLProtocol2
;
145 prot
= kSSLProtocol3
;
152 strcpy(password
, optarg
);
155 clientAuthEnable
= true;
171 /* set up ring buffers */
172 ringBufSetup(&serverToClientRing
, "serveToClient", numBufs
, bufSize
);
173 ringBufSetup(&clientToServerRing
, "clientToServe", numBufs
, bufSize
);
175 /* get server SecIdentity */
176 idArray
= getSslCerts(kcName
,
177 CSSM_FALSE
, /* encryptOnly */
178 CSSM_FALSE
, /* completeCertChain */
179 NULL
, /* anchorFile */
181 if(idArray
== NULL
) {
182 printf("***Can't get signing cert from %s\n", kcName
);
185 idRef
= (SecIdentityRef
)CFArrayGetValueAtIndex(idArray
, 0);
186 ortn
= SecIdentityCopyCertificate(idRef
, &anchorCert
);
188 cssmPerror("SecIdentityCopyCertificate", ortn
);
191 anchorArray
= CFArrayCreate(NULL
, (const void **)&anchorCert
,
192 1, &kCFTypeArrayCallBacks
);
194 /* unlock keychain? */
196 ortn
= SecKeychainUnlock(kcRef
, strlen(password
), password
, true);
198 cssmPerror("SecKeychainUnlock", ortn
);
206 printf("Pausing for MallocDebug setup. CR to proceed: ");
210 /* set up server side */
211 memset(&serverArgs
, 0, sizeof(serverArgs
));
212 serverArgs
.idArray
= idArray
;
213 serverArgs
.trustedRoots
= anchorArray
;
214 serverArgs
.xferSize
= xferSize
;
215 serverArgs
.xferBuf
= serverBuf
;
216 serverArgs
.chunkSize
= chunkSize
;
217 serverArgs
.runForever
= runForever
;
218 serverArgs
.cipherSuite
= cipherSuite
;
219 serverArgs
.prot
= prot
;
220 serverArgs
.ringWrite
= &serverToClientRing
;
221 serverArgs
.ringRead
= &clientToServerRing
;
222 serverArgs
.goFlag
= &clientArgs
.iAmReady
;
223 serverArgs
.abortFlag
= &abortFlag
;
224 serverArgs
.pauseOnError
= pauseOnError
;
226 /* set up client side */
227 memset(&clientArgs
, 0, sizeof(clientArgs
));
228 clientArgs
.idArray
= NULL
; /* until we do client auth */
229 clientArgs
.trustedRoots
= anchorArray
;
230 clientArgs
.xferSize
= xferSize
;
231 clientArgs
.xferBuf
= clientBuf
;
232 clientArgs
.chunkSize
= chunkSize
;
233 clientArgs
.runForever
= runForever
;
234 clientArgs
.cipherSuite
= cipherSuite
;
235 clientArgs
.prot
= prot
;
236 clientArgs
.ringWrite
= &clientToServerRing
;
237 clientArgs
.ringRead
= &serverToClientRing
;
238 clientArgs
.goFlag
= &serverArgs
.iAmReady
;
239 clientArgs
.abortFlag
= &abortFlag
;
240 clientArgs
.pauseOnError
= pauseOnError
;
242 /* fire up client thread */
243 result
= pthread_create(&client_thread
, NULL
,
244 sslRbClientThread
, &clientArgs
);
246 printf("***pthread_create returned %d, aborting\n", result
);
251 * And the server pseudo thread. This returns when all data has been transferred.
253 ortn
= sslRbServerThread(&serverArgs
);
256 printf("***Test aborted.\n");
264 printf("End of test. Pausing for MallocDebug analysis. CR to proceed: ");
268 printf("SSL Protocol Version : %s\n",
269 sslGetProtocolVersionString(serverArgs
.negotiatedProt
));
270 printf("SSL Cipher : %s\n",
271 sslGetCipherSuiteString(serverArgs
.negotiatedCipher
));
273 printf("SSL Handshake : %f s\n",
274 serverArgs
.startData
- serverArgs
.startHandshake
);
275 printf("Data Transfer : %u bytes in %f s\n", (unsigned)xferSize
,
276 serverArgs
.endData
- serverArgs
.startHandshake
);
277 printf(" : %.1f Kbytes/s\n",
278 xferSize
/ (serverArgs
.endData
- serverArgs
.startHandshake
) / 1024.0);