]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/sslAuth/sslAuth.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / sslAuth / sslAuth.cpp
1 /*
2 * sslAuth.cpp - test client-side authentication, client and server side
3 *
4 * This mainly tests proper reporting of SSLGetClientCertificateState.
5 * Detailed error reporting for the myriad things that can go
6 * wrong during client authentication is tested in sslAlert.
7 */
8 #include <Security/SecureTransport.h>
9 #include <Security/Security.h>
10 #include <clAppUtils/sslAppUtils.h>
11 #include <clAppUtils/ioSock.h>
12 #include <clAppUtils/sslThreading.h>
13 #include <utilLib/common.h>
14 #include <security_cdsa_utils/cuPrintCert.h>
15 #include <security_utilities/threading.h>
16 #include <security_utilities/devrandom.h>
17
18 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <string.h>
23 #include <time.h>
24 #include <ctype.h>
25 #include <sys/param.h>
26
27 #define STARTING_PORT 4000
28
29 /*
30 * localcert is a KC containing server cert and signing key.
31 * Password is same as filename of the keychain.
32 */
33 #define SERVER_KC "localcert"
34 #define SERVER_ROOT "localcert.cer"
35
36 /*
37 * clientcert is a KC containing client cert and signing key.
38 * Password is same as filename of the keychain.
39 *
40 * Note common name not checked by SecureTransport when
41 * verifying client cert chain.
42 */
43 #define CLIENT_KC "clientcert"
44 #define CLIENT_ROOT "clientcert.cer"
45
46 /* main() fills these in using sslKeychainPath() */
47 static char serverKcPath[MAXPATHLEN];
48 static char clientKcPath[MAXPATHLEN];
49
50 static void usage(char **argv)
51 {
52 printf("Usage: %s [options]\n", argv[0]);
53 printf("options:\n");
54 printf(" q(uiet)\n");
55 printf(" v(erbose)\n");
56 printf(" p=startingPortNum\n");
57 printf(" t=startTestNum\n");
58 printf(" b (non blocking I/O)\n");
59 printf(" s=serverCertName; default %s\n", SERVER_ROOT);
60 printf(" c=clientCertName; default %s\n", CLIENT_ROOT);
61 printf(" R (ringBuffer I/O)\n");
62 printf(" k (keep keychain list open)\n");
63 printf(" l=loops (default=1; 0=forever)\n");
64 printf(" o (One test only)\n");
65 exit(1);
66 }
67
68 /*
69 * Parameters defining one run
70 */
71 typedef struct {
72 const char *testDesc;
73 SSLProtocol serverTryProt;
74 SSLProtocol serverActProt; // expected negotiated result
75 SSLAuthenticate tryAuth;
76 SSLClientCertificateState serverAuthState;
77 OSStatus serverStatus; // expected OSStatus
78 SSLProtocol clientTryProt;
79 const char *clientKcName; // determines whether or not
80 // to do authentication
81 SSLClientCertificateState clientAuthState;
82 OSStatus clientStatus;
83 } SslAuthParams;
84
85 SslAuthParams authTestParams[] =
86 {
87 {
88 "Server doesn't authenticate, client tries, TLS1",
89 kTLSProtocol1, kTLSProtocol1,
90 kNeverAuthenticate, kSSLClientCertNone, noErr,
91 kTLSProtocol1, NULL, kSSLClientCertNone, noErr
92 },
93 {
94 "Server doesn't authenticate, client tries, SSL3",
95 kTLSProtocol1, kSSLProtocol3,
96 kNeverAuthenticate, kSSLClientCertNone, noErr,
97 kSSLProtocol3, NULL, kSSLClientCertNone, noErr
98 },
99 {
100 "Server tries authentication, client refuses, TLS1",
101 kTLSProtocol1, kTLSProtocol1,
102 kTryAuthenticate, kSSLClientCertRequested, noErr,
103 kTLSProtocol1, NULL, kSSLClientCertRequested, noErr
104 },
105 {
106 "Server tries authentication, client refuses, SSL3",
107 kTLSProtocol1, kSSLProtocol3,
108 kTryAuthenticate, kSSLClientCertRequested, noErr,
109 kSSLProtocol3, NULL, kSSLClientCertRequested, noErr
110 },
111 {
112 "Server tries authentication, client sends cert, TLS1",
113 kTLSProtocol1, kTLSProtocol1,
114 kTryAuthenticate, kSSLClientCertSent, noErr,
115 kTLSProtocol1, clientKcPath, kSSLClientCertSent, noErr
116 },
117 {
118 "Server tries authentication, client sends cert, SSL3",
119 kSSLProtocol3, kSSLProtocol3,
120 kTryAuthenticate, kSSLClientCertSent, noErr,
121 kTLSProtocol1, clientKcPath, kSSLClientCertSent, noErr
122 },
123 {
124 "Server requires authentication, client refuses, TLS1",
125 kTLSProtocol1, kTLSProtocol1,
126 kAlwaysAuthenticate, kSSLClientCertRequested,
127 errSSLXCertChainInvalid,
128 kTLSProtocol1, NULL, kSSLClientCertRequested,
129 errSSLPeerCertUnknown
130 },
131 {
132 "Server requires authentication, client refuses, SSL3",
133 kSSLProtocol3, kSSLProtocol3,
134 kAlwaysAuthenticate, kSSLClientCertRequested, errSSLProtocol,
135 kTLSProtocol1, NULL, kSSLClientCertRequested, errSSLPeerUnexpectedMsg
136 },
137
138 };
139
140 #define NUM_SSL_AUTH_TESTS (sizeof(authTestParams) / sizeof(authTestParams[0]))
141
142 #define IGNORE_SIGPIPE 1
143 #if IGNORE_SIGPIPE
144 #include <signal.h>
145
146 void sigpipe(int sig)
147 {
148 }
149 #endif /* IGNORE_SIGPIPE */
150
151 /*
152 * Default params for each test. Main() will make a copy of this and
153 * adjust its copy on a per-test basis.
154 */
155 SslAppTestParams serverDefaults =
156 {
157 "no name here",
158 false, // skipHostNameCHeck
159 0, // port - test must set this
160 NULL, NULL, // RingBuffers
161 false, // noProtSpec
162 kTLSProtocol1, // set in test loop
163 NULL, // acceptedProts - not used in this test
164 serverKcPath, // myCerts - const
165 SERVER_KC, // password
166 true, // idIsTrustedRoot
167 false, // disableCertVerify
168 CLIENT_ROOT, // anchorFile - only meaningful if client
169 // authenticates
170 false, // replaceAnchors
171 kNeverAuthenticate, // set in test loop
172 false, // resumeEnable
173 NULL, // ciphers,
174 false, // nonBlocking
175 NULL, // dhParams
176 0, // dhParamsLen
177 noErr, // expectRtn
178 kTLSProtocol1, // expectVersion
179 kSSLClientCertNone,
180 SSL_CIPHER_IGNORE,
181 false, // quiet
182 false, // silent
183 false, // verbose
184 {0}, // lock
185 {0}, // cond
186 false, // serverReady
187 0, // clientDone
188 false, // serverAbort
189 /* returned */
190 kSSLProtocolUnknown,
191 SSL_NULL_WITH_NULL_NULL,
192 kSSLClientCertNone,
193 noHardwareErr
194
195 };
196
197 SslAppTestParams clientDefaults =
198 {
199 "localhost",
200 false, // skipHostNameCHeck
201 0, // port - test must set this
202 NULL, NULL, // RingBuffers
203 false, // noProtSpec
204 kTLSProtocol1,
205 NULL, // acceptedProts
206 NULL, // myCertKcName - varies, set in main test loop
207 CLIENT_KC, // password
208 true, // idIsTrustedRoot
209 false, // disableCertVerify
210 SERVER_ROOT, // anchorFile
211 false, // replaceAnchors
212 kNeverAuthenticate,
213 false, // resumeEnable
214 NULL, // ciphers
215 false, // nonBlocking
216 NULL, // dhParams
217 0, // dhParamsLen
218 noErr, // expectRtn
219 kTLSProtocol1, // expectVersion
220 kSSLClientCertNone,
221 SSL_CIPHER_IGNORE,
222 false, // quiet
223 false, // silent
224 false, // verbose
225 {0}, // lock
226 {0}, // cond
227 false, // serverReady
228 0, // clientDone
229 false, // serverAbort
230 /* returned */
231 kSSLProtocolUnknown,
232 SSL_NULL_WITH_NULL_NULL,
233 kSSLClientCertNone,
234 noHardwareErr
235 };
236
237
238 int main(int argc, char **argv)
239 {
240 int ourRtn = 0;
241 char *argp;
242 SslAppTestParams clientParams;
243 SslAppTestParams serverParams;
244 unsigned short portNum = STARTING_PORT;
245 SslAuthParams *authParams;
246 unsigned testNum;
247 int thisRtn;
248 unsigned startTest = 0;
249 unsigned loopNum = 0;
250 unsigned loops = 1;
251 RingBuffer serverToClientRing;
252 RingBuffer clientToServerRing;
253 bool ringBufferIo = false;
254 bool keepKCListOpen = false;
255 CFArrayRef kcList = NULL;
256 bool oneTestOnly = false;
257
258 for(int arg=1; arg<argc; arg++) {
259 argp = argv[arg];
260 switch(argp[0]) {
261 case 'q':
262 serverDefaults.quiet = clientDefaults.quiet = true;
263 break;
264 case 'v':
265 serverDefaults.verbose = clientDefaults.verbose = true;
266 break;
267 case 'p':
268 portNum = atoi(&argp[2]);
269 break;
270 case 'b':
271 serverDefaults.nonBlocking = clientDefaults.nonBlocking =
272 true;
273 break;
274 case 't':
275 startTest = atoi(&argp[2]);
276 break;
277 case 's':
278 clientDefaults.anchorFile = &argp[2];
279 break;
280 case 'c':
281 serverDefaults.anchorFile = &argp[2];
282 break;
283 case 'l':
284 loops = atoi(&argp[2]);
285 break;
286 case 'R':
287 ringBufferIo = true;
288 break;
289 case 'k':
290 keepKCListOpen = true;
291 break;
292 case 'o':
293 oneTestOnly = true;
294 break;
295 default:
296 usage(argv);
297 }
298 }
299
300 if(sslCheckFile(clientDefaults.anchorFile)) {
301 exit(1);
302 }
303 if(sslCheckFile(serverDefaults.anchorFile)) {
304 exit(1);
305 }
306 if(ringBufferIo) {
307 /* set up ring buffers */
308 ringBufSetup(&serverToClientRing, "serveToClient", DEFAULT_NUM_RB_BUFS, DEFAULT_BUF_RB_SIZE);
309 ringBufSetup(&clientToServerRing, "clientToServe", DEFAULT_NUM_RB_BUFS, DEFAULT_BUF_RB_SIZE);
310 serverDefaults.serverToClientRing = &serverToClientRing;
311 serverDefaults.clientToServerRing = &clientToServerRing;
312 clientDefaults.serverToClientRing = &serverToClientRing;
313 clientDefaults.clientToServerRing = &clientToServerRing;
314 }
315 if(keepKCListOpen) {
316 /* this prevents most of the CPU cycles being spent opening keychains */
317 OSStatus ortn = SecKeychainCopySearchList(&kcList);
318 if(ortn) {
319 cssmPerror("SecKeychainCopySearchList", ortn);
320 exit(1);
321 }
322 }
323
324 #if IGNORE_SIGPIPE
325 signal(SIGPIPE, sigpipe);
326 #endif
327
328 /* convert keychain names to paths for root */
329 sslKeychainPath(SERVER_KC, serverKcPath);
330 sslKeychainPath(CLIENT_KC, clientKcPath);
331
332 testStartBanner("sslAuth", argc, argv);
333 // printf("sslAuth: server KC: %s\n", serverKcPath);
334 // printf("sslAuth: client KC: %s\n", clientKcPath);
335
336 serverParams.port = portNum - 1; // gets incremented by SSL_THR_SETUP
337
338 for(;;) {
339 for(testNum=startTest; testNum<NUM_SSL_AUTH_TESTS; testNum++) {
340 authParams = &authTestParams[testNum];
341 SSL_THR_SETUP(serverParams, clientParams, clientDefaults,
342 serverDefault);
343 if(ringBufferIo) {
344 ringBufferReset(&serverToClientRing);
345 ringBufferReset(&clientToServerRing);
346 }
347
348 serverParams.tryVersion = authParams->serverTryProt;
349 serverParams.expectVersion = authParams->serverActProt;
350 serverParams.authenticate = authParams->tryAuth;
351 serverParams.expectCertState = authParams->serverAuthState;
352 serverParams.expectRtn = authParams->serverStatus;
353
354 clientParams.tryVersion = authParams->clientTryProt;
355 clientParams.expectVersion = authParams->serverActProt;
356 clientParams.expectRtn = authParams->clientStatus;
357 clientParams.myCertKcName = authParams->clientKcName;
358 clientParams.expectCertState = authParams->clientAuthState;
359
360 SSL_THR_RUN_NUM(serverParams, clientParams, authParams->testDesc,
361 ourRtn, testNum);
362 if(oneTestOnly) {
363 break;
364 }
365 }
366 if(loops) {
367 if(++loopNum == loops) {
368 break;
369 }
370 printf("...loop %u\n", loopNum);
371 }
372 }
373 done:
374 if(!clientParams.quiet) {
375 if(ourRtn == 0) {
376 printf("===== %s test PASSED =====\n", argv[0]);
377 }
378 else {
379 printf("****FAIL: %d errors detected\n", ourRtn);
380 }
381 }
382
383 return ourRtn;
384 }