sslThreading.h   [plain text]


/*
 * Copyright (c) 2006-2007,2013 Apple Inc. All Rights Reserved.
 *
 * sslThreading.h - support for two-threaded SSL client/server tests.
 */
 
#ifndef _SSL_THREADING_H_
#define _SSL_THREADING_H_ 1

#include <Security/SecureTransport.h>
#include <Security/Security.h>

#ifdef	__cplusplus
extern "C" {
#endif

/* "Don't bother verifying" values */
#define SSL_PROTOCOL_IGNORE		((SSLProtocol)0x123456)
#define SSL_CLIENT_CERT_IGNORE	((SSLClientCertificateState)0x234567)
#define SSL_CIPHER_IGNORE		((SSLCipherSuite)0x345678)

/*
 * Test params passed to both sslClient() and sslServer()
 */
typedef struct {
	
	/* client side only */
	const char					*hostName;
	bool						skipHostNameCheck;	
	
	/* common */
	unsigned short				port;
	SSLProtocol					tryVersion;			// only used if acceptedProts
													//   NULL
	const char					*acceptedProts;
	const char					*myCertKcName;		// required for server, 
													//   optional for client
	const char					*password;			// optional, to unlock keychain
	bool						idIsTrustedRoot;	// cert in KC is trusted root
	bool						disableCertVerify;
	const char					*anchorFile;		// to add/replace anchors
	bool						replaceAnchors;
	SSLAuthenticate				authenticate;
	bool						resumeEnable;
	const SSLCipherSuite 		*ciphers;			// optional array of allowed ciphers, 
													// terminated with SSL_NO_SUCH_CIPHERSUITE
	bool						nonBlocking;
	const unsigned char			*dhParams;			// optional Diffie-Hellman params
	unsigned					dhParamsLen;

	/* expected results */
	OSStatus					expectRtn;
	SSLProtocol					expectVersion;
	SSLClientCertificateState	expectCertState;
	SSLCipherSuite				expectCipher;
	
	/* UI parameters */
	bool						quiet;
	bool						silent;
	bool						verbose;
	
	/* 
	 * Server semaphore: 
	 *
	 * -- main thread inits and sets serverRady false
	 * -- main thread starts up server thread
	 * -- server thread inits and sets of a socket for listening
	 * -- serrver thread sets serverReady true and does pthread_cond_broadcast
	 */
	pthread_mutex_t				pthreadMutex;
	pthread_cond_t				pthreadCond;
	bool						serverReady;
	/* 
	 * To ensure error abort is what we expect instead of just "
	 * peer closed their socket", server avoids closing down the
	 * socket until client sets this flag. It's just polled, no
	 * locking. Setting the serverAbort flag skips this 
	 * step to facilitate testing cases where server explicitly
	 * drops connection (e.g. in response to an unacceptable 
	 * ClientHello). 
	 */
	unsigned					clientDone;
	bool						serverAbort;
	
	/* 
	 * Returned and also verified by sslRunSession().
	 * Conditions in which expected value NOT verified are listed
	 * in following comments.
	 *
	 * NegCipher is only verified if (ortn == errSecSuccess). 
	 */
	SSLProtocol					negVersion;		// SSL_PROTOCOL_IGNORE
	SSLCipherSuite				negCipher;		// SSL_CIPHER_IGNORE
	SSLClientCertificateState 	certState;		// SSL_CLIENT_CERT_IGNORE
	OSStatus					ortn;			// always checked

} SslAppTestParams;

/* client and server in sslClient.cpp and sslServe.cpp */
OSStatus sslAppClient(
	SslAppTestParams		*params);
OSStatus sslAppServe(
	SslAppTestParams		*params);

/*
 * Run one session, with the server in a separate thread.
 * On entry, serverParams->port is the port we attempt to run on;
 * the server thread may overwrite that with a different port if it's 
 * unable to open the port we specify. Whatever is left in 
 * serverParams->port is what's used for the client side. 
 */
int sslRunSession(
	SslAppTestParams	*serverParams,
	SslAppTestParams 	*clientParams,
	const char 			*testDesc);

void sslShowResult(
	char				*whichSide,		// "client" or "server"
	SslAppTestParams	*params);


/*
 * Macros which do the repetetive setup/run work
 */
#define SSL_THR_SETUP(serverParams, clientParams, clientDefaults, serverDefault) \
{										\
	unsigned short serverPort;			\
	serverPort = serverParams.port + 1;	\
	clientParams = clientDefaults; 		\
	serverParams = serverDefaults;		\
	serverParams.port = serverPort;		\
}

#define SSL_THR_RUN(serverParams, clientParams, desc, ourRtn)	\
{																\
	thisRtn = sslRunSession(&serverParams, &clientParams, desc);	\
	ourRtn += thisRtn;												\
	if(thisRtn) {													\
		if(testError(clientParams.quiet)) {						\
			goto done;											\
		}														\
	}															\
}

#define SSL_THR_RUN_NUM(serverParams, clientParams, desc, ourRtn, testNum)	\
{																\
	thisRtn = sslRunSession(&serverParams, &clientParams, desc);\
	ourRtn += thisRtn;											\
	if(thisRtn) {												\
		printf("***Error on test %u\n", testNum);				\
		if(testError(clientParams.quiet)) {						\
			goto done;											\
		}														\
	}															\
}

#define THREADING_DEBUG		0
#if		THREADING_DEBUG

#define sslThrDebug(side, end)	\
	printf("^^^%s thread %p %s\n", side, pthread_self(), end)
#else	/* THREADING_DEBUG */
#define sslThrDebug(side, end)
#endif	/* THREADING_DEBUG */
#ifdef	__cplusplus
}
#endif

#endif	/* _SSL_THREADING_H_ */