CyaSSL example using x509 certs and DTLS over ethernet.
Dependencies: EthernetInterface NTPClient cyassl-lib mbed-rtos mbed-src CyaSSL_DTLS_Ethernet
Dependents: CyaSSL_DTLS_Ethernet
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 "EthernetInterface.h" 00013 #include "NTPClient.h" 00014 00015 #include "logging.h" 00016 00017 #include "certs/device_certificate.h" 00018 #include "certs/device_private_key.h" 00019 #include "certs/root_certificate.h" 00020 00021 /* 00022 // this is how you would setup a client PSK 00023 static INLINE unsigned int my_psk_client_cb(CYASSL* ssl, const char* hint, 00024 char* identity, unsigned int id_max_len, unsigned char* key, 00025 unsigned int key_max_len) 00026 { 00027 (void)ssl; 00028 (void)hint; 00029 (void)key_max_len; 00030 00031 DBG("PSK client callback callled."); 00032 00033 // identity is OpenSSL testing default for openssl s_client, keep same 00034 strncpy(identity, "Client_identity", id_max_len); 00035 00036 00037 // test key in hex is 0x1a2b3c4d , in decimal 439,041,101 , we're using 00038 // unsigned binary 00039 key[0] = 26; 00040 key[1] = 43; 00041 key[2] = 60; 00042 key[3] = 77; 00043 00044 return 4; // length of key in octets or 0 for error 00045 } 00046 */ 00047 00048 sockaddr_in bindAddr,serverAddress; 00049 00050 bool connectToSocketUDP(char *ipAddress, int port, int *sockfd) { 00051 *sockfd = -1; 00052 // create the socket 00053 if((*sockfd=socket(AF_INET,SOCK_DGRAM,0))<0) { 00054 DBG("Error opening socket"); 00055 return false; 00056 } 00057 socklen_t sockAddrInLen = sizeof(struct sockaddr_in); 00058 00059 // bind socket to 11111 00060 memset(&bindAddr, 0x00, sockAddrInLen); 00061 bindAddr.sin_family = AF_INET; // IP family 00062 bindAddr.sin_port = htons(11111); 00063 bindAddr.sin_addr.s_addr = IPADDR_ANY; // 32 bit IP representation 00064 // call bind 00065 if(bind(*sockfd,(const struct sockaddr *)&bindAddr,sockAddrInLen)!=0) { 00066 DBG("Error binding socket"); 00067 perror(NULL); 00068 } 00069 00070 INFO("UDP socket created and bound to: %s:%d",inet_ntoa(bindAddr.sin_addr),ntohs(bindAddr.sin_port)); 00071 00072 // create the socket address 00073 00074 memset(&serverAddress, 0x00, sizeof(struct sockaddr_in)); 00075 serverAddress.sin_addr.s_addr = inet_addr(ipAddress); 00076 serverAddress.sin_family = AF_INET; 00077 serverAddress.sin_port = htons(port); 00078 00079 // do socket connect 00080 //LOG("Connecting socket to %s:%d", inet_ntoa(serverAddress.sin_addr), ntohs(serverAddress.sin_port)); 00081 if(connect(*sockfd, (const struct sockaddr *)&serverAddress, sizeof(serverAddress))<0) { 00082 shutdown(*sockfd,SHUT_RDWR); 00083 close(*sockfd); 00084 DBG("Could not connect"); 00085 return false; 00086 } 00087 return true; 00088 } 00089 00090 DigitalOut myled(LED1); 00091 #define INTERFACE EthernetInterface 00092 00093 void printError(CYASSL *ssl, int resultCode) { 00094 int err = CyaSSL_get_error(ssl, resultCode); 00095 char errorString[80]; 00096 CyaSSL_ERR_error_string(err, errorString); 00097 DBG("Error: CyaSSL_write %s", errorString); 00098 } 00099 00100 void debugCallback(const int logLevel,const char *const logMessage) { 00101 DBG(logMessage); 00102 } 00103 00104 00105 int main() { 00106 DBG_INIT(); 00107 DBG_SET_SPEED(115200); 00108 DBG_SET_NEWLINE("\r\n"); 00109 DBG("\r\n\r\n\r\n\r\n"); 00110 00111 int ret = 0; 00112 00113 // init ethernet 00114 EthernetInterface ethernet; 00115 // connnect ethernet 00116 DBG("Cnnecting to network interface"); 00117 ethernet.init(); 00118 if(ethernet.connect(10000)) { 00119 DBG("Error initialising ethernet interface"); 00120 } 00121 DBG("Connected to network interface"); 00122 00123 DBG("IP: %s",ethernet.getIPAddress()); 00124 00125 // need to set the time before doing anything else 00126 NTPClient ntp; 00127 time_t currentTime = time(NULL); 00128 int obtainedTimeSuccessfully = false; 00129 // try 100 times and then just force a watchdog reboot 00130 for(int i=0; i<100; i++) { 00131 obtainedTimeSuccessfully = false; 00132 00133 if(ntp.setTime("0.pool.ntp.org")==0) { 00134 // there is a bug from somewhere which results in a negative timestamp 00135 currentTime = time(NULL); 00136 if(currentTime>0) { 00137 obtainedTimeSuccessfully = true; 00138 INFO("Time set successfully, time is now (UTC): %s", ctime(¤tTime)); 00139 } 00140 } 00141 if(obtainedTimeSuccessfully) { 00142 break; 00143 } 00144 } 00145 00146 CyaSSL_Init();// Initialize CyaSSL 00147 if(CyaSSL_Debugging_ON()==0) { 00148 DBG("CyaSSL debugging enabled"); 00149 } else { 00150 DBG("CyaSSL debugging not compiled in"); 00151 } 00152 00153 // use our own debugging system for CyaSSL debugging 00154 CyaSSL_SetLoggingCb(&debugCallback); 00155 00156 // set client method 00157 00158 // DTLS 00159 CYASSL_METHOD* method = CyaDTLSv1_2_client_method(); 00160 if(method == NULL) { 00161 // unable to get method 00162 } 00163 CYASSL_CTX* ctx; 00164 ctx = CyaSSL_CTX_new(method); 00165 if(ctx == NULL){ 00166 DBG("CyaSSL_CTX_new error.\n"); 00167 exit(EXIT_FAILURE); 00168 } 00169 00170 DBG("Setup SSL context"); 00171 00172 // use pre-shared keys 00173 //CyaSSL_CTX_set_psk_client_callback(ctx,my_psk_client_cb); 00174 00175 // load certificates for CA and us 00176 // load CA cert 00177 ret = CyaSSL_CTX_load_verify_buffer(ctx,rootCertificate, rootCertificateLength,SSL_FILETYPE_ASN1); 00178 // load device cert 00179 ret = CyaSSL_CTX_use_certificate_buffer(ctx, deviceCertificate, deviceCertificateLength, SSL_FILETYPE_ASN1); 00180 // load device private key 00181 ret = CyaSSL_CTX_use_PrivateKey_buffer(ctx, devicePrivateKey, devicePrivateKeyLength, SSL_FILETYPE_ASN1); 00182 00183 // setup UDP socket 00184 int sockfd = NULL; 00185 if(!connectToSocketUDP("192.168.1.99", 11111, &sockfd)) { 00186 DBG("Error connecting to socket"); 00187 } 00188 00189 DBG("Connected to non-SSL socket"); 00190 00191 // hook into SSL 00192 // Create CYASSL object 00193 CYASSL* ssl; 00194 ssl = CyaSSL_new(ctx); 00195 if(ssl == NULL) { 00196 DBG("CyaSSL_new error."); 00197 exit(EXIT_FAILURE); 00198 } 00199 DBG("CyaSSL_new OK"); 00200 00201 // this is where you set the peer name for the server 00202 // CyaSSL_connect() will return an error which resolves to 00203 // DOMAIN_NAME_MISMATCH via CyaSSL_get_error() 00204 // this is how you ensure that the peer is who you think it is 00205 CyaSSL_check_domain_name(ssl, "DMServer"); 00206 00207 // attach to socket 00208 DBG("Attaching CyaSSL to socket"); 00209 CyaSSL_set_fd(ssl, sockfd); 00210 DBG("Attached CyaSSL to socket"); 00211 00212 // DTLS stuff 00213 ret = CyaSSL_dtls_set_peer(ssl, &serverAddress, sizeof(serverAddress)); 00214 if(ret != SSL_SUCCESS) { 00215 // failed to set DTLS peer 00216 DBG("Failed to set DTLS peer"); 00217 } 00218 00219 ret = CyaSSL_dtls(ssl); 00220 if(ret) { 00221 // SSL session has been configured to use DTLS 00222 DBG("DTLS configured"); 00223 } else { 00224 DBG("DTLS not configured"); 00225 } 00226 00227 DBG("Issuing CyaSSL_connect"); 00228 int result = CyaSSL_connect(ssl); 00229 if(result!=SSL_SUCCESS) { 00230 DBG("CyaSSL_connect failed"); 00231 printError(ssl,result); 00232 } 00233 DBG("CyaSSL_connect OK"); 00234 00235 result = CyaSSL_write(ssl,"onion",5); 00236 DBG("Wrote %d things",result); 00237 if(result<0) { 00238 printError(ssl,result); 00239 } 00240 00241 char buffer[200]; 00242 int d =0; 00243 if((d=CyaSSL_read(ssl, &buffer, 200))>0) { 00244 DBG("Received %d bytes: %s",d,buffer); 00245 } 00246 00247 // clean up 00248 CyaSSL_CTX_free(ctx); 00249 CyaSSL_Cleanup(); 00250 00251 }
Generated on Tue Jul 12 2022 12:46:43 by
![doxygen](doxygen.png)