1/*
2 * sslProt.cpp - test SSL protocol negotiation, client and server side
3 *
4 * This executes a preposterously exhaustive set of client/server runs
5 * in which just about every permutation of server and client
6 * protocol enables (using both SSLSetProtocolVersionEnabled and
7 * SSLSetProtocolVersion) is examined. Resulting negotiated protocols
8 * and error returns are verified.
9 *
10 * There are three different basic negotiation scenarios:
11 *
12 * -- Normal case, server and client agree.
13 *
14 * -- Server detects negotiation error. This can happen in two ways:
15 *    -- server doesn't allow SSL3 or TLS1 but gets an SSL3 client hello
16 *       (regardless of the requested protocol version in the packet)
17 *    -- server gets a client hello containing a protocol version
18 *       when the server supports neither that version not any
19 *       version below that. For example, server allows TLS1 only and
20 *       gets an SSL3 hello with requested version SSL3.
21 *
22 * -- Client detects negotiation error. In this case the server hello
23 *    contains a different version than the client hello (I.e., server
24 *    downgraded), but the client doesn't support the version the
25 *    server requested.
26 *
27 * In both of the failure cases, the peer which detects the error
28 * drops the connection and returns errSSLNegotiation from its
29 * SSLHandshake() call. The other peer sees a dropped connection
30 * and returns errSSLClosedAbort from its SSLHandshake() call.
31 * IN both cases, the negotiated protocol seen by the client is
32 * kSSLProtocolUnknown. However when the client detects the error, the
33 * server will see a valid negotiated protocol containing whatever it
34 * sent to the client in its server hello message.
35 */
36#include <Security/SecureTransport.h>
37#include <Security/Security.h>
38#include <clAppUtils/sslAppUtils.h>
39#include <clAppUtils/ioSock.h>
40#include <clAppUtils/sslThreading.h>
41#include <security_cdsa_utils/cuFileIo.h>
42#include <utilLib/common.h>
43#include <security_cdsa_utils/cuPrintCert.h>
44#include <security_utilities/threading.h>
45#include <security_utilities/devrandom.h>
46#include "dhParams512.h"
47
48#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <unistd.h>
52#include <string.h>
53#include <time.h>
54#include <ctype.h>
55#include <sys/param.h>
56
57#define STARTING_PORT			3000
58
59/*
60 * localcert is a KC containing server cert and signing key
61 * assumptions:
62 *	-- common name = "localcert"
63 *  -- password of KC = "localcert"
64 */
65#define SERVER_KC		"localcert"
66#define SERVER_ROOT		"localcert.cer"
67
68/* main() fills this in using sslKeychainPath() */
69static char serverKcPath[MAXPATHLEN];
70
71static void usage(char **argv)
72{
73	printf("Usage: %s [options]\n", argv[0]);
74	printf("options:\n");
75	printf("   q(uiet)\n");
76	printf("   v(erbose)\n");
77	printf("   d (Diffie-Hellman, no keychain needed)\n");
78	printf("   p=startingPortNum\n");
79	printf("   t=startTestNum\n");
80	printf("   b (non blocking I/O)\n");
81	printf("   s=serverCertName; default %s\n", SERVER_ROOT);
82	printf("   R (ringBuffer I/O)\n");
83	exit(1);
84}
85
86/*
87 * Parameters defining one run
88 */
89typedef struct {
90	const char		*groupDesc;			// optional
91	const char		*testDesc;			// required
92	bool			noServeProt;		// don't set server protocol version
93	SSLProtocol		servTryVersion;
94	const char		*serveAcceptProts;	// use TryVersion if this is NULL
95	SSLProtocol		expectServerProt;	// expected negotiated result
96	OSStatus		serveStatus;		// expected OSStatus
97	bool			noClientProt;		// don't set client protocol version
98	SSLProtocol		clientTryVersion;
99	const char		*clientAcceptProts;
100	SSLProtocol		expectClientProt;
101	OSStatus		clientStatus;
102	bool			serverAbort;		// allows server to close connection early
103} SslProtParams;
104
105SslProtParams protTestParams[] =
106{
107/*
108 * FIXME this fails to compile to to radar 4104919. I really don't want to
109 * remove these pragmas unless/until I hear a positive confirmation that that
110 * Radar is not to be fixed.
111 */
112// #pragma mark Unrestricted server via SSLSetProtocolVersion
113	{
114		"unrestricted server via SSLSetProtocolVersion",
115		"client SSLSetProtocolVersion(TLS1)",
116		false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
117		false, kTLSProtocol1, NULL, kTLSProtocol1, noErr, false
118	},
119	{
120		NULL, "client SSLSetProtocolVersion(TLS1 only)",
121		false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
122		false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr, false
123	},
124	{
125		NULL, "client SSLSetProtocolVersion(SSL3)",
126		false, kTLSProtocol1, NULL, kSSLProtocol3, noErr,
127		false, kSSLProtocol3, NULL, kSSLProtocol3, noErr, false
128	},
129	{
130		NULL, "client SSLSetProtocolVersion(SSL3 only)",
131		false, kTLSProtocol1, NULL, kSSLProtocol3, noErr,
132		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
133	},
134	{
135		NULL, "client SSLSetProtocolVersion(SSL2)",
136		false, kTLSProtocol1, NULL, kSSLProtocol2, noErr,
137		false, kSSLProtocol2, NULL, kSSLProtocol2, noErr, false
138	},
139	{
140		NULL, "client SSLSetProtocolVersionEnabled(t)",
141		false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
142		false, kTLSProtocol1, "t", kTLSProtocol1, noErr, false
143	},
144	{
145		NULL, "client SSLSetProtocolVersionEnabled(3t)",
146		false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
147		false, kTLSProtocol1, "3t", kTLSProtocol1, noErr, false
148	},
149	/* make sure default client is the same as "3t" - Radar 4233139 -
150	 * SSLv3 no longer enabled by default */
151	{
152		NULL, "client default",
153		false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
154		true, kSSLProtocolUnknown, NULL, kTLSProtocol1, noErr, false
155	},
156	{
157		NULL, "client SSLSetProtocolVersionEnabled(23t)",
158		false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
159		false, kTLSProtocol1, "23t", kTLSProtocol1, noErr, false
160	},
161	{
162		NULL, "client SSLSetProtocolVersionEnabled(3)",
163		false, kTLSProtocol1, NULL, kSSLProtocol3, noErr,
164		false, kTLSProtocol1, "3", kSSLProtocol3, noErr, false
165	},
166	{
167		NULL, "client SSLSetProtocolVersionEnabled(23)",
168		false, kTLSProtocol1, NULL, kSSLProtocol3, noErr,
169		false, kTLSProtocol1, "23", kSSLProtocol3, noErr, false
170	},
171	{
172		NULL, "client SSLSetProtocolVersionEnabled(2)",
173		false, kTLSProtocol1, NULL, kSSLProtocol2, noErr,
174		false, kTLSProtocol1, "2", kSSLProtocol2, noErr, false
175	},
176	{
177		NULL, "client SSLSetProtocolVersionEnabled(2t)",
178		false, kTLSProtocol1, NULL, kTLSProtocol1, noErr,
179		false, kTLSProtocol1, "2t", kTLSProtocol1, noErr, false
180	},
181
182	// #pragma mark === Server SSLSetProtocolVersion(TLS1 only)
183	{
184		"server SSLSetProtocolVersion(TLS1 only)",
185		"client SSLSetProtocolVersion(TLS1)",
186		false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
187		false, kTLSProtocol1,     NULL, kTLSProtocol1, noErr, false
188	},
189	{
190		NULL, "client SSLSetProtocolVersion(TLS1 only)",
191		false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
192		false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr, false
193	},
194	{
195		NULL, "client SSLSetProtocolVersion(SSL3)",
196		false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
197		false, kSSLProtocol3,     NULL, kSSLProtocolUnknown, errSSLClosedAbort,
198		false
199	},
200	{
201		NULL, "client SSLSetProtocolVersion(SSL3 only)",
202		false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
203		false, kSSLProtocol3Only, NULL, kSSLProtocolUnknown, errSSLConnectionRefused,
204		true
205	},
206	{
207		NULL, "client SSLSetProtocolVersion(SSL2)",
208		false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
209		false, kSSLProtocol2,     NULL, kSSLProtocolUnknown, errSSLClosedAbort,
210		true
211	},
212	{
213		NULL, "client SSLSetProtocolVersionEnabled(t)",
214		false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
215		false, kTLSProtocol1,    "t",   kTLSProtocol1, noErr, false
216	},
217	{
218		NULL, "client SSLSetProtocolVersionEnabled(3t)",
219		false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
220		false, kTLSProtocol1,    "3t",  kTLSProtocol1, noErr, false
221	},
222	/* make sure default client is the same as "3t" */
223	{
224		NULL, "client default",
225		false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
226		true, kSSLProtocolUnknown,  NULL,  kTLSProtocol1, noErr, false
227	},
228	{
229		NULL, "client SSLSetProtocolVersionEnabled(23t)",
230		false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
231		false, kTLSProtocol1,    "23t", kTLSProtocol1, noErr, false
232	},
233	{
234		NULL, "client SSLSetProtocolVersionEnabled(3)",
235		false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
236		false, kTLSProtocol1,    "3",   kSSLProtocolUnknown, errSSLConnectionRefused,
237		true
238	},
239	{
240		NULL, "client SSLSetProtocolVersionEnabled(23)",
241		false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
242		false, kTLSProtocol1,    "23",  kSSLProtocolUnknown, errSSLClosedAbort,
243		true
244	},
245	{
246		NULL, "client SSLSetProtocolVersionEnabled(2)",
247		false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
248		false, kTLSProtocol1,    "2",   kSSLProtocolUnknown, errSSLClosedAbort,
249		true
250	},
251	{
252		NULL, "client SSLSetProtocolVersionEnabled(2t)",
253		false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr,
254		false, kTLSProtocol1,    "2t",  kTLSProtocol1, noErr, false
255	},
256
257	// #pragma mark === Server SSLSetProtocolVersion(SSL3)
258	{
259		"server SSLSetProtocolVersion(SSL3)",
260		"client SSLSetProtocolVersion(TLS1)",
261		false, kSSLProtocol3,     NULL, kSSLProtocol3, noErr,
262		false, kTLSProtocol1,     NULL, kSSLProtocol3, noErr, false
263	},
264	{
265		NULL, "client SSLSetProtocolVersion(TLS1 only)",
266		/* negotiation error detected by client, not server */
267		false, kSSLProtocol3,     NULL, kSSLProtocol3, errSSLClosedAbort,
268		false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
269		false
270	},
271	{
272		NULL, "client SSLSetProtocolVersion(SSL3)",
273		false, kSSLProtocol3,     NULL, kSSLProtocol3, noErr,
274		false, kSSLProtocol3,     NULL, kSSLProtocol3, noErr, false
275	},
276	{
277		NULL, "client SSLSetProtocolVersion(SSL3 only)",
278		false, kSSLProtocol3,     NULL, kSSLProtocol3, noErr,
279		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
280	},
281	{
282		NULL, "client SSLSetProtocolVersion(SSL2)",
283		false, kSSLProtocol3,     NULL, kSSLProtocol3, noErr,
284		false, kSSLProtocol3,     NULL, kSSLProtocol3, noErr, false
285	},
286	{
287		NULL, "client SSLSetProtocolVersionEnabled(t)",
288		false, kSSLProtocol3,    NULL, kSSLProtocol3, errSSLClosedAbort,
289		false, kTLSProtocol1,    "t",  kSSLProtocolUnknown, errSSLNegotiation,
290		false
291	},
292	{
293		NULL, "client SSLSetProtocolVersionEnabled(3t)",
294		false, kSSLProtocol3,    NULL, kSSLProtocol3, noErr,
295		false, kTLSProtocol1,    "3t", kSSLProtocol3, noErr, false
296	},
297	/* make sure default client is the same as "3t" */
298	{
299		NULL, "client default",
300		false, kSSLProtocol3,    NULL, kSSLProtocol3, noErr,
301		true, kSSLProtocolUnknown,  NULL, kSSLProtocol3, noErr, false
302	},
303	{
304		NULL, "client SSLSetProtocolVersionEnabled(23t)",
305		false, kSSLProtocol3,    NULL,  kSSLProtocol3, noErr,
306		false, kTLSProtocol1,    "23t", kSSLProtocol3, noErr, false
307	},
308	{
309		NULL, "client SSLSetProtocolVersionEnabled(3)",
310		false, kSSLProtocol3,    NULL,  kSSLProtocol3, noErr,
311		false, kTLSProtocol1,    "3",  kSSLProtocol3, noErr, false
312	},
313	{
314		NULL, "client SSLSetProtocolVersionEnabled(23)",
315		false, kSSLProtocol3,    NULL,  kSSLProtocol3, noErr,
316		false, kTLSProtocol1,    "23",  kSSLProtocol3, noErr, false
317	},
318	{
319		NULL, "client SSLSetProtocolVersionEnabled(2)",
320		false, kSSLProtocol3,    NULL,  kSSLProtocol2, noErr,
321		false, kTLSProtocol1,    "2",   kSSLProtocol2, noErr, false
322	},
323	{
324		NULL, "client SSLSetProtocolVersionEnabled(2t)",
325		false, kSSLProtocol3,    NULL,  kSSLProtocol2, noErr,
326		false, kTLSProtocol1,    "2",   kSSLProtocol2, noErr, false
327	},
328
329	// #pragma mark === Server SSLSetProtocolVersion(SSL3 only)
330	{
331		"server SSLSetProtocolVersion(SSL3 only)",
332		"client SSLSetProtocolVersion(TLS1)",
333		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
334		false, kTLSProtocol1,     NULL, kSSLProtocol3, noErr, false
335	},
336	{
337		NULL, "client SSLSetProtocolVersion(TLS1 only)",
338		/* negotiation error detected by client, not server */
339		false, kSSLProtocol3Only, NULL, kSSLProtocol3, errSSLClosedAbort,
340		false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
341		false
342	},
343	{
344		NULL, "client SSLSetProtocolVersion(SSL3)",
345		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
346		false, kSSLProtocol3,     NULL, kSSLProtocol3, noErr, false
347	},
348	{
349		NULL, "client SSLSetProtocolVersion(SSL3 only)",
350		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
351		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
352	},
353	{
354		NULL, "client SSLSetProtocolVersion(SSL2)",
355		false, kSSLProtocol3Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
356		false, kSSLProtocol2,     NULL, kSSLProtocolUnknown, errSSLClosedAbort,
357		true
358	},
359	{
360		NULL, "client SSLSetProtocolVersionEnabled(t)",
361		false, kSSLProtocol3Only, NULL, kSSLProtocol3, errSSLClosedAbort,
362		false, kTLSProtocol1,    "t",   kSSLProtocolUnknown, errSSLNegotiation,
363		false
364	},
365	{
366		NULL, "client SSLSetProtocolVersionEnabled(3t)",
367		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
368		false, kTLSProtocol1,    "3t",  kSSLProtocol3, noErr, false
369	},
370	/* make sure default client is the same as "3t" */
371	{
372		NULL, "client default",
373		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
374		true, kSSLProtocolUnknown,  NULL,  kSSLProtocol3, noErr, false
375	},
376	{
377		NULL, "client SSLSetProtocolVersionEnabled(23t)",
378		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
379		false, kTLSProtocol1,    "23t", kSSLProtocol3, noErr, false
380	},
381	{
382		NULL, "client SSLSetProtocolVersionEnabled(3)",
383		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
384		false, kTLSProtocol1,    "3",   kSSLProtocol3, noErr, false
385	},
386	{
387		NULL, "client SSLSetProtocolVersionEnabled(23)",
388		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr,
389		false, kTLSProtocol1,    "23",  kSSLProtocol3, noErr, false
390	},
391	{
392		NULL, "client SSLSetProtocolVersionEnabled(2)",
393		false, kSSLProtocol3Only, NULL, kSSLProtocolUnknown, errSSLNegotiation,
394		false, kTLSProtocol1,    "2",   kSSLProtocolUnknown, errSSLClosedAbort,
395		false
396	},
397	{
398		NULL, "client SSLSetProtocolVersionEnabled(2t)",
399		false, kSSLProtocol3Only, NULL, kSSLProtocol3, errSSLClosedAbort,
400		false, kTLSProtocol1,    "2t",  kSSLProtocolUnknown, errSSLNegotiation,
401		false
402	},
403
404	// #pragma mark === Server SSLSetProtocolVersion(SSL2)
405	{
406		"server SSLSetProtocolVersion(SSL2)",
407		"client SSLSetProtocolVersion(TLS1)",
408		false, kSSLProtocol2,     NULL, kSSLProtocol2, noErr,
409		false, kTLSProtocol1,     NULL, kSSLProtocol2, noErr, false
410	},
411	{
412		NULL, "client SSLSetProtocolVersion(TLS1 only)",
413		/* server won't even accept the non-SSL2 hello */
414		false, kSSLProtocol2,     NULL, kSSLProtocolUnknown, errSSLNegotiation,
415		false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLConnectionRefused,
416		true
417	},
418	{
419		NULL, "client SSLSetProtocolVersion(SSL3)",
420		false, kSSLProtocol2,     NULL, kSSLProtocol2, noErr,
421		false, kSSLProtocol3,     NULL, kSSLProtocol2, noErr, false
422	},
423	{
424		NULL, "client SSLSetProtocolVersion(SSL3 only)",
425		false, kSSLProtocol2,     NULL, kSSLProtocolUnknown, errSSLNegotiation,
426		false, kSSLProtocol3Only, NULL, kSSLProtocolUnknown, errSSLConnectionRefused,
427		true
428	},
429	{
430		NULL, "client SSLSetProtocolVersion(SSL2)",
431		false, kSSLProtocol2,     NULL, kSSLProtocol2, noErr,
432		false, kSSLProtocol2,     NULL, kSSLProtocol2, noErr, false
433	},
434	{
435		NULL, "client SSLSetProtocolVersionEnabled(t)",
436		false, kSSLProtocol2,     NULL, kSSLProtocolUnknown, errSSLNegotiation,
437		false, kTLSProtocol1,    "t",   kSSLProtocolUnknown, errSSLConnectionRefused,
438		true
439	},
440	{
441		NULL, "client SSLSetProtocolVersionEnabled(3t)",
442		false, kSSLProtocol2,     NULL, kSSLProtocolUnknown, errSSLNegotiation,
443		false, kTLSProtocol1,    "3t",  kSSLProtocolUnknown, errSSLConnectionRefused,
444		true
445	},
446	/* make sure default client is the same as "3t" */
447	{
448		NULL, "client default",
449		false, kSSLProtocol2,     NULL, kSSLProtocolUnknown, errSSLNegotiation,
450		true, kSSLProtocolUnknown,  NULL,  kSSLProtocolUnknown, errSSLConnectionRefused,
451		true
452	},
453	{
454		NULL, "client SSLSetProtocolVersionEnabled(23t)",
455		false, kSSLProtocol2,     NULL, kSSLProtocol2, noErr,
456		false, kTLSProtocol1,    "23t", kSSLProtocol2, noErr, false
457	},
458	{
459		NULL, "client SSLSetProtocolVersionEnabled(3)",
460		false, kSSLProtocol2,     NULL, kSSLProtocolUnknown, errSSLNegotiation,
461		false, kTLSProtocol1,    "3",   kSSLProtocolUnknown, errSSLConnectionRefused,
462		true
463	},
464	{
465		NULL, "client SSLSetProtocolVersionEnabled(23)",
466		false, kSSLProtocol2,     NULL, kSSLProtocol2, noErr,
467		false, kTLSProtocol1,    "23",  kSSLProtocol2, noErr, false
468	},
469	{
470		NULL, "client SSLSetProtocolVersionEnabled(2)",
471		false, kSSLProtocol2,     NULL, kSSLProtocol2, noErr,
472		false, kTLSProtocol1,    "2",   kSSLProtocol2, noErr, false
473	},
474	{
475		NULL, "client SSLSetProtocolVersionEnabled(2t)",
476		false, kSSLProtocol2,     NULL, kSSLProtocol2, noErr,
477		false, kTLSProtocol1,    "2t",  kSSLProtocol2, noErr, false
478	},
479
480	//#pragma mark === Unrestricted server via SSLSetProtocolVersionEnabled
481	{
482		"unrestricted server via SSLSetProtocolVersionEnabled",
483		"client SSLSetProtocolVersion(TLS1)",
484		false, kTLSProtocol1, "23t", kTLSProtocol1, noErr,
485		false, kTLSProtocol1, NULL, kTLSProtocol1, noErr, false
486	},
487	{
488		NULL, "client SSLSetProtocolVersion(TLS1 only)",
489		false, kTLSProtocol1, "23t", kTLSProtocol1, noErr,
490		false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr, false
491	},
492	{
493		NULL, "client SSLSetProtocolVersion(SSL3)",
494		false, kTLSProtocol1, "23t", kSSLProtocol3, noErr,
495		false, kSSLProtocol3, NULL, kSSLProtocol3, noErr, false
496	},
497	{
498		NULL, "client SSLSetProtocolVersion(SSL3 only)",
499		false, kTLSProtocol1, "23t", kSSLProtocol3, noErr,
500		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
501	},
502	{
503		NULL, "client SSLSetProtocolVersion(SSL2)",
504		false, kTLSProtocol1, "23t", kSSLProtocol2, noErr,
505		false, kSSLProtocol2, NULL, kSSLProtocol2, noErr, false
506	},
507	{
508		NULL, "client SSLSetProtocolVersionEnabled(t)",
509		false, kTLSProtocol1, "23t", kTLSProtocol1, noErr,
510		false, kTLSProtocol1, "t", kTLSProtocol1, noErr, false
511	},
512	{
513		NULL, "client SSLSetProtocolVersionEnabled(3t)",
514		false, kTLSProtocol1, "23t", kTLSProtocol1, noErr,
515		false, kTLSProtocol1, "3t", kTLSProtocol1, noErr
516	},
517	{
518		NULL, "client SSLSetProtocolVersionEnabled(23t)",
519		false, kTLSProtocol1, "23t", kTLSProtocol1, noErr,
520		false, kTLSProtocol1, "23t", kTLSProtocol1, noErr, false
521	},
522	{
523		NULL, "client SSLSetProtocolVersionEnabled(3)",
524		false, kTLSProtocol1, "23t", kSSLProtocol3, noErr,
525		false, kTLSProtocol1, "3", kSSLProtocol3, noErr, false
526	},
527	{
528		NULL, "client SSLSetProtocolVersionEnabled(23)",
529		false, kTLSProtocol1, "23t", kSSLProtocol3, noErr,
530		false, kTLSProtocol1, "23", kSSLProtocol3, noErr, false
531	},
532	{
533		NULL, "client SSLSetProtocolVersionEnabled(2)",
534		false, kTLSProtocol1, "23t", kSSLProtocol2, noErr,
535		false, kTLSProtocol1, "2", kSSLProtocol2, noErr, false
536	},
537	{
538		NULL, "client SSLSetProtocolVersionEnabled(2t)",
539		false, kTLSProtocol1, "23t", kTLSProtocol1, noErr,
540		false, kTLSProtocol1, "2t", kTLSProtocol1, noErr, false
541	},
542
543	// #pragma mark === Server SSLSetProtocolVersionEnabled(t)
544
545	{
546		"server SSLSetProtocolVersionEnabled(t)",
547		"client SSLSetProtocolVersion(TLS1)",
548		false, kTLSProtocol1,      "t", kTLSProtocol1, noErr,
549		false, kTLSProtocol1,     NULL, kTLSProtocol1, noErr, false
550	},
551	{
552		NULL, "client SSLSetProtocolVersion(TLS1 only)",
553		false, kTLSProtocol1,      "t", kTLSProtocol1, noErr,
554		false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr, false
555	},
556	{
557		NULL, "client SSLSetProtocolVersion(SSL3)",
558		false, kTLSProtocol1,      "t", kSSLProtocolUnknown, errSSLNegotiation,
559		false, kSSLProtocol3,     NULL, kSSLProtocolUnknown, errSSLClosedAbort, true
560	},
561	{
562		NULL, "client SSLSetProtocolVersion(SSL3 only)",
563		false, kTLSProtocol1,      "t", kSSLProtocolUnknown, errSSLNegotiation,
564		false, kSSLProtocol3Only, NULL, kSSLProtocolUnknown, errSSLConnectionRefused, true
565	},
566	{
567		NULL, "client SSLSetProtocolVersion(SSL2)",
568		false, kTLSProtocol1,      "t", kSSLProtocolUnknown, errSSLNegotiation,
569		false, kSSLProtocol2,     NULL, kSSLProtocolUnknown, errSSLClosedAbort, true
570	},
571	{
572		NULL, "client SSLSetProtocolVersionEnabled(t)",
573		false, kTLSProtocol1,      "t", kTLSProtocol1, noErr,
574		false, kTLSProtocol1,    "t",   kTLSProtocol1, noErr, false
575	},
576	{
577		NULL, "client SSLSetProtocolVersionEnabled(3t)",
578		false, kTLSProtocol1,      "t", kTLSProtocol1, noErr,
579		false, kTLSProtocol1,    "3t",  kTLSProtocol1, noErr, false
580	},
581	{
582		NULL, "client SSLSetProtocolVersionEnabled(23t)",
583		false, kTLSProtocol1,      "t", kTLSProtocol1, noErr,
584		false, kTLSProtocol1,    "23t", kTLSProtocol1, noErr, false
585	},
586	{
587		NULL, "client SSLSetProtocolVersionEnabled(3)",
588		false, kTLSProtocol1,      "t", kSSLProtocolUnknown, errSSLNegotiation,
589		false, kTLSProtocol1,    "3",   kSSLProtocolUnknown, errSSLConnectionRefused,
590		true
591	},
592	{
593		NULL, "client SSLSetProtocolVersionEnabled(23)",
594		false, kTLSProtocol1,      "t", kSSLProtocolUnknown, errSSLNegotiation,
595		false, kTLSProtocol1,    "23",  kSSLProtocolUnknown, errSSLClosedAbort,
596		true
597	},
598	{
599		NULL, "client SSLSetProtocolVersionEnabled(2)",
600		false, kTLSProtocol1,      "t", kSSLProtocolUnknown, errSSLNegotiation,
601		false, kTLSProtocol1,    "2",   kSSLProtocolUnknown, errSSLClosedAbort,
602		true
603	},
604	{
605		NULL, "client SSLSetProtocolVersionEnabled(2t)",
606		false, kTLSProtocol1,      "t", kTLSProtocol1, noErr,
607		false, kTLSProtocol1,    "2t",  kTLSProtocol1, noErr, false
608	},
609
610	// #pragma mark === Server SSLSetProtocolVersionEnabled(23)
611	{
612		"server SSLSetProtocolVersionEnabled(23)",
613		"client SSLSetProtocolVersion(TLS1)",
614		false, kSSLProtocol2,     "23", kSSLProtocol3, noErr,
615		false, kTLSProtocol1,     NULL, kSSLProtocol3, noErr, false
616	},
617	{
618		NULL, "client SSLSetProtocolVersion(TLS1 only)",
619		/* negotiation error detected by client, not server */
620		false, kSSLProtocol2,     "23", kSSLProtocol3, errSSLClosedAbort,
621		false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation, false
622	},
623	{
624		NULL, "client SSLSetProtocolVersion(SSL3)",
625		false, kSSLProtocol2,     "23", kSSLProtocol3, noErr,
626		false, kSSLProtocol3,     NULL, kSSLProtocol3, noErr, false
627	},
628	{
629		NULL, "client SSLSetProtocolVersion(SSL3 only)",
630		false, kSSLProtocol2,     "23", kSSLProtocol3, noErr,
631		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
632	},
633	{
634		NULL, "client SSLSetProtocolVersion(SSL2)",
635		false, kSSLProtocol2,     "23", kSSLProtocol3, noErr,
636		false, kSSLProtocol3,     NULL, kSSLProtocol3, noErr, false
637	},
638	{
639		NULL, "client SSLSetProtocolVersionEnabled(t)",
640		false, kSSLProtocol2,    "23", kSSLProtocol3, errSSLClosedAbort,
641		false, kTLSProtocol1,    "t",  kSSLProtocolUnknown, errSSLNegotiation, false
642	},
643	{
644		NULL, "client SSLSetProtocolVersionEnabled(3t)",
645		false, kSSLProtocol2,    "23", kSSLProtocol3, noErr,
646		false, kTLSProtocol1,    "3t", kSSLProtocol3, noErr, false
647	},
648	{
649		NULL, "client SSLSetProtocolVersionEnabled(23t)",
650		false, kSSLProtocol2,    "23",  kSSLProtocol3, noErr,
651		false, kTLSProtocol1,    "23t", kSSLProtocol3, noErr, false
652	},
653	{
654		NULL, "client SSLSetProtocolVersionEnabled(3)",
655		false, kSSLProtocol2,    "23",  kSSLProtocol3, noErr,
656		false, kTLSProtocol1,    "3",  kSSLProtocol3, noErr, false
657	},
658	{
659		NULL, "client SSLSetProtocolVersionEnabled(23)",
660		false, kSSLProtocol2,    "23",  kSSLProtocol3, noErr,
661		false, kTLSProtocol1,    "23",  kSSLProtocol3, noErr, false
662	},
663	{
664		NULL, "client SSLSetProtocolVersionEnabled(2)",
665		false, kSSLProtocol2,    "23",  kSSLProtocol2, noErr,
666		false, kTLSProtocol1,    "2",   kSSLProtocol2, noErr, false
667	},
668	{
669		NULL, "client SSLSetProtocolVersionEnabled(2t)",
670		false, kSSLProtocol2,    "23",  kSSLProtocol2, noErr,
671		false, kTLSProtocol1,    "2",   kSSLProtocol2, noErr, false
672	},
673
674	// #pragma mark === Server SSLSetProtocolVersionEnabled(3)
675	{
676		"server SSLSetProtocolVersionEnabled(3)",
677		"client SSLSetProtocolVersion(TLS1)",
678		false, kSSLProtocol2,      "3", kSSLProtocol3, noErr,
679		false, kTLSProtocol1,     NULL, kSSLProtocol3, noErr, false
680	},
681	{
682		NULL, "client SSLSetProtocolVersion(TLS1 only)",
683		/* negotiation error detected by client, not server */
684		false, kSSLProtocol2,      "3", kSSLProtocol3, errSSLClosedAbort,
685		false, kTLSProtocol1Only, NULL, kSSLProtocolUnknown, errSSLNegotiation, false
686	},
687	{
688		NULL, "client SSLSetProtocolVersion(SSL3)",
689		false, kSSLProtocol2,      "3", kSSLProtocol3, noErr,
690		false, kSSLProtocol3,     NULL, kSSLProtocol3, noErr, false
691	},
692	{
693		NULL, "client SSLSetProtocolVersion(SSL3 only)",
694		false, kSSLProtocol2,      "3", kSSLProtocol3, noErr,
695		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
696	},
697	{
698		NULL, "client SSLSetProtocolVersion(SSL2)",
699		false, kSSLProtocol2,      "3", kSSLProtocolUnknown, errSSLNegotiation,
700		false, kSSLProtocol2,     NULL, kSSLProtocolUnknown, errSSLClosedAbort, true
701	},
702	{
703		NULL, "client SSLSetProtocolVersionEnabled(t)",
704		false, kSSLProtocol2,      "3", kSSLProtocol3, errSSLClosedAbort,
705		false, kTLSProtocol1,      "t", kSSLProtocolUnknown, errSSLNegotiation, false
706	},
707	{
708		NULL, "client SSLSetProtocolVersionEnabled(3t)",
709		false, kSSLProtocol2,      "3", kSSLProtocol3, noErr,
710		false, kTLSProtocol1,     "3t", kSSLProtocol3, noErr, false
711	},
712	{
713		NULL, "client SSLSetProtocolVersionEnabled(23t)",
714		false, kSSLProtocol2,      "3", kSSLProtocol3, noErr,
715		false, kTLSProtocol1,    "23t", kSSLProtocol3, noErr, false
716	},
717	{
718		NULL, "client SSLSetProtocolVersionEnabled(3)",
719		false, kSSLProtocol2,      "3", kSSLProtocol3, noErr,
720		false, kTLSProtocol1,      "3", kSSLProtocol3, noErr, false
721	},
722	{
723		NULL, "client SSLSetProtocolVersionEnabled(23)",
724		false, kSSLProtocol2,      "3", kSSLProtocol3, noErr,
725		false, kTLSProtocol1,     "23", kSSLProtocol3, noErr, false
726	},
727	{
728		NULL, "client SSLSetProtocolVersionEnabled(2)",
729		false, kSSLProtocol2,      "3", kSSLProtocolUnknown, errSSLNegotiation,
730		false, kTLSProtocol1,      "2", kSSLProtocolUnknown, errSSLClosedAbort, true
731	},
732	{
733		NULL, "client SSLSetProtocolVersionEnabled(2t)",
734		false, kSSLProtocol2,      "3", kSSLProtocol3, errSSLClosedAbort,
735		false, kTLSProtocol1,     "2t", kSSLProtocolUnknown, errSSLNegotiation, false
736	},
737
738	/*
739	 * This is the real difference between
740	 * SSLSetProtocolVersionEnabled and SSLSetProtocolVersion
741	 */
742	// #pragma mark === Server SSLSetProtocolVersionEnabled(3t)
743	{
744		"server SSLSetProtocolVersionEnabled(3t)",
745		"client SSLSetProtocolVersion(TLS1)",
746		false, kSSLProtocol2,     "t3", kTLSProtocol1, noErr,
747		false, kTLSProtocol1,     NULL, kTLSProtocol1, noErr, false
748	},
749	/* make sure default server is the same as "t3" */
750	{
751		NULL,
752		"client SSLSetProtocolVersion(TLS1), server default",
753		true,  kSSLProtocolUnknown,  NULL, kTLSProtocol1, noErr,
754		false, kTLSProtocol1,     NULL, kTLSProtocol1, noErr, false
755	},
756	{
757		NULL, "client SSLSetProtocolVersion(TLS1 only)",
758		false, kSSLProtocol2,     "t3", kTLSProtocol1, noErr,
759		false, kTLSProtocol1Only, NULL, kTLSProtocol1, noErr, false
760	},
761	{
762		NULL, "client SSLSetProtocolVersion(SSL3)",
763		false, kSSLProtocol2,     "t3", kSSLProtocol3, noErr,
764		false, kSSLProtocol3,     NULL, kSSLProtocol3, noErr, false
765	},
766	{
767		NULL, "client SSLSetProtocolVersion(SSL3 only)",
768		false, kSSLProtocol2,     "t3", kSSLProtocol3, noErr,
769		false, kSSLProtocol3Only, NULL, kSSLProtocol3, noErr, false
770	},
771	{
772		NULL, "client SSLSetProtocolVersion(SSL2)",
773		false, kSSLProtocol2,     "t3", kSSLProtocolUnknown, errSSLNegotiation,
774		false, kSSLProtocol2,     NULL, kSSLProtocolUnknown, errSSLClosedAbort, true
775	},
776	/* make sure default server is the same as "t3" */
777	{
778		NULL, "client SSLSetProtocolVersion(SSL2), server default",
779		true,  kSSLProtocolUnknown,  NULL, kSSLProtocolUnknown, errSSLNegotiation,
780		false, kSSLProtocol2,     NULL, kSSLProtocolUnknown, errSSLClosedAbort, true
781	},
782	{
783		NULL, "client SSLSetProtocolVersionEnabled(t)",
784		false, kSSLProtocol2,     "t3", kTLSProtocol1, noErr,
785		false, kTLSProtocol1,      "t", kTLSProtocol1, noErr, false
786	},
787	{
788		NULL, "client SSLSetProtocolVersionEnabled(3t)",
789		false, kSSLProtocol2,     "t3", kTLSProtocol1, noErr,
790		false, kTLSProtocol1,     "3t", kTLSProtocol1, noErr, false
791	},
792	{
793		NULL, "client SSLSetProtocolVersionEnabled(23t)",
794		false, kSSLProtocol2,     "t3", kTLSProtocol1, noErr,
795		false, kTLSProtocol1,    "23t", kTLSProtocol1, noErr, false
796	},
797	{
798		NULL, "client SSLSetProtocolVersionEnabled(3)",
799		false, kSSLProtocol2,     "t3", kSSLProtocol3, noErr,
800		false, kTLSProtocol1,      "3", kSSLProtocol3, noErr, false
801	},
802	{
803		NULL, "client SSLSetProtocolVersionEnabled(23)",
804		false, kSSLProtocol2,     "t3", kSSLProtocol3, noErr,
805		false, kTLSProtocol1,     "23", kSSLProtocol3, noErr, false
806	},
807	{
808		NULL, "client SSLSetProtocolVersionEnabled(2)",
809		false, kSSLProtocol2,     "t3", kSSLProtocolUnknown, errSSLNegotiation,
810		false, kTLSProtocol1,      "2", kSSLProtocolUnknown, errSSLClosedAbort, true
811	},
812	/* make sure default server is the same as "t3" */
813	{
814		NULL, "client SSLSetProtocolVersionEnabled(2)",
815		false, kSSLProtocol2,     "t3", kSSLProtocolUnknown, errSSLNegotiation,
816		false, kTLSProtocol1,      "2", kSSLProtocolUnknown, errSSLClosedAbort, true
817	},
818	{
819		"server default", "client SSLSetProtocolVersionEnabled(2t)",
820		true,  kSSLProtocolUnknown,  NULL, kTLSProtocol1, noErr,
821		false, kTLSProtocol1,  "2t", kTLSProtocol1, noErr, false
822	},
823};
824
825#define NUM_SSL_PROT_TESTS	(sizeof(protTestParams) / sizeof(protTestParams[0]))
826
827#define IGNORE_SIGPIPE	1
828#if 	IGNORE_SIGPIPE
829#include <signal.h>
830
831void sigpipe(int sig)
832{
833}
834#endif	/* IGNORE_SIGPIPE */
835
836#define CERT_VFY_DISABLE	false
837
838/*
839 * Default params for each test. Main() will make a copy of this and
840 * adjust its copy on a per-test basis.
841 */
842SslAppTestParams serverDefaults =
843{
844	"no name here",
845	false,				// skipHostNameCHeck
846	0,					// port - test must set this
847	NULL, NULL,			// RingBuffers
848	false,				// noProtSpec
849	kTLSProtocol1,
850	NULL,				// acceptedProts
851	serverKcPath,		// myCerts
852	SERVER_KC,			// password
853	true,				// idIsTrustedRoot
854	CERT_VFY_DISABLE,	// disableCertVerify
855	NULL,				// anchorFile
856	false,				// replaceAnchors
857	kNeverAuthenticate,
858	false,				// resumeEnable
859	NULL,				// ciphers,
860	false,				// nonBlocking
861	NULL,				// dhParams
862	0,					// dhParamsLen
863	noErr,				// expectRtn
864	kTLSProtocol1,		// expectVersion
865	kSSLClientCertNone,
866	SSL_CIPHER_IGNORE,
867	false,				// quiet
868	false,				// silent
869	false,				// verbose
870	{0},				// lock
871	{0},				// cond
872	false,				// serverReady
873	0,					// clientDone
874	false,				// serverAbort
875	/* returned */
876	kSSLProtocolUnknown,
877	SSL_NULL_WITH_NULL_NULL,
878	kSSLClientCertNone,
879	noHardwareErr
880
881};
882
883SslAppTestParams clientDefaults =
884{
885	"localhost",
886	false,				// skipHostNameCHeck
887	0,					// port - test must set this
888	NULL, NULL,			// RingBuffers
889	false,				// noProtSpec
890	kTLSProtocol1,
891	NULL,				// acceptedProts
892	NULL,				// myCertKcName
893	NULL,				// password
894	false,				// idIsTrustedRoot
895	CERT_VFY_DISABLE,	// disableCertVerify
896	SERVER_ROOT,		// anchorFile
897	false,				// replaceAnchors
898	kNeverAuthenticate,
899	false,				// resumeEnable
900	NULL,				// ciphers
901	false,				// nonBlocking
902	NULL,				// dhParams
903	0,					// dhParamsLen
904	noErr,				// expectRtn
905	kTLSProtocol1,		// expectVersion
906	kSSLClientCertNone,
907	SSL_CIPHER_IGNORE,
908	false,				// quiet
909	false,				// silent
910	false,				// verbose
911	{0},				// lock
912	{0},				// cond
913	false,				// serverReady
914	0,					// clientDone
915	false,				// serverAbort
916	/* returned */
917	kSSLProtocolUnknown,
918	SSL_NULL_WITH_NULL_NULL,
919	kSSLClientCertNone,
920	noHardwareErr
921};
922
923
924int main(int argc, char **argv)
925{
926	int 				ourRtn = 0;
927	char	 			*argp;
928	SslAppTestParams 	clientParams;
929	SslAppTestParams 	serverParams;
930	unsigned short		portNum = STARTING_PORT;
931	SslProtParams		*protParams;
932	unsigned			testNum;
933	int					thisRtn;
934	unsigned			startTest = 0;
935	SSLCipherSuite		ciphers[2];		// for Diffie-Hellman
936	bool				diffieHellman = false;
937	RingBuffer			serverToClientRing;
938	RingBuffer			clientToServerRing;
939	bool				ringBufferIo = false;
940
941	for(int arg=1; arg<argc; arg++) {
942		argp = argv[arg];
943		switch(argp[0]) {
944			case 'q':
945				serverDefaults.quiet = clientDefaults.quiet = true;
946				break;
947			case 'v':
948				serverDefaults.verbose = clientDefaults.verbose = true;
949				break;
950			case 'p':
951				portNum = atoi(&argp[2]);
952				break;
953			case 't':
954				startTest = atoi(&argp[2]);
955				break;
956			case 'd':
957				diffieHellman = true;
958				break;
959			case 'b':
960				serverDefaults.nonBlocking = clientDefaults.nonBlocking =
961						true;
962				break;
963			case 's':
964				clientDefaults.anchorFile = &argp[2];
965				break;
966			case 'R':
967				ringBufferIo = true;
968				break;
969			default:
970				usage(argv);
971		}
972	}
973
974	if(sslCheckFile(clientDefaults.anchorFile)) {
975		exit(1);
976	}
977	if(ringBufferIo) {
978		/* set up ring buffers */
979		ringBufSetup(&serverToClientRing, "serveToClient", DEFAULT_NUM_RB_BUFS, DEFAULT_BUF_RB_SIZE);
980		ringBufSetup(&clientToServerRing, "clientToServe", DEFAULT_NUM_RB_BUFS, DEFAULT_BUF_RB_SIZE);
981		serverDefaults.serverToClientRing = &serverToClientRing;
982		serverDefaults.clientToServerRing = &clientToServerRing;
983		clientDefaults.serverToClientRing = &serverToClientRing;
984		clientDefaults.clientToServerRing = &clientToServerRing;
985	}
986
987	#if IGNORE_SIGPIPE
988	signal(SIGPIPE, sigpipe);
989	#endif
990
991	/* convert keychain names to paths for root */
992	sslKeychainPath(SERVER_KC, serverKcPath);
993
994	testStartBanner("sslProt", argc, argv);
995
996	serverParams.port = portNum - 1;	// gets incremented by SSL_THR_SETUP
997	if(diffieHellman) {
998		ciphers[0] = SSL_DH_anon_WITH_RC4_128_MD5;
999		ciphers[1] = SSL_NO_SUCH_CIPHERSUITE;
1000		serverDefaults.ciphers = ciphers;
1001		serverDefaults.dhParams = dhParams512;
1002		serverDefaults.dhParamsLen = sizeof(dhParams512);
1003		serverDefaults.myCertKcName = NULL;
1004		clientDefaults.anchorFile = NULL;
1005	}
1006	for(testNum=startTest; testNum<NUM_SSL_PROT_TESTS; testNum++) {
1007		protParams = &protTestParams[testNum];
1008
1009		/*
1010		 * Hack for Diffie-Hellman: just skip any tests which attempt
1011		 * or expect SSL2 negotiation, since SSL2 doesn't have DH.
1012		 */
1013		if(diffieHellman) {
1014			if((protParams->servTryVersion == kSSLProtocol2) ||
1015			   (protParams->clientTryVersion == kSSLProtocol2) ||
1016			   (protParams->serveAcceptProts &&
1017			     !strcmp(protParams->serveAcceptProts, "2")) ||
1018			   (protParams->clientAcceptProts &&
1019			     !strcmp(protParams->clientAcceptProts, "2"))) {
1020				if(serverDefaults.verbose) {
1021					printf("...skipping %s for D-H\n",
1022						protParams->testDesc);
1023				}
1024				continue;
1025			}
1026		}
1027		if(protParams->groupDesc && !serverDefaults.quiet) {
1028			printf("...%s\n", protParams->groupDesc);
1029		}
1030		SSL_THR_SETUP(serverParams, clientParams, clientDefaults,
1031				serverDefault);
1032		if(ringBufferIo) {
1033			ringBufferReset(&serverToClientRing);
1034			ringBufferReset(&clientToServerRing);
1035		}
1036		serverParams.tryVersion = protParams->servTryVersion;
1037		clientParams.tryVersion = protParams->clientTryVersion;
1038		serverParams.acceptedProts = protParams->serveAcceptProts;
1039		clientParams.acceptedProts = protParams->clientAcceptProts;
1040		serverParams.expectVersion = protParams->expectServerProt;
1041		clientParams.expectVersion = protParams->expectClientProt;
1042		serverParams.expectRtn = protParams->serveStatus;
1043		clientParams.expectRtn = protParams->clientStatus;
1044		serverParams.serverAbort = protParams->serverAbort;
1045
1046		SSL_THR_RUN_NUM(serverParams, clientParams, protParams->testDesc,
1047			ourRtn, testNum);
1048	}
1049
1050done:
1051	if(!clientParams.quiet) {
1052		if(ourRtn == 0) {
1053			printf("===== sslProt test PASSED =====\n");
1054		}
1055		else {
1056			printf("****FAIL: %d errors detected\n", ourRtn);
1057		}
1058	}
1059
1060	return ourRtn;
1061}
1062