Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of MiniTLS-GPL by
tls_handshake.c
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 }
Generated on Tue Jul 12 2022 19:20:10 by
1.7.2
