]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/sslEAP/sslEAP.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / SecurityTests / clxutils / sslEAP / sslEAP.cpp
1 /*
2 * sslEAP - test EAP-FAST style PAC-based session resumption.
3 *
4 * This only works with a debug Security.framework since server side
5 * PAC support is not present in deployment builds.
6 *
7 * Written by Doug Mitchell.
8 */
9 #include <Security/SecureTransport.h>
10 #include <Security/SecureTransportPriv.h>
11 #include <clAppUtils/sslAppUtils.h>
12 #include <security_cdsa_utils/cuFileIo.h>
13 #include <utilLib/common.h>
14 #include <clAppUtils/ringBufferIo.h>
15 #include "ringBufferThreads.h" /* like the ones in clAppUtils, tailored for EAP/PAC */
16
17 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <time.h>
22 #include <ctype.h>
23 #include <sys/param.h>
24 #include <CoreFoundation/CoreFoundation.h>
25 #include <security_utilities/devrandom.h>
26
27 #define DEFAULT_XFER 1024 /* total xfer size in bytes */
28
29 /* we might make these user-tweakable */
30 #define DEFAULT_NUM_BUFS 16
31 #define DEFAULT_BUF_SIZE 2048 /* in the ring buffers */
32 #define DEFAULT_CHUNK 1024 /* bytes to write per SSLWrite() */
33 #define SESSION_TICKET_SIZE 512
34
35 static void usage(char **argv)
36 {
37 printf("Usage: %s [option ...]\n", argv[0]);
38 printf("Options:\n");
39 printf(" -x transferSize -- default=%d; 0=forever\n", DEFAULT_XFER);
40 printf(" -k keychainName -- not needed if PAC will be done\n");
41 printf(" -n -- *NO* PAC\n");
42 printf(" -h hostName -- force a SSLSetPeerDomainName on client side\n");
43 printf(" -p (pause on error)\n");
44 exit(1);
45 }
46
47 int main(int argc, char **argv)
48 {
49 RingBuffer serverToClientRing;
50 RingBuffer clientToServerRing;
51 unsigned numBufs = DEFAULT_NUM_BUFS;
52 unsigned bufSize = DEFAULT_BUF_SIZE;
53 unsigned chunkSize = DEFAULT_CHUNK;
54 unsigned char clientBuf[DEFAULT_CHUNK];
55 unsigned char serverBuf[DEFAULT_CHUNK];
56 RingBufferArgs clientArgs;
57 RingBufferArgs serverArgs;
58 bool abortFlag = false;
59 pthread_t client_thread = NULL;
60 int result;
61 OSStatus ortn;
62 unsigned char sessionTicket[SESSION_TICKET_SIZE];
63 int ourRtn = 0;
64 CFArrayRef idArray = NULL; /* for SSLSetCertificate */
65 CFArrayRef anchorArray = NULL; /* trusted roots */
66 char *hostName = NULL;
67
68 /* user-spec'd variables */
69 char *kcName = NULL;
70 unsigned xferSize = DEFAULT_XFER;
71 bool pauseOnError = false;
72 bool runForever = false;
73 bool skipPAC = false;
74
75 extern int optind;
76 extern char *optarg;
77 int arg;
78 optind = 1;
79 while ((arg = getopt(argc, argv, "x:c:k:h:np")) != -1) {
80 switch (arg) {
81 case 'x':
82 {
83 unsigned xsize = atoi(optarg);
84 if(xsize == 0) {
85 runForever = true;
86 /* and leave xferSize alone */
87 }
88 else {
89 xferSize = xsize;
90 }
91 break;
92 }
93 case 'k':
94 kcName = optarg;
95 break;
96 case 'n':
97 skipPAC = true;
98 break;
99 case 'h':
100 /* mainly to test EAP session ticket and ServerName simultaneously */
101 hostName = optarg;
102 break;
103 case 'p':
104 pauseOnError = true;
105 break;
106 default:
107 usage(argv);
108 }
109 }
110 if(optind != argc) {
111 usage(argv);
112 }
113
114 /* set up ring buffers */
115 ringBufSetup(&serverToClientRing, "serveToClient", numBufs, bufSize);
116 ringBufSetup(&clientToServerRing, "clientToServe", numBufs, bufSize);
117
118 /* get optional server SecIdentity */
119 if(kcName) {
120 SecKeychainRef kcRef = NULL;
121 SecCertificateRef anchorCert = NULL;
122 SecIdentityRef idRef = NULL;
123 idArray = getSslCerts(kcName,
124 CSSM_FALSE, /* encryptOnly */
125 CSSM_FALSE, /* completeCertChain */
126 NULL, /* anchorFile */
127 &kcRef);
128 if(idArray == NULL) {
129 printf("***Can't get signing cert from %s\n", kcName);
130 exit(1);
131 }
132 idRef = (SecIdentityRef)CFArrayGetValueAtIndex(idArray, 0);
133 ortn = SecIdentityCopyCertificate(idRef, &anchorCert);
134 if(ortn) {
135 cssmPerror("SecIdentityCopyCertificate", ortn);
136 exit(1);
137 }
138 anchorArray = CFArrayCreate(NULL, (const void **)&anchorCert,
139 1, &kCFTypeArrayCallBacks);
140 CFRelease(kcRef);
141 CFRelease(anchorCert);
142 }
143
144 /* set up server side */
145 memset(&serverArgs, 0, sizeof(serverArgs));
146 serverArgs.xferSize = xferSize;
147 serverArgs.xferBuf = serverBuf;
148 serverArgs.chunkSize = chunkSize;
149 serverArgs.ringWrite = &serverToClientRing;
150 serverArgs.ringRead = &clientToServerRing;
151 serverArgs.goFlag = &clientArgs.iAmReady;
152 serverArgs.abortFlag = &abortFlag;
153 serverArgs.pauseOnError = pauseOnError;
154 appGetRandomBytes(serverArgs.sharedSecret, SHARED_SECRET_SIZE);
155 if(!skipPAC) {
156 serverArgs.setMasterSecret = true;
157 }
158 serverArgs.idArray = idArray;
159 serverArgs.trustedRoots = anchorArray;
160
161 /* set up client side */
162 memset(&clientArgs, 0, sizeof(clientArgs));
163 clientArgs.xferSize = xferSize;
164 clientArgs.xferBuf = clientBuf;
165 clientArgs.chunkSize = chunkSize;
166 clientArgs.ringWrite = &clientToServerRing;
167 clientArgs.ringRead = &serverToClientRing;
168 clientArgs.goFlag = &serverArgs.iAmReady;
169 clientArgs.abortFlag = &abortFlag;
170 clientArgs.pauseOnError = pauseOnError;
171 memmove(clientArgs.sharedSecret, serverArgs.sharedSecret, SHARED_SECRET_SIZE);
172 clientArgs.hostName = hostName;
173
174 /* for now set up an easily recognizable ticket */
175 for(unsigned dex=0; dex<SESSION_TICKET_SIZE; dex++) {
176 sessionTicket[dex] = dex;
177 }
178 clientArgs.sessionTicket = sessionTicket;
179 clientArgs.sessionTicketLen = SESSION_TICKET_SIZE;
180 /* client always tries setting the master secret in this test */
181 clientArgs.setMasterSecret = true;
182 clientArgs.trustedRoots = anchorArray;
183
184 /* fire up client thread */
185 result = pthread_create(&client_thread, NULL,
186 rbClientThread, &clientArgs);
187 if(result) {
188 printf("***pthread_create returned %d, aborting\n", result);
189 exit(1);
190 }
191
192 /*
193 * And the server pseudo thread. This returns when all data has been transferred.
194 */
195 ortn = rbServerThread(&serverArgs);
196
197 if(abortFlag) {
198 printf("***Test aborted.\n");
199 exit(1);
200 }
201
202 printf("\n");
203
204 printf("SSL Protocol Version : %s\n",
205 sslGetProtocolVersionString(serverArgs.negotiatedProt));
206 printf("SSL Cipher : %s\n",
207 sslGetCipherSuiteString(serverArgs.negotiatedCipher));
208
209 if(skipPAC) {
210 if(clientArgs.sessionWasResumed) {
211 printf("***skipPAC true, but client reported sessionWasResumed\n");
212 ourRtn = -1;
213 }
214 if(serverArgs.sessionWasResumed) {
215 printf("***skipPAC true, but server reported sessionWasResumed\n");
216 ourRtn = -1;
217 }
218 if(ourRtn == 0) {
219 printf("...PAC session attempted by client; refused by server;\n");
220 printf(" Normal session proceeded correctly.\n");
221 }
222 }
223 else {
224 if(!clientArgs.sessionWasResumed) {
225 printf("***client reported !sessionWasResumed\n");
226 ourRtn = -1;
227 }
228 if(!serverArgs.sessionWasResumed) {
229 printf("***server reported !sessionWasResumed\n");
230 ourRtn = -1;
231 }
232 if(memcmp(clientBuf, serverBuf, DEFAULT_CHUNK)) {
233 printf("***Data miscompare***\n");
234 ourRtn = -1;
235 }
236 if(ourRtn == 0) {
237 printf("...PAC session resumed correctly.\n");
238 }
239 }
240 /* FIXME other stuff? */
241
242 return ourRtn;
243 }
244
245
246