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
main.cpp
00001 #define __DEBUG__ 4 //Maximum verbosity 00002 #ifndef __MODULE__ 00003 #define __MODULE__ "main.cpp" 00004 #endif 00005 00006 #define DEBUG_CYASSL 1 00007 #include "bsd_socket.h" 00008 #include "mbed.h" 00009 #include "rtos.h" 00010 #include "dbg.h" 00011 #include "cyassl/ssl.h" 00012 #include "VodafoneUSBModem.h" 00013 //#include "EthernetInterface.h" 00014 #include "NTPClient.h" 00015 00016 #include "logging.h" 00017 00018 #define APN_GDSP 00019 00020 #ifdef APN_GDSP 00021 #define APN "ppinternetd.gdsp" 00022 #define APN_USERNAME "" 00023 #define APN_PASSWORD "" 00024 #endif 00025 00026 #ifdef APN_CONTRACT 00027 #define APN "internet" 00028 #define APN_USERNAME "web" 00029 #define APN_PASSWORD "web" 00030 #endif 00031 00032 #ifdef APN_PAYG 00033 #define APN "smart" 00034 #define APN_USERNAME "web" 00035 #define APN_PASSWORD "web" 00036 #endif 00037 00038 #include "certs/device_certificate.h" 00039 #include "certs/device_private_key.h" 00040 #include "certs/root_certificate.h" 00041 00042 #include <cyassl/ctaocrypt/types.h> 00043 00044 00045 static INLINE unsigned int my_psk_client_cb(CYASSL* ssl, const char* hint, 00046 char* identity, unsigned int id_max_len, unsigned char* key, 00047 unsigned int key_max_len) 00048 { 00049 (void)ssl; 00050 (void)hint; 00051 (void)key_max_len; 00052 00053 DBG("PSK client callback callled."); 00054 00055 // identity is OpenSSL testing default for openssl s_client, keep same 00056 strncpy(identity, "Client_identity", id_max_len); 00057 00058 00059 // test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using 00060 // unsigned binary 00061 key[0] = 26; 00062 key[1] = 43; 00063 key[2] = 60; 00064 key[3] = 77; 00065 00066 return 4; // length of key in octets or 0 for error 00067 } 00068 /* 00069 00070 static INLINE unsigned int my_psk_server_cb(CYASSL* ssl, const char* identity, 00071 unsigned char* key, unsigned int key_max_len) 00072 { 00073 (void)ssl; 00074 (void)key_max_len; 00075 00076 00077 DBG("PSK server callback called."); 00078 00079 // identity is OpenSSL testing default for openssl s_client, keep same 00080 if (strncmp(identity, "Client_identity", 15) != 0) 00081 return 0; 00082 00083 // test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using 00084 // unsigned binary 00085 key[0] = 26; 00086 key[1] = 43; 00087 key[2] = 60; 00088 key[3] = 77; 00089 00090 return 4; // length of key in octets or 0 for error 00091 } 00092 */ 00093 00094 sockaddr_in bindAddr,serverAddress; 00095 00096 bool connectToSocketUDP(char *ipAddress, int port, int *sockfd) { 00097 *sockfd = -1; 00098 // create the socket 00099 if((*sockfd=socket(AF_INET,SOCK_DGRAM,0))<0) { 00100 DBG("Error opening socket"); 00101 return false; 00102 } 00103 socklen_t sockAddrInLen = sizeof(struct sockaddr_in); 00104 00105 // bind socket to 11111 00106 memset(&bindAddr, 0x00, sockAddrInLen); 00107 bindAddr.sin_family = AF_INET; // IP family 00108 bindAddr.sin_port = htons(11111); 00109 bindAddr.sin_addr.s_addr = IPADDR_ANY; // 32 bit IP representation 00110 // call bind 00111 if(bind(*sockfd,(const struct sockaddr *)&bindAddr,sockAddrInLen)!=0) { 00112 DBG("Error binding socket"); 00113 perror(NULL); 00114 } 00115 00116 INFO("UDP socket created and bound to: %s:%d",inet_ntoa(bindAddr.sin_addr),ntohs(bindAddr.sin_port)); 00117 00118 // create the socket address 00119 00120 memset(&serverAddress, 0x00, sizeof(struct sockaddr_in)); 00121 serverAddress.sin_addr.s_addr = inet_addr(ipAddress); 00122 serverAddress.sin_family = AF_INET; 00123 serverAddress.sin_port = htons(port); 00124 00125 // do socket connect 00126 //LOG("Connecting socket to %s:%d", inet_ntoa(serverAddress.sin_addr), ntohs(serverAddress.sin_port)); 00127 if(connect(*sockfd, (const struct sockaddr *)&serverAddress, sizeof(serverAddress))<0) { 00128 shutdown(*sockfd,SHUT_RDWR); 00129 close(*sockfd); 00130 DBG("Could not connect"); 00131 return false; 00132 } 00133 return true; 00134 } 00135 00136 bool connectToSocket(char *ipAddress, int port, int *sockfd) { 00137 *sockfd = -1; 00138 // create the socket 00139 if((*sockfd=socket(AF_INET,SOCK_STREAM,0))<0) { 00140 DBG("Error opening socket"); 00141 return false; 00142 } 00143 00144 // create the socket address 00145 sockaddr_in serverAddress; 00146 std::memset(&serverAddress, 0, sizeof(struct sockaddr_in)); 00147 serverAddress.sin_addr.s_addr = inet_addr(ipAddress); 00148 serverAddress.sin_family = AF_INET; 00149 serverAddress.sin_port = htons(port); 00150 00151 // do socket connect 00152 //LOG("Connecting socket to %s:%d", inet_ntoa(serverAddress.sin_addr), ntohs(serverAddress.sin_port)); 00153 if(connect(*sockfd, (const struct sockaddr *)&serverAddress, sizeof(serverAddress))<0) { 00154 shutdown(*sockfd,SHUT_RDWR); 00155 close(*sockfd); 00156 DBG("Could not connect"); 00157 return false; 00158 } 00159 return true; 00160 } 00161 /* 00162 int handshakeCallback(HandShakeInfo* hinfo) { 00163 DBG("Handshake callback called"); 00164 } 00165 int timeoutCallback(TimeoutInfo *tinfo) { 00166 DBG("Timeout callback called"); 00167 } 00168 */ 00169 00170 00171 DigitalOut myled(LED1); 00172 //#define INTERFACE EthernetInterface 00173 #define INTERFACE VodafoneUSBModem 00174 00175 void printError(CYASSL *ssl, int resultCode) { 00176 int err = CyaSSL_get_error(ssl, resultCode); 00177 char errorString[80]; 00178 CyaSSL_ERR_error_string(err, errorString); 00179 DBG("Error: CyaSSL_write %s", errorString); 00180 } 00181 00182 void debugCallback(const int logLevel,const char *const logMessage) { 00183 DBG(logMessage); 00184 } 00185 00186 00187 int main() { 00188 DBG_INIT(); 00189 DBG_SET_SPEED(115200); 00190 DBG_SET_NEWLINE("\r\n"); 00191 DBG("\r\n\r\n\r\n\r\n"); 00192 00193 int ret = 0; 00194 00195 // init modem 00196 INTERFACE modem; 00197 // connnect modem to cellular network 00198 DBG("connecting to network interface"); 00199 if(modem.connect(APN,APN_USERNAME,APN_PASSWORD)!=0) { 00200 DBG("Error connecting to mobile network"); 00201 } 00202 /* 00203 modem.init(); 00204 if(modem.connect(10000)) { 00205 DBG("Error initialising ethernet interface"); 00206 } 00207 */ 00208 DBG("Connected to network interface"); 00209 00210 //DBG("IP: %s",modem.getIPAddress()); 00211 00212 // need to set the time before doing anything else 00213 NTPClient ntp; 00214 time_t currentTime = time(NULL); 00215 int obtainedTimeSuccessfully = false; 00216 // try 100 times and then just force a watchdog reboot 00217 for(int i=0; i<100; i++) { 00218 obtainedTimeSuccessfully = false; 00219 00220 if(ntp.setTime("0.pool.ntp.org")==0) { 00221 // there is a bug from somewhere which results in a negative timestamp 00222 currentTime = time(NULL); 00223 if(currentTime>0) { 00224 obtainedTimeSuccessfully = true; 00225 INFO("Time set successfully, time is now (UTC): %s", ctime(¤tTime)); 00226 } 00227 } 00228 if(obtainedTimeSuccessfully) { 00229 break; 00230 } 00231 } 00232 00233 00234 // set SSL method to SSL v3 (TLS v1.2) 00235 //CyaSSLv23_client_method(); 00236 00237 CyaSSL_Init();// Initialize CyaSSL 00238 if(CyaSSL_Debugging_ON()==0) { 00239 DBG("CyaSSL debugging enabled"); 00240 } else { 00241 DBG("CyaSSL debugging not compiled in"); 00242 } 00243 00244 CyaSSL_SetLoggingCb(&debugCallback); 00245 00246 00247 00248 // set client method 00249 00250 // TLS 00251 //CYASSL_CTX* ctx = CyaSSL_CTX_new(CyaSSLv23_client_method()); 00252 00253 // DTLS 00254 CYASSL_METHOD* method = CyaDTLSv1_2_client_method(); 00255 if(method == NULL) { 00256 // unable to get method 00257 } 00258 CYASSL_CTX* ctx; 00259 ctx = CyaSSL_CTX_new(method); 00260 if(ctx == NULL){ 00261 DBG("CyaSSL_CTX_new error.\n"); 00262 exit(EXIT_FAILURE); 00263 } 00264 00265 DBG("Setup SSL context"); 00266 00267 00268 00269 00270 // use pre-shared keys 00271 //CyaSSL_CTX_set_psk_client_callback(ctx,my_psk_client_cb); 00272 /* 00273 if(CyaSSL_CTX_load_verify_buffer(ctx, serverCert, strlen((const char*)serverCert),SSL_FILETYPE_PEM)==0) { 00274 DBG("loaded server cert OK"); 00275 }*/ 00276 00277 00278 // load certificates for CA and us 00279 // load CA cert 00280 ret = CyaSSL_CTX_load_verify_buffer(ctx,rootCertificate, rootCertificateLength,SSL_FILETYPE_ASN1); 00281 // load device cert 00282 ret = CyaSSL_CTX_use_certificate_buffer(ctx, deviceCertificate, deviceCertificateLength, SSL_FILETYPE_ASN1); 00283 // load device private key 00284 ret = CyaSSL_CTX_use_PrivateKey_buffer(ctx, devicePrivateKey, devicePrivateKeyLength, SSL_FILETYPE_ASN1); 00285 00286 00287 int sockfd = NULL; 00288 //if(!connectToSocketUDP("192.168.1.99", 11111, &sockfd)) { 00289 if(!connectToSocketUDP("95.47.118.120", 11111, &sockfd)) { 00290 DBG("Error connecting to socket"); 00291 } 00292 00293 /* 00294 // connect to SSL enabled webserver 00295 int sockfd = NULL; 00296 if(!connectToSocket("95.47.118.120", 11111, &sockfd)) { 00297 DBG("Error connecting to socket"); 00298 } 00299 DBG("Connected to non-SSL socket"); 00300 */ 00301 00302 // hook into SSL 00303 // Create CYASSL object 00304 CYASSL* ssl; 00305 ssl = CyaSSL_new(ctx); 00306 if(ssl == NULL) { 00307 DBG("CyaSSL_new error."); 00308 exit(EXIT_FAILURE); 00309 } 00310 DBG("CyaSSL_new OK"); 00311 00312 // setup callbacks for handshake failure 00313 /* 00314 Timeval timeout; 00315 timeout.tv_sec = 5; 00316 timeout.tv_usec = 0; 00317 ret = CyaSSL_connect_ex(ssl, handshakeCallback, timeoutCallback, timeout); 00318 */ 00319 00320 // attach to socket 00321 DBG("Attaching CyaSSL to socket"); 00322 CyaSSL_set_fd(ssl, sockfd); 00323 DBG("Attached CyaSSL to socket"); 00324 00325 // DTLS stuff 00326 ret = CyaSSL_dtls_set_peer(ssl, &serverAddress, sizeof(serverAddress)); 00327 if(ret != SSL_SUCCESS) { 00328 // failed to set DTLS peer 00329 DBG("Failed to set DTLS peer"); 00330 } 00331 00332 ret = CyaSSL_dtls(ssl); 00333 if(ret) { 00334 // SSL session has been configured to use DTLS 00335 DBG("DTLS configured"); 00336 } else { 00337 DBG("DTLS not configured"); 00338 } 00339 00340 00341 00342 DBG("Issuing CyaSSL_connect"); 00343 int result = CyaSSL_connect(ssl); 00344 if(result!=SSL_SUCCESS) { 00345 DBG("CyaSSL_connect failed"); 00346 printError(ssl,result); 00347 } 00348 DBG("CyaSSL_connect OK"); 00349 00350 result = CyaSSL_write(ssl,"onion",5); 00351 DBG("Wrote %d things",result); 00352 if(result<0) { 00353 printError(ssl,result); 00354 } 00355 00356 char buffer[200]; 00357 int d =0; 00358 if((d=CyaSSL_read(ssl, &buffer, 200))>0) { 00359 DBG("Received %d bytes: %s",d,buffer); 00360 } 00361 00362 // clean up 00363 CyaSSL_CTX_free(ctx); 00364 CyaSSL_Cleanup(); 00365 00366 }
Generated on Sun Jul 24 2022 02:30:46 by 1.7.2