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
);
154 SSLDisposeContext(ctx
);
157 pthread_exit((void *)(intptr_t)ortn
);
161 static void *securetransport_client_thread(void *arg
)
164 ssl_test_handle
* ssl
= (ssl_test_handle
*)arg
;
165 SSLContextRef ctx
= ssl
->handle
;
168 ortn
= SSLHandshake(ctx
);
169 } while (ortn
== errSSLWouldBlock
|| ortn
!= errSSLClosedGraceful
);
172 SSLDisposeContext(ctx
);
175 pthread_exit((void *)(intptr_t)ortn
);
179 static SSLCipherSuite ciphers
[] = {
180 TLS_RSA_WITH_AES_128_CBC_SHA
,
181 //FIXME: re-enable this test when its fixed.
182 //TLS_RSA_WITH_RC4_128_SHA,
185 static ssl_test_handle
*
186 ssl_test_handle_create(uint32_t session_id
, bool server
, int comm
)
188 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
189 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, server
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
191 require(handle
, out
);
194 require_noerr(SSLSetIOFuncs(ctx
,
195 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
196 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)comm
), out
);
199 require_noerr(SSLSetSessionOption(ctx
,
200 kSSLSessionOptionBreakOnClientHello
, true), out
);
202 require_noerr(SSLSetSessionOption(ctx
,
203 kSSLSessionOptionBreakOnServerAuth
, true), out
);
205 /* Tell SecureTransport to not check certs itself: it will break out of the
206 handshake to let us take care of it instead. */
207 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
209 handle
->handle
= ctx
;
210 handle
->is_server
= server
;
211 handle
->session_id
= session_id
;
217 if (ctx
) CFRelease(ctx
);
221 static SSLProtocol versions
[] = {
227 static int nversions
= sizeof(versions
)/sizeof(versions
[0]);
233 pthread_t client_thread
, server_thread
;
235 for(j
=0; j
<nversions
; j
++)
238 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
240 ssl_test_handle
*server
, *client
;
242 uint32_t session_id
= (j
+1) << 16 | 1 << 8;
243 server
= ssl_test_handle_create(session_id
, true /*server*/, sp
[0]);
244 client
= ssl_test_handle_create(session_id
, false/*client*/, sp
[1]);
246 require_noerr(SSLSetPeerID(server
->handle
, &session_id
, sizeof(session_id
)), out
);
247 require_noerr(SSLSetPeerID(client
->handle
, &session_id
, sizeof(session_id
)), out
);
249 /* set fixed cipher on client and server */
250 require_noerr(SSLSetEnabledCiphers(client
->handle
, &ciphers
[0], 1), out
);
251 require_noerr(SSLSetEnabledCiphers(server
->handle
, &ciphers
[0], 1), out
);
253 require_noerr(SSLSetProtocolVersionMax(client
->handle
, versions
[j
]), out
);
254 require_noerr(SSLSetPeerDomainName(client
->handle
, peername
, sizeof(peername
)), out
);
256 require_noerr(SSLSetProtocolVersionMax(server
->handle
, versions
[j
]), out
);
258 pthread_create(&client_thread
, NULL
, securetransport_client_thread
, client
);
259 pthread_create(&server_thread
, NULL
, securetransport_server_thread
, server
);
261 int server_err
, client_err
;
262 pthread_join(client_thread
, (void*)&client_err
);
263 pthread_join(server_thread
, (void*)&server_err
);
272 int ssl_49_sni(int argc
, char *const *argv
)