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