DTLS example using CyaSSL 2.7.0 and x509 certs. Doesn't work at present due to DTLS handshake failure. Debugging.

Dependencies:   NTPClient VodafoneUSBModem cyassl-lib mbed-rtos mbed-src

Committer:
ashleymills
Date:
Thu Sep 05 15:56:41 2013 +0000
Revision:
0:35b690909566
Initial commit. Doesn't work properly. DTLS handshake fails.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:35b690909566 1 #define __DEBUG__ 4 //Maximum verbosity
ashleymills 0:35b690909566 2 #ifndef __MODULE__
ashleymills 0:35b690909566 3 #define __MODULE__ "main.cpp"
ashleymills 0:35b690909566 4 #endif
ashleymills 0:35b690909566 5
ashleymills 0:35b690909566 6 #define DEBUG_CYASSL 1
ashleymills 0:35b690909566 7 #include "bsd_socket.h"
ashleymills 0:35b690909566 8 #include "mbed.h"
ashleymills 0:35b690909566 9 #include "rtos.h"
ashleymills 0:35b690909566 10 #include "dbg.h"
ashleymills 0:35b690909566 11 #include "cyassl/ssl.h"
ashleymills 0:35b690909566 12 #include "VodafoneUSBModem.h"
ashleymills 0:35b690909566 13 //#include "EthernetInterface.h"
ashleymills 0:35b690909566 14 #include "NTPClient.h"
ashleymills 0:35b690909566 15
ashleymills 0:35b690909566 16 #include "logging.h"
ashleymills 0:35b690909566 17
ashleymills 0:35b690909566 18 #define APN_GDSP
ashleymills 0:35b690909566 19
ashleymills 0:35b690909566 20 #ifdef APN_GDSP
ashleymills 0:35b690909566 21 #define APN "ppinternetd.gdsp"
ashleymills 0:35b690909566 22 #define APN_USERNAME ""
ashleymills 0:35b690909566 23 #define APN_PASSWORD ""
ashleymills 0:35b690909566 24 #endif
ashleymills 0:35b690909566 25
ashleymills 0:35b690909566 26 #ifdef APN_CONTRACT
ashleymills 0:35b690909566 27 #define APN "internet"
ashleymills 0:35b690909566 28 #define APN_USERNAME "web"
ashleymills 0:35b690909566 29 #define APN_PASSWORD "web"
ashleymills 0:35b690909566 30 #endif
ashleymills 0:35b690909566 31
ashleymills 0:35b690909566 32 #ifdef APN_PAYG
ashleymills 0:35b690909566 33 #define APN "smart"
ashleymills 0:35b690909566 34 #define APN_USERNAME "web"
ashleymills 0:35b690909566 35 #define APN_PASSWORD "web"
ashleymills 0:35b690909566 36 #endif
ashleymills 0:35b690909566 37
ashleymills 0:35b690909566 38 #include "certs/device_certificate.h"
ashleymills 0:35b690909566 39 #include "certs/device_private_key.h"
ashleymills 0:35b690909566 40 #include "certs/root_certificate.h"
ashleymills 0:35b690909566 41
ashleymills 0:35b690909566 42 #include <cyassl/ctaocrypt/types.h>
ashleymills 0:35b690909566 43
ashleymills 0:35b690909566 44
ashleymills 0:35b690909566 45 static INLINE unsigned int my_psk_client_cb(CYASSL* ssl, const char* hint,
ashleymills 0:35b690909566 46 char* identity, unsigned int id_max_len, unsigned char* key,
ashleymills 0:35b690909566 47 unsigned int key_max_len)
ashleymills 0:35b690909566 48 {
ashleymills 0:35b690909566 49 (void)ssl;
ashleymills 0:35b690909566 50 (void)hint;
ashleymills 0:35b690909566 51 (void)key_max_len;
ashleymills 0:35b690909566 52
ashleymills 0:35b690909566 53 DBG("PSK client callback callled.");
ashleymills 0:35b690909566 54
ashleymills 0:35b690909566 55 // identity is OpenSSL testing default for openssl s_client, keep same
ashleymills 0:35b690909566 56 strncpy(identity, "Client_identity", id_max_len);
ashleymills 0:35b690909566 57
ashleymills 0:35b690909566 58
ashleymills 0:35b690909566 59 // test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
ashleymills 0:35b690909566 60 // unsigned binary
ashleymills 0:35b690909566 61 key[0] = 26;
ashleymills 0:35b690909566 62 key[1] = 43;
ashleymills 0:35b690909566 63 key[2] = 60;
ashleymills 0:35b690909566 64 key[3] = 77;
ashleymills 0:35b690909566 65
ashleymills 0:35b690909566 66 return 4; // length of key in octets or 0 for error
ashleymills 0:35b690909566 67 }
ashleymills 0:35b690909566 68 /*
ashleymills 0:35b690909566 69
ashleymills 0:35b690909566 70 static INLINE unsigned int my_psk_server_cb(CYASSL* ssl, const char* identity,
ashleymills 0:35b690909566 71 unsigned char* key, unsigned int key_max_len)
ashleymills 0:35b690909566 72 {
ashleymills 0:35b690909566 73 (void)ssl;
ashleymills 0:35b690909566 74 (void)key_max_len;
ashleymills 0:35b690909566 75
ashleymills 0:35b690909566 76
ashleymills 0:35b690909566 77 DBG("PSK server callback called.");
ashleymills 0:35b690909566 78
ashleymills 0:35b690909566 79 // identity is OpenSSL testing default for openssl s_client, keep same
ashleymills 0:35b690909566 80 if (strncmp(identity, "Client_identity", 15) != 0)
ashleymills 0:35b690909566 81 return 0;
ashleymills 0:35b690909566 82
ashleymills 0:35b690909566 83 // test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using
ashleymills 0:35b690909566 84 // unsigned binary
ashleymills 0:35b690909566 85 key[0] = 26;
ashleymills 0:35b690909566 86 key[1] = 43;
ashleymills 0:35b690909566 87 key[2] = 60;
ashleymills 0:35b690909566 88 key[3] = 77;
ashleymills 0:35b690909566 89
ashleymills 0:35b690909566 90 return 4; // length of key in octets or 0 for error
ashleymills 0:35b690909566 91 }
ashleymills 0:35b690909566 92 */
ashleymills 0:35b690909566 93
ashleymills 0:35b690909566 94 sockaddr_in bindAddr,serverAddress;
ashleymills 0:35b690909566 95
ashleymills 0:35b690909566 96 bool connectToSocketUDP(char *ipAddress, int port, int *sockfd) {
ashleymills 0:35b690909566 97 *sockfd = -1;
ashleymills 0:35b690909566 98 // create the socket
ashleymills 0:35b690909566 99 if((*sockfd=socket(AF_INET,SOCK_DGRAM,0))<0) {
ashleymills 0:35b690909566 100 DBG("Error opening socket");
ashleymills 0:35b690909566 101 return false;
ashleymills 0:35b690909566 102 }
ashleymills 0:35b690909566 103 socklen_t sockAddrInLen = sizeof(struct sockaddr_in);
ashleymills 0:35b690909566 104
ashleymills 0:35b690909566 105 // bind socket to 11111
ashleymills 0:35b690909566 106 memset(&bindAddr, 0x00, sockAddrInLen);
ashleymills 0:35b690909566 107 bindAddr.sin_family = AF_INET; // IP family
ashleymills 0:35b690909566 108 bindAddr.sin_port = htons(11111);
ashleymills 0:35b690909566 109 bindAddr.sin_addr.s_addr = IPADDR_ANY; // 32 bit IP representation
ashleymills 0:35b690909566 110 // call bind
ashleymills 0:35b690909566 111 if(bind(*sockfd,(const struct sockaddr *)&bindAddr,sockAddrInLen)!=0) {
ashleymills 0:35b690909566 112 DBG("Error binding socket");
ashleymills 0:35b690909566 113 perror(NULL);
ashleymills 0:35b690909566 114 }
ashleymills 0:35b690909566 115
ashleymills 0:35b690909566 116 INFO("UDP socket created and bound to: %s:%d",inet_ntoa(bindAddr.sin_addr),ntohs(bindAddr.sin_port));
ashleymills 0:35b690909566 117
ashleymills 0:35b690909566 118 // create the socket address
ashleymills 0:35b690909566 119
ashleymills 0:35b690909566 120 memset(&serverAddress, 0x00, sizeof(struct sockaddr_in));
ashleymills 0:35b690909566 121 serverAddress.sin_addr.s_addr = inet_addr(ipAddress);
ashleymills 0:35b690909566 122 serverAddress.sin_family = AF_INET;
ashleymills 0:35b690909566 123 serverAddress.sin_port = htons(port);
ashleymills 0:35b690909566 124
ashleymills 0:35b690909566 125 // do socket connect
ashleymills 0:35b690909566 126 //LOG("Connecting socket to %s:%d", inet_ntoa(serverAddress.sin_addr), ntohs(serverAddress.sin_port));
ashleymills 0:35b690909566 127 if(connect(*sockfd, (const struct sockaddr *)&serverAddress, sizeof(serverAddress))<0) {
ashleymills 0:35b690909566 128 shutdown(*sockfd,SHUT_RDWR);
ashleymills 0:35b690909566 129 close(*sockfd);
ashleymills 0:35b690909566 130 DBG("Could not connect");
ashleymills 0:35b690909566 131 return false;
ashleymills 0:35b690909566 132 }
ashleymills 0:35b690909566 133 return true;
ashleymills 0:35b690909566 134 }
ashleymills 0:35b690909566 135
ashleymills 0:35b690909566 136 bool connectToSocket(char *ipAddress, int port, int *sockfd) {
ashleymills 0:35b690909566 137 *sockfd = -1;
ashleymills 0:35b690909566 138 // create the socket
ashleymills 0:35b690909566 139 if((*sockfd=socket(AF_INET,SOCK_STREAM,0))<0) {
ashleymills 0:35b690909566 140 DBG("Error opening socket");
ashleymills 0:35b690909566 141 return false;
ashleymills 0:35b690909566 142 }
ashleymills 0:35b690909566 143
ashleymills 0:35b690909566 144 // create the socket address
ashleymills 0:35b690909566 145 sockaddr_in serverAddress;
ashleymills 0:35b690909566 146 std::memset(&serverAddress, 0, sizeof(struct sockaddr_in));
ashleymills 0:35b690909566 147 serverAddress.sin_addr.s_addr = inet_addr(ipAddress);
ashleymills 0:35b690909566 148 serverAddress.sin_family = AF_INET;
ashleymills 0:35b690909566 149 serverAddress.sin_port = htons(port);
ashleymills 0:35b690909566 150
ashleymills 0:35b690909566 151 // do socket connect
ashleymills 0:35b690909566 152 //LOG("Connecting socket to %s:%d", inet_ntoa(serverAddress.sin_addr), ntohs(serverAddress.sin_port));
ashleymills 0:35b690909566 153 if(connect(*sockfd, (const struct sockaddr *)&serverAddress, sizeof(serverAddress))<0) {
ashleymills 0:35b690909566 154 shutdown(*sockfd,SHUT_RDWR);
ashleymills 0:35b690909566 155 close(*sockfd);
ashleymills 0:35b690909566 156 DBG("Could not connect");
ashleymills 0:35b690909566 157 return false;
ashleymills 0:35b690909566 158 }
ashleymills 0:35b690909566 159 return true;
ashleymills 0:35b690909566 160 }
ashleymills 0:35b690909566 161 /*
ashleymills 0:35b690909566 162 int handshakeCallback(HandShakeInfo* hinfo) {
ashleymills 0:35b690909566 163 DBG("Handshake callback called");
ashleymills 0:35b690909566 164 }
ashleymills 0:35b690909566 165 int timeoutCallback(TimeoutInfo *tinfo) {
ashleymills 0:35b690909566 166 DBG("Timeout callback called");
ashleymills 0:35b690909566 167 }
ashleymills 0:35b690909566 168 */
ashleymills 0:35b690909566 169
ashleymills 0:35b690909566 170
ashleymills 0:35b690909566 171 DigitalOut myled(LED1);
ashleymills 0:35b690909566 172 //#define INTERFACE EthernetInterface
ashleymills 0:35b690909566 173 #define INTERFACE VodafoneUSBModem
ashleymills 0:35b690909566 174
ashleymills 0:35b690909566 175 void printError(CYASSL *ssl, int resultCode) {
ashleymills 0:35b690909566 176 int err = CyaSSL_get_error(ssl, resultCode);
ashleymills 0:35b690909566 177 char errorString[80];
ashleymills 0:35b690909566 178 CyaSSL_ERR_error_string(err, errorString);
ashleymills 0:35b690909566 179 DBG("Error: CyaSSL_write %s", errorString);
ashleymills 0:35b690909566 180 }
ashleymills 0:35b690909566 181
ashleymills 0:35b690909566 182 void debugCallback(const int logLevel,const char *const logMessage) {
ashleymills 0:35b690909566 183 DBG(logMessage);
ashleymills 0:35b690909566 184 }
ashleymills 0:35b690909566 185
ashleymills 0:35b690909566 186
ashleymills 0:35b690909566 187 int main() {
ashleymills 0:35b690909566 188 DBG_INIT();
ashleymills 0:35b690909566 189 DBG_SET_SPEED(115200);
ashleymills 0:35b690909566 190 DBG_SET_NEWLINE("\r\n");
ashleymills 0:35b690909566 191 DBG("\r\n\r\n\r\n\r\n");
ashleymills 0:35b690909566 192
ashleymills 0:35b690909566 193 int ret = 0;
ashleymills 0:35b690909566 194
ashleymills 0:35b690909566 195 // init modem
ashleymills 0:35b690909566 196 INTERFACE modem;
ashleymills 0:35b690909566 197 // connnect modem to cellular network
ashleymills 0:35b690909566 198 DBG("connecting to network interface");
ashleymills 0:35b690909566 199 if(modem.connect(APN,APN_USERNAME,APN_PASSWORD)!=0) {
ashleymills 0:35b690909566 200 DBG("Error connecting to mobile network");
ashleymills 0:35b690909566 201 }
ashleymills 0:35b690909566 202 /*
ashleymills 0:35b690909566 203 modem.init();
ashleymills 0:35b690909566 204 if(modem.connect(10000)) {
ashleymills 0:35b690909566 205 DBG("Error initialising ethernet interface");
ashleymills 0:35b690909566 206 }
ashleymills 0:35b690909566 207 */
ashleymills 0:35b690909566 208 DBG("Connected to network interface");
ashleymills 0:35b690909566 209
ashleymills 0:35b690909566 210 //DBG("IP: %s",modem.getIPAddress());
ashleymills 0:35b690909566 211
ashleymills 0:35b690909566 212 // need to set the time before doing anything else
ashleymills 0:35b690909566 213 NTPClient ntp;
ashleymills 0:35b690909566 214 time_t currentTime = time(NULL);
ashleymills 0:35b690909566 215 int obtainedTimeSuccessfully = false;
ashleymills 0:35b690909566 216 // try 100 times and then just force a watchdog reboot
ashleymills 0:35b690909566 217 for(int i=0; i<100; i++) {
ashleymills 0:35b690909566 218 obtainedTimeSuccessfully = false;
ashleymills 0:35b690909566 219
ashleymills 0:35b690909566 220 if(ntp.setTime("0.pool.ntp.org")==0) {
ashleymills 0:35b690909566 221 // there is a bug from somewhere which results in a negative timestamp
ashleymills 0:35b690909566 222 currentTime = time(NULL);
ashleymills 0:35b690909566 223 if(currentTime>0) {
ashleymills 0:35b690909566 224 obtainedTimeSuccessfully = true;
ashleymills 0:35b690909566 225 INFO("Time set successfully, time is now (UTC): %s", ctime(&currentTime));
ashleymills 0:35b690909566 226 }
ashleymills 0:35b690909566 227 }
ashleymills 0:35b690909566 228 if(obtainedTimeSuccessfully) {
ashleymills 0:35b690909566 229 break;
ashleymills 0:35b690909566 230 }
ashleymills 0:35b690909566 231 }
ashleymills 0:35b690909566 232
ashleymills 0:35b690909566 233
ashleymills 0:35b690909566 234 // set SSL method to SSL v3 (TLS v1.2)
ashleymills 0:35b690909566 235 //CyaSSLv23_client_method();
ashleymills 0:35b690909566 236
ashleymills 0:35b690909566 237 CyaSSL_Init();// Initialize CyaSSL
ashleymills 0:35b690909566 238 if(CyaSSL_Debugging_ON()==0) {
ashleymills 0:35b690909566 239 DBG("CyaSSL debugging enabled");
ashleymills 0:35b690909566 240 } else {
ashleymills 0:35b690909566 241 DBG("CyaSSL debugging not compiled in");
ashleymills 0:35b690909566 242 }
ashleymills 0:35b690909566 243
ashleymills 0:35b690909566 244 CyaSSL_SetLoggingCb(&debugCallback);
ashleymills 0:35b690909566 245
ashleymills 0:35b690909566 246
ashleymills 0:35b690909566 247
ashleymills 0:35b690909566 248 // set client method
ashleymills 0:35b690909566 249
ashleymills 0:35b690909566 250 // TLS
ashleymills 0:35b690909566 251 //CYASSL_CTX* ctx = CyaSSL_CTX_new(CyaSSLv23_client_method());
ashleymills 0:35b690909566 252
ashleymills 0:35b690909566 253 // DTLS
ashleymills 0:35b690909566 254 CYASSL_METHOD* method = CyaDTLSv1_2_client_method();
ashleymills 0:35b690909566 255 if(method == NULL) {
ashleymills 0:35b690909566 256 // unable to get method
ashleymills 0:35b690909566 257 }
ashleymills 0:35b690909566 258 CYASSL_CTX* ctx;
ashleymills 0:35b690909566 259 ctx = CyaSSL_CTX_new(method);
ashleymills 0:35b690909566 260 if(ctx == NULL){
ashleymills 0:35b690909566 261 DBG("CyaSSL_CTX_new error.\n");
ashleymills 0:35b690909566 262 exit(EXIT_FAILURE);
ashleymills 0:35b690909566 263 }
ashleymills 0:35b690909566 264
ashleymills 0:35b690909566 265 DBG("Setup SSL context");
ashleymills 0:35b690909566 266
ashleymills 0:35b690909566 267
ashleymills 0:35b690909566 268
ashleymills 0:35b690909566 269
ashleymills 0:35b690909566 270 // use pre-shared keys
ashleymills 0:35b690909566 271 //CyaSSL_CTX_set_psk_client_callback(ctx,my_psk_client_cb);
ashleymills 0:35b690909566 272 /*
ashleymills 0:35b690909566 273 if(CyaSSL_CTX_load_verify_buffer(ctx, serverCert, strlen((const char*)serverCert),SSL_FILETYPE_PEM)==0) {
ashleymills 0:35b690909566 274 DBG("loaded server cert OK");
ashleymills 0:35b690909566 275 }*/
ashleymills 0:35b690909566 276
ashleymills 0:35b690909566 277
ashleymills 0:35b690909566 278 // load certificates for CA and us
ashleymills 0:35b690909566 279 // load CA cert
ashleymills 0:35b690909566 280 ret = CyaSSL_CTX_load_verify_buffer(ctx,rootCertificate, rootCertificateLength,SSL_FILETYPE_ASN1);
ashleymills 0:35b690909566 281 // load device cert
ashleymills 0:35b690909566 282 ret = CyaSSL_CTX_use_certificate_buffer(ctx, deviceCertificate, deviceCertificateLength, SSL_FILETYPE_ASN1);
ashleymills 0:35b690909566 283 // load device private key
ashleymills 0:35b690909566 284 ret = CyaSSL_CTX_use_PrivateKey_buffer(ctx, devicePrivateKey, devicePrivateKeyLength, SSL_FILETYPE_ASN1);
ashleymills 0:35b690909566 285
ashleymills 0:35b690909566 286
ashleymills 0:35b690909566 287 int sockfd = NULL;
ashleymills 0:35b690909566 288 //if(!connectToSocketUDP("192.168.1.99", 11111, &sockfd)) {
ashleymills 0:35b690909566 289 if(!connectToSocketUDP("95.47.118.120", 11111, &sockfd)) {
ashleymills 0:35b690909566 290 DBG("Error connecting to socket");
ashleymills 0:35b690909566 291 }
ashleymills 0:35b690909566 292
ashleymills 0:35b690909566 293 /*
ashleymills 0:35b690909566 294 // connect to SSL enabled webserver
ashleymills 0:35b690909566 295 int sockfd = NULL;
ashleymills 0:35b690909566 296 if(!connectToSocket("95.47.118.120", 11111, &sockfd)) {
ashleymills 0:35b690909566 297 DBG("Error connecting to socket");
ashleymills 0:35b690909566 298 }
ashleymills 0:35b690909566 299 DBG("Connected to non-SSL socket");
ashleymills 0:35b690909566 300 */
ashleymills 0:35b690909566 301
ashleymills 0:35b690909566 302 // hook into SSL
ashleymills 0:35b690909566 303 // Create CYASSL object
ashleymills 0:35b690909566 304 CYASSL* ssl;
ashleymills 0:35b690909566 305 ssl = CyaSSL_new(ctx);
ashleymills 0:35b690909566 306 if(ssl == NULL) {
ashleymills 0:35b690909566 307 DBG("CyaSSL_new error.");
ashleymills 0:35b690909566 308 exit(EXIT_FAILURE);
ashleymills 0:35b690909566 309 }
ashleymills 0:35b690909566 310 DBG("CyaSSL_new OK");
ashleymills 0:35b690909566 311
ashleymills 0:35b690909566 312 // setup callbacks for handshake failure
ashleymills 0:35b690909566 313 /*
ashleymills 0:35b690909566 314 Timeval timeout;
ashleymills 0:35b690909566 315 timeout.tv_sec = 5;
ashleymills 0:35b690909566 316 timeout.tv_usec = 0;
ashleymills 0:35b690909566 317 ret = CyaSSL_connect_ex(ssl, handshakeCallback, timeoutCallback, timeout);
ashleymills 0:35b690909566 318 */
ashleymills 0:35b690909566 319
ashleymills 0:35b690909566 320 // attach to socket
ashleymills 0:35b690909566 321 DBG("Attaching CyaSSL to socket");
ashleymills 0:35b690909566 322 CyaSSL_set_fd(ssl, sockfd);
ashleymills 0:35b690909566 323 DBG("Attached CyaSSL to socket");
ashleymills 0:35b690909566 324
ashleymills 0:35b690909566 325 // DTLS stuff
ashleymills 0:35b690909566 326 ret = CyaSSL_dtls_set_peer(ssl, &serverAddress, sizeof(serverAddress));
ashleymills 0:35b690909566 327 if(ret != SSL_SUCCESS) {
ashleymills 0:35b690909566 328 // failed to set DTLS peer
ashleymills 0:35b690909566 329 DBG("Failed to set DTLS peer");
ashleymills 0:35b690909566 330 }
ashleymills 0:35b690909566 331
ashleymills 0:35b690909566 332 ret = CyaSSL_dtls(ssl);
ashleymills 0:35b690909566 333 if(ret) {
ashleymills 0:35b690909566 334 // SSL session has been configured to use DTLS
ashleymills 0:35b690909566 335 DBG("DTLS configured");
ashleymills 0:35b690909566 336 } else {
ashleymills 0:35b690909566 337 DBG("DTLS not configured");
ashleymills 0:35b690909566 338 }
ashleymills 0:35b690909566 339
ashleymills 0:35b690909566 340
ashleymills 0:35b690909566 341
ashleymills 0:35b690909566 342 DBG("Issuing CyaSSL_connect");
ashleymills 0:35b690909566 343 int result = CyaSSL_connect(ssl);
ashleymills 0:35b690909566 344 if(result!=SSL_SUCCESS) {
ashleymills 0:35b690909566 345 DBG("CyaSSL_connect failed");
ashleymills 0:35b690909566 346 printError(ssl,result);
ashleymills 0:35b690909566 347 }
ashleymills 0:35b690909566 348 DBG("CyaSSL_connect OK");
ashleymills 0:35b690909566 349
ashleymills 0:35b690909566 350 result = CyaSSL_write(ssl,"onion",5);
ashleymills 0:35b690909566 351 DBG("Wrote %d things",result);
ashleymills 0:35b690909566 352 if(result<0) {
ashleymills 0:35b690909566 353 printError(ssl,result);
ashleymills 0:35b690909566 354 }
ashleymills 0:35b690909566 355
ashleymills 0:35b690909566 356 char buffer[200];
ashleymills 0:35b690909566 357 int d =0;
ashleymills 0:35b690909566 358 if((d=CyaSSL_read(ssl, &buffer, 200))>0) {
ashleymills 0:35b690909566 359 DBG("Received %d bytes: %s",d,buffer);
ashleymills 0:35b690909566 360 }
ashleymills 0:35b690909566 361
ashleymills 0:35b690909566 362 // clean up
ashleymills 0:35b690909566 363 CyaSSL_CTX_free(ctx);
ashleymills 0:35b690909566 364 CyaSSL_Cleanup();
ashleymills 0:35b690909566 365
ashleymills 0:35b690909566 366 }