2 * ringBufferThreads.cpp - SecureTransport client and server thread
3 * routines which use ringBufferIo for I/O (no sockets).
5 * Customized for EAP-FAST testing; uses SSLInternalSetMasterSecretFunction()
6 * and SSLInternalSetSessionTicket().
9 #include "ringBufferThreads.h"
14 #include <clAppUtils/sslAppUtils.h>
15 #include <utilLib/common.h>
16 #include <CommonCrypto/CommonDigest.h>
25 pthread_mutex_lock(&printfMutex
);
26 printf("+++ %s wrote %4lu bytes\n", who
, (unsigned long)written
);
27 pthread_mutex_unlock(&printfMutex
);
34 pthread_mutex_lock(&printfMutex
);
35 printf("+++ %s read %4lu bytes\n", who
, (unsigned long)bytesRead
);
36 pthread_mutex_unlock(&printfMutex
);
39 #else /* LOG_TOP_IO */
40 #define logWrite(who, w)
41 #define logRead(who, r)
42 #endif /* LOG_TOP_IO */
45 * Callback from ST to calculate master secret.
46 * We do a poor person's T_PRF(), taking the hash of:
48 * serverRandom | clientRandom | sharedSecret
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.
54 * We happen to have a digest that produces the required number
57 static void sslMasterSecretFunction(
59 const void *arg
, /* actually a RingBufferArgs */
60 void *secret
, /* mallocd by caller, SSL_MASTER_SECRET_SIZE */
61 size_t *secretLength
) /* in/out */
63 RingBufferArgs
*sslArgs
= (RingBufferArgs
*)arg
;
64 if(*secretLength
< SSL_MASTER_SECRET_SIZE
) {
65 printf("**Hey! insufficient space for master secret!\n");
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
;
82 /* client thread - handshake and write some data */
83 void *rbClientThread(void *arg
)
85 RingBufferArgs
*sslArgs
= (RingBufferArgs
*)arg
;
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
;
94 ortn
= SSLNewContext(false, &ctx
);
96 printSslErrStr("SSLNewContext", ortn
);
99 ortn
= SSLSetIOFuncs(ctx
, ringReadFunc
, ringWriteFunc
);
101 printSslErrStr("SSLSetIOFuncs", ortn
);
104 ortn
= SSLSetConnection(ctx
, (SSLConnectionRef
)&ringBufs
);
106 printSslErrStr("SSLSetConnection", ortn
);
109 /* EAP is TLS only - disable the SSLv2-capable handshake */
110 ortn
= SSLSetProtocolVersionEnabled(ctx
, kSSLProtocol2
, false);
112 printSslErrStr("SSLSetProtocolVersionEnabled", ortn
);
115 ortn
= SSLInternalSetMasterSecretFunction(ctx
, sslMasterSecretFunction
, sslArgs
);
117 printSslErrStr("SSLInternalSetMasterSecretFunction", ortn
);
120 ortn
= SSLInternalSetSessionTicket(ctx
, sslArgs
->sessionTicket
,
121 sslArgs
->sessionTicketLen
);
123 printSslErrStr("SSLInternalSetSessionTicket", ortn
);
126 if(sslArgs
->trustedRoots
) {
127 ortn
= SSLSetTrustedRoots(ctx
, sslArgs
->trustedRoots
, true);
129 printSslErrStr("SSLSetTrustedRoots", ortn
);
133 if(sslArgs
->hostName
) {
134 ortn
= SSLSetPeerDomainName(ctx
, sslArgs
->hostName
, strlen(sslArgs
->hostName
));
136 printSslErrStr("SSLSetPeerDomainName", ortn
);
141 /* tell main thread we're ready; wait for sync flag */
142 sslArgs
->iAmReady
= true;
143 while(!(*sslArgs
->goFlag
)) {
144 if(*sslArgs
->abortFlag
) {
150 sslArgs
->startHandshake
= CFAbsoluteTimeGetCurrent();
152 ortn
= SSLHandshake(ctx
);
153 if(*sslArgs
->abortFlag
) {
156 } while (ortn
== errSSLWouldBlock
);
159 printSslErrStr("SSLHandshake", ortn
);
163 SSLGetNegotiatedCipher(ctx
, &sslArgs
->negotiatedCipher
);
164 SSLGetNegotiatedProtocolVersion(ctx
, &sslArgs
->negotiatedProt
);
166 ortn
= SSLGetResumableSessionInfo(ctx
, &sslArgs
->sessionWasResumed
, sessionID
, &sessionIDLen
);
168 printSslErrStr("SSLGetResumableSessionInfo", ortn
);
172 sslArgs
->startData
= CFAbsoluteTimeGetCurrent();
174 toMove
= sslArgs
->xferSize
;
177 sslArgs
->endData
= sslArgs
->startData
;
183 thisMove
= sslArgs
->chunkSize
;
184 if(thisMove
> toMove
) {
188 ortn
= SSLWrite(ctx
, sslArgs
->xferBuf
, thisMove
, &moved
);
189 /* should never fail - implemented as blocking */
191 printSslErrStr("SSLWrite", ortn
);
194 logWrite("client", moved
);
196 if(*sslArgs
->abortFlag
) {
201 sslArgs
->endData
= CFAbsoluteTimeGetCurrent();
205 *sslArgs
->abortFlag
= true;
207 if(*sslArgs
->abortFlag
&& sslArgs
->pauseOnError
) {
208 /* abort for any reason - freeze! */
209 testError(CSSM_FALSE
);
213 SSLDisposeContext(ctx
);
216 printf("***Client thread returning %lu\n", (unsigned long)ortn
);
218 pthread_exit((void*)ortn
);
224 /* server function - like clientThread except it runs from the main thread */
225 /* handshake and read some data */
226 OSStatus
rbServerThread(RingBufferArgs
*sslArgs
)
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
;
236 ortn
= SSLNewContext(true, &ctx
);
238 printSslErrStr("SSLNewContext", ortn
);
241 ortn
= SSLSetIOFuncs(ctx
, ringReadFunc
, ringWriteFunc
);
243 printSslErrStr("SSLSetIOFuncs", ortn
);
246 ortn
= SSLSetConnection(ctx
, (SSLConnectionRef
)&ringBufs
);
248 printSslErrStr("SSLSetConnection", ortn
);
251 if(sslArgs
->setMasterSecret
) {
252 ortn
= SSLInternalSetMasterSecretFunction(ctx
, sslMasterSecretFunction
, sslArgs
);
254 printSslErrStr("SSLInternalSetMasterSecretFunction", ortn
);
258 if(sslArgs
->idArray
) {
259 ortn
= SSLSetCertificate(ctx
, sslArgs
->idArray
);
261 printSslErrStr("SSLSetCertificate", ortn
);
265 if(sslArgs
->trustedRoots
) {
266 ortn
= SSLSetTrustedRoots(ctx
, sslArgs
->trustedRoots
, true);
268 printSslErrStr("SSLSetTrustedRoots", ortn
);
273 /* tell client thread we're ready; wait for sync flag */
274 sslArgs
->iAmReady
= true;
275 while(!(*sslArgs
->goFlag
)) {
276 if(*sslArgs
->abortFlag
) {
282 sslArgs
->startHandshake
= CFAbsoluteTimeGetCurrent();
284 ortn
= SSLHandshake(ctx
);
285 if(*sslArgs
->abortFlag
) {
288 } while (ortn
== errSSLWouldBlock
);
291 printSslErrStr("SSLHandshake", ortn
);
295 SSLGetNegotiatedCipher(ctx
, &sslArgs
->negotiatedCipher
);
296 SSLGetNegotiatedProtocolVersion(ctx
, &sslArgs
->negotiatedProt
);
297 ortn
= SSLGetResumableSessionInfo(ctx
, &sslArgs
->sessionWasResumed
, sessionID
, &sessionIDLen
);
299 printSslErrStr("SSLGetResumableSessionInfo", ortn
);
303 sslArgs
->startData
= CFAbsoluteTimeGetCurrent();
305 toMove
= sslArgs
->xferSize
;
308 sslArgs
->endData
= sslArgs
->startData
;
314 thisMove
= sslArgs
->xferSize
;
315 if(thisMove
> toMove
) {
319 ortn
= SSLRead(ctx
, sslArgs
->xferBuf
, thisMove
, &moved
);
323 case errSSLWouldBlock
:
324 /* cool, try again */
331 printSslErrStr("SSLRead", ortn
);
334 logRead("server", moved
);
336 if(*sslArgs
->abortFlag
) {
341 sslArgs
->endData
= CFAbsoluteTimeGetCurrent();
345 *sslArgs
->abortFlag
= true;
347 if(*sslArgs
->abortFlag
&& sslArgs
->pauseOnError
) {
348 /* abort for any reason - freeze! */
349 testError(CSSM_FALSE
);
353 SSLDisposeContext(ctx
);
356 printf("***Server thread returning %lu\n", (unsigned long)ortn
);