]> git.saurik.com Git - apple/security.git/blame - OSX/libsecurity_ssl/regressions/ssl-49-sni.c
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / libsecurity_ssl / regressions / ssl-49-sni.c
CommitLineData
5c19dc3a
A
1//
2// ssl-49-sni.c
3// libsecurity_ssl
4//
5//
6
7
8#include <stdbool.h>
9#include <pthread.h>
10#include <fcntl.h>
11#include <sys/mman.h>
12#include <unistd.h>
13
14#include <CoreFoundation/CoreFoundation.h>
15
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>
27
b54c578e 28#include <utilities/SecCFRelease.h>
5c19dc3a
A
29#include <string.h>
30#include <sys/types.h>
31#include <sys/socket.h>
32#include <errno.h>
33#include <stdlib.h>
34#include <mach/mach_time.h>
35
36#if TARGET_OS_IPHONE
37#include <Security/SecRSAKey.h>
38#endif
39
40#include "ssl_regressions.h"
41#include "ssl-utils.h"
42
43typedef struct {
44 SSLContextRef handle;
45 uint32_t session_id;
46 bool is_server;
47 int comm;
48} ssl_test_handle;
49
50
51#pragma mark -
52#pragma mark SecureTransport support
53
54#if 0
55static void hexdump(const uint8_t *bytes, size_t len) {
56 size_t ix;
57 printf("socket write(%p, %lu)\n", bytes, len);
58 for (ix = 0; ix < len; ++ix) {
59 if (!(ix % 16))
60 printf("\n");
61 printf("%02X ", bytes[ix]);
62 }
63 printf("\n");
64}
65#else
66#define hexdump(bytes, len)
67#endif
68
69
70static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length)
71{
72 size_t len = *length;
73 uint8_t *ptr = (uint8_t *)data;
74
75 do {
76 ssize_t ret;
77 do {
78 hexdump(ptr, len);
79 ret = write((int)h, ptr, len);
80 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
81 if (ret > 0) {
82 len -= ret;
83 ptr += ret;
84 }
85 else
86 return -36;
87 } while (len > 0);
88
89 *length = *length - len;
90 return errSecSuccess;
91}
92
93static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length)
94{
95 size_t len = *length;
96 uint8_t *ptr = (uint8_t *)data;
97
98 do {
99 ssize_t ret;
100 do {
101 ret = read((int)h, ptr, len);
102 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
103 if (ret > 0) {
104 len -= ret;
105 ptr += ret;
106 } else {
107 printf("read error(%d): ret=%zd, errno=%d\n", (int)h, ret, errno);
108 return -errno;
109 }
110 } while (len > 0);
111
112 *length = *length - len;
113 return errSecSuccess;
114}
115
116static char peername[] = "localhost";
117
118static void *securetransport_server_thread(void *arg)
119{
120 OSStatus ortn;
121 ssl_test_handle * ssl = (ssl_test_handle *)arg;
122 SSLContextRef ctx = ssl->handle;
123 CFArrayRef server_certs = server_chain();
124
125 do {
126 ortn = SSLHandshake(ctx);
127 } while (ortn == errSSLWouldBlock);
128
129 ok(ortn==errSSLClientHelloReceived, "Unexpected Handshake exit code");
130
131 if (ortn == errSSLClientHelloReceived) {
132 char *sni = NULL;
133 size_t length = 0;
134 SSLCopyRequestedPeerNameLength(ctx, &length);
135 if (length > 0) {
136 sni = malloc(length);
137 SSLCopyRequestedPeerName(ctx, sni, &length);
138 }
139
140 SSLProtocol version = 0;
141 require_noerr(SSLGetProtocolVersionMax(ctx, &version), out);
142 if (version == kSSLProtocol3) {
143 ok(sni==NULL, "Unexpected SNI");
144 } else {
145 ok(sni!=NULL &&
146 length == sizeof(peername) &&
147 (memcmp(sni, peername, sizeof(peername))==0),
148 "SNI does not match");
149 }
150 require_noerr(SSLSetCertificate(ctx, server_certs), out);
fa7225c8 151 free(sni);
5c19dc3a
A
152 }
153
154out:
155 SSLClose(ctx);
156 SSLDisposeContext(ctx);
157 close(ssl->comm);
fa7225c8 158 CFReleaseSafe(server_certs);
5c19dc3a
A
159
160 pthread_exit((void *)(intptr_t)ortn);
161 return NULL;
162}
163
164static void *securetransport_client_thread(void *arg)
165{
166 OSStatus ortn;
167 ssl_test_handle * ssl = (ssl_test_handle *)arg;
168 SSLContextRef ctx = ssl->handle;
169
170 do {
171 ortn = SSLHandshake(ctx);
172 } while (ortn == errSSLWouldBlock || ortn != errSSLClosedGraceful);
173
174 SSLClose(ctx);
175 SSLDisposeContext(ctx);
176 close(ssl->comm);
177
178 pthread_exit((void *)(intptr_t)ortn);
179 return NULL;
180}
181
182static SSLCipherSuite ciphers[] = {
183 TLS_RSA_WITH_AES_128_CBC_SHA,
184 //FIXME: re-enable this test when its fixed.
185 //TLS_RSA_WITH_RC4_128_SHA,
186};
187
188static ssl_test_handle *
189ssl_test_handle_create(uint32_t session_id, bool server, int comm)
190{
191 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
192 SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType);
193
194 require(handle, out);
195 require(ctx, out);
196
197 require_noerr(SSLSetIOFuncs(ctx,
198 (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
199 require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out);
200
201 if (server)
202 require_noerr(SSLSetSessionOption(ctx,
203 kSSLSessionOptionBreakOnClientHello, true), out);
204 else
205 require_noerr(SSLSetSessionOption(ctx,
206 kSSLSessionOptionBreakOnServerAuth, true), out);
207
208 /* Tell SecureTransport to not check certs itself: it will break out of the
209 handshake to let us take care of it instead. */
210 require_noerr(SSLSetEnableCertVerify(ctx, false), out);
211
212 handle->handle = ctx;
213 handle->is_server = server;
214 handle->session_id = session_id;
215 handle->comm = comm;
216
217 return handle;
218
219out:
fa7225c8
A
220 if (handle) free(handle);
221 if (ctx) CFRelease(ctx);
5c19dc3a
A
222 return NULL;
223}
224
225static SSLProtocol versions[] = {
226 kSSLProtocol3,
227 kTLSProtocol1,
228 kTLSProtocol11,
229 kTLSProtocol12,
230};
231static int nversions = sizeof(versions)/sizeof(versions[0]);
232
233static void
234tests(void)
235{
236 int j;
237 pthread_t client_thread, server_thread;
238
239 for(j=0; j<nversions; j++)
240 {
241 int sp[2];
242 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
243
244 ssl_test_handle *server, *client;
245
246 uint32_t session_id = (j+1) << 16 | 1 << 8;
247 server = ssl_test_handle_create(session_id, true /*server*/, sp[0]);
248 client = ssl_test_handle_create(session_id, false/*client*/, sp[1]);
249
250 require_noerr(SSLSetPeerID(server->handle, &session_id, sizeof(session_id)), out);
251 require_noerr(SSLSetPeerID(client->handle, &session_id, sizeof(session_id)), out);
252
253 /* set fixed cipher on client and server */
254 require_noerr(SSLSetEnabledCiphers(client->handle, &ciphers[0], 1), out);
255 require_noerr(SSLSetEnabledCiphers(server->handle, &ciphers[0], 1), out);
256
257 require_noerr(SSLSetProtocolVersionMax(client->handle, versions[j]), out);
258 require_noerr(SSLSetPeerDomainName(client->handle, peername, sizeof(peername)), out);
259
260 require_noerr(SSLSetProtocolVersionMax(server->handle, versions[j]), out);
261
262 pthread_create(&client_thread, NULL, securetransport_client_thread, client);
263 pthread_create(&server_thread, NULL, securetransport_server_thread, server);
264
866f8763 265 intptr_t server_err, client_err;
5c19dc3a
A
266 pthread_join(client_thread, (void*)&client_err);
267 pthread_join(server_thread, (void*)&server_err);
268
269 out:
270 free(client);
271 free(server);
272
273 }
274}
275
276int ssl_49_sni(int argc, char *const *argv)
277{
278
279 plan_tests(8);
280
281
282 tests();
283
284 return 0;
285}