Rough and ready demo of axTLS with 3G modem

Dependencies:   VodafoneUSBModem_bleedingedge axTLS mbed-rtos mbed

Committer:
ashleymills
Date:
Tue May 28 10:18:05 2013 +0000
Revision:
1:db88ff473b1a
Parent:
0:795bb54e1ee8
Rough and ready demo of axtls with 3g modem

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ashleymills 0:795bb54e1ee8 1 #define __DEBUG__ 4 //Maximum verbosity
ashleymills 0:795bb54e1ee8 2 #ifndef __MODULE__
ashleymills 0:795bb54e1ee8 3 #define __MODULE__ "main.cpp"
ashleymills 0:795bb54e1ee8 4 #endif
ashleymills 0:795bb54e1ee8 5
ashleymills 0:795bb54e1ee8 6 #include "mbed.h"
ashleymills 0:795bb54e1ee8 7 #include "rtos.h"
ashleymills 0:795bb54e1ee8 8 #include "VodafoneUSBModem.h"
ashleymills 0:795bb54e1ee8 9 #include "ssl.h"
ashleymills 0:795bb54e1ee8 10 #include "socket.h"
ashleymills 0:795bb54e1ee8 11 #include "cert.h"
ashleymills 0:795bb54e1ee8 12
ashleymills 0:795bb54e1ee8 13 #define APN_PAYG
ashleymills 0:795bb54e1ee8 14
ashleymills 0:795bb54e1ee8 15 #ifdef APN_GDSP
ashleymills 0:795bb54e1ee8 16 #define APN "ppinternetd.gdsp"
ashleymills 0:795bb54e1ee8 17 #define APN_USERNAME ""
ashleymills 0:795bb54e1ee8 18 #define APN_PASSWORD ""
ashleymills 0:795bb54e1ee8 19 #endif
ashleymills 0:795bb54e1ee8 20
ashleymills 0:795bb54e1ee8 21 #ifdef APN_CONTRACT
ashleymills 0:795bb54e1ee8 22 #define APN "internet"
ashleymills 0:795bb54e1ee8 23 #define APN_USERNAME "web"
ashleymills 0:795bb54e1ee8 24 #define APN_PASSWORD "web"
ashleymills 0:795bb54e1ee8 25 #endif
ashleymills 0:795bb54e1ee8 26
ashleymills 0:795bb54e1ee8 27 #ifdef APN_PAYG
ashleymills 0:795bb54e1ee8 28 #define APN "smart"
ashleymills 0:795bb54e1ee8 29 #define APN_USERNAME "web"
ashleymills 0:795bb54e1ee8 30 #define APN_PASSWORD "web"
ashleymills 0:795bb54e1ee8 31 #endif
ashleymills 0:795bb54e1ee8 32
ashleymills 0:795bb54e1ee8 33 DigitalOut myled(LED1);
ashleymills 0:795bb54e1ee8 34
ashleymills 0:795bb54e1ee8 35 static void display_cipher(SSL *ssl)
ashleymills 0:795bb54e1ee8 36 {
ashleymills 0:795bb54e1ee8 37 printf("CIPHER is ");
ashleymills 0:795bb54e1ee8 38 switch (ssl_get_cipher_id(ssl))
ashleymills 0:795bb54e1ee8 39 {
ashleymills 0:795bb54e1ee8 40 case SSL_AES128_SHA:
ashleymills 0:795bb54e1ee8 41 printf("AES128-SHA");
ashleymills 0:795bb54e1ee8 42 break;
ashleymills 0:795bb54e1ee8 43
ashleymills 0:795bb54e1ee8 44 case SSL_AES256_SHA:
ashleymills 0:795bb54e1ee8 45 printf("AES256-SHA");
ashleymills 0:795bb54e1ee8 46 break;
ashleymills 0:795bb54e1ee8 47
ashleymills 0:795bb54e1ee8 48 case SSL_RC4_128_SHA:
ashleymills 0:795bb54e1ee8 49 printf("RC4-SHA");
ashleymills 0:795bb54e1ee8 50 break;
ashleymills 0:795bb54e1ee8 51
ashleymills 0:795bb54e1ee8 52 case SSL_RC4_128_MD5:
ashleymills 0:795bb54e1ee8 53 printf("RC4-MD5");
ashleymills 0:795bb54e1ee8 54 break;
ashleymills 0:795bb54e1ee8 55
ashleymills 0:795bb54e1ee8 56 default:
ashleymills 0:795bb54e1ee8 57 printf("Unknown - %d", ssl_get_cipher_id(ssl));
ashleymills 0:795bb54e1ee8 58 break;
ashleymills 0:795bb54e1ee8 59 }
ashleymills 0:795bb54e1ee8 60
ashleymills 0:795bb54e1ee8 61 printf("\r\n");
ashleymills 0:795bb54e1ee8 62 }
ashleymills 0:795bb54e1ee8 63
ashleymills 0:795bb54e1ee8 64
ashleymills 0:795bb54e1ee8 65 bool connectToSocket(char *ipAddress, int port, int *sockfd) {
ashleymills 0:795bb54e1ee8 66 *sockfd = -1;
ashleymills 0:795bb54e1ee8 67 // create the socket
ashleymills 0:795bb54e1ee8 68 if((*sockfd=socket(AF_INET,SOCK_STREAM,0))<0) {
ashleymills 0:795bb54e1ee8 69 DBG("Error opening socket");
ashleymills 0:795bb54e1ee8 70 return false;
ashleymills 0:795bb54e1ee8 71 }
ashleymills 0:795bb54e1ee8 72
ashleymills 0:795bb54e1ee8 73 // create the socket address
ashleymills 0:795bb54e1ee8 74 sockaddr_in serverAddress;
ashleymills 0:795bb54e1ee8 75 std::memset(&serverAddress, 0, sizeof(struct sockaddr_in));
ashleymills 0:795bb54e1ee8 76 serverAddress.sin_addr.s_addr = inet_addr(ipAddress);
ashleymills 0:795bb54e1ee8 77 serverAddress.sin_family = AF_INET;
ashleymills 0:795bb54e1ee8 78 serverAddress.sin_port = htons(port);
ashleymills 0:795bb54e1ee8 79
ashleymills 0:795bb54e1ee8 80 // do socket connect
ashleymills 0:795bb54e1ee8 81 //LOG("Connecting socket to %s:%d", inet_ntoa(serverAddress.sin_addr), ntohs(serverAddress.sin_port));
ashleymills 0:795bb54e1ee8 82 if(connect(*sockfd, (const struct sockaddr *)&serverAddress, sizeof(serverAddress))<0) {
ashleymills 0:795bb54e1ee8 83 ::close(*sockfd);
ashleymills 0:795bb54e1ee8 84 DBG("Could not connect");
ashleymills 0:795bb54e1ee8 85 return false;
ashleymills 0:795bb54e1ee8 86 }
ashleymills 0:795bb54e1ee8 87 return true;
ashleymills 0:795bb54e1ee8 88 }
ashleymills 0:795bb54e1ee8 89
ashleymills 0:795bb54e1ee8 90 void finishOnError() {
ashleymills 0:795bb54e1ee8 91 DigitalOut l1(LED1);
ashleymills 0:795bb54e1ee8 92 while(1) {
ashleymills 0:795bb54e1ee8 93 Thread::wait(1000);
ashleymills 0:795bb54e1ee8 94 l1 = !l1;
ashleymills 0:795bb54e1ee8 95 }
ashleymills 0:795bb54e1ee8 96 }
ashleymills 0:795bb54e1ee8 97
ashleymills 0:795bb54e1ee8 98 void finishOnOK() {
ashleymills 0:795bb54e1ee8 99 DigitalOut l(LED2);
ashleymills 0:795bb54e1ee8 100 while(1) {
ashleymills 0:795bb54e1ee8 101 Thread::wait(1000);
ashleymills 0:795bb54e1ee8 102 l = !l;
ashleymills 0:795bb54e1ee8 103 }
ashleymills 0:795bb54e1ee8 104 }
ashleymills 0:795bb54e1ee8 105
ashleymills 0:795bb54e1ee8 106 int main() {
ashleymills 0:795bb54e1ee8 107 DBG_INIT();
ashleymills 0:795bb54e1ee8 108 DBG_SET_SPEED(115200);
ashleymills 0:795bb54e1ee8 109 DBG_SET_NEWLINE("\r\n");
ashleymills 0:795bb54e1ee8 110
ashleymills 0:795bb54e1ee8 111 set_time(1368461860);
ashleymills 0:795bb54e1ee8 112
ashleymills 0:795bb54e1ee8 113 // init modem
ashleymills 0:795bb54e1ee8 114 VodafoneUSBModem modem;
ashleymills 0:795bb54e1ee8 115
ashleymills 0:795bb54e1ee8 116 // SSL stuff
ashleymills 0:795bb54e1ee8 117 uint32_t sslOptions = SSL_DISPLAY_CERTS|SSL_DISPLAY_STATES|SSL_SERVER_VERIFY_LATER;
ashleymills 0:795bb54e1ee8 118 SSL_CTX *ssl_ctx;
ashleymills 0:795bb54e1ee8 119 SSL *ssl = NULL;
ashleymills 0:795bb54e1ee8 120 /*
ashleymills 0:795bb54e1ee8 121 char **ca_cert, **cert;
ashleymills 0:795bb54e1ee8 122 int cert_size, ca_cert_size;
ashleymills 0:795bb54e1ee8 123 cert_size = ssl_get_config(SSL_MAX_CERT_CFG_OFFSET);
ashleymills 0:795bb54e1ee8 124 ca_cert_size = ssl_get_config(SSL_MAX_CA_CERT_CFG_OFFSET);
ashleymills 0:795bb54e1ee8 125 ca_cert = (char **)calloc(1, sizeof(char *)*ca_cert_size);
ashleymills 0:795bb54e1ee8 126 cert = (char **)calloc(1, sizeof(char *)*cert_size);
ashleymills 0:795bb54e1ee8 127 */
ashleymills 0:795bb54e1ee8 128 uint8_t session_id[SSL_SESSION_ID_SIZE];
ashleymills 0:795bb54e1ee8 129 int res;
ashleymills 0:795bb54e1ee8 130
ashleymills 0:795bb54e1ee8 131 if((ssl_ctx = ssl_ctx_new(sslOptions, SSL_DEFAULT_CLNT_SESS)) == NULL) {
ashleymills 0:795bb54e1ee8 132 DBG("Error: Client context is invalid");
ashleymills 0:795bb54e1ee8 133 finishOnError();
ashleymills 0:795bb54e1ee8 134 }
ashleymills 0:795bb54e1ee8 135
ashleymills 0:795bb54e1ee8 136 if((res = ssl_obj_memory_load(ssl_ctx,SSL_OBJ_X509_CACERT, default_certificate, default_certificate_len,NULL)) != SSL_OK) {
ashleymills 0:795bb54e1ee8 137 DBG("Error loading CA cert\r\n");
ashleymills 0:795bb54e1ee8 138 }
ashleymills 0:795bb54e1ee8 139
ashleymills 0:795bb54e1ee8 140
ashleymills 0:795bb54e1ee8 141 // connnect modem to cellular network
ashleymills 0:795bb54e1ee8 142 DBG("connecting to mobile network");
ashleymills 0:795bb54e1ee8 143 if(modem.connect(APN,APN_USERNAME,APN_PASSWORD)!=0) {
ashleymills 0:795bb54e1ee8 144 DBG("Error connecting to mobile network");
ashleymills 0:795bb54e1ee8 145 finishOnError();
ashleymills 0:795bb54e1ee8 146 }
ashleymills 0:795bb54e1ee8 147 DBG("Connected to mobile network");
ashleymills 0:795bb54e1ee8 148
ashleymills 0:795bb54e1ee8 149
ashleymills 0:795bb54e1ee8 150 // connect to socket over which TLS will be spoken
ashleymills 0:795bb54e1ee8 151 int sockfd = NULL;
ashleymills 0:795bb54e1ee8 152 if(!connectToSocket("95.47.118.120", 4433, &sockfd)) {
ashleymills 0:795bb54e1ee8 153 DBG("Error connecting to socket");
ashleymills 0:795bb54e1ee8 154 modem.disconnect();
ashleymills 0:795bb54e1ee8 155 finishOnError();
ashleymills 0:795bb54e1ee8 156 }
ashleymills 0:795bb54e1ee8 157 DBG("Connected to non-SSL socket");
ashleymills 0:795bb54e1ee8 158
ashleymills 0:795bb54e1ee8 159 ssl = ssl_client_new(ssl_ctx, sockfd, session_id,sizeof(session_id));
ashleymills 0:795bb54e1ee8 160 if(ssl==NULL) {
ashleymills 0:795bb54e1ee8 161 DBG("SSL client is NULL");
ashleymills 0:795bb54e1ee8 162 modem.disconnect();
ashleymills 0:795bb54e1ee8 163 finishOnError();
ashleymills 0:795bb54e1ee8 164 }
ashleymills 0:795bb54e1ee8 165 if((res = ssl_handshake_status(ssl)) != SSL_OK) {
ashleymills 0:795bb54e1ee8 166 DBG("Error conecting ssl client");
ashleymills 0:795bb54e1ee8 167 modem.disconnect();
ashleymills 0:795bb54e1ee8 168 finishOnError();
ashleymills 0:795bb54e1ee8 169 }
ashleymills 0:795bb54e1ee8 170 const char *common_name = ssl_get_cert_dn(ssl,SSL_X509_CERT_COMMON_NAME);
ashleymills 0:795bb54e1ee8 171 if(common_name) {
ashleymills 0:795bb54e1ee8 172 printf("Server Common Name: %s\r\n", common_name);
ashleymills 0:795bb54e1ee8 173 }
ashleymills 0:795bb54e1ee8 174
ashleymills 0:795bb54e1ee8 175 display_cipher(ssl);
ashleymills 0:795bb54e1ee8 176
ashleymills 0:795bb54e1ee8 177
ashleymills 0:795bb54e1ee8 178
ashleymills 0:795bb54e1ee8 179 DBG("SSL connected ok");
ashleymills 0:795bb54e1ee8 180 // verify cert
ashleymills 0:795bb54e1ee8 181 if((res=ssl_verify_cert(ssl))!= SSL_OK) {
ashleymills 0:795bb54e1ee8 182 DBG("Failed to verify certifcate\r\n");
ashleymills 0:795bb54e1ee8 183 ssl_display_error(res);
ashleymills 0:795bb54e1ee8 184 modem.disconnect();
ashleymills 0:795bb54e1ee8 185 finishOnError();
ashleymills 0:795bb54e1ee8 186 }
ashleymills 0:795bb54e1ee8 187
ashleymills 0:795bb54e1ee8 188 DBG("Server certificate verified\r\n");
ashleymills 0:795bb54e1ee8 189
ashleymills 0:795bb54e1ee8 190 ssl_write(ssl,"hello\r\n",7);
ashleymills 0:795bb54e1ee8 191
ashleymills 0:795bb54e1ee8 192 // dump responses
ashleymills 0:795bb54e1ee8 193 uint8_t *read_buffer = NULL;
ashleymills 0:795bb54e1ee8 194 while(1) {
ashleymills 0:795bb54e1ee8 195 int bytesRead = ssl_read(ssl,&read_buffer);
ashleymills 0:795bb54e1ee8 196 if(bytesRead>0) {
ashleymills 0:795bb54e1ee8 197 DBG("GOT(%d): \"%s\"",bytesRead,read_buffer);
ashleymills 0:795bb54e1ee8 198 } else if(bytesRead==0) {
ashleymills 0:795bb54e1ee8 199 DBG("WARNING: TLS handshake incomplete");
ashleymills 0:795bb54e1ee8 200 } else {
ashleymills 0:795bb54e1ee8 201 break;
ashleymills 0:795bb54e1ee8 202 }
ashleymills 0:795bb54e1ee8 203 Thread::wait(300);
ashleymills 0:795bb54e1ee8 204 }
ashleymills 0:795bb54e1ee8 205
ashleymills 0:795bb54e1ee8 206 modem.disconnect();
ashleymills 0:795bb54e1ee8 207 finishOnOK();
ashleymills 0:795bb54e1ee8 208 }