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>
23 #include <utilities/SecCFRelease.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
29 #include <mach/mach_time.h>
32 #include <Security/SecRSAKey.h>
35 #include "ssl_regressions.h"
36 #include "ssl-utils.h"
39 SSL Renegotiation tests:
41 Test both the client and server side.
44 - Make sure that renegotiation works on both client and server.
47 - handshake pass or fail
52 static OSStatus
SocketWrite(SSLConnectionRef conn
, const void *data
, size_t *length
)
55 uint8_t *ptr
= (uint8_t *)data
;
60 ret
= write((int)conn
, ptr
, len
);
61 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
70 *length
= *length
- len
;
74 static OSStatus
SocketRead(SSLConnectionRef conn
, void *data
, size_t *length
)
77 uint8_t *ptr
= (uint8_t *)data
;
82 ret
= read((int)conn
, ptr
, len
);
83 } while ((ret
< 0) && (errno
== EINPROGRESS
|| errno
== EAGAIN
|| errno
== EINTR
));
88 printf("read error(%d): ret=%zd, errno=%d\n", (int)conn
, ret
, errno
);
93 *length
= *length
- len
;
104 static ssl_client_handle
*
105 ssl_client_handle_create(int comm
, bool renegotiate
)
107 ssl_client_handle
*handle
= calloc(1, sizeof(ssl_client_handle
));
108 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, kSSLClientSide
, kSSLStreamType
);
110 require(handle
, out
);
113 require_noerr(SSLSetIOFuncs(ctx
,
114 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
115 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)comm
), out
);
116 static const char *peer_domain_name
= "localhost";
117 require_noerr(SSLSetPeerDomainName(ctx
, peer_domain_name
,
118 strlen(peer_domain_name
)), out
);
120 require_noerr(SSLSetSessionOption(ctx
, kSSLSessionOptionBreakOnServerAuth
, TRUE
), out
);
122 require_noerr(SSLSetAllowsAnyRoot(ctx
, TRUE
), out
);
127 handle
->renegotiate
= renegotiate
;
141 ssl_client_handle_destroy(ssl_client_handle
*handle
)
144 SSLClose(handle
->st
);
145 CFRelease(handle
->st
);
150 static void *securetransport_ssl_client_thread(void *arg
)
153 ssl_client_handle
* ssl
= (ssl_client_handle
*)arg
;
154 SSLContextRef ctx
= ssl
->st
;
155 SSLSessionState ssl_state
;
156 bool peer_auth_received
= false;
158 pthread_setname_np("client thread");
160 require_noerr(ortn
=SSLGetSessionState(ctx
,&ssl_state
), out
);
161 require_action(ssl_state
==kSSLIdle
, out
, ortn
= -1);
164 ortn
= SSLHandshake(ctx
);
165 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
167 if (ortn
== errSSLPeerAuthCompleted
) {
168 require_action(!peer_auth_received
, out
, ortn
= -1);
169 peer_auth_received
= true;
171 if (ortn
== errSSLWouldBlock
) {
172 require_string(ssl_state
==kSSLHandshake
, out
, "Wrong client handshake state after errSSLWouldBlock");
174 } while (ortn
== errSSLWouldBlock
|| ortn
== errSSLPeerAuthCompleted
);
176 require_noerr(ortn
, out
);
177 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
178 require_action(peer_auth_received
, out
, ortn
= -1);
180 if(ssl
->renegotiate
) {
181 // Renegotiate then write
182 require_noerr(SSLReHandshake(ctx
), out
);
184 peer_auth_received
= false;
187 ortn
= SSLHandshake(ctx
);
188 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
189 if (ortn
== errSSLPeerAuthCompleted
) {
190 require_action(!peer_auth_received
, out
, ortn
= -1);
191 peer_auth_received
= true;
193 if (ortn
== errSSLWouldBlock
) {
194 require_action(ssl_state
==kSSLHandshake
, out
, ortn
= -1);
196 } while (ortn
== errSSLWouldBlock
|| ortn
== errSSLPeerAuthCompleted
);
198 require_noerr(ortn
, out
);
199 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
200 require_action(peer_auth_received
, out
, ortn
= -1);
202 unsigned char obuf
[100];
204 size_t len
= sizeof(obuf
);
206 unsigned char *p
= obuf
;
208 require_action(errSecSuccess
==SecRandomCopyBytes(kSecRandomDefault
, len
, p
), out
, ortn
= -1);
211 require_noerr(ortn
= SSLWrite(ctx
, p
, len
, &olen
), out
);
217 unsigned char ibuf
[100];
219 peer_auth_received
= false;
221 size_t len
= sizeof(ibuf
);
223 unsigned char *p
= ibuf
;
225 ortn
= SSLRead(ctx
, p
, len
, &olen
);
227 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
229 if (ortn
== errSSLPeerAuthCompleted
) {
230 require_action(!peer_auth_received
, out
, ortn
= -1);
231 peer_auth_received
= true;
233 require_noerr(ortn
, out
);
236 /* If we get data, we should have renegotiated */
238 require_noerr(ortn
, out
);
239 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
240 require_action(peer_auth_received
, out
, ortn
= -1);
251 pthread_exit((void *)(intptr_t)ortn
);
263 static ssl_server_handle
*
264 ssl_server_handle_create(int comm
, CFArrayRef certs
, bool renegotiate
)
266 ssl_server_handle
*handle
= calloc(1, sizeof(ssl_server_handle
));
267 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, kSSLServerSide
, kSSLStreamType
);
268 SSLCipherSuite cipher
= TLS_RSA_WITH_AES_256_CBC_SHA256
;
270 require(handle
, out
);
273 require_noerr(SSLSetIOFuncs(ctx
,
274 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
275 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)comm
), out
);
277 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
279 require_noerr(SSLSetEnabledCiphers(ctx
, &cipher
, 1), out
);
281 require_noerr(SSLSetSessionOption(ctx
, kSSLSessionOptionBreakOnClientHello
, TRUE
), out
);
282 require_noerr(SSLSetSessionOption(ctx
, kSSLSessionOptionAllowRenegotiation
, TRUE
), out
);
285 handle
->certs
= certs
;
287 handle
->renegotiate
= renegotiate
;
301 ssl_server_handle_destroy(ssl_server_handle
*handle
)
304 SSLClose(handle
->st
);
305 CFRelease(handle
->st
);
310 static void *securetransport_ssl_server_thread(void *arg
)
313 ssl_server_handle
* ssl
= (ssl_server_handle
*)arg
;
314 SSLContextRef ctx
= ssl
->st
;
315 SSLSessionState ssl_state
;
316 bool client_hello_received
= false;
318 pthread_setname_np("server thread");
320 require_noerr(ortn
=SSLGetSessionState(ctx
,&ssl_state
), out
);
321 require_action(ssl_state
==kSSLIdle
, out
, ortn
= -1);
324 ortn
= SSLHandshake(ctx
);
325 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
326 if (ortn
== errSSLClientHelloReceived
) {
327 require_action(!client_hello_received
, out
, ortn
= -1);
328 client_hello_received
= true;
330 if (ortn
== errSSLWouldBlock
) {
331 require_action(ssl_state
==kSSLHandshake
, out
, ortn
= -1);
333 } while (ortn
== errSSLWouldBlock
|| ortn
== errSSLClientHelloReceived
);
335 require_noerr(ortn
, out
);
336 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
337 require_action(client_hello_received
, out
, ortn
= -1);
339 if(ssl
->renegotiate
) {
340 // Renegotiate then write
341 require_noerr(SSLReHandshake(ctx
), out
);
343 client_hello_received
= false;
346 ortn
= SSLHandshake(ctx
);
347 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
348 if (ortn
== errSSLClientHelloReceived
) {
349 require_action(!client_hello_received
, out
, ortn
= -1);
350 client_hello_received
= true;
352 if (ortn
== errSSLWouldBlock
) {
353 require_action(ssl_state
==kSSLHandshake
, out
, ortn
= -1);
355 } while (ortn
== errSSLWouldBlock
|| ortn
== errSSLClientHelloReceived
);
357 require_noerr(ortn
, out
);
358 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
359 require_action(client_hello_received
, out
, ortn
= -1);
361 unsigned char obuf
[100];
363 size_t len
= sizeof(obuf
);
365 unsigned char *p
= obuf
;
367 require_action(errSecSuccess
==SecRandomCopyBytes(kSecRandomDefault
, len
, p
), out
, ortn
= -1);
370 require_noerr(ortn
= SSLWrite(ctx
, p
, len
, &olen
), out
);
376 unsigned char ibuf
[100];
378 client_hello_received
= false;
380 size_t len
= sizeof(ibuf
);
382 unsigned char *p
= ibuf
;
384 ortn
= SSLRead(ctx
, p
, len
, &olen
);
386 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
388 if (ortn
== errSSLClientHelloReceived
) {
389 require_action(!client_hello_received
, out
, ortn
= -1);
390 client_hello_received
= true;
392 require_noerr(ortn
, out
);
395 /* If we get data, we should have renegotiated */
397 require_noerr(ortn
, out
);
398 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
399 require_action(client_hello_received
, out
, ortn
= -1);
410 pthread_exit((void *)(intptr_t)ortn
);
416 test_renego(bool client_renego
)
418 pthread_t client_thread
, server_thread
;
419 CFArrayRef server_certs
= server_chain();
421 ok(server_certs
, "renego: got server certs");
425 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
426 fcntl(sp
[0], F_SETNOSIGPIPE
, 1);
427 fcntl(sp
[1], F_SETNOSIGPIPE
, 1);
429 ssl_client_handle
*client
;
430 client
= ssl_client_handle_create(sp
[0], client_renego
);
431 ok(client
!=NULL
, "renego: could not create client handle");
434 ssl_server_handle
*server
;
435 server
= ssl_server_handle_create(sp
[1], server_certs
, !client_renego
);
436 ok(server
!=NULL
, "renego: could not create server handle");
438 pthread_create(&client_thread
, NULL
, securetransport_ssl_client_thread
, client
);
439 pthread_create(&server_thread
, NULL
, securetransport_ssl_server_thread
, server
);
441 intptr_t server_err
, client_err
;
443 pthread_join(client_thread
, (void*)&client_err
);
444 pthread_join(server_thread
, (void*)&server_err
);
446 ok(client_err
==0, "renego: unexpected error %ld (client)", client_err
);
447 ok(server_err
==0, "renego: unexpected error %ld (server)", server_err
);
449 ssl_server_handle_destroy(server
);
450 ssl_client_handle_destroy(client
);
453 CFReleaseSafe(server_certs
);
457 int ssl_56_renegotiate(int argc
, char *const *argv
)
461 test_renego(false); // server side trigger renego.
462 test_renego(true); // client side trigger renego.