]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/regressions/ssl-50-server.c
Security-59754.41.1.tar.gz
[apple/security.git] / OSX / libsecurity_ssl / regressions / ssl-50-server.c
1
2 #include <stdbool.h>
3 #include <pthread.h>
4 #include <fcntl.h>
5 #include <sys/mman.h>
6 #include <unistd.h>
7
8 #include <CoreFoundation/CoreFoundation.h>
9
10 #include <AssertMacros.h>
11 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
12 #include <Security/SecureTransport.h>
13 #include <Security/SecPolicy.h>
14 #include <Security/SecTrust.h>
15 #include <Security/SecIdentity.h>
16 #include <Security/SecIdentityPriv.h>
17 #include <Security/SecCertificatePriv.h>
18 #include <Security/SecKeyPriv.h>
19 #include <Security/SecItem.h>
20 #include <Security/SecRandom.h>
21
22 #include <utilities/array_size.h>
23 #include <string.h>
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <errno.h>
27 #include <stdlib.h>
28 #include <mach/mach_time.h>
29
30 #include <stdio.h>
31 #include <unistd.h>
32 #include <strings.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37 #include <netdb.h>
38 #include <errno.h>
39
40
41 #if TARGET_OS_IPHONE
42 #include <Security/SecRSAKey.h>
43 #endif
44
45 #include "ssl_regressions.h"
46 #include "ssl-utils.h"
47
48 typedef struct {
49 SSLContextRef st;
50 int comm;
51 CFArrayRef certs;
52 } ssl_test_handle;
53
54
55 // MARK: -
56 // MARK: SecureTransport support
57
58 #if 0
59 static void hexdump(const uint8_t *bytes, size_t len) {
60 size_t ix;
61 printf("socket write(%p, %lu)\n", bytes, len);
62 for (ix = 0; ix < len; ++ix) {
63 if (!(ix % 16))
64 printf("\n");
65 printf("%02X ", bytes[ix]);
66 }
67 printf("\n");
68 }
69 #else
70 #define hexdump(bytes, len)
71 #endif
72
73
74 /* Listen to on port */
75 static int SocketListen(int port)
76 {
77 struct sockaddr_in sa;
78 int sock;
79 int val = 1;
80
81 if ((sock=socket(AF_INET, SOCK_STREAM, 0))==-1) {
82 perror("socket");
83 return -errno;
84 }
85
86 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(val));
87
88 memset((char *) &sa, 0, sizeof(sa));
89 sa.sin_family = AF_INET;
90 sa.sin_port = htons(port);
91 sa.sin_addr.s_addr = htonl(INADDR_ANY);
92
93 if(bind (sock, (struct sockaddr *)&sa, sizeof(sa))==-1)
94 {
95 perror("bind");
96 return -errno;
97 }
98
99 if(listen(sock, 5)==-1)
100 {
101 perror("listen");
102 return -errno;
103 }
104
105 return sock;
106 }
107
108
109 static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
110 {
111 size_t len = *length;
112 uint8_t *ptr = (uint8_t *)data;
113
114 do {
115 ssize_t ret;
116 do {
117 hexdump(ptr, len);
118 ret = write((int)conn, ptr, len);
119 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
120 if (ret > 0) {
121 len -= ret;
122 ptr += ret;
123 }
124 else
125 return -36;
126 } while (len > 0);
127
128 *length = *length - len;
129 return errSecSuccess;
130 }
131
132 static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
133 {
134 size_t len = *length;
135 uint8_t *ptr = (uint8_t *)data;
136
137 do {
138 ssize_t ret;
139 do {
140 ret = read((int)conn, ptr, len);
141 } while ((ret < 0) && (errno == EINPROGRESS || errno == EAGAIN || errno == EINTR));
142 if (ret > 0) {
143 len -= ret;
144 ptr += ret;
145 } else {
146 printf("read error(%d): ret=%zd, errno=%d\n", (int)conn, ret, errno);
147 return -errno;
148 }
149 } while (len > 0);
150
151 *length = *length - len;
152 return errSecSuccess;
153 }
154
155
156 static SSLContextRef make_ssl_ref(bool server, int sock, CFArrayRef certs)
157 {
158 SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, server?kSSLServerSide:kSSLClientSide, kSSLStreamType);
159 require(ctx, out);
160
161 require_noerr(SSLSetIOFuncs(ctx, (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
162 require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out);
163 require_noerr(SSLSetCertificate(ctx, certs), out);
164
165 return ctx;
166 out:
167 if (ctx)
168 CFRelease(ctx);
169 return NULL;
170 }
171
172
173 static ssl_test_handle *
174 ssl_test_handle_create(int comm, CFArrayRef certs)
175 {
176 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
177 if (handle) {
178 handle->comm = comm;
179 handle->certs = certs;
180 handle->st = make_ssl_ref(true, comm, certs);
181 }
182 return handle;
183 }
184
185 static void *securetransport_ssl_thread(void *arg)
186 {
187 OSStatus ortn;
188 int sock = *((int*)arg);
189
190 int socket = accept(sock, NULL, NULL);
191
192 CFArrayRef server_certs = server_chain();
193 ssl_test_handle * ssl = ssl_test_handle_create(socket, server_certs);
194 SSLContextRef ctx = ssl->st;
195
196 pthread_setname_np("server thread");
197
198 //uint64_t start = mach_absolute_time();
199 do {
200 ortn = SSLHandshake(ctx);
201 } while (ortn == errSSLWouldBlock);
202
203 require_noerr_action_quiet(ortn, out,
204 fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
205
206 //uint64_t elapsed = mach_absolute_time() - start;
207 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
208
209 /*
210 SSLProtocol proto = kSSLProtocolUnknown;
211 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
212
213 SSLCipherSuite cipherSuite;
214 require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
215 //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
216
217
218 out:
219 CFRelease(server_certs);
220
221 SSLClose(ctx);
222 CFRelease(ctx);
223 if(ssl) {
224 close(ssl->comm);
225 free(ssl);
226 }
227 pthread_exit((void *)(intptr_t)ortn);
228 return NULL;
229 }
230
231
232
233 static void
234 tests(void)
235 {
236 pthread_t server_thread;
237 int socket;
238
239 socket = SocketListen(4443);
240
241 ok(socket>=0, "SocketListen failed");
242 if(socket<0) {
243 return;
244 }
245 //fprintf(stderr, "session_id: %d\n", session_id);
246
247 pthread_create(&server_thread, NULL, securetransport_ssl_thread, (void*)&socket);
248
249 system("/usr/bin/openssl s_client -msg -debug -connect localhost:4443");
250
251 int server_err;
252 pthread_join(server_thread, (void*)&server_err);
253
254 ok(!server_err, "Server thread failed err=%d", server_err);
255 }
256
257 int ssl_50_server(int argc, char *const *argv)
258 {
259
260 plan_tests(1 + 1 /*cert*/);
261
262
263 tests();
264
265 return 0;
266 }