]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_ssl/dtlsEcho/dtlsEchoServer.c
Security-57031.20.26.tar.gz
[apple/security.git] / Security / libsecurity_ssl / dtlsEcho / dtlsEchoServer.c
1 /*
2 * Copyright (c) 2011-2014 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 <Security/Security.h>
26 #include <Security/SecBase.h>
27
28 #include "../sslViewer/sslAppUtils.h"
29
30 #include <stdlib.h>
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
35 #include <stdio.h>
36 #include <errno.h>
37 #include <unistd.h> /* close() */
38 #include <string.h> /* memset() */
39 #include <fcntl.h>
40 #include <time.h>
41
42 #ifdef NO_SERVER
43 #include <securityd/spi.h>
44 #endif
45
46 #define PORT 23232
47
48 #include "ssl-utils.h"
49
50 static void dumppacket(const unsigned char *data, unsigned long len)
51 {
52 unsigned long i;
53 for(i=0;i<len;i++)
54 {
55 if((i&0xf)==0) printf("%04lx :",i);
56 printf(" %02x", data[i]);
57 if((i&0xf)==0xf) printf("\n");
58 }
59 printf("\n");
60 }
61
62
63 /* 2K should be enough for everybody */
64 #define MTU 2048
65 static unsigned char readBuffer[MTU];
66 static unsigned int readOff=0;
67 static size_t readLeft=0;
68
69 static
70 OSStatus SocketRead(
71 SSLConnectionRef connection,
72 void *data,
73 size_t *dataLength)
74 {
75 int fd = (int)connection;
76 ssize_t len;
77 uint8_t *d=readBuffer;
78
79 if(readLeft==0)
80 {
81 len = read(fd, readBuffer, MTU);
82
83 if(len>0) {
84 readOff=0;
85 readLeft=(size_t) len;
86 printf("SocketRead: %ld bytes... epoch: %02x seq=%02x%02x\n",
87 len, d[4], d[9], d[10]);
88 } else {
89 int theErr = errno;
90 switch(theErr) {
91 case EAGAIN:
92 // printf("SocketRead: EAGAIN\n");
93 *dataLength=0;
94 /* nonblocking, no data */
95 return errSSLWouldBlock;
96 default:
97 perror("SocketRead");
98 return errSecIO;
99 }
100 }
101 }
102
103 if(readLeft<*dataLength) {
104 *dataLength=readLeft;
105 }
106
107 memcpy(data, readBuffer+readOff, *dataLength);
108 readLeft-=*dataLength;
109 readOff+=*dataLength;
110
111
112 return errSecSuccess;
113
114 }
115
116
117 static
118 OSStatus SocketWrite(
119 SSLConnectionRef connection,
120 const void *data,
121 size_t *dataLength) /* IN/OUT */
122 {
123 int fd = (int)connection;
124 ssize_t len;
125 OSStatus err = errSecSuccess;
126 const uint8_t *d=data;
127
128 #if 1
129 if((rand()&3)==1) {
130 /* drop 1/8 packets */
131 printf("SocketWrite: Drop %ld bytes... epoch: %02x seq=%02x%02x\n",
132 *dataLength, d[4], d[9], d[10]);
133 return errSecSuccess;
134 }
135 #endif
136
137 len = send(fd, data, *dataLength, 0);
138
139 if(len>0) {
140 *dataLength=(size_t)len;
141
142 printf("SocketWrite: Sent %ld bytes... epoch: %02x seq=%02x%02x\n",
143 len, d[4], d[9], d[10]);
144
145 return err;
146 }
147
148 int theErr = errno;
149 switch(theErr) {
150 case EAGAIN:
151 /* nonblocking, no data */
152 err = errSSLWouldBlock;
153 break;
154 default:
155 perror("SocketWrite");
156 err = errSecIO;
157 break;
158 }
159
160 return err;
161
162 }
163
164
165 int main(int argc, char **argv)
166 {
167 struct sockaddr_in sa; /* server address for bind */
168 struct sockaddr_in ca; /* client address for connect */
169 int fd;
170 ssize_t l;
171
172 #ifdef NO_SERVER
173 # if DEBUG
174 securityd_init();
175 # endif
176 #endif
177
178 if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1) {
179 perror("socket");
180 return errno;
181 }
182
183 time_t seed=time(NULL);
184 // time_t seed=1298952496;
185 srand((unsigned)seed);
186 printf("Random drop initialized with seed = %lu\n", seed);
187
188 memset((char *) &sa, 0, sizeof(sa));
189 sa.sin_family = AF_INET;
190 sa.sin_port = htons(PORT);
191 sa.sin_addr.s_addr = htonl(INADDR_ANY);
192
193 if(bind (fd, (struct sockaddr *)&sa, sizeof(sa))==-1)
194 {
195 perror("bind");
196 return errno;
197 }
198
199 printf("Waiting for first packet...\n");
200 /* PEEK only... */
201 socklen_t slen=sizeof(ca);
202 char b;
203 if((l=recvfrom(fd, &b, 1, MSG_PEEK, (struct sockaddr *)&ca, &slen))==-1)
204 {
205 perror("recvfrom");
206 return errno;
207 }
208
209 printf("Received packet from %s (%ld), connecting...\n", inet_ntoa(ca.sin_addr), l);
210
211 if(connect(fd, (struct sockaddr *)&ca, sizeof(ca))==-1)
212 {
213 perror("connect");
214 return errno;
215 }
216
217 /* Change to non blocking */
218 fcntl(fd, F_SETFL, O_NONBLOCK);
219
220
221 SSLConnectionRef c=(SSLConnectionRef)(intptr_t)fd;
222
223
224 OSStatus ortn;
225 SSLContextRef ctx = NULL;
226
227 SSLClientCertificateState certState;
228 SSLCipherSuite negCipher;
229
230 /*
231 * Set up a SecureTransport session.
232 */
233 ortn = SSLNewDatagramContext(true, &ctx);
234 if(ortn) {
235 printSslErrStr("SSLNewDatagramContext", ortn);
236 return ortn;
237 }
238
239 ortn = SSLSetIOFuncs(ctx, SocketRead, SocketWrite);
240 if(ortn) {
241 printSslErrStr("SSLSetIOFuncs", ortn);
242 return ortn;
243 }
244
245 ortn = SSLSetConnection(ctx, c);
246 if(ortn) {
247 printSslErrStr("SSLSetConnection", ortn);
248 return ortn;
249 }
250
251 ortn = SSLSetDatagramHelloCookie(ctx, &ca, 32);
252 if(ortn) {
253 printSslErrStr("SSLSetDatagramHelloCookie", ortn);
254 return ortn;
255 }
256
257 ortn = SSLSetMaxDatagramRecordSize(ctx, 400);
258 if(ortn) {
259 printSslErrStr("SSLSetMaxDatagramRecordSize", ortn);
260 return ortn;
261 }
262
263 /* Lets not verify the cert, which is a random test cert */
264 ortn = SSLSetEnableCertVerify(ctx, false);
265 if(ortn) {
266 printSslErrStr("SSLSetEnableCertVerify", ortn);
267 return ortn;
268 }
269
270 ortn = SSLSetCertificate(ctx, server_chain());
271 if(ortn) {
272 printSslErrStr("SSLSetCertificate", ortn);
273 return ortn;
274 }
275
276 ortn = SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate);
277 if(ortn) {
278 printSslErrStr("SSLSetCertificate", ortn);
279 return ortn;
280 }
281
282 printf("Server Handshake...\n");
283 do {
284 ortn = SSLHandshake(ctx);
285 if(ortn == errSSLWouldBlock) {
286 /* keep UI responsive */
287 sslOutputDot();
288 }
289 } while (ortn == errSSLWouldBlock);
290
291 if(ortn) {
292 printSslErrStr("SSLHandshake", ortn);
293 return ortn;
294 }
295
296 SSLGetClientCertificateState(ctx, &certState);
297 SSLGetNegotiatedCipher(ctx, &negCipher);
298
299 printf("Server Handshake done. Cipher is %s\n", sslGetCipherSuiteString(negCipher));
300
301 unsigned char buffer[MTU];
302 size_t len, readLen;
303
304 while(1) {
305 while((ortn=SSLRead(ctx, buffer, MTU, &readLen))==errSSLWouldBlock);
306 if(ortn) {
307 printSslErrStr("SSLRead", ortn);
308 break;
309 }
310 buffer[readLen]=0;
311 printf("Received %lu bytes:\n", readLen);
312 dumppacket(buffer, readLen);
313
314 ortn=SSLWrite(ctx, buffer, readLen, &len);
315 if(ortn) {
316 printSslErrStr("SSLRead", ortn);
317 break;
318 }
319 printf("Echoing %lu bytes\n", len);
320 }
321
322 SSLDisposeContext(ctx);
323
324 return ortn;
325 }