]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/sslEAP/ringBufferThreads.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / sslEAP / ringBufferThreads.cpp
1 /*
2 * ringBufferThreads.cpp - SecureTransport client and server thread
3 * routines which use ringBufferIo for I/O (no sockets).
4 *
5 * Customized for EAP-FAST testing; uses SSLInternalSetMasterSecretFunction()
6 * and SSLInternalSetSessionTicket().
7 */
8
9 #include "ringBufferThreads.h"
10 #include <stdlib.h>
11 #include <pthread.h>
12 #include <stdio.h>
13 #include <strings.h>
14 #include <clAppUtils/sslAppUtils.h>
15 #include <utilLib/common.h>
16 #include <CommonCrypto/CommonDigest.h>
17
18 #define LOG_TOP_IO 0
19 #if LOG_TOP_IO
20
21 static void logWrite(
22 char *who,
23 size_t written)
24 {
25 pthread_mutex_lock(&printfMutex);
26 printf("+++ %s wrote %4lu bytes\n", who, (unsigned long)written);
27 pthread_mutex_unlock(&printfMutex);
28 }
29
30 static void logRead(
31 char *who,
32 size_t bytesRead)
33 {
34 pthread_mutex_lock(&printfMutex);
35 printf("+++ %s read %4lu bytes\n", who, (unsigned long)bytesRead);
36 pthread_mutex_unlock(&printfMutex);
37 }
38
39 #else /* LOG_TOP_IO */
40 #define logWrite(who, w)
41 #define logRead(who, r)
42 #endif /* LOG_TOP_IO */
43
44 /*
45 * Callback from ST to calculate master secret.
46 * We do a poor person's T_PRF(), taking the hash of:
47 *
48 * serverRandom | clientRandom | sharedSecret
49 *
50 * ...to prove that both sides can come up with a master secret
51 * independently, using both sides' random values and the shared secret
52 * supplied by the app.
53 *
54 * We happen to have a digest that produces the required number
55 * of bytes (48)...
56 */
57 static void sslMasterSecretFunction(
58 SSLContextRef ctx,
59 const void *arg, /* actually a RingBufferArgs */
60 void *secret, /* mallocd by caller, SSL_MASTER_SECRET_SIZE */
61 size_t *secretLength) /* in/out */
62 {
63 RingBufferArgs *sslArgs = (RingBufferArgs *)arg;
64 if(*secretLength < SSL_MASTER_SECRET_SIZE) {
65 printf("**Hey! insufficient space for master secret!\n");
66 return;
67 }
68
69 unsigned char r[SSL_CLIENT_SRVR_RAND_SIZE];
70 size_t rSize = SSL_CLIENT_SRVR_RAND_SIZE;
71 CC_SHA512_CTX digestCtx;
72 CC_SHA384_Init(&digestCtx);
73 SSLInternalServerRandom(ctx, r, &rSize);
74 CC_SHA384_Update(&digestCtx, r, rSize);
75 SSLInternalClientRandom(ctx, r, &rSize);
76 CC_SHA384_Update(&digestCtx, r, rSize);
77 CC_SHA384_Update(&digestCtx, sslArgs->sharedSecret, SHARED_SECRET_SIZE);
78 CC_SHA384_Final((unsigned char *)secret, &digestCtx);
79 *secretLength = CC_SHA384_DIGEST_LENGTH;
80 }
81
82 /* client thread - handshake and write some data */
83 void *rbClientThread(void *arg)
84 {
85 RingBufferArgs *sslArgs = (RingBufferArgs *)arg;
86 OSStatus ortn;
87 SSLContextRef ctx = NULL;
88 RingBuffers ringBufs = {sslArgs->ringRead, sslArgs->ringWrite};
89 char sessionID[MAX_SESSION_ID_LENGTH];
90 size_t sessionIDLen = MAX_SESSION_ID_LENGTH;
91 unsigned toMove;
92 unsigned thisMove;
93
94 ortn = SSLNewContext(false, &ctx);
95 if(ortn) {
96 printSslErrStr("SSLNewContext", ortn);
97 goto cleanup;
98 }
99 ortn = SSLSetIOFuncs(ctx, ringReadFunc, ringWriteFunc);
100 if(ortn) {
101 printSslErrStr("SSLSetIOFuncs", ortn);
102 goto cleanup;
103 }
104 ortn = SSLSetConnection(ctx, (SSLConnectionRef)&ringBufs);
105 if(ortn) {
106 printSslErrStr("SSLSetConnection", ortn);
107 goto cleanup;
108 }
109 /* EAP is TLS only - disable the SSLv2-capable handshake */
110 ortn = SSLSetProtocolVersionEnabled(ctx, kSSLProtocol2, false);
111 if(ortn) {
112 printSslErrStr("SSLSetProtocolVersionEnabled", ortn);
113 goto cleanup;
114 }
115 ortn = SSLInternalSetMasterSecretFunction(ctx, sslMasterSecretFunction, sslArgs);
116 if(ortn) {
117 printSslErrStr("SSLInternalSetMasterSecretFunction", ortn);
118 goto cleanup;
119 }
120 ortn = SSLInternalSetSessionTicket(ctx, sslArgs->sessionTicket,
121 sslArgs->sessionTicketLen);
122 if(ortn) {
123 printSslErrStr("SSLInternalSetSessionTicket", ortn);
124 goto cleanup;
125 }
126 if(sslArgs->trustedRoots) {
127 ortn = SSLSetTrustedRoots(ctx, sslArgs->trustedRoots, true);
128 if(ortn) {
129 printSslErrStr("SSLSetTrustedRoots", ortn);
130 goto cleanup;
131 }
132 }
133 if(sslArgs->hostName) {
134 ortn = SSLSetPeerDomainName(ctx, sslArgs->hostName, strlen(sslArgs->hostName));
135 if(ortn) {
136 printSslErrStr("SSLSetPeerDomainName", ortn);
137 goto cleanup;
138 }
139 }
140
141 /* tell main thread we're ready; wait for sync flag */
142 sslArgs->iAmReady = true;
143 while(!(*sslArgs->goFlag)) {
144 if(*sslArgs->abortFlag) {
145 goto cleanup;
146 }
147 }
148
149 /* GO handshake */
150 sslArgs->startHandshake = CFAbsoluteTimeGetCurrent();
151 do {
152 ortn = SSLHandshake(ctx);
153 if(*sslArgs->abortFlag) {
154 goto cleanup;
155 }
156 } while (ortn == errSSLWouldBlock);
157
158 if(ortn) {
159 printSslErrStr("SSLHandshake", ortn);
160 goto cleanup;
161 }
162
163 SSLGetNegotiatedCipher(ctx, &sslArgs->negotiatedCipher);
164 SSLGetNegotiatedProtocolVersion(ctx, &sslArgs->negotiatedProt);
165
166 ortn = SSLGetResumableSessionInfo(ctx, &sslArgs->sessionWasResumed, sessionID, &sessionIDLen);
167 if(ortn) {
168 printSslErrStr("SSLGetResumableSessionInfo", ortn);
169 goto cleanup;
170 }
171
172 sslArgs->startData = CFAbsoluteTimeGetCurrent();
173
174 toMove = sslArgs->xferSize;
175
176 if(toMove == 0) {
177 sslArgs->endData = sslArgs->startData;
178 goto cleanup;
179 }
180
181 /* GO data xfer */
182 do {
183 thisMove = sslArgs->chunkSize;
184 if(thisMove > toMove) {
185 thisMove = toMove;
186 }
187 size_t moved;
188 ortn = SSLWrite(ctx, sslArgs->xferBuf, thisMove, &moved);
189 /* should never fail - implemented as blocking */
190 if(ortn) {
191 printSslErrStr("SSLWrite", ortn);
192 goto cleanup;
193 }
194 logWrite("client", moved);
195 toMove -= moved;
196 if(*sslArgs->abortFlag) {
197 goto cleanup;
198 }
199 } while(toMove);
200
201 sslArgs->endData = CFAbsoluteTimeGetCurrent();
202
203 cleanup:
204 if(ortn) {
205 *sslArgs->abortFlag = true;
206 }
207 if(*sslArgs->abortFlag && sslArgs->pauseOnError) {
208 /* abort for any reason - freeze! */
209 testError(CSSM_FALSE);
210 }
211 if(ctx) {
212 SSLClose(ctx);
213 SSLDisposeContext(ctx);
214 }
215 if(ortn) {
216 printf("***Client thread returning %lu\n", (unsigned long)ortn);
217 }
218 pthread_exit((void*)ortn);
219 /* NOT REACHED */
220 return (void *)ortn;
221
222 }
223
224 /* server function - like clientThread except it runs from the main thread */
225 /* handshake and read some data */
226 OSStatus rbServerThread(RingBufferArgs *sslArgs)
227 {
228 OSStatus ortn;
229 SSLContextRef ctx = NULL;
230 RingBuffers ringBufs = {sslArgs->ringRead, sslArgs->ringWrite};
231 char sessionID[MAX_SESSION_ID_LENGTH];
232 size_t sessionIDLen = MAX_SESSION_ID_LENGTH;
233 unsigned toMove;
234 unsigned thisMove;
235
236 ortn = SSLNewContext(true, &ctx);
237 if(ortn) {
238 printSslErrStr("SSLNewContext", ortn);
239 goto cleanup;
240 }
241 ortn = SSLSetIOFuncs(ctx, ringReadFunc, ringWriteFunc);
242 if(ortn) {
243 printSslErrStr("SSLSetIOFuncs", ortn);
244 goto cleanup;
245 }
246 ortn = SSLSetConnection(ctx, (SSLConnectionRef)&ringBufs);
247 if(ortn) {
248 printSslErrStr("SSLSetConnection", ortn);
249 goto cleanup;
250 }
251 if(sslArgs->setMasterSecret) {
252 ortn = SSLInternalSetMasterSecretFunction(ctx, sslMasterSecretFunction, sslArgs);
253 if(ortn) {
254 printSslErrStr("SSLInternalSetMasterSecretFunction", ortn);
255 goto cleanup;
256 }
257 }
258 if(sslArgs->idArray) {
259 ortn = SSLSetCertificate(ctx, sslArgs->idArray);
260 if(ortn) {
261 printSslErrStr("SSLSetCertificate", ortn);
262 goto cleanup;
263 }
264 }
265 if(sslArgs->trustedRoots) {
266 ortn = SSLSetTrustedRoots(ctx, sslArgs->trustedRoots, true);
267 if(ortn) {
268 printSslErrStr("SSLSetTrustedRoots", ortn);
269 goto cleanup;
270 }
271 }
272
273 /* tell client thread we're ready; wait for sync flag */
274 sslArgs->iAmReady = true;
275 while(!(*sslArgs->goFlag)) {
276 if(*sslArgs->abortFlag) {
277 goto cleanup;
278 }
279 }
280
281 /* GO handshake */
282 sslArgs->startHandshake = CFAbsoluteTimeGetCurrent();
283 do {
284 ortn = SSLHandshake(ctx);
285 if(*sslArgs->abortFlag) {
286 goto cleanup;
287 }
288 } while (ortn == errSSLWouldBlock);
289
290 if(ortn) {
291 printSslErrStr("SSLHandshake", ortn);
292 goto cleanup;
293 }
294
295 SSLGetNegotiatedCipher(ctx, &sslArgs->negotiatedCipher);
296 SSLGetNegotiatedProtocolVersion(ctx, &sslArgs->negotiatedProt);
297 ortn = SSLGetResumableSessionInfo(ctx, &sslArgs->sessionWasResumed, sessionID, &sessionIDLen);
298 if(ortn) {
299 printSslErrStr("SSLGetResumableSessionInfo", ortn);
300 goto cleanup;
301 }
302
303 sslArgs->startData = CFAbsoluteTimeGetCurrent();
304
305 toMove = sslArgs->xferSize;
306
307 if(toMove == 0) {
308 sslArgs->endData = sslArgs->startData;
309 goto cleanup;
310 }
311
312 /* GO data xfer */
313 do {
314 thisMove = sslArgs->xferSize;
315 if(thisMove > toMove) {
316 thisMove = toMove;
317 }
318 size_t moved;
319 ortn = SSLRead(ctx, sslArgs->xferBuf, thisMove, &moved);
320 switch(ortn) {
321 case noErr:
322 break;
323 case errSSLWouldBlock:
324 /* cool, try again */
325 ortn = noErr;
326 break;
327 default:
328 break;
329 }
330 if(ortn) {
331 printSslErrStr("SSLRead", ortn);
332 goto cleanup;
333 }
334 logRead("server", moved);
335 toMove -= moved;
336 if(*sslArgs->abortFlag) {
337 goto cleanup;
338 }
339 } while(toMove);
340
341 sslArgs->endData = CFAbsoluteTimeGetCurrent();
342
343 cleanup:
344 if(ortn) {
345 *sslArgs->abortFlag = true;
346 }
347 if(*sslArgs->abortFlag && sslArgs->pauseOnError) {
348 /* abort for any reason - freeze! */
349 testError(CSSM_FALSE);
350 }
351 if(ctx) {
352 SSLClose(ctx);
353 SSLDisposeContext(ctx);
354 }
355 if(ortn) {
356 printf("***Server thread returning %lu\n", (unsigned long)ortn);
357 }
358 return ortn;
359 }