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