X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/SecurityTests/clxutils/sslAuth/sslAuth.cpp diff --git a/SecurityTests/clxutils/sslAuth/sslAuth.cpp b/SecurityTests/clxutils/sslAuth/sslAuth.cpp new file mode 100644 index 00000000..c30120aa --- /dev/null +++ b/SecurityTests/clxutils/sslAuth/sslAuth.cpp @@ -0,0 +1,384 @@ +/* + * sslAuth.cpp - test client-side authentication, client and server side + * + * This mainly tests proper reporting of SSLGetClientCertificateState. + * Detailed error reporting for the myriad things that can go + * wrong during client authentication is tested in sslAlert. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define STARTING_PORT 4000 + +/* + * localcert is a KC containing server cert and signing key. + * Password is same as filename of the keychain. + */ +#define SERVER_KC "localcert" +#define SERVER_ROOT "localcert.cer" + +/* + * clientcert is a KC containing client cert and signing key. + * Password is same as filename of the keychain. + * + * Note common name not checked by SecureTransport when + * verifying client cert chain. + */ +#define CLIENT_KC "clientcert" +#define CLIENT_ROOT "clientcert.cer" + +/* main() fills these in using sslKeychainPath() */ +static char serverKcPath[MAXPATHLEN]; +static char clientKcPath[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(" b (non blocking I/O)\n"); + printf(" s=serverCertName; default %s\n", SERVER_ROOT); + printf(" c=clientCertName; default %s\n", CLIENT_ROOT); + printf(" R (ringBuffer I/O)\n"); + printf(" k (keep keychain list open)\n"); + printf(" l=loops (default=1; 0=forever)\n"); + printf(" o (One test only)\n"); + exit(1); +} + +/* + * Parameters defining one run + */ +typedef struct { + const char *testDesc; + SSLProtocol serverTryProt; + SSLProtocol serverActProt; // expected negotiated result + SSLAuthenticate tryAuth; + SSLClientCertificateState serverAuthState; + OSStatus serverStatus; // expected OSStatus + SSLProtocol clientTryProt; + const char *clientKcName; // determines whether or not + // to do authentication + SSLClientCertificateState clientAuthState; + OSStatus clientStatus; +} SslAuthParams; + +SslAuthParams authTestParams[] = +{ + { + "Server doesn't authenticate, client tries, TLS1", + kTLSProtocol1, kTLSProtocol1, + kNeverAuthenticate, kSSLClientCertNone, noErr, + kTLSProtocol1, NULL, kSSLClientCertNone, noErr + }, + { + "Server doesn't authenticate, client tries, SSL3", + kTLSProtocol1, kSSLProtocol3, + kNeverAuthenticate, kSSLClientCertNone, noErr, + kSSLProtocol3, NULL, kSSLClientCertNone, noErr + }, + { + "Server tries authentication, client refuses, TLS1", + kTLSProtocol1, kTLSProtocol1, + kTryAuthenticate, kSSLClientCertRequested, noErr, + kTLSProtocol1, NULL, kSSLClientCertRequested, noErr + }, + { + "Server tries authentication, client refuses, SSL3", + kTLSProtocol1, kSSLProtocol3, + kTryAuthenticate, kSSLClientCertRequested, noErr, + kSSLProtocol3, NULL, kSSLClientCertRequested, noErr + }, + { + "Server tries authentication, client sends cert, TLS1", + kTLSProtocol1, kTLSProtocol1, + kTryAuthenticate, kSSLClientCertSent, noErr, + kTLSProtocol1, clientKcPath, kSSLClientCertSent, noErr + }, + { + "Server tries authentication, client sends cert, SSL3", + kSSLProtocol3, kSSLProtocol3, + kTryAuthenticate, kSSLClientCertSent, noErr, + kTLSProtocol1, clientKcPath, kSSLClientCertSent, noErr + }, + { + "Server requires authentication, client refuses, TLS1", + kTLSProtocol1, kTLSProtocol1, + kAlwaysAuthenticate, kSSLClientCertRequested, + errSSLXCertChainInvalid, + kTLSProtocol1, NULL, kSSLClientCertRequested, + errSSLPeerCertUnknown + }, + { + "Server requires authentication, client refuses, SSL3", + kSSLProtocol3, kSSLProtocol3, + kAlwaysAuthenticate, kSSLClientCertRequested, errSSLProtocol, + kTLSProtocol1, NULL, kSSLClientCertRequested, errSSLPeerUnexpectedMsg + }, + +}; + +#define NUM_SSL_AUTH_TESTS (sizeof(authTestParams) / sizeof(authTestParams[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. + */ +SslAppTestParams serverDefaults = +{ + "no name here", + false, // skipHostNameCHeck + 0, // port - test must set this + NULL, NULL, // RingBuffers + false, // noProtSpec + kTLSProtocol1, // set in test loop + NULL, // acceptedProts - not used in this test + serverKcPath, // myCerts - const + SERVER_KC, // password + true, // idIsTrustedRoot + false, // disableCertVerify + CLIENT_ROOT, // anchorFile - only meaningful if client + // authenticates + false, // replaceAnchors + kNeverAuthenticate, // set in test loop + false, // resumeEnable + NULL, // ciphers, + false, // nonBlocking + NULL, // dhParams + 0, // dhParamsLen + noErr, // expectRtn + kTLSProtocol1, // expectVersion + kSSLClientCertNone, + SSL_CIPHER_IGNORE, + 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 + kTLSProtocol1, + NULL, // acceptedProts + NULL, // myCertKcName - varies, set in main test loop + CLIENT_KC, // password + true, // idIsTrustedRoot + false, // disableCertVerify + SERVER_ROOT, // anchorFile + false, // replaceAnchors + kNeverAuthenticate, + false, // resumeEnable + NULL, // ciphers + false, // nonBlocking + NULL, // dhParams + 0, // dhParamsLen + noErr, // expectRtn + kTLSProtocol1, // expectVersion + kSSLClientCertNone, + SSL_CIPHER_IGNORE, + 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; + SslAuthParams *authParams; + unsigned testNum; + int thisRtn; + unsigned startTest = 0; + unsigned loopNum = 0; + unsigned loops = 1; + RingBuffer serverToClientRing; + RingBuffer clientToServerRing; + bool ringBufferIo = false; + bool keepKCListOpen = false; + CFArrayRef kcList = NULL; + bool oneTestOnly = false; + + for(int arg=1; argserverTryProt; + serverParams.expectVersion = authParams->serverActProt; + serverParams.authenticate = authParams->tryAuth; + serverParams.expectCertState = authParams->serverAuthState; + serverParams.expectRtn = authParams->serverStatus; + + clientParams.tryVersion = authParams->clientTryProt; + clientParams.expectVersion = authParams->serverActProt; + clientParams.expectRtn = authParams->clientStatus; + clientParams.myCertKcName = authParams->clientKcName; + clientParams.expectCertState = authParams->clientAuthState; + + SSL_THR_RUN_NUM(serverParams, clientParams, authParams->testDesc, + ourRtn, testNum); + if(oneTestOnly) { + break; + } + } + if(loops) { + if(++loopNum == loops) { + break; + } + printf("...loop %u\n", loopNum); + } + } +done: + if(!clientParams.quiet) { + if(ourRtn == 0) { + printf("===== %s test PASSED =====\n", argv[0]); + } + else { + printf("****FAIL: %d errors detected\n", ourRtn); + } + } + + return ourRtn; +}