14 #include <CoreFoundation/CoreFoundation.h>
16 #include <AssertMacros.h>
17 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
18 #include <Security/SecureTransport.h>
19 #include <Security/SecPolicy.h>
20 #include <Security/SecTrust.h>
21 #include <Security/SecIdentity.h>
22 #include <Security/SecIdentityPriv.h>
23 #include <Security/SecCertificatePriv.h>
24 #include <Security/SecKeyPriv.h>
25 #include <Security/SecItem.h>
26 #include <Security/SecRandom.h>
29 #include <sys/types.h>
30 #include <sys/socket.h>
33 #include <mach/mach_time.h>
36 #include <Security/SecRSAKey.h>
39 #include "ssl_regressions.h"
40 #include "ssl-utils.h"
51 #pragma mark SecureTransport support
54 static void hexdump(const uint8_t *bytes
, size_t len
) {
56 printf("socket write(%p, %lu)\n", bytes
, len
);
57 for (ix
= 0; ix
< len
; ++ix
) {
60 printf("%02X ", bytes
[ix
]);
65 #define hexdump(bytes, len)
69 static OSStatus
SocketWrite(SSLConnectionRef h
, const void *data
, size_t *length
)
72 uint8_t *ptr
= (uint8_t *)data
;
78 ret
= write((int)h
, ptr
, len
);
79 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
88 *length
= *length
- len
;
92 static OSStatus
SocketRead(SSLConnectionRef h
, void *data
, size_t *length
)
95 uint8_t *ptr
= (uint8_t *)data
;
100 ret
= read((int)h
, ptr
, len
);
101 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
106 printf("read error(%d): ret=%zd, errno=%d\n", (int)h
, ret
, errno
);
111 *length
= *length
- len
;
112 return errSecSuccess
;
115 static char peername
[] = "localhost";
117 static void *securetransport_server_thread(void *arg
)
120 ssl_test_handle
* ssl
= (ssl_test_handle
*)arg
;
121 SSLContextRef ctx
= ssl
->handle
;
122 CFArrayRef server_certs
= server_chain();
125 ortn
= SSLHandshake(ctx
);
126 } while (ortn
== errSSLWouldBlock
);
128 ok(ortn
==errSSLClientHelloReceived
, "Unexpected Handshake exit code");
130 if (ortn
== errSSLClientHelloReceived
) {
133 SSLCopyRequestedPeerNameLength(ctx
, &length
);
135 sni
= malloc(length
);
136 SSLCopyRequestedPeerName(ctx
, sni
, &length
);
139 SSLProtocol version
= 0;
140 require_noerr(SSLGetProtocolVersionMax(ctx
, &version
), out
);
141 if (version
== kSSLProtocol3
) {
142 ok(sni
==NULL
, "Unexpected SNI");
145 length
== sizeof(peername
) &&
146 (memcmp(sni
, peername
, sizeof(peername
))==0),
147 "SNI does not match");
149 require_noerr(SSLSetCertificate(ctx
, server_certs
), out
);
155 SSLDisposeContext(ctx
);
157 CFReleaseSafe(server_certs
);
159 pthread_exit((void *)(intptr_t)ortn
);
163 static void *securetransport_client_thread(void *arg
)
166 ssl_test_handle
* ssl
= (ssl_test_handle
*)arg
;
167 SSLContextRef ctx
= ssl
->handle
;
170 ortn
= SSLHandshake(ctx
);
171 } while (ortn
== errSSLWouldBlock
|| ortn
!= errSSLClosedGraceful
);
174 SSLDisposeContext(ctx
);
177 pthread_exit((void *)(intptr_t)ortn
);
181 static SSLCipherSuite ciphers
[] = {
182 TLS_RSA_WITH_AES_128_CBC_SHA
,
183 //FIXME: re-enable this test when its fixed.
184 //TLS_RSA_WITH_RC4_128_SHA,
187 static ssl_test_handle
*
188 ssl_test_handle_create(uint32_t session_id
, bool server
, int comm
)
190 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
191 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, server
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
193 require(handle
, out
);
196 require_noerr(SSLSetIOFuncs(ctx
,
197 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
198 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)comm
), out
);
201 require_noerr(SSLSetSessionOption(ctx
,
202 kSSLSessionOptionBreakOnClientHello
, true), out
);
204 require_noerr(SSLSetSessionOption(ctx
,
205 kSSLSessionOptionBreakOnServerAuth
, true), out
);
207 /* Tell SecureTransport to not check certs itself: it will break out of the
208 handshake to let us take care of it instead. */
209 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
211 handle
->handle
= ctx
;
212 handle
->is_server
= server
;
213 handle
->session_id
= session_id
;
219 if (handle
) free(handle
);
220 if (ctx
) CFRelease(ctx
);
224 static SSLProtocol versions
[] = {
230 static int nversions
= sizeof(versions
)/sizeof(versions
[0]);
236 pthread_t client_thread
, server_thread
;
238 for(j
=0; j
<nversions
; j
++)
241 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
243 ssl_test_handle
*server
, *client
;
245 uint32_t session_id
= (j
+1) << 16 | 1 << 8;
246 server
= ssl_test_handle_create(session_id
, true /*server*/, sp
[0]);
247 client
= ssl_test_handle_create(session_id
, false/*client*/, sp
[1]);
249 require_noerr(SSLSetPeerID(server
->handle
, &session_id
, sizeof(session_id
)), out
);
250 require_noerr(SSLSetPeerID(client
->handle
, &session_id
, sizeof(session_id
)), out
);
252 /* set fixed cipher on client and server */
253 require_noerr(SSLSetEnabledCiphers(client
->handle
, &ciphers
[0], 1), out
);
254 require_noerr(SSLSetEnabledCiphers(server
->handle
, &ciphers
[0], 1), out
);
256 require_noerr(SSLSetProtocolVersionMax(client
->handle
, versions
[j
]), out
);
257 require_noerr(SSLSetPeerDomainName(client
->handle
, peername
, sizeof(peername
)), out
);
259 require_noerr(SSLSetProtocolVersionMax(server
->handle
, versions
[j
]), out
);
261 pthread_create(&client_thread
, NULL
, securetransport_client_thread
, client
);
262 pthread_create(&server_thread
, NULL
, securetransport_server_thread
, server
);
264 intptr_t server_err
, client_err
;
265 pthread_join(client_thread
, (void*)&client_err
);
266 pthread_join(server_thread
, (void*)&server_err
);
275 int ssl_49_sni(int argc
, char *const *argv
)