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>
33 #include "ssl-utils.h"
35 static void dumppacket(const unsigned char *data
, unsigned long len
)
40 if((i
&0xf)==0) printf("%04lx :",i
);
41 printf(" %02x", data
[i
]);
42 if((i
&0xf)==0xf) printf("\n");
48 /* 2K should be enough for everybody */
50 static unsigned char readBuffer
[MTU
];
51 static unsigned int readOff
=0;
52 static size_t readLeft
=0;
56 SSLConnectionRef connection
,
60 int fd
= (int)connection
;
62 uint8_t *d
=readBuffer
;
66 len
= read(fd
, readBuffer
, MTU
);
70 readLeft
=(size_t) len
;
71 printf("SocketRead: %ld bytes... epoch: %02x seq=%02x%02x\n",
72 len
, d
[4], d
[9], d
[10]);
77 // printf("SocketRead: EAGAIN\n");
79 /* nonblocking, no data */
80 return errSSLWouldBlock
;
88 if(readLeft
<*dataLength
) {
92 memcpy(data
, readBuffer
+readOff
, *dataLength
);
93 readLeft
-=*dataLength
;
103 OSStatus
SocketWrite(
104 SSLConnectionRef connection
,
106 size_t *dataLength
) /* IN/OUT */
108 int fd
= (int)connection
;
110 OSStatus err
= errSecSuccess
;
111 const uint8_t *d
=data
;
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
;
122 len
= send(fd
, data
, *dataLength
, 0);
125 *dataLength
=(size_t)len
;
127 printf("SocketWrite: Sent %ld bytes... epoch: %02x seq=%02x%02x\n",
128 len
, d
[4], d
[9], d
[10]);
136 /* nonblocking, no data */
137 err
= errSSLWouldBlock
;
140 perror("SocketWrite");
150 int main(int argc
, char **argv
)
152 struct sockaddr_in sa
; /* server address for bind */
153 struct sockaddr_in ca
; /* client address for connect */
163 if ((fd
=socket(AF_INET
, SOCK_DGRAM
, 0))==-1) {
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
);
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
);
178 if(bind (fd
, (struct sockaddr
*)&sa
, sizeof(sa
))==-1)
184 printf("Waiting for first packet...\n");
186 socklen_t slen
=sizeof(ca
);
188 if((l
=recvfrom(fd
, &b
, 1, MSG_PEEK
, (struct sockaddr
*)&ca
, &slen
))==-1)
194 printf("Received packet from %s (%ld), connecting...\n", inet_ntoa(ca
.sin_addr
), l
);
196 if(connect(fd
, (struct sockaddr
*)&ca
, sizeof(ca
))==-1)
202 /* Change to non blocking */
203 fcntl(fd
, F_SETFL
, O_NONBLOCK
);
206 SSLConnectionRef c
=(SSLConnectionRef
)(intptr_t)fd
;
210 SSLContextRef ctx
= NULL
;
212 SSLClientCertificateState certState
;
213 SSLCipherSuite negCipher
;
216 * Set up a SecureTransport session.
218 ortn
= SSLNewDatagramContext(true, &ctx
);
220 printSslErrStr("SSLNewDatagramContext", ortn
);
224 ortn
= SSLSetIOFuncs(ctx
, SocketRead
, SocketWrite
);
226 printSslErrStr("SSLSetIOFuncs", ortn
);
230 ortn
= SSLSetConnection(ctx
, c
);
232 printSslErrStr("SSLSetConnection", ortn
);
236 ortn
= SSLSetDatagramHelloCookie(ctx
, &ca
, 32);
238 printSslErrStr("SSLSetDatagramHelloCookie", ortn
);
242 ortn
= SSLSetMaxDatagramRecordSize(ctx
, 600);
244 printSslErrStr("SSLSetMaxDatagramRecordSize", ortn
);
248 /* Lets not verify the cert, which is a random test cert */
249 ortn
= SSLSetEnableCertVerify(ctx
, false);
251 printSslErrStr("SSLSetEnableCertVerify", ortn
);
255 ortn
= SSLSetCertificate(ctx
, server_chain());
257 printSslErrStr("SSLSetCertificate", ortn
);
261 ortn
= SSLSetClientSideAuthenticate(ctx
, kAlwaysAuthenticate
);
263 printSslErrStr("SSLSetCertificate", ortn
);
267 printf("Server Handshake...\n");
269 ortn
= SSLHandshake(ctx
);
270 if(ortn
== errSSLWouldBlock
) {
271 /* keep UI responsive */
274 } while (ortn
== errSSLWouldBlock
);
277 printSslErrStr("SSLHandshake", ortn
);
281 SSLGetClientCertificateState(ctx
, &certState
);
282 SSLGetNegotiatedCipher(ctx
, &negCipher
);
284 printf("Server Handshake done. Cipher is %s\n", sslGetCipherSuiteString(negCipher
));
286 unsigned char buffer
[MTU
];
290 while((ortn
=SSLRead(ctx
, buffer
, MTU
, &readLen
))==errSSLWouldBlock
);
292 printSslErrStr("SSLRead", ortn
);
296 printf("Received %lu bytes:\n", readLen
);
297 dumppacket(buffer
, readLen
);
299 ortn
=SSLWrite(ctx
, buffer
, readLen
, &len
);
301 printSslErrStr("SSLRead", ortn
);
304 printf("Echoing %lu bytes\n", len
);
307 SSLDisposeContext(ctx
);