8 #include <CoreFoundation/CoreFoundation.h>
10 #include <AssertMacros.h>
11 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
12 #include <Security/SecureTransport.h>
13 #include <Security/SecPolicy.h>
14 #include <Security/SecTrust.h>
15 #include <Security/SecIdentity.h>
16 #include <Security/SecIdentityPriv.h>
17 #include <Security/SecCertificatePriv.h>
18 #include <Security/SecKeyPriv.h>
19 #include <Security/SecItem.h>
20 #include <Security/SecRandom.h>
22 #include <utilities/array_size.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
28 #include <mach/mach_time.h>
31 #include <Security/SecRSAKey.h>
34 #include "ssl_regressions.h"
35 #include "ssl-utils.h"
38 SSL Session Cache tests:
40 Test both the client and server side.
43 - Make sure that resumption fails after session cache TTL.
46 - handshake pass or fail
51 static OSStatus
SocketWrite(SSLConnectionRef conn
, const void *data
, size_t *length
)
54 uint8_t *ptr
= (uint8_t *)data
;
59 ret
= write((int)conn
, ptr
, len
);
60 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
69 *length
= *length
- len
;
73 static OSStatus
SocketRead(SSLConnectionRef conn
, void *data
, size_t *length
)
76 uint8_t *ptr
= (uint8_t *)data
;
81 ret
= read((int)conn
, ptr
, len
);
82 } while ((ret
< 0) && (errno
== EINPROGRESS
|| errno
== EAGAIN
|| errno
== EINTR
));
87 printf("read error(%d): ret=%zd, errno=%d\n", (int)conn
, ret
, errno
);
92 *length
= *length
- len
;
102 static ssl_client_handle
*
103 ssl_client_handle_create(int comm
, CFArrayRef trustedCA
, uint32_t cache_ttl
, uintptr_t peerID
)
105 ssl_client_handle
*handle
= calloc(1, sizeof(ssl_client_handle
));
106 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, kSSLClientSide
, kSSLStreamType
);
108 require(handle
, out
);
111 require_noerr(SSLSetIOFuncs(ctx
,
112 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
113 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)comm
), out
);
114 static const char *peer_domain_name
= "localhost";
115 require_noerr(SSLSetPeerDomainName(ctx
, peer_domain_name
,
116 strlen(peer_domain_name
)), out
);
118 require_noerr(SSLSetTrustedRoots(ctx
, trustedCA
, true), out
);
120 require_noerr(SSLSetSessionCacheTimeout(ctx
, cache_ttl
), out
);
122 require_noerr(SSLSetPeerID(ctx
, &peerID
, sizeof(peerID
)), out
);
139 ssl_client_handle_destroy(ssl_client_handle
*handle
)
142 SSLClose(handle
->st
);
143 CFRelease(handle
->st
);
148 static void *securetransport_ssl_client_thread(void *arg
)
151 ssl_client_handle
* ssl
= (ssl_client_handle
*)arg
;
152 SSLContextRef ctx
= ssl
->st
;
153 SSLSessionState ssl_state
;
155 pthread_setname_np("client thread");
157 require_noerr(ortn
=SSLGetSessionState(ctx
,&ssl_state
), out
);
158 require_action(ssl_state
==kSSLIdle
, out
, ortn
= -1);
161 ortn
= SSLHandshake(ctx
);
162 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
164 if (ortn
== errSSLWouldBlock
) {
165 require_string(ssl_state
==kSSLHandshake
, out
, "Wrong client handshake state after errSSLWouldBlock");
167 } while (ortn
== errSSLWouldBlock
);
172 pthread_exit((void *)(intptr_t)ortn
);
184 static ssl_server_handle
*
185 ssl_server_handle_create(int comm
, CFArrayRef certs
, uint32_t cache_ttl
)
187 ssl_server_handle
*handle
= calloc(1, sizeof(ssl_server_handle
));
188 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, kSSLServerSide
, kSSLStreamType
);
189 SSLCipherSuite cipher
= TLS_RSA_WITH_AES_256_CBC_SHA256
;
190 uintptr_t peerID
= 0xdeadbeef;
192 require(handle
, out
);
195 require_noerr(SSLSetIOFuncs(ctx
,
196 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
197 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)comm
), out
);
199 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
201 require_noerr(SSLSetEnabledCiphers(ctx
, &cipher
, 1), out
);
203 require_noerr(SSLSetSessionCacheTimeout(ctx
, cache_ttl
), out
);
205 require_noerr(SSLSetPeerID(ctx
, &peerID
, sizeof(peerID
)), out
);
208 handle
->certs
= certs
;
223 ssl_server_handle_destroy(ssl_server_handle
*handle
)
226 SSLClose(handle
->st
);
227 CFRelease(handle
->st
);
232 static void *securetransport_ssl_server_thread(void *arg
)
235 ssl_server_handle
* ssl
= (ssl_server_handle
*)arg
;
236 SSLContextRef ctx
= ssl
->st
;
237 SSLSessionState ssl_state
;
239 pthread_setname_np("server thread");
241 require_noerr(ortn
=SSLGetSessionState(ctx
,&ssl_state
), out
);
242 require_action(ssl_state
==kSSLIdle
, out
, ortn
= -1);
245 ortn
= SSLHandshake(ctx
);
246 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
248 if (ortn
== errSSLWouldBlock
) {
249 require_action(ssl_state
==kSSLHandshake
, out
, ortn
= -1);
251 } while (ortn
== errSSLWouldBlock
);
253 require_noerr_quiet(ortn
, out
);
255 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
260 pthread_exit((void *)(intptr_t)ortn
);
268 pthread_t client_thread
, server_thread
;
269 CFArrayRef server_certs
= server_chain();
270 CFArrayRef trusted_ca
= trusted_roots();
272 ok(server_certs
, "got server certs");
273 ok(trusted_ca
, "got trusted roots");
277 for (i
=0; i
<2; i
++) {
278 for (j
=0; j
<2; j
++) {
279 for (k
=0; k
<2; k
++) {
282 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
283 fcntl(sp
[0], F_SETNOSIGPIPE
, 1);
284 fcntl(sp
[1], F_SETNOSIGPIPE
, 1);
286 ssl_client_handle
*client
;
287 client
= ssl_client_handle_create(sp
[0], trusted_ca
, i
, (i
<<8)|(j
+1));
288 ok(client
!=NULL
, "could not create client handle (%d:%d:%d)", i
, j
, k
);
291 ssl_server_handle
*server
;
292 server
= ssl_server_handle_create(sp
[1], server_certs
, j
);
293 ok(server
!=NULL
, "could not create server handle (%d:%d:%d)", i
, j
, k
);
295 pthread_create(&client_thread
, NULL
, securetransport_ssl_client_thread
, client
);
296 pthread_create(&server_thread
, NULL
, securetransport_ssl_server_thread
, server
);
298 intptr_t server_err
, client_err
;
300 pthread_join(client_thread
, (void*)&client_err
);
301 pthread_join(server_thread
, (void*)&server_err
);
304 unsigned char sessionID
[32];
305 size_t sessionIDLength
= sizeof(sessionID
);
307 ok(client_err
==0, "unexpected error %ld (client %d:%d:%d)", client_err
, i
, j
, k
);
308 ok(server_err
==0, "unexpected error %ld (server %d:%d:%d)", server_err
, i
, j
, k
);
309 ok_status(SSLGetResumableSessionInfo(client
->st
, &resumed
, sessionID
, &sessionIDLength
), "SSLGetResumableSessionInfo");
311 ok(i
|| j
|| (!k
) || resumed
, "Unexpected resumption state=%d (%d:%d:%d)", resumed
, i
, j
, k
);
313 ssl_server_handle_destroy(server
);
314 ssl_client_handle_destroy(client
);
318 /* Sleep one second so that Session cache TTL can expire */
324 CFReleaseSafe(server_certs
);
325 CFReleaseSafe(trusted_ca
);
328 int ssl_55_sessioncache(int argc
, char *const *argv
)
331 plan_tests(6 * 8 + 2 /*cert*/);