5 * Created by Fabrice Gautier on 1/31/11.
6 * Copyright 2011 Apple, Inc. All rights reserved.
10 #include <Security/Security.h>
11 #include <Security/SecBase.h>
13 #include "../sslViewer/sslAppUtils.h"
16 #include <sys/types.h>
17 #include <sys/socket.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
22 #include <unistd.h> /* close() */
23 #include <string.h> /* memset() */
28 #include <securityd/spi.h>
31 #include "ssl-utils.h"
33 #define SERVER "127.0.0.1"
34 //#define SERVER "17.201.58.114"
40 static void dumppacket(const unsigned char *data
, unsigned long len
)
45 if((i
&0xf)==0) printf("%04lx :",i
);
46 printf(" %02x", data
[i
]);
47 if((i
&0xf)==0xf) printf("\n");
53 /* 2K should be enough for everybody */
55 static unsigned char readBuffer
[MTU
];
56 static unsigned int readOff
=0;
57 static size_t readLeft
=0;
61 SSLConnectionRef connection
,
65 int fd
= (int)connection
;
67 uint8_t *d
=readBuffer
;
71 len
= read(fd
, readBuffer
, MTU
);
75 readLeft
=(size_t) len
;
76 printf("SocketRead: %ld bytes... epoch: %02x seq=%02x%02x\n",
77 len
, d
[4], d
[9], d
[10]);
83 //printf("SocketRead: EAGAIN\n");
85 /* nonblocking, no data */
86 return errSSLWouldBlock
;
94 if(readLeft
<*dataLength
) {
98 memcpy(data
, readBuffer
+readOff
, *dataLength
);
99 readLeft
-=*dataLength
;
100 readOff
+=*dataLength
;
102 return errSecSuccess
;
107 OSStatus
SocketWrite(
108 SSLConnectionRef connection
,
110 size_t *dataLength
) /* IN/OUT */
112 int fd
= (int)connection
;
114 OSStatus err
= errSecSuccess
;
115 const uint8_t *d
=data
;
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
;
128 len
= send(fd
, data
, *dataLength
, 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]);
140 /* nonblocking, no data */
141 err
= errSSLWouldBlock
;
144 perror("SocketWrite");
154 int main(int argc
, char **argv
)
157 struct sockaddr_in sa
;
159 if ((fd
=socket(AF_INET
, SOCK_DGRAM
, 0))==-1) {
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");
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
);
183 if(connect(fd
, (struct sockaddr
*)&sa
, sizeof(sa
))==-1)
189 /* Change to non blocking io */
190 fcntl(fd
, F_SETFL
, O_NONBLOCK
);
192 SSLConnectionRef c
=(SSLConnectionRef
)(intptr_t)fd
;
196 SSLContextRef ctx
= NULL
;
198 SSLClientCertificateState certState
;
199 SSLCipherSuite negCipher
;
200 SSLProtocol negVersion
;
203 * Set up a SecureTransport session.
205 ortn
= SSLNewDatagramContext(false, &ctx
);
207 printSslErrStr("SSLNewDatagramContext", ortn
);
210 ortn
= SSLSetIOFuncs(ctx
, SocketRead
, SocketWrite
);
212 printSslErrStr("SSLSetIOFuncs", ortn
);
216 ortn
= SSLSetConnection(ctx
, c
);
218 printSslErrStr("SSLSetConnection", ortn
);
222 ortn
= SSLSetMaxDatagramRecordSize(ctx
, 600);
224 printSslErrStr("SSLSetMaxDatagramRecordSize", ortn
);
228 /* Lets not verify the cert, which is a random test cert */
229 ortn
= SSLSetEnableCertVerify(ctx
, false);
231 printSslErrStr("SSLSetEnableCertVerify", ortn
);
235 ortn
= SSLSetCertificate(ctx
, server_chain());
237 printSslErrStr("SSLSetCertificate", ortn
);
242 ortn
= SSLHandshake(ctx
);
243 if(ortn
== errSSLWouldBlock
) {
244 /* keep UI responsive */
247 } while (ortn
== errSSLWouldBlock
);
250 SSLGetClientCertificateState(ctx
, &certState
);
251 SSLGetNegotiatedCipher(ctx
, &negCipher
);
252 SSLGetNegotiatedProtocolVersion(ctx
, &negVersion
);
255 size_t len
, readLen
, writeLen
;
262 snprintf(buffer
, BUFLEN
, "Message %d", count
);
263 len
= strlen(buffer
);
265 ortn
=SSLWrite(ctx
, buffer
, len
, &writeLen
);
267 printSslErrStr("SSLWrite", ortn
);
270 printf("Wrote %lu bytes\n", writeLen
);
275 ortn
=SSLRead(ctx
, buffer
, BUFLEN
, &readLen
);
276 } while((ortn
==errSSLWouldBlock
) && (timeout
--));
277 if(ortn
==errSSLWouldBlock
) {
278 printf("Echo timeout...\n");
282 printSslErrStr("SSLRead", ortn
);
286 printf("Received %lu bytes: %s\n", readLen
, buffer
);
292 SSLDisposeContext(ctx
);