2 * sslAuth.cpp - test client-side authentication, client and server side
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.
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>
18 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
25 #include <sys/param.h>
27 #define STARTING_PORT 4000
30 * localcert is a KC containing server cert and signing key.
31 * Password is same as filename of the keychain.
33 #define SERVER_KC "localcert"
34 #define SERVER_ROOT "localcert.cer"
37 * clientcert is a KC containing client cert and signing key.
38 * Password is same as filename of the keychain.
40 * Note common name not checked by SecureTransport when
41 * verifying client cert chain.
43 #define CLIENT_KC "clientcert"
44 #define CLIENT_ROOT "clientcert.cer"
46 /* main() fills these in using sslKeychainPath() */
47 static char serverKcPath
[MAXPATHLEN
];
48 static char clientKcPath
[MAXPATHLEN
];
50 static void usage(char **argv
)
52 printf("Usage: %s [options]\n", argv
[0]);
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");
69 * Parameters defining one run
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
;
85 SslAuthParams authTestParams
[] =
88 "Server doesn't authenticate, client tries, TLS1",
89 kTLSProtocol1
, kTLSProtocol1
,
90 kNeverAuthenticate
, kSSLClientCertNone
, noErr
,
91 kTLSProtocol1
, NULL
, kSSLClientCertNone
, noErr
94 "Server doesn't authenticate, client tries, SSL3",
95 kTLSProtocol1
, kSSLProtocol3
,
96 kNeverAuthenticate
, kSSLClientCertNone
, noErr
,
97 kSSLProtocol3
, NULL
, kSSLClientCertNone
, noErr
100 "Server tries authentication, client refuses, TLS1",
101 kTLSProtocol1
, kTLSProtocol1
,
102 kTryAuthenticate
, kSSLClientCertRequested
, noErr
,
103 kTLSProtocol1
, NULL
, kSSLClientCertRequested
, noErr
106 "Server tries authentication, client refuses, SSL3",
107 kTLSProtocol1
, kSSLProtocol3
,
108 kTryAuthenticate
, kSSLClientCertRequested
, noErr
,
109 kSSLProtocol3
, NULL
, kSSLClientCertRequested
, noErr
112 "Server tries authentication, client sends cert, TLS1",
113 kTLSProtocol1
, kTLSProtocol1
,
114 kTryAuthenticate
, kSSLClientCertSent
, noErr
,
115 kTLSProtocol1
, clientKcPath
, kSSLClientCertSent
, noErr
118 "Server tries authentication, client sends cert, SSL3",
119 kSSLProtocol3
, kSSLProtocol3
,
120 kTryAuthenticate
, kSSLClientCertSent
, noErr
,
121 kTLSProtocol1
, clientKcPath
, kSSLClientCertSent
, noErr
124 "Server requires authentication, client refuses, TLS1",
125 kTLSProtocol1
, kTLSProtocol1
,
126 kAlwaysAuthenticate
, kSSLClientCertRequested
,
127 errSSLXCertChainInvalid
,
128 kTLSProtocol1
, NULL
, kSSLClientCertRequested
,
129 errSSLPeerCertUnknown
132 "Server requires authentication, client refuses, SSL3",
133 kSSLProtocol3
, kSSLProtocol3
,
134 kAlwaysAuthenticate
, kSSLClientCertRequested
, errSSLProtocol
,
135 kTLSProtocol1
, NULL
, kSSLClientCertRequested
, errSSLPeerUnexpectedMsg
140 #define NUM_SSL_AUTH_TESTS (sizeof(authTestParams) / sizeof(authTestParams[0]))
142 #define IGNORE_SIGPIPE 1
146 void sigpipe(int sig
)
149 #endif /* IGNORE_SIGPIPE */
152 * Default params for each test. Main() will make a copy of this and
153 * adjust its copy on a per-test basis.
155 SslAppTestParams serverDefaults
=
158 false, // skipHostNameCHeck
159 0, // port - test must set this
160 NULL
, NULL
, // RingBuffers
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
170 false, // replaceAnchors
171 kNeverAuthenticate
, // set in test loop
172 false, // resumeEnable
174 false, // nonBlocking
178 kTLSProtocol1
, // expectVersion
186 false, // serverReady
188 false, // serverAbort
191 SSL_NULL_WITH_NULL_NULL
,
197 SslAppTestParams clientDefaults
=
200 false, // skipHostNameCHeck
201 0, // port - test must set this
202 NULL
, NULL
, // RingBuffers
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
213 false, // resumeEnable
215 false, // nonBlocking
219 kTLSProtocol1
, // expectVersion
227 false, // serverReady
229 false, // serverAbort
232 SSL_NULL_WITH_NULL_NULL
,
238 int main(int argc
, char **argv
)
242 SslAppTestParams clientParams
;
243 SslAppTestParams serverParams
;
244 unsigned short portNum
= STARTING_PORT
;
245 SslAuthParams
*authParams
;
248 unsigned startTest
= 0;
249 unsigned loopNum
= 0;
251 RingBuffer serverToClientRing
;
252 RingBuffer clientToServerRing
;
253 bool ringBufferIo
= false;
254 bool keepKCListOpen
= false;
255 CFArrayRef kcList
= NULL
;
256 bool oneTestOnly
= false;
258 for(int arg
=1; arg
<argc
; arg
++) {
262 serverDefaults
.quiet
= clientDefaults
.quiet
= true;
265 serverDefaults
.verbose
= clientDefaults
.verbose
= true;
268 portNum
= atoi(&argp
[2]);
271 serverDefaults
.nonBlocking
= clientDefaults
.nonBlocking
=
275 startTest
= atoi(&argp
[2]);
278 clientDefaults
.anchorFile
= &argp
[2];
281 serverDefaults
.anchorFile
= &argp
[2];
284 loops
= atoi(&argp
[2]);
290 keepKCListOpen
= true;
300 if(sslCheckFile(clientDefaults
.anchorFile
)) {
303 if(sslCheckFile(serverDefaults
.anchorFile
)) {
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
;
316 /* this prevents most of the CPU cycles being spent opening keychains */
317 OSStatus ortn
= SecKeychainCopySearchList(&kcList
);
319 cssmPerror("SecKeychainCopySearchList", ortn
);
325 signal(SIGPIPE
, sigpipe
);
328 /* convert keychain names to paths for root */
329 sslKeychainPath(SERVER_KC
, serverKcPath
);
330 sslKeychainPath(CLIENT_KC
, clientKcPath
);
332 testStartBanner("sslAuth", argc
, argv
);
333 // printf("sslAuth: server KC: %s\n", serverKcPath);
334 // printf("sslAuth: client KC: %s\n", clientKcPath);
336 serverParams
.port
= portNum
- 1; // gets incremented by SSL_THR_SETUP
339 for(testNum
=startTest
; testNum
<NUM_SSL_AUTH_TESTS
; testNum
++) {
340 authParams
= &authTestParams
[testNum
];
341 SSL_THR_SETUP(serverParams
, clientParams
, clientDefaults
,
344 ringBufferReset(&serverToClientRing
);
345 ringBufferReset(&clientToServerRing
);
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
;
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
;
360 SSL_THR_RUN_NUM(serverParams
, clientParams
, authParams
->testDesc
,
367 if(++loopNum
== loops
) {
370 printf("...loop %u\n", loopNum
);
374 if(!clientParams
.quiet
) {
376 printf("===== %s test PASSED =====\n", argv
[0]);
379 printf("****FAIL: %d errors detected\n", ourRtn
);