]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+split.m
Security-58286.200.222.tar.gz
[apple/security.git] / OSX / libsecurity_ssl / regressions / SecureTransportTests / STLegacyTests+split.m
1 #include <stdbool.h>
2 #include <pthread.h>
3 #include <fcntl.h>
4 #include <sys/mman.h>
5 #include <unistd.h>
6
7 #include <CoreFoundation/CoreFoundation.h>
8
9 #include <AssertMacros.h>
10 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
11 #include <Security/SecureTransport.h>
12 #include <Security/SecPolicy.h>
13 #include <Security/SecTrust.h>
14 #include <Security/SecIdentity.h>
15 #include <Security/SecIdentityPriv.h>
16 #include <Security/SecCertificatePriv.h>
17 #include <Security/SecKeyPriv.h>
18 #include <Security/SecItem.h>
19 #include <Security/SecRandom.h>
20
21 #include <string.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <errno.h>
25 #include <stdlib.h>
26 #include <mach/mach_time.h>
27
28 #if TARGET_OS_IPHONE
29 #include <Security/SecRSAKey.h>
30 #endif
31
32 #include "ssl-utils.h"
33
34 #include <tls_stream_parser.h>
35 #import "STLegacyTests.h"
36
37 @implementation STLegacyTests (split)
38
39 typedef struct {
40 SSLContextRef st;
41 bool is_server;
42 int comm;
43 CFArrayRef certs;
44 int write_counter;
45 tls_stream_parser_t parser;
46 size_t write_size;
47 } ssl_test_handle;
48
49
50 #pragma mark -
51 #pragma mark SecureTransport support
52
53 #if 0
54 static void hexdump(const char *s, const uint8_t *bytes, size_t len) {
55 size_t ix;
56 printf("socket %s(%p, %lu)\n", s, bytes, len);
57 for (ix = 0; ix < len; ++ix) {
58 if (!(ix % 16))
59 printf("\n");
60 printf("%02X ", bytes[ix]);
61 }
62 printf("\n");
63 }
64 #else
65 #define hexdump(string, bytes, len)
66 #endif
67
68 static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length)
69 {
70 ssl_test_handle *handle =(ssl_test_handle *)h;
71 int conn = handle->comm;
72 size_t len = *length;
73 uint8_t *ptr = (uint8_t *)data;
74
75 if(handle->is_server) {
76 //printf("SocketWrite: server write len=%zd\n", len);
77
78 tls_buffer buffer;
79 buffer.data = ptr;
80 buffer.length = len;
81 tls_stream_parser_parse(handle->parser, buffer);
82 }
83
84 do {
85 ssize_t ret;
86 do {
87 hexdump("write", ptr, len);
88 ret = write((int)conn, ptr, len);
89 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
90 if (ret > 0) {
91 len -= ret;
92 ptr += ret;
93 }
94 else
95 return -36;
96 } while (len > 0);
97
98 *length = *length - len;
99 return errSecSuccess;
100 }
101
102 static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length)
103 {
104 const ssl_test_handle *handle=h;
105 int conn = handle->comm;
106 size_t len = *length;
107 uint8_t *ptr = (uint8_t *)data;
108
109
110 do {
111 ssize_t ret;
112 do {
113 ret = read((int)conn, ptr, len);
114 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
115 if (ret > 0) {
116 len -= ret;
117 ptr += ret;
118 }
119 else
120 return -36;
121 } while (len > 0);
122
123 if(len!=0)
124 printf("Something went wrong here... len=%d\n", (int)len);
125
126 *length = *length - len;
127 return errSecSuccess;
128 }
129
130 static int process(tls_stream_parser_ctx_t ctx, tls_buffer record)
131 {
132 ssl_test_handle *handle = (ssl_test_handle *)ctx;
133
134 // printf("processing record len=%zd, type=%d\n", record.length, record.data[0]);
135 if(record.data[0]==tls_record_type_AppData) {
136 handle->write_counter++;
137 // printf("record count = %d\n", handle->write_counter);
138 }
139
140 return 0;
141 }
142
143
144 static void *securetransport_ssl_thread(void *arg)
145 {
146 OSStatus ortn;
147 ssl_test_handle * ssl = (ssl_test_handle *)arg;
148 SSLContextRef ctx = ssl->st;
149 bool got_server_auth = false;
150
151 //uint64_t start = mach_absolute_time();
152 do {
153 ortn = SSLHandshake(ctx);
154
155 if (ortn == errSSLServerAuthCompleted)
156 {
157 require_string(!got_server_auth, out, "second server auth");
158 got_server_auth = true;
159 }
160 } while (ortn == errSSLWouldBlock
161 || ortn == errSSLServerAuthCompleted);
162
163 require_noerr_action_quiet(ortn, out,
164 fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
165
166 unsigned char ibuf[90000], obuf[45000];
167
168 if (ssl->is_server) {
169 size_t len;
170 require_action(errSecSuccess==SecRandomCopyBytes(kSecRandomDefault, ssl->write_size, obuf), out, ortn = -1);
171 require_noerr(ortn = SSLWrite(ctx, obuf, ssl->write_size, &len), out);
172 require_action(len == ssl->write_size, out, ortn = -1);
173 require_noerr(ortn = SSLWrite(ctx, obuf, ssl->write_size, &len), out);
174 require_action(len == ssl->write_size, out, ortn = -1);
175 } else {
176 size_t len = ssl->write_size*2;
177 size_t olen;
178 unsigned char *p = ibuf;
179 while (len) {
180 require_noerr(ortn = SSLRead(ctx, p, len, &olen), out);
181 len -= olen;
182 p += olen;
183 }
184 }
185
186 out:
187 SSLClose(ctx);
188 CFRelease(ctx);
189 close(ssl->comm);
190 pthread_exit((void *)(intptr_t)ortn);
191 return NULL;
192 }
193
194 static void
195 ssl_test_handle_destroy(ssl_test_handle *handle)
196 {
197 if(handle) {
198 if(handle->parser) tls_stream_parser_destroy(handle->parser);
199 free(handle);
200 }
201 }
202
203 static ssl_test_handle *
204 ssl_test_handle_create(bool server, int comm, CFArrayRef certs)
205 {
206 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
207 SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType);
208
209 require(handle, out);
210 require(ctx, out);
211
212 require_noerr(SSLSetIOFuncs(ctx,
213 (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
214 require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)handle), out);
215
216 if (server)
217 require_noerr(SSLSetCertificate(ctx, certs), out);
218
219 require_noerr(SSLSetSessionOption(ctx,
220 kSSLSessionOptionBreakOnServerAuth, true), out);
221
222 /* Tell SecureTransport to not check certs itself: it will break out of the
223 handshake to let us take care of it instead. */
224 require_noerr(SSLSetEnableCertVerify(ctx, false), out);
225
226 handle->is_server = server;
227 handle->comm = comm;
228 handle->certs = certs;
229 handle->st = ctx;
230 handle->write_counter = 0;
231 handle->parser = tls_stream_parser_create(handle, process);
232
233 return handle;
234
235 out:
236 if (handle) free(handle);
237 if (ctx) CFRelease(ctx);
238 return NULL;
239 }
240
241 static SSLCipherSuite ciphers[] = {
242 TLS_RSA_WITH_AES_128_CBC_SHA,
243 };
244 static int nciphers = sizeof(ciphers)/sizeof(ciphers[0]);
245
246 static SSLProtocol versions[] = {
247 kSSLProtocol3,
248 kTLSProtocol1,
249 kTLSProtocol11,
250 kTLSProtocol12,
251 };
252 static int nversions = sizeof(versions)/sizeof(versions[0]);
253
254 // { write size, expected count when nosplit, expected count when split }
255 static size_t wsizes[][3] = {
256 { 1, 2, 2 },
257 { 2, 2, 3 },
258 { 3, 2, 3 },
259 { 4, 2, 3 },
260 { 16384, 2, 3 },
261 { 16385, 4, 4 },
262 { 16386, 4, 5 },
263 { 16387, 4, 5 },
264 { 16388, 4, 5 },
265 { 32768, 4, 5 },
266 { 32769, 6, 6 },
267 { 32770, 6, 7 },
268 { 32771, 6, 7 },
269 { 32772, 6, 7 },
270 };
271 static int nwsizes = sizeof(wsizes)/sizeof(wsizes[0]);
272
273 -(void) testSplit
274 {
275 pthread_t client_thread, server_thread;
276 CFArrayRef server_certs = server_chain();
277 XCTAssert(server_certs, "got server certs");
278
279 int i,j,k,s;
280
281 for(i=0; i<nciphers; i++)
282 for(j=0; j<nversions; j++)
283 for(k=0; k<nwsizes; k++)
284 for(s=0; s<3; s++)
285 {
286 int sp[2];
287 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno);
288 fcntl(sp[0], F_SETNOSIGPIPE, 1);
289 fcntl(sp[1], F_SETNOSIGPIPE, 1);
290
291 ssl_test_handle *server, *client;
292
293 server = ssl_test_handle_create(true /*server*/, sp[0], server_certs);
294 client = ssl_test_handle_create(false/*client*/, sp[1], NULL);
295
296 server->write_size = wsizes[k][0];
297 client->write_size = wsizes[k][0];
298
299 require(client, out);
300 require(server, out);
301
302 require_noerr(SSLSetProtocolVersionMin(server->st, kSSLProtocol3), out); // We need this server to do SSL3.
303 require_noerr(SSLSetProtocolVersionMax(client->st, versions[j]), out);
304 require_noerr(SSLSetEnabledCiphers(client->st, &ciphers[i], 1), out);
305 if(s) {
306 // s=0: default (should be enabled)
307 // s=1: explicit enable
308 // s=2: expliciti disable
309 require_noerr(SSLSetSessionOption(server->st, kSSLSessionOptionSendOneByteRecord, (s==1)?true:false), out);
310 }
311 // printf("**** Test Case: i=%d, j=%d, k=%d (%zd), s=%d ****\n", i, j, k, wsizes[k][0], s);
312
313 pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
314 pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
315
316 intptr_t server_err, client_err;
317 pthread_join(client_thread, (void*)&client_err);
318 pthread_join(server_thread, (void*)&server_err);
319
320 XCTAssert(!server_err, "Server error = %ld", server_err);
321 XCTAssert(!client_err, "Client error = %ld", client_err);
322
323 /* one byte split is expected only for AES when using TLS 1.0 or lower, and when not disabled */
324 bool expected_split = (i==0) && (s!=2) && (versions[j]<=kTLSProtocol1);
325 int expected_count = (int)(expected_split ? wsizes[k][2]: wsizes[k][1]);
326
327 XCTAssertEqual(server->write_counter, expected_count, "wrong number of data records");
328
329 // fprintf(stderr, "Server write counter = %d, expected %d\n", server->write_counter, expected_count);
330
331 out:
332 ssl_test_handle_destroy(client);
333 ssl_test_handle_destroy(server);
334
335 }
336 CFReleaseNull(server_certs);
337 }
338
339 @end