1/*
2 * sslThreading.h - support for two-threaded SSL client/server tests.
3 */
4
5#ifndef _SSL_THREADING_H_
6#define _SSL_THREADING_H_ 1
7
8#include <Security/SecureTransport.h>
9#include <Security/Security.h>
10#include <clAppUtils/ringBufferIo.h>
11
12#ifdef	__cplusplus
13extern "C" {
14#endif
15
16/* "Don't bother verifying" values */
17#define SSL_PROTOCOL_IGNORE		((SSLProtocol)0x123456)
18#define SSL_CLIENT_CERT_IGNORE	((SSLClientCertificateState)0x234567)
19#define SSL_CIPHER_IGNORE		((SSLCipherSuite)0x345678)
20
21/*
22 * Test params passed to both sslClient() and sslServer()
23 */
24typedef struct {
25
26	/* client side only */
27	const char					*hostName;
28	bool						skipHostNameCheck;
29
30	/* common */
31	unsigned short				port;
32	RingBuffer					*serverToClientRing;
33	RingBuffer					*clientToServerRing;
34
35	bool						noProtSpec;			// if true, don't set protocol in either
36													//    fashion
37	SSLProtocol					tryVersion;			// only used if acceptedProts
38													//   NULL
39	const char					*acceptedProts;
40	const char					*myCertKcName;		// required for server,
41													//   optional for client
42	const char					*password;			// optional, to unlock keychain
43	bool						idIsTrustedRoot;	// cert in KC is trusted root
44	bool						disableCertVerify;
45	const char					*anchorFile;		// to add/replace anchors
46	bool						replaceAnchors;
47	SSLAuthenticate				authenticate;
48	bool						resumeEnable;
49	const SSLCipherSuite 		*ciphers;			// optional array of allowed ciphers,
50													// terminated with SSL_NO_SUCH_CIPHERSUITE
51	bool						nonBlocking;
52	const unsigned char			*dhParams;			// optional Diffie-Hellman params
53	unsigned					dhParamsLen;
54
55	/* expected results */
56	OSStatus					expectRtn;
57	SSLProtocol					expectVersion;
58	SSLClientCertificateState	expectCertState;
59	SSLCipherSuite				expectCipher;
60
61	/* UI parameters */
62	bool						quiet;
63	bool						silent;
64	bool						verbose;
65
66	/*
67	 * Server semaphore:
68	 *
69	 * -- main thread inits and sets serverReady false
70	 * -- main thread starts up server thread
71	 * -- server thread inits and sets up a socket for listening
72	 * -- server thread sets serverReady true and does pthread_cond_broadcast
73	 */
74	pthread_mutex_t				pthreadMutex;
75	pthread_cond_t				pthreadCond;
76	bool						serverReady;
77
78	/*
79	 * To ensure error abort is what we expect instead of just
80	 * "peer closed their socket", server avoids closing down the
81	 * socket until client sets this flag. It's just polled, no
82	 * locking. Setting the serverAbort flag skips this
83	 * step to facilitate testing cases where server explicitly
84	 * drops connection (e.g. in response to an unacceptable
85	 * ClientHello).
86	 */
87	unsigned					clientDone;
88	bool						serverAbort;
89
90	/*
91	 * Returned and also verified by sslRunSession().
92	 * Conditions in which expected value NOT verified are listed
93	 * in following comments.
94	 *
95	 * NegCipher is only verified if (ortn == noErr).
96	 */
97	SSLProtocol					negVersion;		// SSL_PROTOCOL_IGNORE
98	SSLCipherSuite				negCipher;		// SSL_CIPHER_IGNORE
99	SSLClientCertificateState 	certState;		// SSL_CLIENT_CERT_IGNORE
100	OSStatus					ortn;			// always checked
101
102} SslAppTestParams;
103
104/* client and server in sslClient.cpp and sslServe.cpp */
105OSStatus sslAppClient(
106	SslAppTestParams		*params);
107OSStatus sslAppServe(
108	SslAppTestParams		*params);
109
110/*
111 * Run one session, with the server in a separate thread.
112 * On entry, serverParams->port is the port we attempt to run on;
113 * the server thread may overwrite that with a different port if it's
114 * unable to open the port we specify. Whatever is left in
115 * serverParams->port is what's used for the client side.
116 */
117int sslRunSession(
118	SslAppTestParams	*serverParams,
119	SslAppTestParams 	*clientParams,
120	const char 			*testDesc);
121
122void sslShowResult(
123	const char			*whichSide,		// "client" or "server"
124	SslAppTestParams	*params);
125
126
127/*
128 * Macros which do the repetetive setup/run work
129 */
130#define SSL_THR_SETUP(serverParams, clientParams, clientDefaults, serverDefault) \
131{										\
132	unsigned short serverPort;			\
133	serverPort = serverParams.port + 1;	\
134	clientParams = clientDefaults; 		\
135	serverParams = serverDefaults;		\
136	serverParams.port = serverPort;		\
137}
138
139#define SSL_THR_RUN(serverParams, clientParams, desc, ourRtn)	\
140{																\
141	thisRtn = sslRunSession(&serverParams, &clientParams, desc);	\
142	ourRtn += thisRtn;												\
143	if(thisRtn) {													\
144		if(testError(clientParams.quiet)) {						\
145			goto done;											\
146		}														\
147	}															\
148}
149
150#define SSL_THR_RUN_NUM(serverParams, clientParams, desc, ourRtn, testNum)	\
151{																\
152	thisRtn = sslRunSession(&serverParams, &clientParams, desc);\
153	ourRtn += thisRtn;											\
154	if(thisRtn) {												\
155		printf("***Error on test %u\n", testNum);				\
156		if(testError(clientParams.quiet)) {						\
157			goto done;											\
158		}														\
159	}															\
160}
161
162#define THREADING_DEBUG		0
163#if		THREADING_DEBUG
164
165#define sslThrDebug(side, end)	\
166	printf("^^^%s thread %p %s\n", side, pthread_self(), end)
167#else	/* THREADING_DEBUG */
168#define sslThrDebug(side, end)
169#endif	/* THREADING_DEBUG */
170#ifdef	__cplusplus
171}
172#endif
173
174#endif	/* _SSL_THREADING_H_ */
175