ARM Shanghai IoT Team (Internal) / newMiniTLS-GPL

Fork of MiniTLS-GPL by Donatien Garnier

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tls_handshake.c Source File

tls_handshake.c

Go to the documentation of this file.
00001 /*
00002 MiniTLS - A super trimmed down TLS/SSL Library for embedded devices
00003 Author: Donatien Garnier
00004 Copyright (C) 2013-2014 AppNearMe Ltd
00005 
00006 This program is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU General Public License
00008 as published by the Free Software Foundation; either version 2
00009 of the License, or (at your option) any later version.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with this program; if not, write to the Free Software
00018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019 *//**
00020  * \file tls_handshake.c
00021  * \copyright Copyright (c) AppNearMe Ltd 2013
00022  * \author Donatien Garnier
00023  */
00024 
00025 #define __DEBUG__ 4
00026 #ifndef __MODULE__
00027 #define __MODULE__ "tls_handshake.c"
00028 #endif
00029 
00030 #include "core/fwk.h"
00031 
00032 #include "tls_handshake.h"
00033 #include "tls_record.h"
00034 #include "tls_socket.h"
00035 #include "tls_alert.h"
00036 #include "crypto/crypto_ecc.h"
00037 #include "crypto/crypto_sha1.h"
00038 #include "crypto/crypto_sha256.h"
00039 #include "crypto/crypto_hmac_sha1.h"
00040 #include "crypto/crypto_hmac_sha256.h"
00041 
00042 #define HANDSHAKE_MAX_PREMASTER_KEY_SIZE 64
00043 #define HANDSHAKE_RSA_PREMASTER_KEY_SIZE 48
00044 
00045 #if MINITLS_CFG_KEY_RSA_2048
00046 #define RSA_PREMASTER_KEY_SIZE 256
00047 #elif MINITLS_CFG_KEY_RSA_1024
00048 #define RSA_PREMASTER_KEY_SIZE 128
00049 #endif
00050 
00051 typedef enum __handshake_type
00052 {
00053   hello_request = (0), client_hello = (1), server_hello = (2),
00054   certificate = (11), server_key_exchange = (12),
00055   certificate_request = (13), server_hello_done = (14),
00056   certificate_verify = (15), client_key_exchange = (16),
00057   finished = (20), unknown = (255)
00058 } handshake_type_t;
00059 
00060 static minitls_err_t send_hello_client(tls_handshake_t* handshake, buffer_t* buffer);
00061 static minitls_err_t parse_hello_server (tls_handshake_t* handshake, buffer_t* buffer, bool* resumed);
00062 static minitls_err_t parse_server_certificate(tls_handshake_t* handshake, buffer_t* buffer);
00063 static minitls_err_t parse_server_key_exchange(tls_handshake_t* handshake, buffer_t* buffer);
00064 static minitls_err_t parse_client_certificate_request(tls_handshake_t* handshake, buffer_t* buffer);
00065 static minitls_err_t parse_hello_done_server(tls_handshake_t* handshake, buffer_t* buffer);
00066 static minitls_err_t send_client_certificate(tls_handshake_t* handshake, buffer_t* buffer);
00067 static minitls_err_t send_client_key_exchange(tls_handshake_t* handshake, buffer_t* buffer);
00068 static minitls_err_t send_finished(tls_handshake_t* handshake, buffer_t* buffer);
00069 static minitls_err_t parse_finished(tls_handshake_t* handshake, buffer_t* buffer);
00070 
00071 static minitls_err_t generate_record_keys(tls_handshake_t* handshake);
00072 
00073 //Receive stuff
00074 static minitls_err_t parse_message(tls_handshake_t* handshake, buffer_t* buffer, handshake_type_t* message_type);
00075 
00076 //Send stuff
00077 static minitls_err_t prepare_message(tls_handshake_t* handshake, handshake_type_t message_type, buffer_t* buffer, size_t size);
00078 static minitls_err_t prepare_message_adjust_size(tls_handshake_t* handshake, buffer_t* buffer, size_t size);
00079 static minitls_err_t send_message(tls_handshake_t* handshake, buffer_t* buffer);
00080 
00081 //Error handlers
00082 static void handle_ret(tls_handshake_t* handshake, minitls_err_t ret);
00083 
00084 /*
00085       P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
00086                              HMAC_hash(secret, A(2) + seed) +
00087                              HMAC_hash(secret, A(3) + seed) + ...
00088 
00089       PRF(secret, label, seed) = P_hash(secret, label + seed)
00090  */
00091 
00092 //PRF computation
00093 static minitls_err_t prf_compute(const uint8_t* secret, size_t secret_size,
00094     const char* label,
00095     const uint8_t* seed1, size_t seed1_size,
00096     const uint8_t* seed2, size_t seed2_size,
00097     uint8_t* out, size_t out_size);
00098 
00099 //Record-level change cipher spec request
00100 static minitls_err_t change_cipher_spec_request(tls_handshake_t* handshake, buffer_t* buffer);
00101 
00102 minitls_err_t tls_handshake_init(tls_handshake_t* handshake, tls_socket_t* socket)
00103 {
00104   handshake->tls_socket = socket;
00105 
00106   tls_handshake_clean(handshake);
00107   //memset(handshake->master_key, 0, sizeof(HANDSHAKE_MASTER_KEY_SIZE));
00108 
00109   //Reset state machine
00110   handshake->state = TLS_HANDSHAKE_INIT;
00111 
00112   return MINITLS_OK;
00113 }
00114 
00115 
00116 minitls_err_t tls_handshake_start(tls_handshake_t* handshake)
00117 {
00118   minitls_err_t ret = send_hello_client(handshake, &handshake->tls_socket->record.buffer);
00119   if(ret)
00120   {
00121     handle_ret(handshake, ret);
00122     return ret;
00123   }
00124   handshake->state = TLS_HANDSHAKE_HELLO_SENT;
00125   return MINITLS_OK;
00126 }
00127 
00128 minitls_err_t tls_handshake_process(tls_handshake_t* handshake, buffer_t* buffer)
00129 {
00130   //Parse buffer
00131   DBG("Parsing message");
00132   handshake_type_t type;
00133   minitls_err_t ret = parse_message(handshake, buffer, &type);
00134   if(ret)
00135   {
00136     ERR("Parsing error");
00137     handle_ret(handshake, ret);
00138     return ret;
00139   }
00140 
00141   bool resumed = false;
00142 
00143   DBG("Message type %d", type);
00144 
00145   switch(type)
00146   {
00147   case hello_request:
00148     if( (handshake->state == TLS_HANDSHAKE_INIT) || (handshake->state == TLS_HANDSHAKE_HELLO_SENT) )
00149     {
00150       DBG("Hello request");
00151     }
00152     else
00153     {
00154       ret = MINITLS_ERR_NOT_IMPLEMENTED;
00155       handle_ret(handshake, ret);
00156       return ret;
00157     }
00158     break;
00159   case server_hello:
00160     if(handshake->state == TLS_HANDSHAKE_HELLO_SENT)
00161     {
00162       DBG("Server hello");
00163       //Parse hello
00164       handshake->state = TLS_HANDSHAKE_HELLO_RECEIVED;
00165       ret = parse_hello_server (handshake, buffer, &resumed);
00166       if(ret)
00167       {
00168         handle_ret(handshake, ret);
00169         return ret;
00170       }
00171       if(resumed)
00172       {
00173         handshake->state = TLS_HANDSHAKE_HELLO_RECEIVED_SESSION_RESUMPTION;
00174 
00175         //Complete handshake
00176         DBG("Expanding master key");
00177 
00178         ret = generate_record_keys(handshake);
00179         if(ret)
00180         {
00181           handle_ret(handshake, ret);
00182           return ret;
00183         }
00184 
00185         DBG("Change cipher spec request");
00186 
00187         ret = change_cipher_spec_request(handshake, buffer);
00188         if(ret)
00189         {
00190           handle_ret(handshake, ret);
00191           return ret;
00192         }
00193 
00194         DBG("Changing cipher spec (TX)");
00195         //Now we can change cipher spec -- TX way
00196         ret = tls_record_change_cipher_spec(&handshake->tls_socket->record, true);
00197         if(ret)
00198         {
00199           handle_ret(handshake, ret);
00200           return ret;
00201         }
00202 
00203         DBG("Send finished");
00204         //Now send finished message
00205         ret = send_finished(handshake, buffer);
00206         if(ret)
00207         {
00208           handle_ret(handshake, ret);
00209           return ret;
00210         }
00211 
00212         handshake->state = TLS_HANDSHAKE_FINISHED_SENT;
00213       }
00214     }
00215     else
00216     {
00217       ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00218       handle_ret(handshake, ret);
00219       return ret;
00220     }
00221     break;
00222   case certificate:
00223     if(handshake->state == TLS_HANDSHAKE_HELLO_RECEIVED)
00224     {
00225       DBG("Server certificate");
00226       //Parse certificate
00227       handshake->state = TLS_HANDSHAKE_CERTIFICATE_RECEIVED;
00228       ret = parse_server_certificate(handshake, buffer);
00229       if(ret)
00230       {
00231         handle_ret(handshake, ret);
00232         return ret;
00233       }
00234     }
00235     else
00236     {
00237       ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00238       handle_ret(handshake, ret);
00239       return ret;
00240     }
00241     break;
00242   case server_key_exchange:
00243     //With other types of authentication methods (PSK, anon) we could receive this message after the server's hello; however we don't support these cipher suites
00244     if(CRYPTO_ECC && (handshake->state == TLS_HANDSHAKE_CERTIFICATE_RECEIVED))
00245     {
00246       DBG("Server key exchange");
00247       //Parse server key
00248       handshake->state = TLS_HANDSHAKE_SERVER_KEY_EXCHANGE_RECEIVED;
00249       ret = parse_server_key_exchange(handshake, buffer);
00250       if(ret)
00251       {
00252         handle_ret(handshake, ret);
00253         return ret;
00254       }
00255     }
00256     else
00257     {
00258       ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00259       handle_ret(handshake, ret);
00260       return ret;
00261     }
00262     break;
00263   case certificate_request:
00264     //Obvi, we could receive this right after certificate - but we don't support this
00265     if(handshake->state == TLS_HANDSHAKE_CERTIFICATE_RECEIVED)
00266     {
00267       WARN("Not supported");
00268       ret = MINITLS_ERR_NOT_IMPLEMENTED;
00269       handle_ret(handshake, ret);
00270       return ret;
00271     }
00272     else if( (CRYPTO_ECC && (handshake->state == TLS_HANDSHAKE_SERVER_KEY_EXCHANGE_RECEIVED)) || (CRYPTO_RSA && (handshake->state == TLS_HANDSHAKE_CERTIFICATE_RECEIVED)) )
00273     {
00274       DBG("Client certificate request");
00275       //Parse certificate request
00276       handshake->state = TLS_HANDSHAKE_CERTIFICATE_REQUEST_RECEIVED;
00277       handshake->certificate_requested = true;
00278       ret = parse_client_certificate_request(handshake, buffer);
00279       if(ret)
00280       {
00281         handle_ret(handshake, ret);
00282         return ret;
00283       }
00284     }
00285     else
00286     {
00287       ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00288       handle_ret(handshake, ret);
00289       return ret;
00290     }
00291     break;
00292   case server_hello_done:
00293     if( (CRYPTO_ECC && (handshake->state == TLS_HANDSHAKE_SERVER_KEY_EXCHANGE_RECEIVED)) || (CRYPTO_RSA && (handshake->state == TLS_HANDSHAKE_CERTIFICATE_RECEIVED))
00294         || (handshake->state == TLS_HANDSHAKE_CERTIFICATE_REQUEST_RECEIVED) )
00295     {
00296       DBG("Hello done");
00297       //Parse hello done
00298       handshake->state = TLS_HANDSHAKE_HELLO_DONE_RECEIVED;
00299       ret = parse_hello_done_server(handshake, buffer);
00300       if(ret)
00301       {
00302         handle_ret(handshake, ret);
00303         return ret;
00304       }
00305 
00306       //Now reply
00307       if(handshake->certificate_requested)
00308       {
00309         DBG("Send client certificate");
00310         //Send client certificate if requested
00311         ret = send_client_certificate(handshake, buffer);
00312         if(ret)
00313         {
00314           handle_ret(handshake, ret);
00315           return ret;
00316         }
00317         handshake->state = TLS_HANDSHAKE_CERTIFICATE_SENT;
00318       }
00319 
00320       DBG("Send client key exchange");
00321       //Send client key exchange
00322       ret = send_client_key_exchange(handshake, buffer);
00323       if(ret)
00324       {
00325         handle_ret(handshake, ret);
00326         return ret;
00327       }
00328 
00329       handshake->state = TLS_HANDSHAKE_CLIENT_KEY_EXCHANGE_SENT;
00330 
00331       //Send certificate verify -- not for now
00332       /*
00333       ret = send_client_certificate_verify(handshake, buffer);
00334       if(ret)
00335       {
00336         handle_ret(handshake, ret);
00337         return ret;
00338       }
00339 
00340       handshake->state = TLS_HANDSHAKE_CERTIFICATE_VERIFY_SENT;
00341       */
00342 
00343       DBG("Expanding master key");
00344 
00345       ret = generate_record_keys(handshake);
00346       if(ret)
00347       {
00348         handle_ret(handshake, ret);
00349         return ret;
00350       }
00351 
00352       DBG("Change cipher spec request");
00353 
00354       ret = change_cipher_spec_request(handshake, buffer);
00355       if(ret)
00356       {
00357         handle_ret(handshake, ret);
00358         return ret;
00359       }
00360 
00361       DBG("Changing cipher spec (TX)");
00362       //Now we can change cipher spec -- TX way
00363       ret = tls_record_change_cipher_spec(&handshake->tls_socket->record, true);
00364       if(ret)
00365       {
00366         handle_ret(handshake, ret);
00367         return ret;
00368       }
00369 
00370       DBG("Send finished");
00371       //Now send finished message
00372       ret = send_finished(handshake, buffer);
00373       if(ret)
00374       {
00375         handle_ret(handshake, ret);
00376         return ret;
00377       }
00378 
00379       handshake->state = TLS_HANDSHAKE_FINISHED_SENT;
00380     }
00381     else
00382     {
00383       ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00384       handle_ret(handshake, ret);
00385       return ret;
00386     }
00387     break;
00388   case finished:
00389     if(handshake->state == TLS_HANDSHAKE_FINISHED_SENT)
00390     {
00391       //First check that the ChangeCipherSpec message has been sent by the other party (and that we are therefore secure in both ways)
00392       DBG("Receive finished");
00393       if(!tls_record_is_secure(&handshake->tls_socket->record))
00394       {
00395         ERR("Record is insecure");
00396         ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00397         handle_ret(handshake, ret);
00398         return ret;
00399       }
00400 
00401       //Parse finished message and check integrity of exchange
00402       handshake->state = TLS_HANDSHAKE_FINISHED_RECEIVED;
00403       ret = parse_finished(handshake, buffer);
00404       if(ret)
00405       {
00406         ERR("Integrity check failed");
00407         handle_ret(handshake, ret);
00408         return ret;
00409       }
00410 
00411       DBG("Handshake done!");
00412       handshake->state = TLS_HANDSHAKE_DONE;
00413     }
00414     else
00415     {
00416       ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00417       handle_ret(handshake, ret);
00418       return ret;
00419     }
00420     break;
00421   default:
00422     ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00423     handle_ret(handshake, ret);
00424     return ret;
00425   }
00426 
00427   return MINITLS_OK;
00428 }
00429 
00430 void tls_handshake_clean(tls_handshake_t* handshake)
00431 {
00432   memset(handshake->random_client, 0, HANDSHAKE_RANDOM_SIZE);
00433   memset(handshake->random_client, 0, HANDSHAKE_RANDOM_SIZE);
00434 
00435   handshake->certificate_requested = false;
00436   //memset(&handshake->ecc_curve, 0, sizeof(crypto_ecc_curve_t*));
00437   //handshake->ecc_curve_type = 0;
00438 #if CRYPTO_ECC
00439   handshake->key_exchange.ecc.curve = NULL;
00440   memset(&handshake->key_exchange.ecc.server_key, 0, sizeof(crypto_ecc_public_key_t));
00441   memset(&handshake->key_exchange.ecc.client_key, 0, sizeof(crypto_ecc_private_key_t));
00442 #endif
00443 #if CRYPTO_RSA
00444   //
00445 #endif
00446 
00447 #if MINITLS_CFG_PROTOCOL_TLS_1_2
00448   crypto_sha256_init(&handshake->hash.sha256);
00449 #endif
00450 #if (MINITLS_CFG_PROTOCOL_TLS_1_1 || MINITLS_CFG_PROTOCOL_TLS_1_0 || MINITLS_CFG_PROTOCOL_SSL_3)
00451   crypto_sha1_init(&handshake->hash.md5_sha1.sha1);
00452   crypto_md5_init(&handshake->hash.md5_sha1.md5);
00453 #endif
00454 
00455 }
00456 
00457 bool tls_handshake_is_done(tls_handshake_t* handshake)
00458 {
00459   if(handshake->state == TLS_HANDSHAKE_DONE)
00460   {
00461     return true;
00462   }
00463   return false;
00464 }
00465 
00466 #define HELLO_CLIENT_SIZE 41
00467 #define HELLO_CLIENT_EXTENSIONS_HEADER_SIZE 2
00468 #define HELLO_CLIENT_MAX_FRAGMENT_EXTENSION_SIZE 5
00469 #define HELLO_CLIENT_SIGNATURE_ALGORITHM_EXTENSION_SIZE 8
00470 #define HELLO_CLIENT_SUPPORTED_ECC_CURVES_SIZE 8
00471 
00472 #if CRYPTO_ECC
00473 const uint8_t TLS_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_CBC_SHA[]  = { 0xC0, 0x09 };
00474 #elif CRYPTO_RSA
00475 const uint8_t TLS_CIPHERSUITE_RSA_WITH_AES_128_CBC_SHA[]  = { 0x00, 0x2F };
00476 const uint8_t TLS_CIPHERSUITE_RSA_WITH_ARC4_SHA[]      = { 0x00, 0x05 };
00477 #endif
00478 
00479 #define TLS_COMPRESSION_METHOD_NULL 0x00
00480 #define TLS_EXTENSION_TYPE_MAX_FRAGMENT_LENGTH 1
00481 #define TLS_EXTENSION_TYPE_SIGNATURE_ALGORITHM 13
00482 #define TLS_EXTENSION_TYPE_SUPPORTED_ECC_CURVES 10
00483 
00484 typedef enum __hash_algorithm {
00485           none = (0), md5 = (1), sha1 = (2), sha224 = (3), sha256 = (4), sha384 = (5),
00486           sha512 = (6)
00487 } hash_algorithm_t;
00488 
00489 typedef enum __signature_algorithm { anonymous = (0), rsa = (1), dsa = (2), ecdsa = (3)
00490 } signature_algorithm_t;
00491 
00492 minitls_err_t send_hello_client(tls_handshake_t* handshake, buffer_t* buffer)
00493 {
00494   //Form hello packet
00495   /*
00496   struct {
00497     ProtocolVersion client_version;
00498     Random random;
00499     SessionID session_id;
00500     CipherSuite cipher_suites<2..2^16-2>;
00501     CompressionMethod compression_methods<1..2^8-1>;
00502     select (extensions_present) {
00503         case false:
00504             struct {};
00505         case true:
00506             Extension extensions<0..2^16-1>;
00507     };
00508   } ClientHello;
00509   */
00510   minitls_err_t ret;
00511 
00512   //Write header
00513   if(handshake->tls_socket->record.max_fragment_size < TLS_DEFAULT_MAX_FRAGMENT_SIZE)
00514   {
00515     ret = prepare_message(handshake, client_hello, buffer, HELLO_CLIENT_SIZE + handshake->tls_socket->session.session_id_length +
00516         HELLO_CLIENT_EXTENSIONS_HEADER_SIZE
00517 #if CRYPTO_ECC
00518         + HELLO_CLIENT_SIGNATURE_ALGORITHM_EXTENSION_SIZE + HELLO_CLIENT_SUPPORTED_ECC_CURVES_SIZE
00519 #endif
00520         + HELLO_CLIENT_MAX_FRAGMENT_EXTENSION_SIZE);
00521   }
00522   else
00523   {
00524     ret = prepare_message(handshake, client_hello, buffer, HELLO_CLIENT_SIZE + handshake->tls_socket->session.session_id_length +
00525         HELLO_CLIENT_EXTENSIONS_HEADER_SIZE
00526 #if CRYPTO_ECC
00527         + HELLO_CLIENT_SIGNATURE_ALGORITHM_EXTENSION_SIZE + HELLO_CLIENT_SUPPORTED_ECC_CURVES_SIZE
00528 #endif
00529         );
00530   }
00531   if(ret)
00532   {
00533     return ret;
00534   }
00535 
00536   //Generate 28-bytes long random
00537   crypto_prng_get(handshake->tls_socket->minitls->prng, handshake->random_client, HANDSHAKE_RANDOM_SIZE);
00538 
00539   //Write most recent protocol version supported
00540 #if MINITLS_CFG_PROTOCOL_TLS_1_2
00541   buffer_nu8_write(buffer, TLS_1_2_VERSION_MAJOR);
00542   buffer_nu8_write(buffer, TLS_1_2_VERSION_MINOR);
00543 #elif MINITLS_CFG_PROTOCOL_TLS_1_1
00544   buffer_nu8_write(buffer, TLS_1_1_VERSION_MAJOR);
00545   buffer_nu8_write(buffer, TLS_1_1_VERSION_MINOR);
00546 #elif MINITLS_CFG_PROTOCOL_TLS_1_0
00547   buffer_nu8_write(buffer, TLS_1_0_VERSION_MAJOR);
00548   buffer_nu8_write(buffer, TLS_1_0_VERSION_MINOR);
00549 #elif MINITLS_CFG_PROTOCOL_SSL_3
00550   buffer_nu8_write(buffer, SSL_3_VERSION_MAJOR);
00551   buffer_nu8_write(buffer, SSL_3_VERSION_MINOR);
00552 #else
00553 #error No SSL/TLS protocol version enabled
00554 #endif
00555 
00556   //Write random
00557   //buffer_nu32_write(buffer, 0); //UNIX Timestamp -- not mandatory, write 0s -- Don't do this, just use a 32bytes long random
00558   buffer_nbytes_write(buffer, handshake->random_client, HANDSHAKE_RANDOM_SIZE);
00559   //Write session ID
00560   buffer_nu8_write(buffer, handshake->tls_socket->session.session_id_length);
00561   buffer_nbytes_write(buffer, handshake->tls_socket->session.session_id, handshake->tls_socket->session.session_id_length);
00562   //Write the one cipher suite we support
00563 #if CRYPTO_ECC
00564   buffer_nu16_write(buffer, 2); //2 bytes long
00565   buffer_nbytes_write(buffer, TLS_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 2);
00566 #elif CRYPTO_RSA
00567   buffer_nu16_write(buffer, (CRYPTO_AES_128 + CRYPTO_ARC4)*2); //2 or 4 bytes long
00568 #if CRYPTO_AES_128
00569   buffer_nbytes_write(buffer, TLS_CIPHERSUITE_RSA_WITH_AES_128_CBC_SHA, 2);
00570 #endif
00571 #if CRYPTO_ARC4
00572   buffer_nbytes_write(buffer, TLS_CIPHERSUITE_RSA_WITH_ARC4_SHA, 2);
00573 #endif
00574 #else
00575 #error You must enable one cipher suite
00576 #endif
00577   //Write the one compression method we support (null)
00578   buffer_nu8_write(buffer, 1); //1 byte long
00579   buffer_nu8_write(buffer, TLS_COMPRESSION_METHOD_NULL);
00580 
00581   if(handshake->tls_socket->record.max_fragment_size < TLS_DEFAULT_MAX_FRAGMENT_SIZE)
00582   {
00583     //3 extensions (ECC) / 1 (RSA)
00584     buffer_nu16_write(buffer,
00585 #if CRYPTO_ECC
00586         + HELLO_CLIENT_SIGNATURE_ALGORITHM_EXTENSION_SIZE + HELLO_CLIENT_SUPPORTED_ECC_CURVES_SIZE
00587 #endif
00588         + HELLO_CLIENT_MAX_FRAGMENT_EXTENSION_SIZE);
00589   }
00590   else
00591   {
00592     //2 (ECC) extensions / 0 (RSA)
00593     buffer_nu16_write(buffer, 0
00594 #if CRYPTO_ECC
00595         + HELLO_CLIENT_SIGNATURE_ALGORITHM_EXTENSION_SIZE + HELLO_CLIENT_SUPPORTED_ECC_CURVES_SIZE
00596 #endif
00597     );
00598   }
00599 #if CRYPTO_ECC
00600   //Use signature algorithm extension
00601   buffer_nu16_write(buffer, TLS_EXTENSION_TYPE_SIGNATURE_ALGORITHM);
00602   /*
00603      enum {
00604           none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
00605           sha512(6), (255)
00606       } HashAlgorithm;
00607 
00608       enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
00609         SignatureAlgorithm;
00610 
00611       struct {
00612             HashAlgorithm hash;
00613             SignatureAlgorithm signature;
00614       } SignatureAndHashAlgorithm;
00615 
00616       SignatureAndHashAlgorithm
00617         supported_signature_algorithms<2..2^16-2>;
00618    */
00619 
00620   buffer_nu16_write(buffer, 4); //2 bytes of list length, 2 bytes of hash and signature algo
00621   buffer_nu16_write(buffer, 2); //2 bytes of hash and signature algo
00622 
00623   //Supported algo is ECDSA-SHA1
00624   buffer_nu8_write(buffer, sha1);
00625   buffer_nu8_write(buffer, ecdsa);
00626 
00627   //Use supported elliptic curves extensions
00628 
00629   buffer_nu16_write(buffer, TLS_EXTENSION_TYPE_SUPPORTED_ECC_CURVES);
00630   /*
00631   struct {
00632       NamedCurve elliptic_curve_list<1..2^16-1>
00633   } EllipticCurveList;
00634   */
00635   buffer_nu16_write(buffer, 4); //2 bytes of list length, 2 bytes of curve type
00636   buffer_nu16_write(buffer, 2); //2 bytes of curve type
00637   buffer_nu16_write(buffer, secp192r1); //The one curve we support -- TODO clean this up
00638 #endif
00639 
00640   if(handshake->tls_socket->record.max_fragment_size < TLS_DEFAULT_MAX_FRAGMENT_SIZE)
00641   {
00642     //Use MaxFragmentLength extension to decrease the maximum fragment length (RFC4366)
00643     buffer_nu16_write(buffer, TLS_EXTENSION_TYPE_MAX_FRAGMENT_LENGTH);
00644 
00645     buffer_nu16_write(buffer, 1); //1 byte of data
00646     /*
00647     enum{
00648       2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
00649     } MaxFragmentLength;
00650     */
00651     if( handshake->tls_socket->record.max_fragment_size >= 4096 )
00652     {
00653       buffer_nu8_write(buffer, 4);
00654     }
00655     else if( handshake->tls_socket->record.max_fragment_size >= 2048 )
00656     {
00657       buffer_nu8_write(buffer, 3);
00658     }
00659     else if( handshake->tls_socket->record.max_fragment_size >= 1024 )
00660     {
00661       buffer_nu8_write(buffer, 2);
00662     }
00663     else if( handshake->tls_socket->record.max_fragment_size >= 512 )
00664     {
00665       buffer_nu8_write(buffer, 1);
00666     }
00667     else
00668     {
00669       WARN("Fragment size is too small - using 512 bytes fragment size");
00670       buffer_nu8_write(buffer, 1);
00671     }
00672   }
00673 
00674   ret = send_message(handshake, buffer);
00675   if(ret)
00676   {
00677     return ret;
00678   }
00679 
00680   return MINITLS_OK;
00681 }
00682 
00683 minitls_err_t parse_hello_server (tls_handshake_t* handshake, buffer_t* buffer, bool* resumed)
00684 {
00685   //Header has already been parsed
00686   /*
00687   struct {
00688       ProtocolVersion server_version;
00689       Random random;
00690       SessionID session_id;
00691       CipherSuite cipher_suite;
00692       CompressionMethod compression_method;
00693       select (extensions_present) {
00694           case false:
00695               struct {};
00696           case true:
00697               Extension extensions<0..2^16-1>;
00698       };
00699   } ServerHello;
00700   */
00701 
00702   if( buffer_length(buffer) < 35) //protocol version + random + session_id length
00703   {
00704     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00705   }
00706 
00707   tls_protocol_version_t version;
00708   version.major = buffer_nu8_read(buffer);
00709   version.minor = buffer_nu8_read(buffer);
00710 
00711   //Check that version is one of the supported ones
00712   if(
00713 #if MINITLS_CFG_PROTOCOL_TLS_1_2
00714       ( (version.major != TLS_1_2_VERSION_MAJOR) || (version.minor != TLS_1_2_VERSION_MINOR) ) &&
00715 #endif
00716 #if MINITLS_CFG_PROTOCOL_TLS_1_1
00717       ( (version.major != TLS_1_1_VERSION_MAJOR) || (version.minor != TLS_1_1_VERSION_MINOR) ) &&
00718 #endif
00719 #if MINITLS_CFG_PROTOCOL_TLS_1_0
00720       ( (version.major != TLS_1_0_VERSION_MAJOR) || (version.minor != TLS_1_0_VERSION_MINOR) ) &&
00721 #endif
00722 #if MINITLS_CFG_PROTOCOL_SSL_3
00723       ( (version.major != SSL_3_VERSION_MAJOR) || (version.minor != SSL_3_VERSION_MINOR) ) &&
00724 #endif
00725       true )
00726   {
00727     ERR("Version mismatch");
00728     return MINITLS_ERR_PROTOCOL_VERSION;
00729   }
00730 
00731   //Set record version accordingly
00732   tls_record_set_protocol_version(&handshake->tls_socket->record, version.major, version.minor);
00733 
00734   //buffer_nu32_read(buffer); //UNIX Timestamp -- Don't read that, read it as part of the random
00735   buffer_nbytes_read(buffer, handshake->random_server, HANDSHAKE_RANDOM_SIZE);
00736   size_t server_session_id_length = buffer_nu8_read(buffer);
00737   if( buffer_length(buffer) < server_session_id_length + 3 ) //session id + cipher suite + compression mode
00738   {
00739     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; ///Will raise a "decode error" alert
00740   }
00741   if(server_session_id_length > SESSION_ID_MAX_SIZE) //Buffer overflow attack
00742   {
00743     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; ///Will raise a "decode error" alert
00744   }
00745 
00746   uint8_t server_session_id[SESSION_ID_MAX_SIZE];
00747   buffer_nbytes_read(buffer, server_session_id, server_session_id_length);
00748 
00749   if( (handshake->tls_socket->session.session_id_length == 0)
00750       || (server_session_id_length != handshake->tls_socket->session.session_id_length)
00751       || (memcmp(server_session_id, handshake->tls_socket->session.session_id, server_session_id_length) != 0))
00752   {
00753     //Session ID does not match, start a new one
00754     handshake->tls_socket->session.session_id_length = server_session_id_length;
00755     memcpy(handshake->tls_socket->session.session_id, server_session_id, server_session_id_length);
00756     *resumed = false;
00757   }
00758   else
00759   {
00760     //Resume session
00761     *resumed = true;
00762   }
00763 
00764   uint8_t cipher_suite[2];
00765   buffer_nbytes_read(buffer, cipher_suite, 2);
00766   uint8_t compression_mode = buffer_nu8_read(buffer);
00767 
00768 #if CRYPTO_ECC
00769   if(memcmp(cipher_suite, TLS_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 2) == 0)
00770   {
00771     handshake->target_security = TLS_SECURITY_TYPE_AES_128_CBC_SHA;
00772   }
00773   else
00774 #elif CRYPTO_RSA
00775   if(memcmp(cipher_suite, TLS_CIPHERSUITE_RSA_WITH_AES_128_CBC_SHA, 2) == 0)
00776   {
00777     handshake->target_security = TLS_SECURITY_TYPE_AES_128_CBC_SHA;
00778   }
00779   else if(memcmp(cipher_suite, TLS_CIPHERSUITE_RSA_WITH_ARC4_SHA, 2) == 0)
00780   {
00781     handshake->target_security = TLS_SECURITY_TYPE_ARC4_SHA;
00782   }
00783   else
00784 #else
00785 #error
00786 #endif
00787   {
00788     ERR("Unsupported cipher suite");
00789     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; //Protocol error as we did not advertise any other cipher suite/compression method in the hello client message
00790   }
00791 
00792   if( compression_mode != TLS_COMPRESSION_METHOD_NULL )
00793   {
00794     ERR("Unsupported compression method");
00795     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; //Protocol error as we did not advertise any other cipher suite/compression method in the hello client message
00796   }
00797 
00798   if( buffer_length(buffer) > 0 )
00799   {
00800     //Extensions are present, TODO
00801     DBG("Some extensions are present; ignoring them");
00802   }
00803 
00804   DBG("Hello Server OK");
00805 
00806   return MINITLS_OK;
00807 }
00808 
00809 minitls_err_t parse_server_certificate(tls_handshake_t* handshake, buffer_t* buffer)
00810 {
00811   if( buffer_length(buffer) < 3) //Certificate list size
00812   {
00813     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00814   }
00815 
00816   size_t cert_list_size = buffer_nu24_read(buffer);
00817 
00818   if( buffer_length(buffer) < cert_list_size ) //Certificate list
00819   {
00820     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00821   }
00822 
00823   if( buffer_length(buffer) < 3) //Certificate size
00824   {
00825     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00826   }
00827 
00828   size_t cert_size = buffer_nu24_read(buffer);
00829 
00830   if( (buffer_length(buffer) < cert_size) || (cert_size + 3 > cert_list_size) ) //Certificate
00831   {
00832     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00833   }
00834 
00835   //Only parse first certificate in the chain, ignore others
00836   if( cert_size != handshake->tls_socket->minitls->certificate->certificate_size )
00837   {
00838     ERR("Certificate does not match");
00839     //Cannot contain certificate, return security error
00840     return MINITLS_ERR_WRONG_CERTIFICATE;
00841   }
00842 
00843   //Do a plain, stupid, comparison with the certificate we have
00844   if( memcmp( handshake->tls_socket->minitls->certificate->certificate, buffer_current_read_position(buffer), handshake->tls_socket->minitls->certificate->certificate_size) != 0 )
00845   {
00846     ERR("Certificate does not match");
00847     //This is not the same certificate
00848     return MINITLS_ERR_WRONG_CERTIFICATE;
00849   }
00850   buffer_n_discard(buffer, handshake->tls_socket->minitls->certificate->certificate_size);
00851 
00852 
00853   return MINITLS_OK;
00854 }
00855 
00856 minitls_err_t parse_server_key_exchange(tls_handshake_t* handshake, buffer_t* buffer)
00857 {
00858 #if CRYPTO_ECC
00859   //For now we only support the ECDHE_ECDSA key exchange algo, so we hardcode the recovery of ephemeral key values here
00860   /*
00861   enum { explicit_prime (1), explicit_char2 (2),
00862          named_curve (3), reserved(248..255) } ECCurveType;
00863 
00864   enum {
00865       sect163k1 (1), sect163r1 (2), sect163r2 (3),
00866       sect193r1 (4), sect193r2 (5), sect233k1 (6),
00867       sect233r1 (7), sect239k1 (8), sect283k1 (9),
00868       sect283r1 (10), sect409k1 (11), sect409r1 (12),
00869       sect571k1 (13), sect571r1 (14), secp160k1 (15),
00870       secp160r1 (16), secp160r2 (17), secp192k1 (18),
00871       secp192r1 (19), secp224k1 (20), secp224r1 (21),
00872       secp256k1 (22), secp256r1 (23), secp384r1 (24),
00873       secp521r1 (25),
00874       reserved (0xFE00..0xFEFF),
00875       arbitrary_explicit_prime_curves(0xFF01),
00876       arbitrary_explicit_char2_curves(0xFF02),
00877       (0xFFFF)
00878   } NamedCurve;
00879 
00880   struct {
00881       ECCurveType    curve_type;
00882       select (curve_type) {
00883           case explicit_prime:
00884               opaque      prime_p <1..2^8-1>;
00885               ECCurve     curve;
00886               ECPoint     base;
00887               opaque      order <1..2^8-1>;
00888               opaque      cofactor <1..2^8-1>;
00889           case explicit_char2:
00890               uint16      m;
00891               ECBasisType basis;
00892               select (basis) {
00893                   case ec_trinomial:
00894                       opaque  k <1..2^8-1>;
00895                   case ec_pentanomial:
00896                       opaque  k1 <1..2^8-1>;
00897                       opaque  k2 <1..2^8-1>;
00898                       opaque  k3 <1..2^8-1>;
00899               };
00900               ECCurve     curve;
00901               ECPoint     base;
00902               opaque      order <1..2^8-1>;
00903               opaque      cofactor <1..2^8-1>;
00904           case named_curve:
00905               NamedCurve namedcurve;
00906       };
00907   } ECParameters;
00908 
00909   struct {
00910     opaque point <1..2^8-1>;
00911   } ECPoint;
00912 
00913   struct {
00914     ECParameters    curve_params;
00915     ECPoint         public;
00916   } ServerECDHParams;
00917 
00918   //signed_params - TLS1.2 specific
00919   struct {
00920      SignatureAndHashAlgorithm algorithm;
00921      opaque signature<0..2^16-1>;
00922   } DigitallySigned;
00923 
00924   enum { ecdsa } SignatureAlgorithm;
00925 
00926   select (SignatureAlgorithm) {
00927       case ecdsa:
00928           digitally-signed struct {
00929               opaque sha_hash[sha_size];
00930           };
00931   } Signature;
00932 
00933 
00934   ServerKeyExchange.signed_params.sha_hash
00935       SHA(ClientHello.random + ServerHello.random +
00936                                         ServerKeyExchange.params);
00937 
00938   select (KeyExchangeAlgorithm) {
00939       case ec_diffie_hellman:
00940           ServerECDHParams    params;
00941           Signature           signed_params;
00942   } ServerKeyExchange;
00943   */
00944 
00945   //Save position as we will have to perform a hash starting from here
00946   uint8_t* params_position = buffer_current_read_position(buffer);
00947 
00948   //Only supporting named curves as we have no means of validating other new curves
00949   if( buffer_length(buffer) < 1 )
00950   {
00951     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00952   }
00953 
00954   uint8_t curve_desc_type = buffer_nu8_read(buffer);
00955   if(curve_desc_type != 3) //Named curve
00956   {
00957     WARN("Not a named curve");
00958     return MINITLS_ERR_NOT_IMPLEMENTED;
00959   }
00960 
00961   crypto_ecc_curve_type_t curve_type = buffer_nu16_read(buffer);
00962 
00963   DBG("ECC Curve %d", curve_type);
00964 
00965   minitls_err_t ret = crypto_ecc_curve_get(&handshake->key_exchange.ecc.curve, curve_type);
00966   if(ret)
00967   {
00968     ERR("Could not get curve");
00969     return ret;
00970   }
00971 
00972   if( buffer_length(buffer) < 1 )
00973   {
00974     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00975   }
00976 
00977   size_t point_size = buffer_nu8_read(buffer);
00978 
00979   if( buffer_length(buffer) < point_size )
00980   {
00981     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00982   }
00983 
00984   //Read point
00985   ret = crypto_ecc_ansi_x963_import(&handshake->key_exchange.ecc.server_key, handshake->key_exchange.ecc.curve, buffer_current_read_position(buffer), point_size);
00986   buffer_n_discard(buffer, point_size);
00987   if(ret)
00988   {
00989     ERR("Error decoding ANSI X9.63 key");
00990     return ret;
00991   }
00992 
00993   size_t params_size = buffer_current_read_position(buffer) - params_position;
00994 
00995   if( buffer_length(buffer) < 2 )
00996   {
00997     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
00998   }
00999 
01000   //Check hash and signature algorithms -- this was introduced in TLS1.2
01001   uint8_t hash_alg = buffer_nu8_read(buffer);
01002   uint8_t sig_alg = buffer_nu8_read(buffer);
01003 
01004   //We only support SHA1 / ECDSA so check that this is what the server is offering
01005 
01006   if( (hash_alg != sha1) || (sig_alg != ecdsa) )
01007   {
01008     ERR("Unsupported hash/signature algorithms");
01009   }
01010 
01011   //Signature length is 2 bytes long
01012   if( buffer_length(buffer) < 2 )
01013   {
01014     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
01015   }
01016 
01017   size_t signature_length = buffer_nu16_read(buffer);
01018 
01019   //Signature length is 2 bytes long
01020   if( buffer_length(buffer) < signature_length )
01021   {
01022     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
01023   }
01024 
01025   //Compute hash
01026   uint8_t hash_result[SHA1_SIZE];
01027   crypto_sha1_t sha1;
01028   crypto_sha1_init(&sha1);
01029   crypto_sha1_update(&sha1, handshake->random_client, HANDSHAKE_RANDOM_SIZE);
01030   crypto_sha1_update(&sha1, handshake->random_server, HANDSHAKE_RANDOM_SIZE);
01031   crypto_sha1_update(&sha1, params_position, params_size);
01032   crypto_sha1_end(&sha1, hash_result);
01033 
01034   DBG("SHA-1 Hash:");
01035   DBG_BLOCK(
01036   buffer_t hash_result_buf;
01037   buffer_byref(&hash_result_buf, hash_result, SHA1_SIZE);
01038   buffer_dump(&hash_result_buf); )
01039 
01040   //Finally check signature
01041   ret = crypto_ecc_dsa_check(&handshake->tls_socket->minitls->certificate->public_key.ecc, hash_result, SHA1_SIZE, buffer_current_read_position(buffer), signature_length);
01042   buffer_n_discard(buffer, signature_length);
01043   if(ret)
01044   {
01045     ERR("Signature check failed");
01046     return ret;
01047   }
01048 
01049   DBG("Server key exchange parsed");
01050 
01051   return MINITLS_OK;
01052 #else
01053   return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; //Illegal for these cipher suites
01054 #endif
01055 }
01056 
01057 minitls_err_t parse_client_certificate_request(tls_handshake_t* handshake, buffer_t* buffer)
01058 {
01059   //Ignore that, we won't offer a certificate in return anyway (or an empty one)
01060   return MINITLS_OK;
01061 }
01062 
01063 minitls_err_t parse_hello_done_server(tls_handshake_t* handshake, buffer_t* buffer)
01064 {
01065   if( buffer_length(buffer) != 0 )
01066   {
01067     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
01068   }
01069   return MINITLS_OK;
01070 }
01071 
01072 #define CLIENT_CERTIFICATE_NOCERTS_SIZE 3
01073 
01074 minitls_err_t send_client_certificate(tls_handshake_t* handshake, buffer_t* buffer)
01075 {
01076   //Send a 0-length certificate structure
01077 
01078   minitls_err_t ret;
01079 
01080   //Write header
01081   ret = prepare_message(handshake, certificate, buffer, CLIENT_CERTIFICATE_NOCERTS_SIZE);
01082   if(ret)
01083   {
01084     return ret;
01085   }
01086 
01087   buffer_nu24_write(buffer, 0); //empty list
01088 
01089   ret = send_message(handshake, buffer);
01090   if(ret)
01091   {
01092     return ret;
01093   }
01094 
01095   return MINITLS_OK;
01096 }
01097 
01098 #define CLIENT_KEY_EXCHANGE_BASE_SIZE 0
01099 
01100 minitls_err_t send_client_key_exchange(tls_handshake_t* handshake, buffer_t* buffer)
01101 {
01102   minitls_err_t ret;
01103 
01104   //Write header
01105   ret = prepare_message(handshake, client_key_exchange, buffer, CLIENT_KEY_EXCHANGE_BASE_SIZE);
01106   if(ret)
01107   {
01108     return ret;
01109   }
01110 
01111 
01112 #if CRYPTO_ECC
01113   //Send a 0-length certificate structure
01114 
01115   //Key size
01116   DBG_BLOCK(
01117   size_t key_size = crypto_ecc_get_key_size_for_curve(handshake->ecc_curve);
01118 
01119   DBG("Generating ephemeral key of size %d", key_size);
01120   )
01121 
01122   //Generate client key
01123   ret = crypto_ecc_generate_key(&handshake->key_exchange.ecc.client_key, handshake->key_exchange.ecc.curve, handshake->tls_socket->minitls->prng);
01124   if(ret)
01125   {
01126     return ret;
01127   }
01128 
01129   DBG("Key generated");
01130 
01131   //Skip key size
01132   size_t point_size = 0;
01133   buffer_nu8_write(buffer, point_size);
01134 
01135   DBG("Exporting key in X9.63 format");
01136 
01137   //Write key
01138   ret = crypto_ecc_ansi_x963_export(crypto_ecc_get_public_key(&handshake->key_exchange.ecc.client_key), /*handshake->ecc_curve,*/ buffer_current_write_position(buffer), buffer_space(buffer), &point_size);
01139   if(ret)
01140   {
01141     return ret;
01142   }
01143 
01144   buffer_n_skip(buffer, point_size);
01145 
01146   DBG("Adjusting size");
01147 
01148   //Rewind, write position and re-adjust
01149   size_t length = buffer_length(buffer);
01150   buffer_set_length(buffer, length - point_size - 1);
01151 
01152   buffer_nu8_write(buffer, point_size);
01153 
01154   buffer_set_length(buffer, length);
01155 
01156   //Adjust message size
01157   ret = prepare_message_adjust_size(handshake, buffer, CLIENT_KEY_EXCHANGE_BASE_SIZE + 1 + point_size);
01158   if(ret)
01159   {
01160     return ret;
01161   }
01162 
01163   ret = send_message(handshake, buffer);
01164   if(ret)
01165   {
01166     return ret;
01167   }
01168 #elif CRYPTO_RSA
01169   /*
01170   struct {
01171       ProtocolVersion client_version;
01172       opaque random[46];
01173   } PreMasterSecret;
01174 
01175   client_version
01176      The latest (newest) version supported by the client.  This is
01177      used to detect version rollback attacks.
01178 
01179   random
01180      46 securely-generated random bytes.
01181 
01182   struct {
01183       public-key-encrypted PreMasterSecret pre_master_secret;
01184   } EncryptedPreMasterSecret;
01185 
01186   pre_master_secret
01187      This random value is generated by the client and is used to
01188      generate the master secret, as specified in Section 8.1.
01189      */
01190 
01191   //Premaster key is generated first
01192 
01193 #else
01194 #error
01195 #endif
01196 
01197   DBG("Generating premaster key");
01198 
01199   uint8_t premaster_key[HANDSHAKE_MAX_PREMASTER_KEY_SIZE];
01200   size_t premaster_key_size = 0;
01201 
01202 #if CRYPTO_ECC
01203   //At this point we can generate the pre-master key
01204   ret = crypto_ecc_dh_generate_shared_secret(&handshake->key_exchange.ecc.client_key, &handshake->key_exchange.ecc.server_key, premaster_key, HANDSHAKE_MAX_PREMASTER_KEY_SIZE, &premaster_key_size);
01205   if(ret)
01206   {
01207     memset(premaster_key, 0, HANDSHAKE_MAX_PREMASTER_KEY_SIZE); //Don't want to leak this
01208     return ret;
01209   }
01210 #elif CRYPTO_RSA
01211   //The two first bytes should be the SSL/TLS version advertised in ClientHello (prevents version rollback attacks)
01212 #if MINITLS_CFG_PROTOCOL_TLS_1_2
01213   premaster_key[0] = TLS_1_2_VERSION_MAJOR;
01214   premaster_key[1] = TLS_1_2_VERSION_MINOR;
01215 #elif MINITLS_CFG_PROTOCOL_TLS_1_1
01216   premaster_key[0] = TLS_1_1_VERSION_MAJOR;
01217   premaster_key[1] = TLS_1_1_VERSION_MINOR;
01218 #elif MINITLS_CFG_PROTOCOL_TLS_1_0
01219   premaster_key[0] = TLS_1_0_VERSION_MAJOR;
01220   premaster_key[1] = TLS_1_0_VERSION_MINOR;
01221 #elif MINITLS_CFG_PROTOCOL_SSL_3
01222   premaster_key[0] = SSL_3_VERSION_MAJOR;
01223   premaster_key[1] = SSL_3_VERSION_MINOR;
01224 #else
01225 #error No SSL/TLS protocol version enabled
01226 #endif
01227 
01228   //Other 46 bytes are random
01229   crypto_prng_get(handshake->tls_socket->minitls->prng, &premaster_key[2], HANDSHAKE_RSA_PREMASTER_KEY_SIZE - 2);
01230   premaster_key_size = HANDSHAKE_RSA_PREMASTER_KEY_SIZE;
01231 
01232   //Encrypt it using RSA
01233   uint8_t encrypted_premaster_key[RSA_PREMASTER_KEY_SIZE];
01234 
01235   size_t encrypted_premaster_key_size = 0;
01236   ret = crypto_rsa_encrypt(&handshake->tls_socket->minitls->certificate->public_key.rsa,
01237       premaster_key, premaster_key_size,
01238       encrypted_premaster_key, sizeof(encrypted_premaster_key), &encrypted_premaster_key_size, handshake->tls_socket->minitls->prng);
01239   if(ret)
01240   {
01241     WARN("Error %d", ret);
01242     return ret;
01243   }
01244 
01245   DBG("Encrypted premaster key size: %d", encrypted_premaster_key_size);
01246 
01247   //Now send it
01248   buffer_nu16_write(buffer, encrypted_premaster_key_size);
01249   buffer_nbytes_write(buffer, encrypted_premaster_key, encrypted_premaster_key_size);
01250 
01251   //Adjust message size
01252   ret = prepare_message_adjust_size(handshake, buffer, CLIENT_KEY_EXCHANGE_BASE_SIZE + 2 + encrypted_premaster_key_size);
01253   if(ret)
01254   {
01255     return ret;
01256   }
01257 
01258   ret = send_message(handshake, buffer);
01259   if(ret)
01260   {
01261     return ret;
01262   }
01263 #endif
01264 
01265   DBG_BLOCK(
01266   DBG("Premaster key size: %d", premaster_key_size);
01267 
01268   buffer_t dump_buf;
01269   DBG("Premaster key");
01270   buffer_byref(&dump_buf, premaster_key, premaster_key_size);
01271   buffer_dump(&dump_buf);
01272 
01273   DBG("Random client");
01274   buffer_byref(&dump_buf, handshake->random_client, HANDSHAKE_RANDOM_SIZE);
01275   buffer_dump(&dump_buf);
01276 
01277   DBG("Random server");
01278   buffer_byref(&dump_buf, handshake->random_server, HANDSHAKE_RANDOM_SIZE);
01279   buffer_dump(&dump_buf);
01280   )
01281 
01282 
01283   //Now generate the shared AES128 key
01284 
01285   DBG("Expanding the key");
01286 
01287   /*
01288    master_secret = PRF(pre_master_secret, "master secret",
01289                           ClientHello.random + ServerHello.random)
01290                           [0..47];
01291    */
01292 
01293   ret = prf_compute(premaster_key, premaster_key_size, "master secret",
01294       handshake->random_client, HANDSHAKE_RANDOM_SIZE,
01295       handshake->random_server, HANDSHAKE_RANDOM_SIZE,
01296       handshake->tls_socket->session.master_key, HANDSHAKE_MASTER_KEY_SIZE);
01297   memset(premaster_key, 0, HANDSHAKE_MAX_PREMASTER_KEY_SIZE); //Don't want to leak this
01298   if(ret)
01299   {
01300     return ret;
01301   }
01302 
01303   DBG_BLOCK(
01304   DBG("Key expanded into master key");
01305   buffer_byref(&dump_buf, handshake->tls_socket->session.master_key, HANDSHAKE_MASTER_KEY_SIZE);
01306   buffer_dump(&dump_buf);
01307   )
01308 
01309   return MINITLS_OK;
01310 }
01311 
01312 #define VERIFY_DATA_LENGTH 12
01313 #define FINISHED_SIZE 12 // 12 bytes PRF // -- no 13 //length + 12 bytes prf
01314 
01315 minitls_err_t send_finished(tls_handshake_t* handshake, buffer_t* buffer)
01316 {
01317   minitls_err_t ret;
01318 
01319   //Write header
01320   ret = prepare_message(handshake, finished, buffer, FINISHED_SIZE);
01321   if(ret)
01322   {
01323     return ret;
01324   }
01325 
01326   crypto_sha256_t hash;
01327   crypto_sha256_copy(&hash, &handshake->hash.sha256); //We need to keep the global hash to check the server's finished message
01328 
01329   //Compute final hash
01330   uint8_t result[SHA256_SIZE];
01331   crypto_sha256_end(&hash, result);
01332 
01333   /*
01334       struct {
01335           opaque verify_data[verify_data_length];
01336       } Finished;
01337 
01338       verify_data
01339          PRF(master_secret, finished_label, Hash(handshake_messages))
01340             [0..verify_data_length-1];
01341   */
01342 
01343   //buffer_nu8_write(buffer, VERIFY_DATA_LENGTH); //This is optional but anyway -- NOPE
01344 
01345   ret = prf_compute(handshake->tls_socket->session.master_key, HANDSHAKE_MASTER_KEY_SIZE, "client finished",
01346       result, SHA256_SIZE,
01347       NULL, 0,
01348       buffer_current_write_position(buffer), VERIFY_DATA_LENGTH);
01349   buffer_n_skip(buffer, VERIFY_DATA_LENGTH);
01350   if(ret)
01351   {
01352     return ret;
01353   }
01354 
01355   ret = send_message(handshake, buffer);
01356   if(ret)
01357   {
01358     return ret;
01359   }
01360 
01361   return MINITLS_OK;
01362 }
01363 
01364 minitls_err_t parse_finished(tls_handshake_t* handshake, buffer_t* buffer)
01365 {
01366   if(buffer_length(buffer) < VERIFY_DATA_LENGTH)
01367   {
01368     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
01369   }
01370 /*
01371   size_t length = VERIFY_DATA_LENGTH;
01372   if(buffer_length(buffer) > VERIFY_DATA_LENGTH)
01373   {
01374     length = buffer_nu8_read(buffer);
01375   }
01376 */
01377   if( (buffer_length(buffer)/*length*/ != VERIFY_DATA_LENGTH) )
01378   {
01379     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
01380   }
01381 
01382   crypto_sha256_t hash;
01383   crypto_sha256_copy(&hash, &handshake->hash.sha256); //We need to keep the global hash to check the server's finished message
01384 
01385   //Compute final hash
01386   uint8_t result[SHA256_SIZE];
01387   crypto_sha256_end(&hash, result);
01388 
01389   /*
01390       struct {
01391           opaque verify_data[verify_data_length];
01392       } Finished;
01393 
01394       verify_data
01395          PRF(master_secret, finished_label, Hash(handshake_messages))
01396             [0..verify_data_length-1];
01397   */
01398 
01399   uint8_t prf[VERIFY_DATA_LENGTH];
01400   minitls_err_t ret = prf_compute(handshake->tls_socket->session.master_key, HANDSHAKE_MASTER_KEY_SIZE, "server finished",
01401       result, SHA256_SIZE,
01402       NULL, 0,
01403       prf, VERIFY_DATA_LENGTH);
01404   if(ret)
01405   {
01406     return ret;
01407   }
01408 
01409 
01410   if(memcmp(prf, buffer_current_read_position(buffer), VERIFY_DATA_LENGTH) != 0)
01411   {
01412     ERR("PRF differs; computed PRF was:");
01413 
01414     DBG_BLOCK(
01415     buffer_t computed_prf;
01416     buffer_byref(&computed_prf, prf, VERIFY_DATA_LENGTH);
01417     buffer_dump(&computed_prf);)
01418 
01419     return MINITLS_ERR_WRONG_MAC;
01420   }
01421 
01422   buffer_n_discard(buffer, VERIFY_DATA_LENGTH);
01423 
01424   return MINITLS_OK;
01425 }
01426 
01427 minitls_err_t generate_record_keys(tls_handshake_t* handshake)
01428 {
01429   //Expand master key
01430 
01431   /*
01432    To generate the key material, compute
01433 
01434       key_block = PRF(SecurityParameters.master_secret,
01435                       "key expansion",
01436                       SecurityParameters.server_random +
01437                       SecurityParameters.client_random);
01438 
01439    until enough output has been generated.  Then, the key_block is
01440    partitioned as follows:
01441 
01442       client_write_MAC_key[SecurityParameters.mac_key_length]
01443       server_write_MAC_key[SecurityParameters.mac_key_length]
01444       client_write_key[SecurityParameters.enc_key_length]
01445       server_write_key[SecurityParameters.enc_key_length]
01446       client_write_IV[SecurityParameters.fixed_iv_length]
01447       server_write_IV[SecurityParameters.fixed_iv_length]
01448    */
01449 
01450   /*
01451   Cipher        Type    Material  Size  Size
01452   ------------  ------  --------  ----  -----
01453   AES_128_CBC   Block      16      16     16
01454 
01455   MAC       Algorithm    mac_length  mac_key_length
01456   --------  -----------  ----------  --------------
01457   SHA       HMAC-SHA1       20            20
01458   */
01459 
01460   //For our cipher we don't need the initialization vectors
01461 
01462   DBG("Expand master key");
01463 
01464   //Expand key
01465   uint8_t key_expansion[2*TLS_HMAC_SHA1_KEY_SIZE + 2*AES_128_KEY_SIZE];
01466   minitls_err_t ret = prf_compute(handshake->tls_socket->session.master_key, HANDSHAKE_MASTER_KEY_SIZE, "key expansion",
01467       handshake->random_server, HANDSHAKE_RANDOM_SIZE,
01468       handshake->random_client, HANDSHAKE_RANDOM_SIZE,
01469       key_expansion, 2*TLS_HMAC_SHA1_KEY_SIZE + 2*AES_128_KEY_SIZE);
01470   if(ret)
01471   {
01472     return ret;
01473   }
01474 
01475   //Init cipher/mac
01476   tls_record_set_keys(&handshake->tls_socket->record, handshake->target_security,
01477       &key_expansion[0*TLS_HMAC_SHA1_KEY_SIZE + 0*AES_128_KEY_SIZE],
01478       &key_expansion[1*TLS_HMAC_SHA1_KEY_SIZE + 0*AES_128_KEY_SIZE],
01479       &key_expansion[2*TLS_HMAC_SHA1_KEY_SIZE + 0*AES_128_KEY_SIZE],
01480       &key_expansion[2*TLS_HMAC_SHA1_KEY_SIZE + 1*AES_128_KEY_SIZE]
01481   );
01482 
01483   return MINITLS_OK;
01484 }
01485 
01486 #define HANDSHAKE_HEADER_SIZE 4
01487 
01488 minitls_err_t parse_message(tls_handshake_t* handshake, buffer_t* buffer, handshake_type_t* message_type)
01489 {
01490   if( buffer_length(buffer) < HANDSHAKE_HEADER_SIZE )
01491   {
01492     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
01493   }
01494 
01495   //Update SHA to use in FINISHED message
01496   if(handshake->state < TLS_HANDSHAKE_FINISHED_SENT) //Don't update if it is the FINISHED message sent from the server
01497   {
01498     //If TLS1.2 or protocol version unknown for now
01499     crypto_sha256_update(&handshake->hash.sha256, buffer_current_read_position(buffer), buffer_length(buffer));
01500 
01501     //FIXME SSL3-TLS1.1 or protocol version unknown for now
01502 
01503   }
01504 
01505   *message_type = (uint8_t) buffer_nu8_read(buffer);
01506   size_t size = buffer_nu24_read(buffer);
01507 
01508   if( buffer_length(buffer) != size )
01509   {
01510     return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
01511   }
01512 
01513   return MINITLS_OK;
01514 }
01515 
01516 minitls_err_t prepare_message(tls_handshake_t* handshake, handshake_type_t message_type, buffer_t* buffer, size_t size)
01517 {
01518   buffer_reset(buffer);
01519   if( buffer_size(buffer) < size + HANDSHAKE_HEADER_SIZE /* header size*/ )
01520   {
01521     ERR("Buffer too small");
01522     return MINITLS_ERR_BUFFER_TOO_SMALL;
01523   }
01524 
01525   buffer_nu8_write(buffer, (uint8_t)message_type);
01526   buffer_nu24_write(buffer, size);
01527 
01528   return MINITLS_OK;
01529 }
01530 
01531 minitls_err_t prepare_message_adjust_size(tls_handshake_t* handshake, buffer_t* buffer, size_t size)
01532 {
01533   size_t length = buffer_length(buffer);
01534 
01535   buffer_reset(buffer);
01536   if( buffer_size(buffer) < size + HANDSHAKE_HEADER_SIZE /* header size*/ )
01537   {
01538     return MINITLS_ERR_BUFFER_TOO_SMALL;
01539   }
01540 
01541   buffer_set_length(buffer, 1); //Skip message type
01542 
01543   buffer_nu24_write(buffer, size);
01544 
01545   buffer_set_length(buffer, length);
01546 
01547   return MINITLS_OK;
01548 }
01549 
01550 
01551 minitls_err_t send_message(tls_handshake_t* handshake, buffer_t* buffer)
01552 {
01553   //Update SHA to use in FINISHED messages
01554   crypto_sha256_update(&handshake->hash.sha256, buffer_current_read_position(buffer), buffer_length(buffer));
01555 
01556   //DEBUG TODO: check mismatch with length
01557 
01558   minitls_err_t ret = tls_record_send(&handshake->tls_socket->record, TLS_HANDSHAKE, buffer);
01559   if(ret)
01560   {
01561     ERR("Send returned %d", ret);
01562     return ret;
01563   }
01564   return MINITLS_OK;
01565 }
01566 
01567 void handle_ret(tls_handshake_t* handshake, minitls_err_t ret)
01568 {
01569   ERR("Will return error %d", ret);
01570 
01571   //Make handshake fail
01572   handshake->state = TLS_HANDSHAKE_FAILED;
01573 
01574   //Send alert to other party
01575   switch(ret)
01576   {
01577   case MINITLS_ERR_WRONG_CERTIFICATE:
01578     tls_alert_send(&handshake->tls_socket->record, TLS_ALERT_FATAL, CERTIFICATE_UNKNOWN, &handshake->tls_socket->record.buffer);
01579     break;
01580   case MINITLS_ERR_PROTOCOL_NON_CONFORMANT:
01581     tls_alert_send(&handshake->tls_socket->record, TLS_ALERT_FATAL, UNEXPECTED_MESSAGE, &handshake->tls_socket->record.buffer);
01582     break;
01583   case MINITLS_ERR_NOT_IMPLEMENTED:
01584   default:
01585     tls_alert_send(&handshake->tls_socket->record, TLS_ALERT_FATAL, HANDSHAKE_FAILURE, &handshake->tls_socket->record.buffer);
01586     break;
01587   }
01588 }
01589 
01590 
01591 minitls_err_t prf_compute(const uint8_t* secret, size_t secret_size,
01592     const char* label,
01593     const uint8_t* seed1, size_t seed1_size,
01594     const uint8_t* seed2, size_t seed2_size,
01595     uint8_t* out, size_t out_size)
01596 {
01597   //PRF TLS1.2
01598   //TODO add PRF SSL3-TLS1.1
01599 
01600   //DBG("PRF: Secret %p [%d] - label '%s' - Seed %p [%d] - out %p [%d]", secret, secret_size, label, seed, seed_size, out, out_size);
01601   //We are using the HMAC-SHA256 MAC (non negotiable)
01602 
01603   /*
01604   P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
01605                          HMAC_hash(secret, A(2) + seed) +
01606                          HMAC_hash(secret, A(3) + seed) + ...
01607 
01608   A(0) = seed
01609   A(i) = HMAC_hash(secret, A(i-1))
01610 
01611   PRF(secret, label, seed) = P_hash(secret, label + seed)
01612 
01613   */
01614 
01615   //MAC_HMAC_SHA1_SIZE
01616   uint8_t mac[HMAC_SHA256_SIZE];
01617   uint8_t A[HMAC_SHA256_SIZE];
01618 
01619   //A[0] = seed
01620   crypto_hmac_sha256_t hmac_sha256;
01621 
01622   //minitls_err_t ret;
01623 
01624   size_t current_size = 0;
01625 
01626   while(current_size < out_size)
01627   {
01628     //DBG("Current size %d", current_size);
01629 
01630     //Compute A[n]=f(A[n-1])
01631     crypto_hmac_sha256_init(&hmac_sha256, secret, secret_size);
01632 
01633     if(current_size == 0) //First iteration
01634     {
01635       crypto_hmac_sha256_update(&hmac_sha256, (const uint8_t*)label, strlen(label));
01636 
01637       crypto_hmac_sha256_update(&hmac_sha256, seed1, seed1_size);
01638       if(seed2 != NULL)
01639       {
01640         crypto_hmac_sha256_update(&hmac_sha256, seed2, seed2_size);
01641       }
01642     }
01643     else
01644     {
01645       crypto_hmac_sha256_update(&hmac_sha256, A, HMAC_SHA256_SIZE);
01646     }
01647 
01648     crypto_hmac_sha256_end(&hmac_sha256, A);
01649 
01650     //Compute HMAC_hash(secret, A[n] + seed)
01651     crypto_hmac_sha256_init(&hmac_sha256, secret, secret_size);
01652 
01653     crypto_hmac_sha256_update(&hmac_sha256, A, HMAC_SHA256_SIZE);
01654 
01655     crypto_hmac_sha256_update(&hmac_sha256, (const uint8_t*)label, strlen(label));
01656 
01657     crypto_hmac_sha256_update(&hmac_sha256, seed1, seed1_size);
01658     if(seed2 != NULL)
01659     {
01660       crypto_hmac_sha256_update(&hmac_sha256, seed2, seed2_size);
01661     }
01662 
01663     crypto_hmac_sha256_end(&hmac_sha256, mac);
01664 
01665     //Copy and truncate if needed
01666     size_t append_size = MIN( out_size - current_size, HMAC_SHA256_SIZE );
01667     memcpy(out + current_size, mac, append_size);
01668 
01669     current_size += append_size;
01670   }
01671 
01672   return MINITLS_OK;
01673 }
01674 
01675 minitls_err_t change_cipher_spec_request(tls_handshake_t* handshake, buffer_t* buffer)
01676 {
01677   /*
01678   The change cipher spec protocol exists to signal transitions in
01679   ciphering strategies.  The protocol consists of a single message,
01680   which is encrypted and compressed under the current (not the pending)
01681   connection state.  The message consists of a single byte of value 1.
01682 
01683   struct {
01684       enum { change_cipher_spec(1), (255) } type;
01685   } ChangeCipherSpec;
01686   */
01687   buffer_reset(buffer);
01688   if( buffer_size(buffer) < 1 )
01689   {
01690    return MINITLS_ERR_BUFFER_TOO_SMALL;
01691   }
01692 
01693   buffer_nu8_write(buffer, 1);
01694 
01695   minitls_err_t ret = tls_record_send(&handshake->tls_socket->record, TLS_CHANGE_CIPHER_SPEC, buffer);
01696   if(ret)
01697   {
01698     return ret;
01699   }
01700 
01701   return MINITLS_OK;
01702 }