]> git.saurik.com Git - apple/security.git/blob - libsecurity_ssl/dtlsEcho/dtlsEchoClient.c
Security-55471.14.tar.gz
[apple/security.git] / libsecurity_ssl / dtlsEcho / dtlsEchoClient.c
1 /*
2 * dtlsEchoClient.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 #include "ssl-utils.h"
32
33 #define SERVER "127.0.0.1"
34 //#define SERVER "17.201.58.114"
35 #define PORT 23232
36 #define BUFLEN 128
37 #define COUNT 10
38
39 #if 0
40 static void dumppacket(const unsigned char *data, unsigned long len)
41 {
42 unsigned long i;
43 for(i=0;i<len;i++)
44 {
45 if((i&0xf)==0) printf("%04lx :",i);
46 printf(" %02x", data[i]);
47 if((i&0xf)==0xf) printf("\n");
48 }
49 printf("\n");
50 }
51 #endif
52
53 /* 2K should be enough for everybody */
54 #define MTU 2048
55 static unsigned char readBuffer[MTU];
56 static unsigned int readOff=0;
57 static size_t readLeft=0;
58
59 static
60 OSStatus SocketRead(
61 SSLConnectionRef connection,
62 void *data,
63 size_t *dataLength)
64 {
65 int fd = (int)connection;
66 ssize_t len;
67 uint8_t *d=readBuffer;
68
69 if(readLeft==0)
70 {
71 len = read(fd, readBuffer, MTU);
72
73 if(len>0) {
74 readOff=0;
75 readLeft=(size_t) len;
76 printf("SocketRead: %ld bytes... epoch: %02x seq=%02x%02x\n",
77 len, d[4], d[9], d[10]);
78
79 } else {
80 int theErr = errno;
81 switch(theErr) {
82 case EAGAIN:
83 //printf("SocketRead: EAGAIN\n");
84 *dataLength=0;
85 /* nonblocking, no data */
86 return errSSLWouldBlock;
87 default:
88 perror("SocketRead");
89 return errSecIO;
90 }
91 }
92 }
93
94 if(readLeft<*dataLength) {
95 *dataLength=readLeft;
96 }
97
98 memcpy(data, readBuffer+readOff, *dataLength);
99 readLeft-=*dataLength;
100 readOff+=*dataLength;
101
102 return errSecSuccess;
103
104 }
105
106 static
107 OSStatus SocketWrite(
108 SSLConnectionRef connection,
109 const void *data,
110 size_t *dataLength) /* IN/OUT */
111 {
112 int fd = (int)connection;
113 ssize_t len;
114 OSStatus err = errSecSuccess;
115 const uint8_t *d=data;
116
117 #if 0
118 if((rand()&3)==1) {
119
120 /* drop 1/8th packets */
121 printf("SocketWrite: Drop %ld bytes... epoch: %02x seq=%02x%02x\n",
122 *dataLength, d[4], d[9], d[10]);
123 return errSecSuccess;
124
125 }
126 #endif
127
128 len = send(fd, data, *dataLength, 0);
129
130 if(len>0) {
131 *dataLength=(size_t)len;
132 printf("SocketWrite: Sent %ld bytes... epoch: %02x seq=%02x%02x\n",
133 len, d[4], d[9], d[10]);
134 return err;
135 }
136
137 int theErr = errno;
138 switch(theErr) {
139 case EAGAIN:
140 /* nonblocking, no data */
141 err = errSSLWouldBlock;
142 break;
143 default:
144 perror("SocketWrite");
145 err = errSecIO;
146 break;
147 }
148
149 return err;
150
151 }
152
153
154 int main(int argc, char **argv)
155 {
156 int fd;
157 struct sockaddr_in sa;
158
159 if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1) {
160 perror("socket");
161 exit(-1);
162 }
163
164 #ifdef NO_SERVER
165 # if DEBUG
166 securityd_init();
167 # endif
168 #endif
169
170 memset((char *) &sa, 0, sizeof(sa));
171 sa.sin_family = AF_INET;
172 sa.sin_port = htons(PORT);
173 if (inet_aton(SERVER, &sa.sin_addr)==0) {
174 fprintf(stderr, "inet_aton() failed\n");
175 exit(1);
176 }
177
178 time_t seed=time(NULL);
179 // time_t seed=1298952499;
180 srand((unsigned)seed);
181 printf("Random drop initialized with seed = %lu\n", seed);
182
183 if(connect(fd, (struct sockaddr *)&sa, sizeof(sa))==-1)
184 {
185 perror("connect");
186 return errno;
187 }
188
189 /* Change to non blocking io */
190 fcntl(fd, F_SETFL, O_NONBLOCK);
191
192 SSLConnectionRef c=(SSLConnectionRef)(intptr_t)fd;
193
194
195 OSStatus ortn;
196 SSLContextRef ctx = NULL;
197
198 SSLClientCertificateState certState;
199 SSLCipherSuite negCipher;
200 SSLProtocol negVersion;
201
202 /*
203 * Set up a SecureTransport session.
204 */
205 ortn = SSLNewDatagramContext(false, &ctx);
206 if(ortn) {
207 printSslErrStr("SSLNewDatagramContext", ortn);
208 return ortn;
209 }
210 ortn = SSLSetIOFuncs(ctx, SocketRead, SocketWrite);
211 if(ortn) {
212 printSslErrStr("SSLSetIOFuncs", ortn);
213 return ortn;
214 }
215
216 ortn = SSLSetConnection(ctx, c);
217 if(ortn) {
218 printSslErrStr("SSLSetConnection", ortn);
219 return ortn;
220 }
221
222 ortn = SSLSetMaxDatagramRecordSize(ctx, 600);
223 if(ortn) {
224 printSslErrStr("SSLSetMaxDatagramRecordSize", ortn);
225 return ortn;
226 }
227
228 /* Lets not verify the cert, which is a random test cert */
229 ortn = SSLSetEnableCertVerify(ctx, false);
230 if(ortn) {
231 printSslErrStr("SSLSetEnableCertVerify", ortn);
232 return ortn;
233 }
234
235 ortn = SSLSetCertificate(ctx, server_chain());
236 if(ortn) {
237 printSslErrStr("SSLSetCertificate", ortn);
238 return ortn;
239 }
240
241 do {
242 ortn = SSLHandshake(ctx);
243 if(ortn == errSSLWouldBlock) {
244 /* keep UI responsive */
245 sslOutputDot();
246 }
247 } while (ortn == errSSLWouldBlock);
248
249
250 SSLGetClientCertificateState(ctx, &certState);
251 SSLGetNegotiatedCipher(ctx, &negCipher);
252 SSLGetNegotiatedProtocolVersion(ctx, &negVersion);
253
254 int count;
255 size_t len, readLen, writeLen;
256 char buffer[BUFLEN];
257
258 count = 0;
259 while(count<COUNT) {
260 int timeout = 10000;
261
262 snprintf(buffer, BUFLEN, "Message %d", count);
263 len = strlen(buffer);
264
265 ortn=SSLWrite(ctx, buffer, len, &writeLen);
266 if(ortn) {
267 printSslErrStr("SSLWrite", ortn);
268 break;
269 }
270 printf("Wrote %lu bytes\n", writeLen);
271
272 count++;
273
274 do {
275 ortn=SSLRead(ctx, buffer, BUFLEN, &readLen);
276 } while((ortn==errSSLWouldBlock) && (timeout--));
277 if(ortn==errSSLWouldBlock) {
278 printf("Echo timeout...\n");
279 continue;
280 }
281 if(ortn) {
282 printSslErrStr("SSLRead", ortn);
283 break;
284 }
285 buffer[readLen]=0;
286 printf("Received %lu bytes: %s\n", readLen, buffer);
287
288 }
289
290 SSLClose(ctx);
291
292 SSLDisposeContext(ctx);
293
294 return ortn;
295 }