2 * sslCipher.cpp - test SSL ciphersuite protocol negotiation, client
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>
16 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
23 #include <sys/param.h>
25 /* default start port; caller can specify random start port */
26 #define STARTING_PORT 5000
28 #define MIN_RAND_PORT 1500
29 #define MAX_RAND_PORT 7000
32 * Expected errors for negotiation failure
34 #define SERVER_NEGOTIATE_FAIL errSSLNegotiation
35 #define CLIENT_NEGOTIATE_FAIL errSSLPeerHandshakeFail
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"
42 #define DH_PARAM_FILE_512 "dhParams_512.der"
43 #define DH_PARAM_FILE_1024 "dhParams_1024.der"
45 /* main() fills these in using sslKeychainPath() */
46 static char rsaKcPath
[MAXPATHLEN
];
47 static char dsaKcPath
[MAXPATHLEN
];
49 static void usage(char **argv
)
51 printf("Usage: %s [options]\n", argv
[0]);
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");
69 * Parameters defining one group of tests
72 const char *groupDesc
;
73 const char *serveAcceptProts
;
74 const char *clientAcceptProts
;
75 SSLProtocol expectProt
;
79 * Certificate parameters
83 const char *kcPassword
; // last component of KC name */
88 * Parameters defining one individual test
92 SSLCipherSuite expectCipher
;
93 const CertParams
*certParams
;
95 * In this test all failures are the same
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
};
105 /* Note we're skipping SSL2-specific testing for simplicity's sake */
106 static const GroupParams sslGroupParams
[] =
108 { "TLS1", "23t", "3t", kTLSProtocol1
},
109 { "SSL3", "23", "3t", kSSLProtocol3
}
111 #define NUM_GROUP_PARAMS \
112 (sizeof(sslGroupParams) / sizeof(sslGroupParams[0]))
114 /* some special-purpose ciphersuite arrays */
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
124 /* declare test name and expected cipher suite */
125 #define SSL_NAC(cname) #cname, cname
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
133 const CipherParams sslCipherParams
[] =
136 SSL_NAC(TLS_RSA_WITH_AES_128_CBC_SHA
),
140 SSL_NAC(TLS_DH_DSS_WITH_AES_128_CBC_SHA
),
144 SSL_NAC(TLS_DH_RSA_WITH_AES_128_CBC_SHA
),
148 SSL_NAC(TLS_DHE_DSS_WITH_AES_128_CBC_SHA
),
152 SSL_NAC(TLS_DHE_RSA_WITH_AES_128_CBC_SHA
),
156 SSL_NAC(TLS_DH_anon_WITH_AES_128_CBC_SHA
),
160 SSL_NAC(TLS_RSA_WITH_AES_256_CBC_SHA
),
164 SSL_NAC(TLS_DH_DSS_WITH_AES_256_CBC_SHA
),
168 SSL_NAC(TLS_DH_RSA_WITH_AES_256_CBC_SHA
),
172 SSL_NAC(TLS_DHE_DSS_WITH_AES_256_CBC_SHA
),
176 SSL_NAC(TLS_DHE_RSA_WITH_AES_256_CBC_SHA
),
180 SSL_NAC(TLS_DH_anon_WITH_AES_256_CBC_SHA
),
184 SSL_NAC(SSL_RSA_EXPORT_WITH_RC4_40_MD5
),
188 SSL_NAC(SSL_RSA_WITH_RC4_128_MD5
),
192 SSL_NAC(SSL_RSA_WITH_RC4_128_SHA
),
196 SSL_NAC(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
),
199 /* skip SSL_RSA_WITH_IDEA_CBC_SHA, check later as unimpl */
201 SSL_NAC(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
),
205 SSL_NAC(SSL_RSA_WITH_DES_CBC_SHA
),
209 SSL_NAC(SSL_RSA_WITH_3DES_EDE_CBC_SHA
),
213 SSL_NAC(SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
),
217 SSL_NAC(SSL_DH_DSS_WITH_DES_CBC_SHA
),
221 SSL_NAC(SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA
),
225 SSL_NAC(SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
),
229 SSL_NAC(SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
),
233 SSL_NAC(SSL_DHE_DSS_WITH_DES_CBC_SHA
),
237 SSL_NAC(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
),
241 SSL_NAC(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
),
245 SSL_NAC(SSL_DHE_RSA_WITH_DES_CBC_SHA
),
249 SSL_NAC(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
),
253 SSL_NAC(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
),
257 SSL_NAC(SSL_DH_anon_WITH_RC4_128_MD5
),
261 SSL_NAC(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
),
265 SSL_NAC(SSL_DH_anon_WITH_DES_CBC_SHA
),
269 SSL_NAC(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
),
273 SSL_NAC(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
),
277 SSL_NAC(SSL_FORTEZZA_DMS_WITH_NULL_SHA
),
281 SSL_NAC(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA
),
286 #define NUM_CIPHER_PARAMS \
287 (sizeof(sslCipherParams) / sizeof(sslCipherParams[0]))
289 #define IGNORE_SIGPIPE 1
293 void sigpipe(int sig
)
296 #endif /* IGNORE_SIGPIPE */
299 * Default params for each test. Main() will make a copy of this and
300 * adjust its copy on a per-test basis.
302 static SslAppTestParams serverDefaults
=
305 false, // skipHostNameCHeck
306 0, // port - test must set this
307 NULL
, NULL
, // RingBuffers
309 kSSLProtocolUnknown
,// not used
310 NULL
, // acceptedProts
313 true, // idIsTrustedRoot
314 false, // disableCertVerify
316 false, // replaceAnchors
318 false, // resumeEnable
319 NULL
, // ciphers - default - server accepts all
320 false, // nonBlocking
324 kTLSProtocol1
, // expectVersion
326 SSL_NULL_WITH_NULL_NULL
,
332 false, // serverReady
334 false, // serverAbort
337 SSL_NULL_WITH_NULL_NULL
,
343 SslAppTestParams clientDefaults
=
346 false, // skipHostNameCHeck
347 0, // port - test must set this
348 NULL
, NULL
, // RingBuffers
350 kSSLProtocolUnknown
,// not used
351 NULL
, // acceptedProts
352 NULL
, // myCertKcName
354 true, // idIsTrustedRoot
355 false, // disableCertVerify
357 true, // replaceAnchors
359 false, // resumeEnable
360 NULL
, // ciphers - set in test loop
361 false, // nonBlocking
365 kTLSProtocol1
, // expectVersion
367 SSL_NULL_WITH_NULL_NULL
,
373 false, // serverReady
375 false, // serverAbort
378 SSL_NULL_WITH_NULL_NULL
,
384 int main(int argc
, char **argv
)
388 SslAppTestParams clientParams
;
389 SslAppTestParams serverParams
;
390 unsigned short portNum
= STARTING_PORT
;
391 const GroupParams
*groupParams
;
392 const CipherParams
*cipherParams
;
396 SSLCipherSuite clientCiphers
[3];
397 SSLCipherSuite serverCiphers
[3];
398 RingBuffer serverToClientRing
;
399 RingBuffer clientToServerRing
;
400 bool ringBufferIo
= false;
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
;
408 for(int arg
=1; arg
<argc
; arg
++) {
412 serverDefaults
.quiet
= clientDefaults
.quiet
= true;
415 serverDefaults
.verbose
= clientDefaults
.verbose
= true;
418 portNum
= atoi(&argp
[2]);
421 startTest
= atoi(&argp
[2]);
424 endTest
= atoi(&argp
[2]) + 1;
427 startGroup
= atoi(&argp
[2]);
430 serverDefaults
.nonBlocking
= clientDefaults
.nonBlocking
=
434 dhParamFile
= DH_PARAM_FILE_1024
;
437 portNum
= genRand(MIN_RAND_PORT
, MAX_RAND_PORT
);
440 certRSA
.rootName
= &argp
[2];
443 certDSA
.rootName
= &argp
[2];
453 if(sslCheckFile(certRSA
.rootName
)) {
456 if(sslCheckFile(certDSA
.rootName
)) {
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
;
470 signal(SIGPIPE
, sigpipe
);
473 /* convert keychain names to paths for root */
474 sslKeychainPath(RSA_SERVER_KC
, rsaKcPath
);
475 sslKeychainPath(DSA_SERVER_KC
, dsaKcPath
);
477 /* Diffie-Hellman params, we're going to need them */
478 int r
= readFile(dhParamFile
, (unsigned char **)&serverDefaults
.dhParams
,
479 &serverDefaults
.dhParamsLen
);
481 printf("***Error reading diffie-hellman params from %s; aborting\n",
486 testStartBanner("sslCipher", argc
, argv
);
488 serverParams
.port
= portNum
- 1; // gets incremented by SSL_THR_SETUP
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).
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
;
501 for(groupNum
=startGroup
; groupNum
<NUM_GROUP_PARAMS
; groupNum
++) {
502 groupParams
= &sslGroupParams
[groupNum
];
503 if(!serverDefaults
.quiet
) {
504 printf("...%s\n", groupParams
->groupDesc
);
506 for(testNum
=startTest
; testNum
<endTest
; testNum
++) {
507 cipherParams
= &sslCipherParams
[testNum
];
508 SSL_THR_SETUP(serverParams
, clientParams
, clientDefaults
,
511 ringBufferReset(&serverToClientRing
);
512 ringBufferReset(&clientToServerRing
);
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
;
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
;
528 const CertParams
*certParams
= cipherParams
->certParams
;
529 serverParams
.myCertKcName
= certParams
->kcName
;
530 serverParams
.password
= certParams
->kcPassword
;
531 clientParams
.anchorFile
= certParams
->rootName
;
533 if(cipherParams
->shouldWork
) {
534 serverParams
.expectRtn
= noErr
;
535 clientParams
.expectRtn
= noErr
;
538 serverParams
.expectRtn
= SERVER_NEGOTIATE_FAIL
;
539 clientParams
.expectRtn
= CLIENT_NEGOTIATE_FAIL
;
541 /* server completed protocol version negotiation,
542 * but client didn't */
543 clientParams
.expectVersion
= kSSLProtocolUnknown
;
545 SSL_THR_RUN_NUM(serverParams
, clientParams
,
546 cipherParams
->testDesc
, ourRtn
, testNum
);
551 if(!clientParams
.quiet
) {
553 printf("===== %s test PASSED =====\n", argv
[0]);
556 printf("****%s FAIL: %d errors detected\n", argv
[0],ourRtn
);