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 Renegotiation tests:
40 Test both the client and server side.
43 - Make sure that renegotiation works on both client and server.
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
;
103 static ssl_client_handle
*
104 ssl_client_handle_create(int comm
, bool renegotiate
)
106 ssl_client_handle
*handle
= calloc(1, sizeof(ssl_client_handle
));
107 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, kSSLClientSide
, kSSLStreamType
);
109 require(handle
, out
);
112 require_noerr(SSLSetIOFuncs(ctx
,
113 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
114 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)comm
), out
);
115 static const char *peer_domain_name
= "localhost";
116 require_noerr(SSLSetPeerDomainName(ctx
, peer_domain_name
,
117 strlen(peer_domain_name
)), out
);
119 require_noerr(SSLSetSessionOption(ctx
, kSSLSessionOptionBreakOnServerAuth
, TRUE
), out
);
121 require_noerr(SSLSetAllowsAnyRoot(ctx
, TRUE
), out
);
126 handle
->renegotiate
= renegotiate
;
140 ssl_client_handle_destroy(ssl_client_handle
*handle
)
143 SSLClose(handle
->st
);
144 CFRelease(handle
->st
);
149 static void *securetransport_ssl_client_thread(void *arg
)
152 ssl_client_handle
* ssl
= (ssl_client_handle
*)arg
;
153 SSLContextRef ctx
= ssl
->st
;
154 SSLSessionState ssl_state
;
155 bool peer_auth_received
= false;
157 pthread_setname_np("client thread");
159 require_noerr(ortn
=SSLGetSessionState(ctx
,&ssl_state
), out
);
160 require_action(ssl_state
==kSSLIdle
, out
, ortn
= -1);
163 ortn
= SSLHandshake(ctx
);
164 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
166 if (ortn
== errSSLPeerAuthCompleted
) {
167 require_action(!peer_auth_received
, out
, ortn
= -1);
168 peer_auth_received
= true;
170 if (ortn
== errSSLWouldBlock
) {
171 require_string(ssl_state
==kSSLHandshake
, out
, "Wrong client handshake state after errSSLWouldBlock");
173 } while (ortn
== errSSLWouldBlock
|| ortn
== errSSLPeerAuthCompleted
);
175 require_noerr(ortn
, out
);
176 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
177 require_action(peer_auth_received
, out
, ortn
= -1);
179 if(ssl
->renegotiate
) {
180 // Renegotiate then write
181 require_noerr(SSLReHandshake(ctx
), out
);
183 peer_auth_received
= false;
186 ortn
= SSLHandshake(ctx
);
187 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
188 if (ortn
== errSSLPeerAuthCompleted
) {
189 require_action(!peer_auth_received
, out
, ortn
= -1);
190 peer_auth_received
= true;
192 if (ortn
== errSSLWouldBlock
) {
193 require_action(ssl_state
==kSSLHandshake
, out
, ortn
= -1);
195 } while (ortn
== errSSLWouldBlock
|| ortn
== errSSLPeerAuthCompleted
);
197 require_noerr(ortn
, out
);
198 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
199 require_action(peer_auth_received
, out
, ortn
= -1);
201 unsigned char obuf
[100];
203 size_t len
= sizeof(obuf
);
205 unsigned char *p
= obuf
;
207 require_action(errSecSuccess
==SecRandomCopyBytes(kSecRandomDefault
, len
, p
), out
, ortn
= -1);
210 require_noerr(ortn
= SSLWrite(ctx
, p
, len
, &olen
), out
);
216 unsigned char ibuf
[100];
218 peer_auth_received
= false;
220 size_t len
= sizeof(ibuf
);
222 unsigned char *p
= ibuf
;
224 ortn
= SSLRead(ctx
, p
, len
, &olen
);
226 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
228 if (ortn
== errSSLPeerAuthCompleted
) {
229 require_action(!peer_auth_received
, out
, ortn
= -1);
230 peer_auth_received
= true;
232 require_noerr(ortn
, out
);
235 /* If we get data, we should have renegotiated */
237 require_noerr(ortn
, out
);
238 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
239 require_action(peer_auth_received
, out
, ortn
= -1);
250 pthread_exit((void *)(intptr_t)ortn
);
262 static ssl_server_handle
*
263 ssl_server_handle_create(int comm
, CFArrayRef certs
, bool renegotiate
)
265 ssl_server_handle
*handle
= calloc(1, sizeof(ssl_server_handle
));
266 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, kSSLServerSide
, kSSLStreamType
);
267 SSLCipherSuite cipher
= TLS_RSA_WITH_AES_256_CBC_SHA256
;
269 require(handle
, out
);
272 require_noerr(SSLSetIOFuncs(ctx
,
273 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
274 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)comm
), out
);
276 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
278 require_noerr(SSLSetEnabledCiphers(ctx
, &cipher
, 1), out
);
280 require_noerr(SSLSetSessionOption(ctx
, kSSLSessionOptionBreakOnClientHello
, TRUE
), out
);
281 require_noerr(SSLSetSessionOption(ctx
, kSSLSessionOptionAllowRenegotiation
, TRUE
), out
);
284 handle
->certs
= certs
;
286 handle
->renegotiate
= renegotiate
;
300 ssl_server_handle_destroy(ssl_server_handle
*handle
)
303 SSLClose(handle
->st
);
304 CFRelease(handle
->st
);
309 static void *securetransport_ssl_server_thread(void *arg
)
312 ssl_server_handle
* ssl
= (ssl_server_handle
*)arg
;
313 SSLContextRef ctx
= ssl
->st
;
314 SSLSessionState ssl_state
;
315 bool client_hello_received
= false;
317 pthread_setname_np("server thread");
319 require_noerr(ortn
=SSLGetSessionState(ctx
,&ssl_state
), out
);
320 require_action(ssl_state
==kSSLIdle
, out
, ortn
= -1);
323 ortn
= SSLHandshake(ctx
);
324 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
325 if (ortn
== errSSLClientHelloReceived
) {
326 require_action(!client_hello_received
, out
, ortn
= -1);
327 client_hello_received
= true;
329 if (ortn
== errSSLWouldBlock
) {
330 require_action(ssl_state
==kSSLHandshake
, out
, ortn
= -1);
332 } while (ortn
== errSSLWouldBlock
|| ortn
== errSSLClientHelloReceived
);
334 require_noerr(ortn
, out
);
335 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
336 require_action(client_hello_received
, out
, ortn
= -1);
338 if(ssl
->renegotiate
) {
339 // Renegotiate then write
340 require_noerr(SSLReHandshake(ctx
), out
);
342 client_hello_received
= false;
345 ortn
= SSLHandshake(ctx
);
346 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
347 if (ortn
== errSSLClientHelloReceived
) {
348 require_action(!client_hello_received
, out
, ortn
= -1);
349 client_hello_received
= true;
351 if (ortn
== errSSLWouldBlock
) {
352 require_action(ssl_state
==kSSLHandshake
, out
, ortn
= -1);
354 } while (ortn
== errSSLWouldBlock
|| ortn
== errSSLClientHelloReceived
);
356 require_noerr(ortn
, out
);
357 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
358 require_action(client_hello_received
, out
, ortn
= -1);
360 unsigned char obuf
[100];
362 size_t len
= sizeof(obuf
);
364 unsigned char *p
= obuf
;
366 require_action(errSecSuccess
==SecRandomCopyBytes(kSecRandomDefault
, len
, p
), out
, ortn
= -1);
369 require_noerr(ortn
= SSLWrite(ctx
, p
, len
, &olen
), out
);
375 unsigned char ibuf
[100];
377 client_hello_received
= false;
379 size_t len
= sizeof(ibuf
);
381 unsigned char *p
= ibuf
;
383 ortn
= SSLRead(ctx
, p
, len
, &olen
);
385 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
387 if (ortn
== errSSLClientHelloReceived
) {
388 require_action(!client_hello_received
, out
, ortn
= -1);
389 client_hello_received
= true;
391 require_noerr(ortn
, out
);
394 /* If we get data, we should have renegotiated */
396 require_noerr(ortn
, out
);
397 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
398 require_action(client_hello_received
, out
, ortn
= -1);
409 pthread_exit((void *)(intptr_t)ortn
);
415 test_renego(bool client_renego
)
417 pthread_t client_thread
, server_thread
;
418 CFArrayRef server_certs
= server_chain();
420 ok(server_certs
, "renego: got server certs");
424 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
425 fcntl(sp
[0], F_SETNOSIGPIPE
, 1);
426 fcntl(sp
[1], F_SETNOSIGPIPE
, 1);
428 ssl_client_handle
*client
;
429 client
= ssl_client_handle_create(sp
[0], client_renego
);
430 ok(client
!=NULL
, "renego: could not create client handle");
433 ssl_server_handle
*server
;
434 server
= ssl_server_handle_create(sp
[1], server_certs
, !client_renego
);
435 ok(server
!=NULL
, "renego: could not create server handle");
437 pthread_create(&client_thread
, NULL
, securetransport_ssl_client_thread
, client
);
438 pthread_create(&server_thread
, NULL
, securetransport_ssl_server_thread
, server
);
440 intptr_t server_err
, client_err
;
442 pthread_join(client_thread
, (void*)&client_err
);
443 pthread_join(server_thread
, (void*)&server_err
);
445 ok(client_err
==0, "renego: unexpected error %ld (client)", client_err
);
446 ok(server_err
==0, "renego: unexpected error %ld (server)", server_err
);
448 ssl_server_handle_destroy(server
);
449 ssl_client_handle_destroy(client
);
452 CFReleaseSafe(server_certs
);
456 int ssl_56_renegotiate(int argc
, char *const *argv
)
460 test_renego(false); // server side trigger renego.
461 test_renego(true); // client side trigger renego.