A super trimmed down TLS stack, GPL licensed

Dependents:   MiniTLS-HTTPS-Example

MiniTLS - A super trimmed down TLS/SSL Library for embedded devices Author: Donatien Garnier Copyright (C) 2013-2014 AppNearMe Ltd

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Revision:
3:eb324ffffd2b
Parent:
2:527a66d0a1a9
--- a/tls/tls_handshake.c	Mon Jun 09 14:57:54 2014 +0000
+++ b/tls/tls_handshake.c	Tue Jun 10 14:22:36 2014 +0000
@@ -22,7 +22,7 @@
  * \author Donatien Garnier
  */
 
-#define __DEBUG__ 0
+#define __DEBUG__ 4
 #ifndef __MODULE__
 #define __MODULE__ "tls_handshake.c"
 #endif
@@ -42,6 +42,12 @@
 #define HANDSHAKE_MAX_PREMASTER_KEY_SIZE 64
 #define HANDSHAKE_RSA_PREMASTER_KEY_SIZE 48
 
+#if MINITLS_CFG_KEY_RSA_2048
+#define RSA_PREMASTER_KEY_SIZE 256
+#elif MINITLS_CFG_KEY_RSA_1024
+#define RSA_PREMASTER_KEY_SIZE 128
+#endif
+
 typedef enum __handshake_type
 {
   hello_request = (0), client_hello = (1), server_hello = (2),
@@ -467,6 +473,7 @@
 const uint8_t TLS_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_CBC_SHA[]  = { 0xC0, 0x09 };
 #elif CRYPTO_RSA
 const uint8_t TLS_CIPHERSUITE_RSA_WITH_AES_128_CBC_SHA[]  = { 0x00, 0x2F };
+const uint8_t TLS_CIPHERSUITE_RSA_WITH_ARC4_SHA[]      = { 0x00, 0x05 };
 #endif
 
 #define TLS_COMPRESSION_METHOD_NULL 0x00
@@ -553,11 +560,17 @@
   buffer_nu8_write(buffer, handshake->tls_socket->session.session_id_length);
   buffer_nbytes_write(buffer, handshake->tls_socket->session.session_id, handshake->tls_socket->session.session_id_length);
   //Write the one cipher suite we support
+#if CRYPTO_ECC
   buffer_nu16_write(buffer, 2); //2 bytes long
-#if CRYPTO_ECC
   buffer_nbytes_write(buffer, TLS_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 2);
 #elif CRYPTO_RSA
+  buffer_nu16_write(buffer, (CRYPTO_AES_128 + CRYPTO_ARC4)*2); //2 or 4 bytes long
+#if CRYPTO_AES_128
   buffer_nbytes_write(buffer, TLS_CIPHERSUITE_RSA_WITH_AES_128_CBC_SHA, 2);
+#endif
+#if CRYPTO_ARC4
+  buffer_nbytes_write(buffer, TLS_CIPHERSUITE_RSA_WITH_ARC4_SHA, 2);
+#endif
 #else
 #error You must enable one cipher suite
 #endif
@@ -752,17 +765,33 @@
   buffer_nbytes_read(buffer, cipher_suite, 2);
   uint8_t compression_mode = buffer_nu8_read(buffer);
 
-  if(
 #if CRYPTO_ECC
-      (memcmp(cipher_suite, TLS_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 2) != 0)
+  if(memcmp(cipher_suite, TLS_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 2) == 0)
+  {
+    handshake->target_security = TLS_SECURITY_TYPE_AES_128_CBC_SHA;
+  }
+  else
 #elif CRYPTO_RSA
-      (memcmp(cipher_suite, TLS_CIPHERSUITE_RSA_WITH_AES_128_CBC_SHA, 2) != 0)
+  if(memcmp(cipher_suite, TLS_CIPHERSUITE_RSA_WITH_AES_128_CBC_SHA, 2) == 0)
+  {
+    handshake->target_security = TLS_SECURITY_TYPE_AES_128_CBC_SHA;
+  }
+  else if(memcmp(cipher_suite, TLS_CIPHERSUITE_RSA_WITH_ARC4_SHA, 2) == 0)
+  {
+    handshake->target_security = TLS_SECURITY_TYPE_ARC4_SHA;
+  }
+  else
 #else
 #error
 #endif
-      || (compression_mode != TLS_COMPRESSION_METHOD_NULL) )
   {
-    ERR("Unsupported cipher suite / compression method");
+    ERR("Unsupported cipher suite");
+    return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; //Protocol error as we did not advertise any other cipher suite/compression method in the hello client message
+  }
+
+  if( compression_mode != TLS_COMPRESSION_METHOD_NULL )
+  {
+    ERR("Unsupported compression method");
     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; //Protocol error as we did not advertise any other cipher suite/compression method in the hello client message
   }
 
@@ -1201,13 +1230,15 @@
   premaster_key_size = HANDSHAKE_RSA_PREMASTER_KEY_SIZE;
 
   //Encrypt it using RSA
-  uint8_t encrypted_premaster_key[128];
+  uint8_t encrypted_premaster_key[RSA_PREMASTER_KEY_SIZE];
+
   size_t encrypted_premaster_key_size = 0;
   ret = crypto_rsa_encrypt(&handshake->tls_socket->minitls->certificate->public_key.rsa,
       premaster_key, premaster_key_size,
       encrypted_premaster_key, sizeof(encrypted_premaster_key), &encrypted_premaster_key_size, handshake->tls_socket->minitls->prng);
   if(ret)
   {
+    WARN("Error %d", ret);
     return ret;
   }
 
@@ -1442,7 +1473,7 @@
   }
 
   //Init cipher/mac
-  tls_record_set_keys(&handshake->tls_socket->record, TLS_SECURITY_TYPE_AES_128_CBC_SHA,
+  tls_record_set_keys(&handshake->tls_socket->record, handshake->target_security,
       &key_expansion[0*TLS_HMAC_SHA1_KEY_SIZE + 0*AES_128_KEY_SIZE],
       &key_expansion[1*TLS_HMAC_SHA1_KEY_SIZE + 0*AES_128_KEY_SIZE],
       &key_expansion[2*TLS_HMAC_SHA1_KEY_SIZE + 0*AES_128_KEY_SIZE],