]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+crashes.m
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / libsecurity_ssl / regressions / SecureTransportTests / STLegacyTests+crashes.m
1 /*
2 * Copyright (c) 2012-2015 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 #include <AssertMacros.h>
26 #import "STLegacyTests.h"
27 #include <stdbool.h>
28 #include <pthread.h>
29 #include <fcntl.h>
30 #include <sys/mman.h>
31 #include <unistd.h>
32
33 #include <CoreFoundation/CoreFoundation.h>
34
35 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
36 #include <Security/SecureTransport.h>
37 #include <Security/SecPolicy.h>
38 #include <Security/SecTrust.h>
39 #include <Security/SecIdentity.h>
40 #include <Security/SecIdentityPriv.h>
41 #include <Security/SecCertificatePriv.h>
42 #include <Security/SecKeyPriv.h>
43 #include <Security/SecItem.h>
44 #include <Security/SecRandom.h>
45
46 #include <utilities/SecCFRelease.h>
47
48 #include <string.h>
49 #include <sys/types.h>
50 #include <sys/socket.h>
51 #include <errno.h>
52 #include <stdlib.h>
53 #include <mach/mach_time.h>
54
55 #if TARGET_OS_IPHONE
56 #include <Security/SecRSAKey.h>
57 #endif
58
59 #include "ssl-utils.h"
60
61 #pragma clang diagnostic push
62 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
63
64 @implementation STLegacyTests (crashes)
65
66 typedef struct {
67 SSLContextRef st;
68 bool is_server;
69 int comm;
70 CFArrayRef certs;
71 int test;
72 } ssl_test_handle;
73
74
75 #pragma mark -
76 #pragma mark SecureTransport support
77
78 #if SECTRANS_VERBOSE_DEBUG
79 static void hexdump(const char *s, const uint8_t *bytes, size_t len) {
80 size_t ix;
81 printf("socket %s(%p, %lu)\n", s, bytes, len);
82 for (ix = 0; ix < len; ++ix) {
83 if (!(ix % 16))
84 printf("\n");
85 printf("%02X ", bytes[ix]);
86 }
87 printf("\n");
88 }
89 #else
90 #define hexdump(string, bytes, len)
91 #endif
92
93 static OSStatus SocketWrite(SSLConnectionRef h, const void *data, size_t *length)
94 {
95 int conn = ((const ssl_test_handle *)h)->comm;
96 size_t len = *length;
97 uint8_t *ptr = (uint8_t *)data;
98
99 do {
100 ssize_t ret;
101 do {
102 hexdump("write", ptr, len);
103 ret = write((int)conn, ptr, len);
104 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
105 if (ret > 0) {
106 len -= ret;
107 ptr += ret;
108 }
109 else
110 return -36;
111 } while (len > 0);
112
113 *length = *length - len;
114 return errSecSuccess;
115 }
116
117 static int changepad=0;
118
119 static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length)
120 {
121 const ssl_test_handle *handle=h;
122 int conn = handle->comm;
123 size_t len = *length;
124 uint8_t *ptr = (uint8_t *)data;
125
126
127 do {
128 ssize_t ret;
129 do {
130 ret = read((int)conn, ptr, len);
131 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
132 if (ret > 0) {
133 len -= ret;
134 ptr += ret;
135 }
136 else
137 return -36;
138 } while (len > 0);
139
140 if(len!=0)
141 printf("Something went wrong here... len=%d\n", (int)len);
142
143 *length = *length - len;
144
145 ptr=data;
146
147 /* change pad in the data */
148 if(changepad==1) {
149 changepad=0;
150 ptr[31]=ptr[31]^0x08^0xff; // expected padding was 8, changing it to 0xff to trigger integer underflow.
151 }
152
153 /* We are reading the server cert */
154 if((ptr[0]==0x0b) && (handle->test==3)) {
155 #if 1 // cert length for TARGET_OS_IPHONE
156 size_t expected_len = 631;
157 #else
158 size_t expected_len = 500;
159 #endif
160 if(*length!=expected_len) {
161 fprintf(stderr, "Expected cert length %ld, got %ld... test might fail\n",
162 (long)expected_len, (long)*length);
163 }
164 ptr[0x16] = 0x4; // version = 4 certificate should cause error, but not crash .
165 }
166
167 /* We are reading a data application header */
168 if(*length==5 && ptr[0]==0x17) {
169 switch(handle->test) {
170 case 0:
171 ptr[4]=32; // reduce the size to 2 blocks and trigger integer underflow.
172 break;
173 case 1:
174 ptr[4]=48; // reduce the size to 3 blocks and triggering integer underflow in the padding.
175 break;
176 case 2:
177 changepad=1;
178 break;
179 default:
180 break;
181 }
182 }
183
184
185 return errSecSuccess;
186 }
187
188
189
190 static void *securetransport_ssl_thread(void *arg)
191 {
192 OSStatus ortn;
193 ssl_test_handle * ssl = (ssl_test_handle *)arg;
194 SSLContextRef ctx = ssl->st;
195 bool got_server_auth = false;
196
197 do {
198 ortn = SSLHandshake(ctx);
199
200 if (ortn == errSSLServerAuthCompleted) {
201 require_string(!got_server_auth, out, "second server auth");
202 got_server_auth = true;
203 }
204 } while (ortn == errSSLWouldBlock
205 || ortn == errSSLServerAuthCompleted);
206
207 require_noerr_quiet(ortn, out);
208
209 unsigned char ibuf[8], obuf[8];
210 size_t len;
211 if (ssl->is_server) {
212 require_action_quiet(errSecSuccess==SecRandomCopyBytes(kSecRandomDefault, sizeof(obuf), obuf), out, ortn = -1);
213 require_noerr_quiet(ortn = SSLWrite(ctx, obuf, sizeof(obuf), &len), out);
214 require_action_quiet(len == sizeof(obuf), out, ortn = -1);
215 } else {
216 require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out);
217 require_action_quiet(len == sizeof(ibuf), out, ortn = -1);
218 }
219
220 out:
221 SSLClose(ctx);
222 CFRelease(ctx);
223 close(ssl->comm);
224 pthread_exit((void *)(intptr_t)ortn);
225 return NULL;
226 }
227
228
229 static ssl_test_handle *
230 ssl_test_handle_create(bool server, int comm, CFArrayRef certs)
231 {
232 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
233 SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType);
234
235 require(handle, out);
236 require(ctx, out);
237
238 require_noerr(SSLSetIOFuncs(ctx,
239 (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
240 require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)handle), out);
241
242 if (server)
243 require_noerr(SSLSetCertificate(ctx, certs), out);
244
245 require_noerr(SSLSetSessionOption(ctx,
246 kSSLSessionOptionBreakOnServerAuth, true), out);
247
248 handle->is_server = server;
249 handle->comm = comm;
250 handle->certs = certs;
251 handle->st = ctx;
252
253 return handle;
254
255 out:
256 if (handle) free(handle);
257 if (ctx) CFRelease(ctx);
258 return NULL;
259 }
260
261 -(void)testCrashes
262 {
263 pthread_t client_thread, server_thread;
264 CFArrayRef server_certs = server_chain();
265 XCTAssert(server_certs, "got server certs");
266
267 int i;
268
269 for (i = 0; i < 4; i++) {
270 int sp[2];
271 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) {
272 exit(errno);
273 }
274 fcntl(sp[0], F_SETNOSIGPIPE, 1);
275 fcntl(sp[1], F_SETNOSIGPIPE, 1);
276
277 ssl_test_handle *server, *client;
278
279 server = ssl_test_handle_create(true /*server*/, sp[0], server_certs);
280 client = ssl_test_handle_create(false/*client*/, sp[1], NULL);
281
282 server->test = i;
283 client->test = i;
284
285 require(client, out);
286 require(server, out);
287
288 SSLCipherSuite cipher = TLS_RSA_WITH_AES_128_CBC_SHA256;
289 require_noerr(SSLSetEnabledCiphers(client->st, &cipher, 1), out);
290
291 pthread_create(&client_thread, NULL, securetransport_ssl_thread, client);
292 pthread_create(&server_thread, NULL, securetransport_ssl_thread, server);
293
294 intptr_t server_err, client_err;
295 pthread_join(client_thread, (void*)&client_err);
296 pthread_join(server_thread, (void*)&server_err);
297
298 XCTAssert(server_err==((i==3)?errSSLPeerCertUnknown:0), "Server error = %zu (i=%d)", server_err, i);
299 /* tests 0/1 should cause errSSLClosedAbort, 2 should cause errSSLBadRecordMac, 3 should cause errSSLXCertChainInvalid */
300 XCTAssert(client_err==((i==3)?errSSLXCertChainInvalid:(i==2)?errSSLBadRecordMac:errSSLClosedAbort), "Client error = %zu (i=%d)", client_err, i);
301
302 out:
303 free(client);
304 free(server);
305
306 }
307 CFReleaseNull(server_certs);
308 }
309
310 @end
311
312 #pragma clang diagnostic pop