]> git.saurik.com Git - apple/security.git/blame - OSX/libsecurity_ssl/regressions/ssl-50-server.c
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / libsecurity_ssl / regressions / ssl-50-server.c
CommitLineData
d8f41ccd
A
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
48typedef 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
59static 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 */
75static 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
109static 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
132static 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
156static 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;
166out:
167 if (ctx)
168 CFRelease(ctx);
169 return NULL;
170}
171
172
173static ssl_test_handle *
174ssl_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
185static void *securetransport_ssl_thread(void *arg)
186{
187 OSStatus ortn;
d64be36e 188 int sock = *((int*)arg);
d8f41ccd
A
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
218out:
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
233static void
234tests(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
d64be36e 247 pthread_create(&server_thread, NULL, securetransport_ssl_thread, (void*)&socket);
d8f41ccd
A
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
257int 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}