+++ /dev/null
-/*
- * sslCipher.cpp - test SSL ciphersuite protocol negotiation, client
- * and server side
- */
-#include <Security/SecureTransport.h>
-#include <Security/Security.h>
-#include <clAppUtils/sslAppUtils.h>
-#include <clAppUtils/ioSock.h>
-#include <clAppUtils/sslThreading.h>
-#include <security_cdsa_utils/cuFileIo.h>
-#include <utilLib/common.h>
-#include <security_cdsa_utils/cuPrintCert.h>
-#include <security_utilities/threading.h>
-#include <security_utilities/devrandom.h>
-
-#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <time.h>
-#include <ctype.h>
-#include <sys/param.h>
-
-/* default start port; caller can specify random start port */
-#define STARTING_PORT 5000
-
-#define MIN_RAND_PORT 1500
-#define MAX_RAND_PORT 7000
-
-/*
- * Expected errors for negotiation failure
- */
-#define SERVER_NEGOTIATE_FAIL errSSLNegotiation
-#define CLIENT_NEGOTIATE_FAIL errSSLPeerHandshakeFail
-
-#define RSA_SERVER_KC "localcert"
-#define RSA_SERVER_ROOT "localcert.cer"
-#define DSA_SERVER_KC "dsacert"
-#define DSA_SERVER_ROOT "dsacert.cer"
-
-#define DH_PARAM_FILE_512 "dhParams_512.der"
-#define DH_PARAM_FILE_1024 "dhParams_1024.der"
-
-/* main() fills these in using sslKeychainPath() */
-static char rsaKcPath[MAXPATHLEN];
-static char dsaKcPath[MAXPATHLEN];
-
-static void usage(char **argv)
-{
- printf("Usage: %s [options]\n", argv[0]);
- printf("options:\n");
- printf(" q(uiet)\n");
- printf(" v(erbose)\n");
- printf(" p=startingPortNum\n");
- printf(" t=startTestNum\n");
- printf(" T=endTestNum\n");
- printf(" g=startGroupNum\n");
- printf(" l (large, 1024 bit Diffie-Hellman; default is 512)\n");
- printf(" r(andom start port, default=%d)\n", STARTING_PORT);
- printf(" b (non blocking I/O)\n");
- printf(" s=serverCertName; default %s\n", RSA_SERVER_ROOT);
- printf(" d=clientCertName; default %s\n", DSA_SERVER_ROOT);
- printf(" R (ringBuffer I/O)\n");
- exit(1);
-}
-
-/*
- * Parameters defining one group of tests
- */
-typedef struct {
- const char *groupDesc;
- const char *serveAcceptProts;
- const char *clientAcceptProts;
- SSLProtocol expectProt;
-} GroupParams;
-
-/*
- * Certificate parameters
- */
-typedef struct {
- const char *kcName;
- const char *kcPassword; // last component of KC name */
- const char *rootName;
-} CertParams;
-
-/*
- * Parameters defining one individual test
- */
-typedef struct {
- const char *testDesc;
- SSLCipherSuite expectCipher;
- const CertParams *certParams;
- /*
- * In this test all failures are the same
- */
- bool shouldWork;
-} CipherParams;
-
-/* one of three cert params */
-static CertParams certRSA = { rsaKcPath, RSA_SERVER_KC, RSA_SERVER_ROOT };
-static CertParams certDSA = { dsaKcPath, DSA_SERVER_KC, DSA_SERVER_ROOT };
-static CertParams certNone = {NULL, NULL};
-
-/* Note we're skipping SSL2-specific testing for simplicity's sake */
-static const GroupParams sslGroupParams[] =
-{
- { "TLS1", "23t", "3t", kTLSProtocol1 },
- { "SSL3", "23", "3t", kSSLProtocol3 }
-};
-#define NUM_GROUP_PARAMS \
- (sizeof(sslGroupParams) / sizeof(sslGroupParams[0]))
-
-/* some special-purpose ciphersuite arrays */
-
-#ifdef not_used
-/* just SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA */
-static const SSLCipherSuite suites_RsaExpDh40[] = {
- SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
- SSL_NO_SUCH_CIPHERSUITE
-};
-#endif
-
-/* declare test name and expected cipher suite */
-#define SSL_NAC(cname) #cname, cname
-
-/*
- * Note: the client is the only side which actually gets to
- * prioritize its requested CipherSuites. The server has to
- * go along with the first one on the client's list which the
- * server implements.
- */
-const CipherParams sslCipherParams[] =
-{
- {
- SSL_NAC(TLS_RSA_WITH_AES_128_CBC_SHA),
- &certRSA, true
- },
- {
- SSL_NAC(TLS_DH_DSS_WITH_AES_128_CBC_SHA),
- &certDSA, false
- },
- {
- SSL_NAC(TLS_DH_RSA_WITH_AES_128_CBC_SHA),
- &certRSA, false
- },
- {
- SSL_NAC(TLS_DHE_DSS_WITH_AES_128_CBC_SHA),
- &certDSA, true
- },
- {
- SSL_NAC(TLS_DHE_RSA_WITH_AES_128_CBC_SHA),
- &certRSA, true
- },
- {
- SSL_NAC(TLS_DH_anon_WITH_AES_128_CBC_SHA),
- &certNone, true
- },
- {
- SSL_NAC(TLS_RSA_WITH_AES_256_CBC_SHA),
- &certRSA, true
- },
- {
- SSL_NAC(TLS_DH_DSS_WITH_AES_256_CBC_SHA),
- &certDSA, false
- },
- {
- SSL_NAC(TLS_DH_RSA_WITH_AES_256_CBC_SHA),
- &certRSA, false
- },
- {
- SSL_NAC(TLS_DHE_DSS_WITH_AES_256_CBC_SHA),
- &certDSA, true
- },
- {
- SSL_NAC(TLS_DHE_RSA_WITH_AES_256_CBC_SHA),
- &certRSA, true
- },
- {
- SSL_NAC(TLS_DH_anon_WITH_AES_256_CBC_SHA),
- &certNone, true
- },
- {
- SSL_NAC(SSL_RSA_EXPORT_WITH_RC4_40_MD5),
- &certRSA, true
- },
- {
- SSL_NAC(SSL_RSA_WITH_RC4_128_MD5),
- &certRSA, true
- },
- {
- SSL_NAC(SSL_RSA_WITH_RC4_128_SHA),
- &certRSA, true
- },
- {
- SSL_NAC(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5),
- &certRSA, true
- },
- /* skip SSL_RSA_WITH_IDEA_CBC_SHA, check later as unimpl */
- {
- SSL_NAC(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA),
- &certRSA, true
- },
- {
- SSL_NAC(SSL_RSA_WITH_DES_CBC_SHA),
- &certRSA, true
- },
- {
- SSL_NAC(SSL_RSA_WITH_3DES_EDE_CBC_SHA),
- &certRSA, true
- },
- {
- SSL_NAC(SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA),
- &certDSA, false
- },
- {
- SSL_NAC(SSL_DH_DSS_WITH_DES_CBC_SHA),
- &certDSA, false
- },
- {
- SSL_NAC(SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA),
- &certDSA, false
- },
- {
- SSL_NAC(SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA),
- &certRSA, false
- },
- {
- SSL_NAC(SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA),
- &certDSA, true
- },
- {
- SSL_NAC(SSL_DHE_DSS_WITH_DES_CBC_SHA),
- &certDSA, true
- },
- {
- SSL_NAC(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA),
- &certDSA, true
- },
- {
- SSL_NAC(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA),
- &certRSA, true
- },
- {
- SSL_NAC(SSL_DHE_RSA_WITH_DES_CBC_SHA),
- &certRSA, true
- },
- {
- SSL_NAC(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA),
- &certRSA, true
- },
- {
- SSL_NAC(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5),
- &certNone, true
- },
- {
- SSL_NAC(SSL_DH_anon_WITH_RC4_128_MD5),
- &certNone, true
- },
- {
- SSL_NAC(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA),
- &certNone, true
- },
- {
- SSL_NAC(SSL_DH_anon_WITH_DES_CBC_SHA),
- &certNone, true
- },
- {
- SSL_NAC(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA),
- &certNone, true
- },
- {
- SSL_NAC(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA),
- &certNone, true
- },
- {
- SSL_NAC(SSL_FORTEZZA_DMS_WITH_NULL_SHA),
- &certNone, false
- },
- {
- SSL_NAC(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA),
- &certNone, false
- },
-};
-
-#define NUM_CIPHER_PARAMS \
- (sizeof(sslCipherParams) / sizeof(sslCipherParams[0]))
-
-#define IGNORE_SIGPIPE 1
-#if IGNORE_SIGPIPE
-#include <signal.h>
-
-void sigpipe(int sig)
-{
-}
-#endif /* IGNORE_SIGPIPE */
-
-/*
- * Default params for each test. Main() will make a copy of this and
- * adjust its copy on a per-test basis.
- */
-static SslAppTestParams serverDefaults =
-{
- "no name here",
- false, // skipHostNameCHeck
- 0, // port - test must set this
- NULL, NULL, // RingBuffers
- false, // noProtSpec
- kSSLProtocolUnknown,// not used
- NULL, // acceptedProts
- NULL, // myCerts
- NULL, // password
- true, // idIsTrustedRoot
- false, // disableCertVerify
- NULL, // anchorFile
- false, // replaceAnchors
- kNeverAuthenticate,
- false, // resumeEnable
- NULL, // ciphers - default - server accepts all
- false, // nonBlocking
- NULL, // dhParams
- 0, // dhParamsLen
- noErr, // expectRtn
- kTLSProtocol1, // expectVersion
- kSSLClientCertNone,
- SSL_NULL_WITH_NULL_NULL,
- false, // quiet
- false, // silent
- false, // verbose
- {0}, // lock
- {0}, // cond
- false, // serverReady
- 0, // clientDone
- false, // serverAbort
- /* returned */
- kSSLProtocolUnknown,
- SSL_NULL_WITH_NULL_NULL,
- kSSLClientCertNone,
- noHardwareErr
-
-};
-
-SslAppTestParams clientDefaults =
-{
- "localhost",
- false, // skipHostNameCHeck
- 0, // port - test must set this
- NULL, NULL, // RingBuffers
- false, // noProtSpec
- kSSLProtocolUnknown,// not used
- NULL, // acceptedProts
- NULL, // myCertKcName
- NULL, // password
- true, // idIsTrustedRoot
- false, // disableCertVerify
- NULL, // anchorFile
- true, // replaceAnchors
- kNeverAuthenticate,
- false, // resumeEnable
- NULL, // ciphers - set in test loop
- false, // nonBlocking
- NULL, // dhParams
- 0, // dhParamsLen
- noErr, // expectRtn
- kTLSProtocol1, // expectVersion
- kSSLClientCertNone,
- SSL_NULL_WITH_NULL_NULL,
- false, // quiet
- false, // silent
- false, // verbose
- {0}, // lock
- {0}, // cond
- false, // serverReady
- 0, // clientDone
- false, // serverAbort
- /* returned */
- kSSLProtocolUnknown,
- SSL_NULL_WITH_NULL_NULL,
- kSSLClientCertNone,
- noHardwareErr
-};
-
-
-int main(int argc, char **argv)
-{
- int ourRtn = 0;
- char *argp;
- SslAppTestParams clientParams;
- SslAppTestParams serverParams;
- unsigned short portNum = STARTING_PORT;
- const GroupParams *groupParams;
- const CipherParams *cipherParams;
- unsigned testNum;
- unsigned groupNum;
- int thisRtn;
- SSLCipherSuite clientCiphers[3];
- SSLCipherSuite serverCiphers[3];
- RingBuffer serverToClientRing;
- RingBuffer clientToServerRing;
- bool ringBufferIo = false;
-
- /* user-spec'd variables */
- unsigned startTest = 0;
- unsigned endTest = NUM_CIPHER_PARAMS;
- unsigned startGroup = 0;
- const char *dhParamFile = DH_PARAM_FILE_512;
-
- for(int arg=1; arg<argc; arg++) {
- argp = argv[arg];
- switch(argp[0]) {
- case 'q':
- serverDefaults.quiet = clientDefaults.quiet = true;
- break;
- case 'v':
- serverDefaults.verbose = clientDefaults.verbose = true;
- break;
- case 'p':
- portNum = atoi(&argp[2]);
- break;
- case 't':
- startTest = atoi(&argp[2]);
- break;
- case 'T':
- endTest = atoi(&argp[2]) + 1;
- break;
- case 'g':
- startGroup = atoi(&argp[2]);
- break;
- case 'b':
- serverDefaults.nonBlocking = clientDefaults.nonBlocking =
- true;
- break;
- case 'l':
- dhParamFile = DH_PARAM_FILE_1024;
- break;
- case 'r':
- portNum = genRand(MIN_RAND_PORT, MAX_RAND_PORT);
- break;
- case 's':
- certRSA.rootName = &argp[2];
- break;
- case 'd':
- certDSA.rootName = &argp[2];
- break;
- case 'R':
- ringBufferIo = true;
- break;
- default:
- usage(argv);
- }
- }
-
- if(sslCheckFile(certRSA.rootName)) {
- exit(1);
- }
- if(sslCheckFile(certDSA.rootName)) {
- exit(1);
- }
- if(ringBufferIo) {
- /* set up ring buffers */
- ringBufSetup(&serverToClientRing, "serveToClient", DEFAULT_NUM_RB_BUFS, DEFAULT_BUF_RB_SIZE);
- ringBufSetup(&clientToServerRing, "clientToServe", DEFAULT_NUM_RB_BUFS, DEFAULT_BUF_RB_SIZE);
- serverDefaults.serverToClientRing = &serverToClientRing;
- serverDefaults.clientToServerRing = &clientToServerRing;
- clientDefaults.serverToClientRing = &serverToClientRing;
- clientDefaults.clientToServerRing = &clientToServerRing;
- }
-
-#if IGNORE_SIGPIPE
- signal(SIGPIPE, sigpipe);
- #endif
-
- /* convert keychain names to paths for root */
- sslKeychainPath(RSA_SERVER_KC, rsaKcPath);
- sslKeychainPath(DSA_SERVER_KC, dsaKcPath);
-
- /* Diffie-Hellman params, we're going to need them */
- int r = readFile(dhParamFile, (unsigned char **)&serverDefaults.dhParams,
- &serverDefaults.dhParamsLen);
- if(r) {
- printf("***Error reading diffie-hellman params from %s; aborting\n",
- dhParamFile);
- exit(1);
- }
-
- testStartBanner("sslCipher", argc, argv);
-
- serverParams.port = portNum - 1; // gets incremented by SSL_THR_SETUP
-
- /*
- * To enable negotiation failures to occur, we have to pass
- * in ciphersuite arrays which contain at least one valid
- * ciphersuite to both client and server, but they can not
- * be the same (or else that valid suite will be used).
- */
- clientCiphers[1] = SSL_RSA_WITH_RC4_128_MD5;
- serverCiphers[1] = SSL_RSA_WITH_RC4_128_SHA;
- clientCiphers[2] = SSL_NO_SUCH_CIPHERSUITE;
- serverCiphers[2] = SSL_NO_SUCH_CIPHERSUITE;
-
- for(groupNum=startGroup; groupNum<NUM_GROUP_PARAMS; groupNum++) {
- groupParams = &sslGroupParams[groupNum];
- if(!serverDefaults.quiet) {
- printf("...%s\n", groupParams->groupDesc);
- }
- for(testNum=startTest; testNum<endTest; testNum++) {
- cipherParams = &sslCipherParams[testNum];
- SSL_THR_SETUP(serverParams, clientParams, clientDefaults,
- serverDefault);
- if(ringBufferIo) {
- ringBufferReset(&serverToClientRing);
- ringBufferReset(&clientToServerRing);
- }
- /* per-group (must be after SSL_THR_SETUP) */
- serverParams.acceptedProts = groupParams->serveAcceptProts;
- clientParams.acceptedProts = groupParams->clientAcceptProts;
- serverParams.expectVersion = groupParams->expectProt;
- clientParams.expectVersion = groupParams->expectProt;
-
- /* per-test */
- clientCiphers[0] = cipherParams->expectCipher;
- serverCiphers[0] = cipherParams->expectCipher;
- clientParams.ciphers = clientCiphers;
- serverParams.ciphers = serverCiphers;
- serverParams.expectCipher = cipherParams->expectCipher;
- clientParams.expectCipher = cipherParams->expectCipher;
-
- const CertParams *certParams = cipherParams->certParams;
- serverParams.myCertKcName = certParams->kcName;
- serverParams.password = certParams->kcPassword;
- clientParams.anchorFile = certParams->rootName;
-
- if(cipherParams->shouldWork) {
- serverParams.expectRtn = noErr;
- clientParams.expectRtn = noErr;
- }
- else {
- serverParams.expectRtn = SERVER_NEGOTIATE_FAIL;
- clientParams.expectRtn = CLIENT_NEGOTIATE_FAIL;
-
- /* server completed protocol version negotiation,
- * but client didn't */
- clientParams.expectVersion = kSSLProtocolUnknown;
- }
- SSL_THR_RUN_NUM(serverParams, clientParams,
- cipherParams->testDesc, ourRtn, testNum);
- }
- }
-
-done:
- if(!clientParams.quiet) {
- if(ourRtn == 0) {
- printf("===== %s test PASSED =====\n", argv[0]);
- }
- else {
- printf("****%s FAIL: %d errors detected\n", argv[0],ourRtn);
- }
- }
-
- return ourRtn;
-}