Rough and ready demo of axTLS with 3G modem
Dependencies: VodafoneUSBModem_bleedingedge axTLS mbed-rtos mbed
main.cpp@1:db88ff473b1a, 2013-05-28 (annotated)
- 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?
User | Revision | Line number | New 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 | } |