X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/SecurityTests/clxutils/sslCipher/sslCipher.cpp diff --git a/SecurityTests/clxutils/sslCipher/sslCipher.cpp b/SecurityTests/clxutils/sslCipher/sslCipher.cpp new file mode 100644 index 00000000..08199f09 --- /dev/null +++ b/SecurityTests/clxutils/sslCipher/sslCipher.cpp @@ -0,0 +1,561 @@ +/* + * sslCipher.cpp - test SSL ciphersuite protocol negotiation, client + * and server side + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +/* 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 + +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; arggroupDesc); + } + for(testNum=startTest; testNumserveAcceptProts; + 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; +}