]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/sslCipher/sslCipher.cpp
Security-57031.30.12.tar.gz
[apple/security.git] / SecurityTests / clxutils / sslCipher / sslCipher.cpp
1 /*
2 * sslCipher.cpp - test SSL ciphersuite protocol negotiation, client
3 * and server side
4 */
5 #include <Security/SecureTransport.h>
6 #include <Security/Security.h>
7 #include <clAppUtils/sslAppUtils.h>
8 #include <clAppUtils/ioSock.h>
9 #include <clAppUtils/sslThreading.h>
10 #include <security_cdsa_utils/cuFileIo.h>
11 #include <utilLib/common.h>
12 #include <security_cdsa_utils/cuPrintCert.h>
13 #include <security_utilities/threading.h>
14 #include <security_utilities/devrandom.h>
15
16 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <time.h>
22 #include <ctype.h>
23 #include <sys/param.h>
24
25 /* default start port; caller can specify random start port */
26 #define STARTING_PORT 5000
27
28 #define MIN_RAND_PORT 1500
29 #define MAX_RAND_PORT 7000
30
31 /*
32 * Expected errors for negotiation failure
33 */
34 #define SERVER_NEGOTIATE_FAIL errSSLNegotiation
35 #define CLIENT_NEGOTIATE_FAIL errSSLPeerHandshakeFail
36
37 #define RSA_SERVER_KC "localcert"
38 #define RSA_SERVER_ROOT "localcert.cer"
39 #define DSA_SERVER_KC "dsacert"
40 #define DSA_SERVER_ROOT "dsacert.cer"
41
42 #define DH_PARAM_FILE_512 "dhParams_512.der"
43 #define DH_PARAM_FILE_1024 "dhParams_1024.der"
44
45 /* main() fills these in using sslKeychainPath() */
46 static char rsaKcPath[MAXPATHLEN];
47 static char dsaKcPath[MAXPATHLEN];
48
49 static void usage(char **argv)
50 {
51 printf("Usage: %s [options]\n", argv[0]);
52 printf("options:\n");
53 printf(" q(uiet)\n");
54 printf(" v(erbose)\n");
55 printf(" p=startingPortNum\n");
56 printf(" t=startTestNum\n");
57 printf(" T=endTestNum\n");
58 printf(" g=startGroupNum\n");
59 printf(" l (large, 1024 bit Diffie-Hellman; default is 512)\n");
60 printf(" r(andom start port, default=%d)\n", STARTING_PORT);
61 printf(" b (non blocking I/O)\n");
62 printf(" s=serverCertName; default %s\n", RSA_SERVER_ROOT);
63 printf(" d=clientCertName; default %s\n", DSA_SERVER_ROOT);
64 printf(" R (ringBuffer I/O)\n");
65 exit(1);
66 }
67
68 /*
69 * Parameters defining one group of tests
70 */
71 typedef struct {
72 const char *groupDesc;
73 const char *serveAcceptProts;
74 const char *clientAcceptProts;
75 SSLProtocol expectProt;
76 } GroupParams;
77
78 /*
79 * Certificate parameters
80 */
81 typedef struct {
82 const char *kcName;
83 const char *kcPassword; // last component of KC name */
84 const char *rootName;
85 } CertParams;
86
87 /*
88 * Parameters defining one individual test
89 */
90 typedef struct {
91 const char *testDesc;
92 SSLCipherSuite expectCipher;
93 const CertParams *certParams;
94 /*
95 * In this test all failures are the same
96 */
97 bool shouldWork;
98 } CipherParams;
99
100 /* one of three cert params */
101 static CertParams certRSA = { rsaKcPath, RSA_SERVER_KC, RSA_SERVER_ROOT };
102 static CertParams certDSA = { dsaKcPath, DSA_SERVER_KC, DSA_SERVER_ROOT };
103 static CertParams certNone = {NULL, NULL};
104
105 /* Note we're skipping SSL2-specific testing for simplicity's sake */
106 static const GroupParams sslGroupParams[] =
107 {
108 { "TLS1", "23t", "3t", kTLSProtocol1 },
109 { "SSL3", "23", "3t", kSSLProtocol3 }
110 };
111 #define NUM_GROUP_PARAMS \
112 (sizeof(sslGroupParams) / sizeof(sslGroupParams[0]))
113
114 /* some special-purpose ciphersuite arrays */
115
116 #ifdef not_used
117 /* just SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA */
118 static const SSLCipherSuite suites_RsaExpDh40[] = {
119 SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
120 SSL_NO_SUCH_CIPHERSUITE
121 };
122 #endif
123
124 /* declare test name and expected cipher suite */
125 #define SSL_NAC(cname) #cname, cname
126
127 /*
128 * Note: the client is the only side which actually gets to
129 * prioritize its requested CipherSuites. The server has to
130 * go along with the first one on the client's list which the
131 * server implements.
132 */
133 const CipherParams sslCipherParams[] =
134 {
135 {
136 SSL_NAC(TLS_RSA_WITH_AES_128_CBC_SHA),
137 &certRSA, true
138 },
139 {
140 SSL_NAC(TLS_DH_DSS_WITH_AES_128_CBC_SHA),
141 &certDSA, false
142 },
143 {
144 SSL_NAC(TLS_DH_RSA_WITH_AES_128_CBC_SHA),
145 &certRSA, false
146 },
147 {
148 SSL_NAC(TLS_DHE_DSS_WITH_AES_128_CBC_SHA),
149 &certDSA, true
150 },
151 {
152 SSL_NAC(TLS_DHE_RSA_WITH_AES_128_CBC_SHA),
153 &certRSA, true
154 },
155 {
156 SSL_NAC(TLS_DH_anon_WITH_AES_128_CBC_SHA),
157 &certNone, true
158 },
159 {
160 SSL_NAC(TLS_RSA_WITH_AES_256_CBC_SHA),
161 &certRSA, true
162 },
163 {
164 SSL_NAC(TLS_DH_DSS_WITH_AES_256_CBC_SHA),
165 &certDSA, false
166 },
167 {
168 SSL_NAC(TLS_DH_RSA_WITH_AES_256_CBC_SHA),
169 &certRSA, false
170 },
171 {
172 SSL_NAC(TLS_DHE_DSS_WITH_AES_256_CBC_SHA),
173 &certDSA, true
174 },
175 {
176 SSL_NAC(TLS_DHE_RSA_WITH_AES_256_CBC_SHA),
177 &certRSA, true
178 },
179 {
180 SSL_NAC(TLS_DH_anon_WITH_AES_256_CBC_SHA),
181 &certNone, true
182 },
183 {
184 SSL_NAC(SSL_RSA_EXPORT_WITH_RC4_40_MD5),
185 &certRSA, true
186 },
187 {
188 SSL_NAC(SSL_RSA_WITH_RC4_128_MD5),
189 &certRSA, true
190 },
191 {
192 SSL_NAC(SSL_RSA_WITH_RC4_128_SHA),
193 &certRSA, true
194 },
195 {
196 SSL_NAC(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5),
197 &certRSA, true
198 },
199 /* skip SSL_RSA_WITH_IDEA_CBC_SHA, check later as unimpl */
200 {
201 SSL_NAC(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA),
202 &certRSA, true
203 },
204 {
205 SSL_NAC(SSL_RSA_WITH_DES_CBC_SHA),
206 &certRSA, true
207 },
208 {
209 SSL_NAC(SSL_RSA_WITH_3DES_EDE_CBC_SHA),
210 &certRSA, true
211 },
212 {
213 SSL_NAC(SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA),
214 &certDSA, false
215 },
216 {
217 SSL_NAC(SSL_DH_DSS_WITH_DES_CBC_SHA),
218 &certDSA, false
219 },
220 {
221 SSL_NAC(SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA),
222 &certDSA, false
223 },
224 {
225 SSL_NAC(SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA),
226 &certRSA, false
227 },
228 {
229 SSL_NAC(SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA),
230 &certDSA, true
231 },
232 {
233 SSL_NAC(SSL_DHE_DSS_WITH_DES_CBC_SHA),
234 &certDSA, true
235 },
236 {
237 SSL_NAC(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA),
238 &certDSA, true
239 },
240 {
241 SSL_NAC(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA),
242 &certRSA, true
243 },
244 {
245 SSL_NAC(SSL_DHE_RSA_WITH_DES_CBC_SHA),
246 &certRSA, true
247 },
248 {
249 SSL_NAC(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA),
250 &certRSA, true
251 },
252 {
253 SSL_NAC(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5),
254 &certNone, true
255 },
256 {
257 SSL_NAC(SSL_DH_anon_WITH_RC4_128_MD5),
258 &certNone, true
259 },
260 {
261 SSL_NAC(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA),
262 &certNone, true
263 },
264 {
265 SSL_NAC(SSL_DH_anon_WITH_DES_CBC_SHA),
266 &certNone, true
267 },
268 {
269 SSL_NAC(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA),
270 &certNone, true
271 },
272 {
273 SSL_NAC(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA),
274 &certNone, true
275 },
276 {
277 SSL_NAC(SSL_FORTEZZA_DMS_WITH_NULL_SHA),
278 &certNone, false
279 },
280 {
281 SSL_NAC(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA),
282 &certNone, false
283 },
284 };
285
286 #define NUM_CIPHER_PARAMS \
287 (sizeof(sslCipherParams) / sizeof(sslCipherParams[0]))
288
289 #define IGNORE_SIGPIPE 1
290 #if IGNORE_SIGPIPE
291 #include <signal.h>
292
293 void sigpipe(int sig)
294 {
295 }
296 #endif /* IGNORE_SIGPIPE */
297
298 /*
299 * Default params for each test. Main() will make a copy of this and
300 * adjust its copy on a per-test basis.
301 */
302 static SslAppTestParams serverDefaults =
303 {
304 "no name here",
305 false, // skipHostNameCHeck
306 0, // port - test must set this
307 NULL, NULL, // RingBuffers
308 false, // noProtSpec
309 kSSLProtocolUnknown,// not used
310 NULL, // acceptedProts
311 NULL, // myCerts
312 NULL, // password
313 true, // idIsTrustedRoot
314 false, // disableCertVerify
315 NULL, // anchorFile
316 false, // replaceAnchors
317 kNeverAuthenticate,
318 false, // resumeEnable
319 NULL, // ciphers - default - server accepts all
320 false, // nonBlocking
321 NULL, // dhParams
322 0, // dhParamsLen
323 noErr, // expectRtn
324 kTLSProtocol1, // expectVersion
325 kSSLClientCertNone,
326 SSL_NULL_WITH_NULL_NULL,
327 false, // quiet
328 false, // silent
329 false, // verbose
330 {0}, // lock
331 {0}, // cond
332 false, // serverReady
333 0, // clientDone
334 false, // serverAbort
335 /* returned */
336 kSSLProtocolUnknown,
337 SSL_NULL_WITH_NULL_NULL,
338 kSSLClientCertNone,
339 noHardwareErr
340
341 };
342
343 SslAppTestParams clientDefaults =
344 {
345 "localhost",
346 false, // skipHostNameCHeck
347 0, // port - test must set this
348 NULL, NULL, // RingBuffers
349 false, // noProtSpec
350 kSSLProtocolUnknown,// not used
351 NULL, // acceptedProts
352 NULL, // myCertKcName
353 NULL, // password
354 true, // idIsTrustedRoot
355 false, // disableCertVerify
356 NULL, // anchorFile
357 true, // replaceAnchors
358 kNeverAuthenticate,
359 false, // resumeEnable
360 NULL, // ciphers - set in test loop
361 false, // nonBlocking
362 NULL, // dhParams
363 0, // dhParamsLen
364 noErr, // expectRtn
365 kTLSProtocol1, // expectVersion
366 kSSLClientCertNone,
367 SSL_NULL_WITH_NULL_NULL,
368 false, // quiet
369 false, // silent
370 false, // verbose
371 {0}, // lock
372 {0}, // cond
373 false, // serverReady
374 0, // clientDone
375 false, // serverAbort
376 /* returned */
377 kSSLProtocolUnknown,
378 SSL_NULL_WITH_NULL_NULL,
379 kSSLClientCertNone,
380 noHardwareErr
381 };
382
383
384 int main(int argc, char **argv)
385 {
386 int ourRtn = 0;
387 char *argp;
388 SslAppTestParams clientParams;
389 SslAppTestParams serverParams;
390 unsigned short portNum = STARTING_PORT;
391 const GroupParams *groupParams;
392 const CipherParams *cipherParams;
393 unsigned testNum;
394 unsigned groupNum;
395 int thisRtn;
396 SSLCipherSuite clientCiphers[3];
397 SSLCipherSuite serverCiphers[3];
398 RingBuffer serverToClientRing;
399 RingBuffer clientToServerRing;
400 bool ringBufferIo = false;
401
402 /* user-spec'd variables */
403 unsigned startTest = 0;
404 unsigned endTest = NUM_CIPHER_PARAMS;
405 unsigned startGroup = 0;
406 const char *dhParamFile = DH_PARAM_FILE_512;
407
408 for(int arg=1; arg<argc; arg++) {
409 argp = argv[arg];
410 switch(argp[0]) {
411 case 'q':
412 serverDefaults.quiet = clientDefaults.quiet = true;
413 break;
414 case 'v':
415 serverDefaults.verbose = clientDefaults.verbose = true;
416 break;
417 case 'p':
418 portNum = atoi(&argp[2]);
419 break;
420 case 't':
421 startTest = atoi(&argp[2]);
422 break;
423 case 'T':
424 endTest = atoi(&argp[2]) + 1;
425 break;
426 case 'g':
427 startGroup = atoi(&argp[2]);
428 break;
429 case 'b':
430 serverDefaults.nonBlocking = clientDefaults.nonBlocking =
431 true;
432 break;
433 case 'l':
434 dhParamFile = DH_PARAM_FILE_1024;
435 break;
436 case 'r':
437 portNum = genRand(MIN_RAND_PORT, MAX_RAND_PORT);
438 break;
439 case 's':
440 certRSA.rootName = &argp[2];
441 break;
442 case 'd':
443 certDSA.rootName = &argp[2];
444 break;
445 case 'R':
446 ringBufferIo = true;
447 break;
448 default:
449 usage(argv);
450 }
451 }
452
453 if(sslCheckFile(certRSA.rootName)) {
454 exit(1);
455 }
456 if(sslCheckFile(certDSA.rootName)) {
457 exit(1);
458 }
459 if(ringBufferIo) {
460 /* set up ring buffers */
461 ringBufSetup(&serverToClientRing, "serveToClient", DEFAULT_NUM_RB_BUFS, DEFAULT_BUF_RB_SIZE);
462 ringBufSetup(&clientToServerRing, "clientToServe", DEFAULT_NUM_RB_BUFS, DEFAULT_BUF_RB_SIZE);
463 serverDefaults.serverToClientRing = &serverToClientRing;
464 serverDefaults.clientToServerRing = &clientToServerRing;
465 clientDefaults.serverToClientRing = &serverToClientRing;
466 clientDefaults.clientToServerRing = &clientToServerRing;
467 }
468
469 #if IGNORE_SIGPIPE
470 signal(SIGPIPE, sigpipe);
471 #endif
472
473 /* convert keychain names to paths for root */
474 sslKeychainPath(RSA_SERVER_KC, rsaKcPath);
475 sslKeychainPath(DSA_SERVER_KC, dsaKcPath);
476
477 /* Diffie-Hellman params, we're going to need them */
478 int r = readFile(dhParamFile, (unsigned char **)&serverDefaults.dhParams,
479 &serverDefaults.dhParamsLen);
480 if(r) {
481 printf("***Error reading diffie-hellman params from %s; aborting\n",
482 dhParamFile);
483 exit(1);
484 }
485
486 testStartBanner("sslCipher", argc, argv);
487
488 serverParams.port = portNum - 1; // gets incremented by SSL_THR_SETUP
489
490 /*
491 * To enable negotiation failures to occur, we have to pass
492 * in ciphersuite arrays which contain at least one valid
493 * ciphersuite to both client and server, but they can not
494 * be the same (or else that valid suite will be used).
495 */
496 clientCiphers[1] = SSL_RSA_WITH_RC4_128_MD5;
497 serverCiphers[1] = SSL_RSA_WITH_RC4_128_SHA;
498 clientCiphers[2] = SSL_NO_SUCH_CIPHERSUITE;
499 serverCiphers[2] = SSL_NO_SUCH_CIPHERSUITE;
500
501 for(groupNum=startGroup; groupNum<NUM_GROUP_PARAMS; groupNum++) {
502 groupParams = &sslGroupParams[groupNum];
503 if(!serverDefaults.quiet) {
504 printf("...%s\n", groupParams->groupDesc);
505 }
506 for(testNum=startTest; testNum<endTest; testNum++) {
507 cipherParams = &sslCipherParams[testNum];
508 SSL_THR_SETUP(serverParams, clientParams, clientDefaults,
509 serverDefault);
510 if(ringBufferIo) {
511 ringBufferReset(&serverToClientRing);
512 ringBufferReset(&clientToServerRing);
513 }
514 /* per-group (must be after SSL_THR_SETUP) */
515 serverParams.acceptedProts = groupParams->serveAcceptProts;
516 clientParams.acceptedProts = groupParams->clientAcceptProts;
517 serverParams.expectVersion = groupParams->expectProt;
518 clientParams.expectVersion = groupParams->expectProt;
519
520 /* per-test */
521 clientCiphers[0] = cipherParams->expectCipher;
522 serverCiphers[0] = cipherParams->expectCipher;
523 clientParams.ciphers = clientCiphers;
524 serverParams.ciphers = serverCiphers;
525 serverParams.expectCipher = cipherParams->expectCipher;
526 clientParams.expectCipher = cipherParams->expectCipher;
527
528 const CertParams *certParams = cipherParams->certParams;
529 serverParams.myCertKcName = certParams->kcName;
530 serverParams.password = certParams->kcPassword;
531 clientParams.anchorFile = certParams->rootName;
532
533 if(cipherParams->shouldWork) {
534 serverParams.expectRtn = noErr;
535 clientParams.expectRtn = noErr;
536 }
537 else {
538 serverParams.expectRtn = SERVER_NEGOTIATE_FAIL;
539 clientParams.expectRtn = CLIENT_NEGOTIATE_FAIL;
540
541 /* server completed protocol version negotiation,
542 * but client didn't */
543 clientParams.expectVersion = kSSLProtocolUnknown;
544 }
545 SSL_THR_RUN_NUM(serverParams, clientParams,
546 cipherParams->testDesc, ourRtn, testNum);
547 }
548 }
549
550 done:
551 if(!clientParams.quiet) {
552 if(ourRtn == 0) {
553 printf("===== %s test PASSED =====\n", argv[0]);
554 }
555 else {
556 printf("****%s FAIL: %d errors detected\n", argv[0],ourRtn);
557 }
558 }
559
560 return ourRtn;
561 }