A super trimmed down TLS stack, GPL licensed

Dependents:   MiniTLS-HTTPS-Example

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

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

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

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

Committer:
MiniTLS
Date:
Tue Jun 10 14:22:36 2014 +0000
Revision:
3:eb324ffffd2b
Parent:
2:527a66d0a1a9
Fixes for mbed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MiniTLS 2:527a66d0a1a9 1 /*
MiniTLS 2:527a66d0a1a9 2 MiniTLS - A super trimmed down TLS/SSL Library for embedded devices
MiniTLS 2:527a66d0a1a9 3 Author: Donatien Garnier
MiniTLS 2:527a66d0a1a9 4 Copyright (C) 2013-2014 AppNearMe Ltd
MiniTLS 2:527a66d0a1a9 5
MiniTLS 2:527a66d0a1a9 6 This program is free software; you can redistribute it and/or
MiniTLS 2:527a66d0a1a9 7 modify it under the terms of the GNU General Public License
MiniTLS 2:527a66d0a1a9 8 as published by the Free Software Foundation; either version 2
MiniTLS 2:527a66d0a1a9 9 of the License, or (at your option) any later version.
MiniTLS 2:527a66d0a1a9 10
MiniTLS 2:527a66d0a1a9 11 This program is distributed in the hope that it will be useful,
MiniTLS 2:527a66d0a1a9 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
MiniTLS 2:527a66d0a1a9 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
MiniTLS 2:527a66d0a1a9 14 GNU General Public License for more details.
MiniTLS 2:527a66d0a1a9 15
MiniTLS 2:527a66d0a1a9 16 You should have received a copy of the GNU General Public License
MiniTLS 2:527a66d0a1a9 17 along with this program; if not, write to the Free Software
MiniTLS 2:527a66d0a1a9 18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
MiniTLS 2:527a66d0a1a9 19 *//**
MiniTLS 2:527a66d0a1a9 20 * \file tls_handshake.c
MiniTLS 2:527a66d0a1a9 21 * \copyright Copyright (c) AppNearMe Ltd 2013
MiniTLS 2:527a66d0a1a9 22 * \author Donatien Garnier
MiniTLS 2:527a66d0a1a9 23 */
MiniTLS 2:527a66d0a1a9 24
MiniTLS 3:eb324ffffd2b 25 #define __DEBUG__ 4
MiniTLS 2:527a66d0a1a9 26 #ifndef __MODULE__
MiniTLS 2:527a66d0a1a9 27 #define __MODULE__ "tls_handshake.c"
MiniTLS 2:527a66d0a1a9 28 #endif
MiniTLS 2:527a66d0a1a9 29
MiniTLS 2:527a66d0a1a9 30 #include "core/fwk.h"
MiniTLS 2:527a66d0a1a9 31
MiniTLS 2:527a66d0a1a9 32 #include "tls_handshake.h"
MiniTLS 2:527a66d0a1a9 33 #include "tls_record.h"
MiniTLS 2:527a66d0a1a9 34 #include "tls_socket.h"
MiniTLS 2:527a66d0a1a9 35 #include "tls_alert.h"
MiniTLS 2:527a66d0a1a9 36 #include "crypto/crypto_ecc.h"
MiniTLS 2:527a66d0a1a9 37 #include "crypto/crypto_sha1.h"
MiniTLS 2:527a66d0a1a9 38 #include "crypto/crypto_sha256.h"
MiniTLS 2:527a66d0a1a9 39 #include "crypto/crypto_hmac_sha1.h"
MiniTLS 2:527a66d0a1a9 40 #include "crypto/crypto_hmac_sha256.h"
MiniTLS 2:527a66d0a1a9 41
MiniTLS 2:527a66d0a1a9 42 #define HANDSHAKE_MAX_PREMASTER_KEY_SIZE 64
MiniTLS 2:527a66d0a1a9 43 #define HANDSHAKE_RSA_PREMASTER_KEY_SIZE 48
MiniTLS 2:527a66d0a1a9 44
MiniTLS 3:eb324ffffd2b 45 #if MINITLS_CFG_KEY_RSA_2048
MiniTLS 3:eb324ffffd2b 46 #define RSA_PREMASTER_KEY_SIZE 256
MiniTLS 3:eb324ffffd2b 47 #elif MINITLS_CFG_KEY_RSA_1024
MiniTLS 3:eb324ffffd2b 48 #define RSA_PREMASTER_KEY_SIZE 128
MiniTLS 3:eb324ffffd2b 49 #endif
MiniTLS 3:eb324ffffd2b 50
MiniTLS 2:527a66d0a1a9 51 typedef enum __handshake_type
MiniTLS 2:527a66d0a1a9 52 {
MiniTLS 2:527a66d0a1a9 53 hello_request = (0), client_hello = (1), server_hello = (2),
MiniTLS 2:527a66d0a1a9 54 certificate = (11), server_key_exchange = (12),
MiniTLS 2:527a66d0a1a9 55 certificate_request = (13), server_hello_done = (14),
MiniTLS 2:527a66d0a1a9 56 certificate_verify = (15), client_key_exchange = (16),
MiniTLS 2:527a66d0a1a9 57 finished = (20), unknown = (255)
MiniTLS 2:527a66d0a1a9 58 } handshake_type_t;
MiniTLS 2:527a66d0a1a9 59
MiniTLS 2:527a66d0a1a9 60 static minitls_err_t send_hello_client(tls_handshake_t* handshake, buffer_t* buffer);
MiniTLS 2:527a66d0a1a9 61 static minitls_err_t parse_hello_server(tls_handshake_t* handshake, buffer_t* buffer, bool* resumed);
MiniTLS 2:527a66d0a1a9 62 static minitls_err_t parse_server_certificate(tls_handshake_t* handshake, buffer_t* buffer);
MiniTLS 2:527a66d0a1a9 63 static minitls_err_t parse_server_key_exchange(tls_handshake_t* handshake, buffer_t* buffer);
MiniTLS 2:527a66d0a1a9 64 static minitls_err_t parse_client_certificate_request(tls_handshake_t* handshake, buffer_t* buffer);
MiniTLS 2:527a66d0a1a9 65 static minitls_err_t parse_hello_done_server(tls_handshake_t* handshake, buffer_t* buffer);
MiniTLS 2:527a66d0a1a9 66 static minitls_err_t send_client_certificate(tls_handshake_t* handshake, buffer_t* buffer);
MiniTLS 2:527a66d0a1a9 67 static minitls_err_t send_client_key_exchange(tls_handshake_t* handshake, buffer_t* buffer);
MiniTLS 2:527a66d0a1a9 68 static minitls_err_t send_finished(tls_handshake_t* handshake, buffer_t* buffer);
MiniTLS 2:527a66d0a1a9 69 static minitls_err_t parse_finished(tls_handshake_t* handshake, buffer_t* buffer);
MiniTLS 2:527a66d0a1a9 70
MiniTLS 2:527a66d0a1a9 71 static minitls_err_t generate_record_keys(tls_handshake_t* handshake);
MiniTLS 2:527a66d0a1a9 72
MiniTLS 2:527a66d0a1a9 73 //Receive stuff
MiniTLS 2:527a66d0a1a9 74 static minitls_err_t parse_message(tls_handshake_t* handshake, buffer_t* buffer, handshake_type_t* message_type);
MiniTLS 2:527a66d0a1a9 75
MiniTLS 2:527a66d0a1a9 76 //Send stuff
MiniTLS 2:527a66d0a1a9 77 static minitls_err_t prepare_message(tls_handshake_t* handshake, handshake_type_t message_type, buffer_t* buffer, size_t size);
MiniTLS 2:527a66d0a1a9 78 static minitls_err_t prepare_message_adjust_size(tls_handshake_t* handshake, buffer_t* buffer, size_t size);
MiniTLS 2:527a66d0a1a9 79 static minitls_err_t send_message(tls_handshake_t* handshake, buffer_t* buffer);
MiniTLS 2:527a66d0a1a9 80
MiniTLS 2:527a66d0a1a9 81 //Error handlers
MiniTLS 2:527a66d0a1a9 82 static void handle_ret(tls_handshake_t* handshake, minitls_err_t ret);
MiniTLS 2:527a66d0a1a9 83
MiniTLS 2:527a66d0a1a9 84 /*
MiniTLS 2:527a66d0a1a9 85 P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
MiniTLS 2:527a66d0a1a9 86 HMAC_hash(secret, A(2) + seed) +
MiniTLS 2:527a66d0a1a9 87 HMAC_hash(secret, A(3) + seed) + ...
MiniTLS 2:527a66d0a1a9 88
MiniTLS 2:527a66d0a1a9 89 PRF(secret, label, seed) = P_hash(secret, label + seed)
MiniTLS 2:527a66d0a1a9 90 */
MiniTLS 2:527a66d0a1a9 91
MiniTLS 2:527a66d0a1a9 92 //PRF computation
MiniTLS 2:527a66d0a1a9 93 static minitls_err_t prf_compute(const uint8_t* secret, size_t secret_size,
MiniTLS 2:527a66d0a1a9 94 const char* label,
MiniTLS 2:527a66d0a1a9 95 const uint8_t* seed1, size_t seed1_size,
MiniTLS 2:527a66d0a1a9 96 const uint8_t* seed2, size_t seed2_size,
MiniTLS 2:527a66d0a1a9 97 uint8_t* out, size_t out_size);
MiniTLS 2:527a66d0a1a9 98
MiniTLS 2:527a66d0a1a9 99 //Record-level change cipher spec request
MiniTLS 2:527a66d0a1a9 100 static minitls_err_t change_cipher_spec_request(tls_handshake_t* handshake, buffer_t* buffer);
MiniTLS 2:527a66d0a1a9 101
MiniTLS 2:527a66d0a1a9 102 minitls_err_t tls_handshake_init(tls_handshake_t* handshake, tls_socket_t* socket)
MiniTLS 2:527a66d0a1a9 103 {
MiniTLS 2:527a66d0a1a9 104 handshake->tls_socket = socket;
MiniTLS 2:527a66d0a1a9 105
MiniTLS 2:527a66d0a1a9 106 tls_handshake_clean(handshake);
MiniTLS 2:527a66d0a1a9 107 //memset(handshake->master_key, 0, sizeof(HANDSHAKE_MASTER_KEY_SIZE));
MiniTLS 2:527a66d0a1a9 108
MiniTLS 2:527a66d0a1a9 109 //Reset state machine
MiniTLS 2:527a66d0a1a9 110 handshake->state = TLS_HANDSHAKE_INIT;
MiniTLS 2:527a66d0a1a9 111
MiniTLS 2:527a66d0a1a9 112 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 113 }
MiniTLS 2:527a66d0a1a9 114
MiniTLS 2:527a66d0a1a9 115
MiniTLS 2:527a66d0a1a9 116 minitls_err_t tls_handshake_start(tls_handshake_t* handshake)
MiniTLS 2:527a66d0a1a9 117 {
MiniTLS 2:527a66d0a1a9 118 minitls_err_t ret = send_hello_client(handshake, &handshake->tls_socket->record.buffer);
MiniTLS 2:527a66d0a1a9 119 if(ret)
MiniTLS 2:527a66d0a1a9 120 {
MiniTLS 2:527a66d0a1a9 121 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 122 return ret;
MiniTLS 2:527a66d0a1a9 123 }
MiniTLS 2:527a66d0a1a9 124 handshake->state = TLS_HANDSHAKE_HELLO_SENT;
MiniTLS 2:527a66d0a1a9 125 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 126 }
MiniTLS 2:527a66d0a1a9 127
MiniTLS 2:527a66d0a1a9 128 minitls_err_t tls_handshake_process(tls_handshake_t* handshake, buffer_t* buffer)
MiniTLS 2:527a66d0a1a9 129 {
MiniTLS 2:527a66d0a1a9 130 //Parse buffer
MiniTLS 2:527a66d0a1a9 131 DBG("Parsing message");
MiniTLS 2:527a66d0a1a9 132 handshake_type_t type;
MiniTLS 2:527a66d0a1a9 133 minitls_err_t ret = parse_message(handshake, buffer, &type);
MiniTLS 2:527a66d0a1a9 134 if(ret)
MiniTLS 2:527a66d0a1a9 135 {
MiniTLS 2:527a66d0a1a9 136 ERR("Parsing error");
MiniTLS 2:527a66d0a1a9 137 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 138 return ret;
MiniTLS 2:527a66d0a1a9 139 }
MiniTLS 2:527a66d0a1a9 140
MiniTLS 2:527a66d0a1a9 141 bool resumed = false;
MiniTLS 2:527a66d0a1a9 142
MiniTLS 2:527a66d0a1a9 143 DBG("Message type %d", type);
MiniTLS 2:527a66d0a1a9 144
MiniTLS 2:527a66d0a1a9 145 switch(type)
MiniTLS 2:527a66d0a1a9 146 {
MiniTLS 2:527a66d0a1a9 147 case hello_request:
MiniTLS 2:527a66d0a1a9 148 if( (handshake->state == TLS_HANDSHAKE_INIT) || (handshake->state == TLS_HANDSHAKE_HELLO_SENT) )
MiniTLS 2:527a66d0a1a9 149 {
MiniTLS 2:527a66d0a1a9 150 DBG("Hello request");
MiniTLS 2:527a66d0a1a9 151 }
MiniTLS 2:527a66d0a1a9 152 else
MiniTLS 2:527a66d0a1a9 153 {
MiniTLS 2:527a66d0a1a9 154 ret = MINITLS_ERR_NOT_IMPLEMENTED;
MiniTLS 2:527a66d0a1a9 155 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 156 return ret;
MiniTLS 2:527a66d0a1a9 157 }
MiniTLS 2:527a66d0a1a9 158 break;
MiniTLS 2:527a66d0a1a9 159 case server_hello:
MiniTLS 2:527a66d0a1a9 160 if(handshake->state == TLS_HANDSHAKE_HELLO_SENT)
MiniTLS 2:527a66d0a1a9 161 {
MiniTLS 2:527a66d0a1a9 162 DBG("Server hello");
MiniTLS 2:527a66d0a1a9 163 //Parse hello
MiniTLS 2:527a66d0a1a9 164 handshake->state = TLS_HANDSHAKE_HELLO_RECEIVED;
MiniTLS 2:527a66d0a1a9 165 ret = parse_hello_server(handshake, buffer, &resumed);
MiniTLS 2:527a66d0a1a9 166 if(ret)
MiniTLS 2:527a66d0a1a9 167 {
MiniTLS 2:527a66d0a1a9 168 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 169 return ret;
MiniTLS 2:527a66d0a1a9 170 }
MiniTLS 2:527a66d0a1a9 171 if(resumed)
MiniTLS 2:527a66d0a1a9 172 {
MiniTLS 2:527a66d0a1a9 173 handshake->state = TLS_HANDSHAKE_HELLO_RECEIVED_SESSION_RESUMPTION;
MiniTLS 2:527a66d0a1a9 174
MiniTLS 2:527a66d0a1a9 175 //Complete handshake
MiniTLS 2:527a66d0a1a9 176 DBG("Expanding master key");
MiniTLS 2:527a66d0a1a9 177
MiniTLS 2:527a66d0a1a9 178 ret = generate_record_keys(handshake);
MiniTLS 2:527a66d0a1a9 179 if(ret)
MiniTLS 2:527a66d0a1a9 180 {
MiniTLS 2:527a66d0a1a9 181 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 182 return ret;
MiniTLS 2:527a66d0a1a9 183 }
MiniTLS 2:527a66d0a1a9 184
MiniTLS 2:527a66d0a1a9 185 DBG("Change cipher spec request");
MiniTLS 2:527a66d0a1a9 186
MiniTLS 2:527a66d0a1a9 187 ret = change_cipher_spec_request(handshake, buffer);
MiniTLS 2:527a66d0a1a9 188 if(ret)
MiniTLS 2:527a66d0a1a9 189 {
MiniTLS 2:527a66d0a1a9 190 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 191 return ret;
MiniTLS 2:527a66d0a1a9 192 }
MiniTLS 2:527a66d0a1a9 193
MiniTLS 2:527a66d0a1a9 194 DBG("Changing cipher spec (TX)");
MiniTLS 2:527a66d0a1a9 195 //Now we can change cipher spec -- TX way
MiniTLS 2:527a66d0a1a9 196 ret = tls_record_change_cipher_spec(&handshake->tls_socket->record, true);
MiniTLS 2:527a66d0a1a9 197 if(ret)
MiniTLS 2:527a66d0a1a9 198 {
MiniTLS 2:527a66d0a1a9 199 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 200 return ret;
MiniTLS 2:527a66d0a1a9 201 }
MiniTLS 2:527a66d0a1a9 202
MiniTLS 2:527a66d0a1a9 203 DBG("Send finished");
MiniTLS 2:527a66d0a1a9 204 //Now send finished message
MiniTLS 2:527a66d0a1a9 205 ret = send_finished(handshake, buffer);
MiniTLS 2:527a66d0a1a9 206 if(ret)
MiniTLS 2:527a66d0a1a9 207 {
MiniTLS 2:527a66d0a1a9 208 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 209 return ret;
MiniTLS 2:527a66d0a1a9 210 }
MiniTLS 2:527a66d0a1a9 211
MiniTLS 2:527a66d0a1a9 212 handshake->state = TLS_HANDSHAKE_FINISHED_SENT;
MiniTLS 2:527a66d0a1a9 213 }
MiniTLS 2:527a66d0a1a9 214 }
MiniTLS 2:527a66d0a1a9 215 else
MiniTLS 2:527a66d0a1a9 216 {
MiniTLS 2:527a66d0a1a9 217 ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 218 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 219 return ret;
MiniTLS 2:527a66d0a1a9 220 }
MiniTLS 2:527a66d0a1a9 221 break;
MiniTLS 2:527a66d0a1a9 222 case certificate:
MiniTLS 2:527a66d0a1a9 223 if(handshake->state == TLS_HANDSHAKE_HELLO_RECEIVED)
MiniTLS 2:527a66d0a1a9 224 {
MiniTLS 2:527a66d0a1a9 225 DBG("Server certificate");
MiniTLS 2:527a66d0a1a9 226 //Parse certificate
MiniTLS 2:527a66d0a1a9 227 handshake->state = TLS_HANDSHAKE_CERTIFICATE_RECEIVED;
MiniTLS 2:527a66d0a1a9 228 ret = parse_server_certificate(handshake, buffer);
MiniTLS 2:527a66d0a1a9 229 if(ret)
MiniTLS 2:527a66d0a1a9 230 {
MiniTLS 2:527a66d0a1a9 231 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 232 return ret;
MiniTLS 2:527a66d0a1a9 233 }
MiniTLS 2:527a66d0a1a9 234 }
MiniTLS 2:527a66d0a1a9 235 else
MiniTLS 2:527a66d0a1a9 236 {
MiniTLS 2:527a66d0a1a9 237 ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 238 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 239 return ret;
MiniTLS 2:527a66d0a1a9 240 }
MiniTLS 2:527a66d0a1a9 241 break;
MiniTLS 2:527a66d0a1a9 242 case server_key_exchange:
MiniTLS 2:527a66d0a1a9 243 //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
MiniTLS 2:527a66d0a1a9 244 if(CRYPTO_ECC && (handshake->state == TLS_HANDSHAKE_CERTIFICATE_RECEIVED))
MiniTLS 2:527a66d0a1a9 245 {
MiniTLS 2:527a66d0a1a9 246 DBG("Server key exchange");
MiniTLS 2:527a66d0a1a9 247 //Parse server key
MiniTLS 2:527a66d0a1a9 248 handshake->state = TLS_HANDSHAKE_SERVER_KEY_EXCHANGE_RECEIVED;
MiniTLS 2:527a66d0a1a9 249 ret = parse_server_key_exchange(handshake, buffer);
MiniTLS 2:527a66d0a1a9 250 if(ret)
MiniTLS 2:527a66d0a1a9 251 {
MiniTLS 2:527a66d0a1a9 252 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 253 return ret;
MiniTLS 2:527a66d0a1a9 254 }
MiniTLS 2:527a66d0a1a9 255 }
MiniTLS 2:527a66d0a1a9 256 else
MiniTLS 2:527a66d0a1a9 257 {
MiniTLS 2:527a66d0a1a9 258 ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 259 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 260 return ret;
MiniTLS 2:527a66d0a1a9 261 }
MiniTLS 2:527a66d0a1a9 262 break;
MiniTLS 2:527a66d0a1a9 263 case certificate_request:
MiniTLS 2:527a66d0a1a9 264 //Obvi, we could receive this right after certificate - but we don't support this
MiniTLS 2:527a66d0a1a9 265 if(handshake->state == TLS_HANDSHAKE_CERTIFICATE_RECEIVED)
MiniTLS 2:527a66d0a1a9 266 {
MiniTLS 2:527a66d0a1a9 267 WARN("Not supported");
MiniTLS 2:527a66d0a1a9 268 ret = MINITLS_ERR_NOT_IMPLEMENTED;
MiniTLS 2:527a66d0a1a9 269 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 270 return ret;
MiniTLS 2:527a66d0a1a9 271 }
MiniTLS 2:527a66d0a1a9 272 else if( (CRYPTO_ECC && (handshake->state == TLS_HANDSHAKE_SERVER_KEY_EXCHANGE_RECEIVED)) || (CRYPTO_RSA && (handshake->state == TLS_HANDSHAKE_CERTIFICATE_RECEIVED)) )
MiniTLS 2:527a66d0a1a9 273 {
MiniTLS 2:527a66d0a1a9 274 DBG("Client certificate request");
MiniTLS 2:527a66d0a1a9 275 //Parse certificate request
MiniTLS 2:527a66d0a1a9 276 handshake->state = TLS_HANDSHAKE_CERTIFICATE_REQUEST_RECEIVED;
MiniTLS 2:527a66d0a1a9 277 handshake->certificate_requested = true;
MiniTLS 2:527a66d0a1a9 278 ret = parse_client_certificate_request(handshake, buffer);
MiniTLS 2:527a66d0a1a9 279 if(ret)
MiniTLS 2:527a66d0a1a9 280 {
MiniTLS 2:527a66d0a1a9 281 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 282 return ret;
MiniTLS 2:527a66d0a1a9 283 }
MiniTLS 2:527a66d0a1a9 284 }
MiniTLS 2:527a66d0a1a9 285 else
MiniTLS 2:527a66d0a1a9 286 {
MiniTLS 2:527a66d0a1a9 287 ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 288 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 289 return ret;
MiniTLS 2:527a66d0a1a9 290 }
MiniTLS 2:527a66d0a1a9 291 break;
MiniTLS 2:527a66d0a1a9 292 case server_hello_done:
MiniTLS 2:527a66d0a1a9 293 if( (CRYPTO_ECC && (handshake->state == TLS_HANDSHAKE_SERVER_KEY_EXCHANGE_RECEIVED)) || (CRYPTO_RSA && (handshake->state == TLS_HANDSHAKE_CERTIFICATE_RECEIVED))
MiniTLS 2:527a66d0a1a9 294 || (handshake->state == TLS_HANDSHAKE_CERTIFICATE_REQUEST_RECEIVED) )
MiniTLS 2:527a66d0a1a9 295 {
MiniTLS 2:527a66d0a1a9 296 DBG("Hello done");
MiniTLS 2:527a66d0a1a9 297 //Parse hello done
MiniTLS 2:527a66d0a1a9 298 handshake->state = TLS_HANDSHAKE_HELLO_DONE_RECEIVED;
MiniTLS 2:527a66d0a1a9 299 ret = parse_hello_done_server(handshake, buffer);
MiniTLS 2:527a66d0a1a9 300 if(ret)
MiniTLS 2:527a66d0a1a9 301 {
MiniTLS 2:527a66d0a1a9 302 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 303 return ret;
MiniTLS 2:527a66d0a1a9 304 }
MiniTLS 2:527a66d0a1a9 305
MiniTLS 2:527a66d0a1a9 306 //Now reply
MiniTLS 2:527a66d0a1a9 307 if(handshake->certificate_requested)
MiniTLS 2:527a66d0a1a9 308 {
MiniTLS 2:527a66d0a1a9 309 DBG("Send client certificate");
MiniTLS 2:527a66d0a1a9 310 //Send client certificate if requested
MiniTLS 2:527a66d0a1a9 311 ret = send_client_certificate(handshake, buffer);
MiniTLS 2:527a66d0a1a9 312 if(ret)
MiniTLS 2:527a66d0a1a9 313 {
MiniTLS 2:527a66d0a1a9 314 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 315 return ret;
MiniTLS 2:527a66d0a1a9 316 }
MiniTLS 2:527a66d0a1a9 317 handshake->state = TLS_HANDSHAKE_CERTIFICATE_SENT;
MiniTLS 2:527a66d0a1a9 318 }
MiniTLS 2:527a66d0a1a9 319
MiniTLS 2:527a66d0a1a9 320 DBG("Send client key exchange");
MiniTLS 2:527a66d0a1a9 321 //Send client key exchange
MiniTLS 2:527a66d0a1a9 322 ret = send_client_key_exchange(handshake, buffer);
MiniTLS 2:527a66d0a1a9 323 if(ret)
MiniTLS 2:527a66d0a1a9 324 {
MiniTLS 2:527a66d0a1a9 325 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 326 return ret;
MiniTLS 2:527a66d0a1a9 327 }
MiniTLS 2:527a66d0a1a9 328
MiniTLS 2:527a66d0a1a9 329 handshake->state = TLS_HANDSHAKE_CLIENT_KEY_EXCHANGE_SENT;
MiniTLS 2:527a66d0a1a9 330
MiniTLS 2:527a66d0a1a9 331 //Send certificate verify -- not for now
MiniTLS 2:527a66d0a1a9 332 /*
MiniTLS 2:527a66d0a1a9 333 ret = send_client_certificate_verify(handshake, buffer);
MiniTLS 2:527a66d0a1a9 334 if(ret)
MiniTLS 2:527a66d0a1a9 335 {
MiniTLS 2:527a66d0a1a9 336 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 337 return ret;
MiniTLS 2:527a66d0a1a9 338 }
MiniTLS 2:527a66d0a1a9 339
MiniTLS 2:527a66d0a1a9 340 handshake->state = TLS_HANDSHAKE_CERTIFICATE_VERIFY_SENT;
MiniTLS 2:527a66d0a1a9 341 */
MiniTLS 2:527a66d0a1a9 342
MiniTLS 2:527a66d0a1a9 343 DBG("Expanding master key");
MiniTLS 2:527a66d0a1a9 344
MiniTLS 2:527a66d0a1a9 345 ret = generate_record_keys(handshake);
MiniTLS 2:527a66d0a1a9 346 if(ret)
MiniTLS 2:527a66d0a1a9 347 {
MiniTLS 2:527a66d0a1a9 348 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 349 return ret;
MiniTLS 2:527a66d0a1a9 350 }
MiniTLS 2:527a66d0a1a9 351
MiniTLS 2:527a66d0a1a9 352 DBG("Change cipher spec request");
MiniTLS 2:527a66d0a1a9 353
MiniTLS 2:527a66d0a1a9 354 ret = change_cipher_spec_request(handshake, buffer);
MiniTLS 2:527a66d0a1a9 355 if(ret)
MiniTLS 2:527a66d0a1a9 356 {
MiniTLS 2:527a66d0a1a9 357 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 358 return ret;
MiniTLS 2:527a66d0a1a9 359 }
MiniTLS 2:527a66d0a1a9 360
MiniTLS 2:527a66d0a1a9 361 DBG("Changing cipher spec (TX)");
MiniTLS 2:527a66d0a1a9 362 //Now we can change cipher spec -- TX way
MiniTLS 2:527a66d0a1a9 363 ret = tls_record_change_cipher_spec(&handshake->tls_socket->record, true);
MiniTLS 2:527a66d0a1a9 364 if(ret)
MiniTLS 2:527a66d0a1a9 365 {
MiniTLS 2:527a66d0a1a9 366 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 367 return ret;
MiniTLS 2:527a66d0a1a9 368 }
MiniTLS 2:527a66d0a1a9 369
MiniTLS 2:527a66d0a1a9 370 DBG("Send finished");
MiniTLS 2:527a66d0a1a9 371 //Now send finished message
MiniTLS 2:527a66d0a1a9 372 ret = send_finished(handshake, buffer);
MiniTLS 2:527a66d0a1a9 373 if(ret)
MiniTLS 2:527a66d0a1a9 374 {
MiniTLS 2:527a66d0a1a9 375 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 376 return ret;
MiniTLS 2:527a66d0a1a9 377 }
MiniTLS 2:527a66d0a1a9 378
MiniTLS 2:527a66d0a1a9 379 handshake->state = TLS_HANDSHAKE_FINISHED_SENT;
MiniTLS 2:527a66d0a1a9 380 }
MiniTLS 2:527a66d0a1a9 381 else
MiniTLS 2:527a66d0a1a9 382 {
MiniTLS 2:527a66d0a1a9 383 ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 384 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 385 return ret;
MiniTLS 2:527a66d0a1a9 386 }
MiniTLS 2:527a66d0a1a9 387 break;
MiniTLS 2:527a66d0a1a9 388 case finished:
MiniTLS 2:527a66d0a1a9 389 if(handshake->state == TLS_HANDSHAKE_FINISHED_SENT)
MiniTLS 2:527a66d0a1a9 390 {
MiniTLS 2:527a66d0a1a9 391 //First check that the ChangeCipherSpec message has been sent by the other party (and that we are therefore secure in both ways)
MiniTLS 2:527a66d0a1a9 392 DBG("Receive finished");
MiniTLS 2:527a66d0a1a9 393 if(!tls_record_is_secure(&handshake->tls_socket->record))
MiniTLS 2:527a66d0a1a9 394 {
MiniTLS 2:527a66d0a1a9 395 ERR("Record is insecure");
MiniTLS 2:527a66d0a1a9 396 ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 397 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 398 return ret;
MiniTLS 2:527a66d0a1a9 399 }
MiniTLS 2:527a66d0a1a9 400
MiniTLS 2:527a66d0a1a9 401 //Parse finished message and check integrity of exchange
MiniTLS 2:527a66d0a1a9 402 handshake->state = TLS_HANDSHAKE_FINISHED_RECEIVED;
MiniTLS 2:527a66d0a1a9 403 ret = parse_finished(handshake, buffer);
MiniTLS 2:527a66d0a1a9 404 if(ret)
MiniTLS 2:527a66d0a1a9 405 {
MiniTLS 2:527a66d0a1a9 406 ERR("Integrity check failed");
MiniTLS 2:527a66d0a1a9 407 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 408 return ret;
MiniTLS 2:527a66d0a1a9 409 }
MiniTLS 2:527a66d0a1a9 410
MiniTLS 2:527a66d0a1a9 411 DBG("Handshake done!");
MiniTLS 2:527a66d0a1a9 412 handshake->state = TLS_HANDSHAKE_DONE;
MiniTLS 2:527a66d0a1a9 413 }
MiniTLS 2:527a66d0a1a9 414 else
MiniTLS 2:527a66d0a1a9 415 {
MiniTLS 2:527a66d0a1a9 416 ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 417 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 418 return ret;
MiniTLS 2:527a66d0a1a9 419 }
MiniTLS 2:527a66d0a1a9 420 break;
MiniTLS 2:527a66d0a1a9 421 default:
MiniTLS 2:527a66d0a1a9 422 ret = MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 423 handle_ret(handshake, ret);
MiniTLS 2:527a66d0a1a9 424 return ret;
MiniTLS 2:527a66d0a1a9 425 }
MiniTLS 2:527a66d0a1a9 426
MiniTLS 2:527a66d0a1a9 427 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 428 }
MiniTLS 2:527a66d0a1a9 429
MiniTLS 2:527a66d0a1a9 430 void tls_handshake_clean(tls_handshake_t* handshake)
MiniTLS 2:527a66d0a1a9 431 {
MiniTLS 2:527a66d0a1a9 432 memset(handshake->random_client, 0, HANDSHAKE_RANDOM_SIZE);
MiniTLS 2:527a66d0a1a9 433 memset(handshake->random_client, 0, HANDSHAKE_RANDOM_SIZE);
MiniTLS 2:527a66d0a1a9 434
MiniTLS 2:527a66d0a1a9 435 handshake->certificate_requested = false;
MiniTLS 2:527a66d0a1a9 436 //memset(&handshake->ecc_curve, 0, sizeof(crypto_ecc_curve_t*));
MiniTLS 2:527a66d0a1a9 437 //handshake->ecc_curve_type = 0;
MiniTLS 2:527a66d0a1a9 438 #if CRYPTO_ECC
MiniTLS 2:527a66d0a1a9 439 handshake->key_exchange.ecc.curve = NULL;
MiniTLS 2:527a66d0a1a9 440 memset(&handshake->key_exchange.ecc.server_key, 0, sizeof(crypto_ecc_public_key_t));
MiniTLS 2:527a66d0a1a9 441 memset(&handshake->key_exchange.ecc.client_key, 0, sizeof(crypto_ecc_private_key_t));
MiniTLS 2:527a66d0a1a9 442 #endif
MiniTLS 2:527a66d0a1a9 443 #if CRYPTO_RSA
MiniTLS 2:527a66d0a1a9 444 //
MiniTLS 2:527a66d0a1a9 445 #endif
MiniTLS 2:527a66d0a1a9 446
MiniTLS 2:527a66d0a1a9 447 #if MINITLS_CFG_PROTOCOL_TLS_1_2
MiniTLS 2:527a66d0a1a9 448 crypto_sha256_init(&handshake->hash.sha256);
MiniTLS 2:527a66d0a1a9 449 #endif
MiniTLS 2:527a66d0a1a9 450 #if (MINITLS_CFG_PROTOCOL_TLS_1_1 || MINITLS_CFG_PROTOCOL_TLS_1_0 || MINITLS_CFG_PROTOCOL_SSL_3)
MiniTLS 2:527a66d0a1a9 451 crypto_sha1_init(&handshake->hash.md5_sha1.sha1);
MiniTLS 2:527a66d0a1a9 452 crypto_md5_init(&handshake->hash.md5_sha1.md5);
MiniTLS 2:527a66d0a1a9 453 #endif
MiniTLS 2:527a66d0a1a9 454
MiniTLS 2:527a66d0a1a9 455 }
MiniTLS 2:527a66d0a1a9 456
MiniTLS 2:527a66d0a1a9 457 bool tls_handshake_is_done(tls_handshake_t* handshake)
MiniTLS 2:527a66d0a1a9 458 {
MiniTLS 2:527a66d0a1a9 459 if(handshake->state == TLS_HANDSHAKE_DONE)
MiniTLS 2:527a66d0a1a9 460 {
MiniTLS 2:527a66d0a1a9 461 return true;
MiniTLS 2:527a66d0a1a9 462 }
MiniTLS 2:527a66d0a1a9 463 return false;
MiniTLS 2:527a66d0a1a9 464 }
MiniTLS 2:527a66d0a1a9 465
MiniTLS 2:527a66d0a1a9 466 #define HELLO_CLIENT_SIZE 41
MiniTLS 2:527a66d0a1a9 467 #define HELLO_CLIENT_EXTENSIONS_HEADER_SIZE 2
MiniTLS 2:527a66d0a1a9 468 #define HELLO_CLIENT_MAX_FRAGMENT_EXTENSION_SIZE 5
MiniTLS 2:527a66d0a1a9 469 #define HELLO_CLIENT_SIGNATURE_ALGORITHM_EXTENSION_SIZE 8
MiniTLS 2:527a66d0a1a9 470 #define HELLO_CLIENT_SUPPORTED_ECC_CURVES_SIZE 8
MiniTLS 2:527a66d0a1a9 471
MiniTLS 2:527a66d0a1a9 472 #if CRYPTO_ECC
MiniTLS 2:527a66d0a1a9 473 const uint8_t TLS_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_CBC_SHA[] = { 0xC0, 0x09 };
MiniTLS 2:527a66d0a1a9 474 #elif CRYPTO_RSA
MiniTLS 2:527a66d0a1a9 475 const uint8_t TLS_CIPHERSUITE_RSA_WITH_AES_128_CBC_SHA[] = { 0x00, 0x2F };
MiniTLS 3:eb324ffffd2b 476 const uint8_t TLS_CIPHERSUITE_RSA_WITH_ARC4_SHA[] = { 0x00, 0x05 };
MiniTLS 2:527a66d0a1a9 477 #endif
MiniTLS 2:527a66d0a1a9 478
MiniTLS 2:527a66d0a1a9 479 #define TLS_COMPRESSION_METHOD_NULL 0x00
MiniTLS 2:527a66d0a1a9 480 #define TLS_EXTENSION_TYPE_MAX_FRAGMENT_LENGTH 1
MiniTLS 2:527a66d0a1a9 481 #define TLS_EXTENSION_TYPE_SIGNATURE_ALGORITHM 13
MiniTLS 2:527a66d0a1a9 482 #define TLS_EXTENSION_TYPE_SUPPORTED_ECC_CURVES 10
MiniTLS 2:527a66d0a1a9 483
MiniTLS 2:527a66d0a1a9 484 typedef enum __hash_algorithm {
MiniTLS 2:527a66d0a1a9 485 none = (0), md5 = (1), sha1 = (2), sha224 = (3), sha256 = (4), sha384 = (5),
MiniTLS 2:527a66d0a1a9 486 sha512 = (6)
MiniTLS 2:527a66d0a1a9 487 } hash_algorithm_t;
MiniTLS 2:527a66d0a1a9 488
MiniTLS 2:527a66d0a1a9 489 typedef enum __signature_algorithm { anonymous = (0), rsa = (1), dsa = (2), ecdsa = (3)
MiniTLS 2:527a66d0a1a9 490 } signature_algorithm_t;
MiniTLS 2:527a66d0a1a9 491
MiniTLS 2:527a66d0a1a9 492 minitls_err_t send_hello_client(tls_handshake_t* handshake, buffer_t* buffer)
MiniTLS 2:527a66d0a1a9 493 {
MiniTLS 2:527a66d0a1a9 494 //Form hello packet
MiniTLS 2:527a66d0a1a9 495 /*
MiniTLS 2:527a66d0a1a9 496 struct {
MiniTLS 2:527a66d0a1a9 497 ProtocolVersion client_version;
MiniTLS 2:527a66d0a1a9 498 Random random;
MiniTLS 2:527a66d0a1a9 499 SessionID session_id;
MiniTLS 2:527a66d0a1a9 500 CipherSuite cipher_suites<2..2^16-2>;
MiniTLS 2:527a66d0a1a9 501 CompressionMethod compression_methods<1..2^8-1>;
MiniTLS 2:527a66d0a1a9 502 select (extensions_present) {
MiniTLS 2:527a66d0a1a9 503 case false:
MiniTLS 2:527a66d0a1a9 504 struct {};
MiniTLS 2:527a66d0a1a9 505 case true:
MiniTLS 2:527a66d0a1a9 506 Extension extensions<0..2^16-1>;
MiniTLS 2:527a66d0a1a9 507 };
MiniTLS 2:527a66d0a1a9 508 } ClientHello;
MiniTLS 2:527a66d0a1a9 509 */
MiniTLS 2:527a66d0a1a9 510 minitls_err_t ret;
MiniTLS 2:527a66d0a1a9 511
MiniTLS 2:527a66d0a1a9 512 //Write header
MiniTLS 2:527a66d0a1a9 513 if(handshake->tls_socket->record.max_fragment_size < TLS_DEFAULT_MAX_FRAGMENT_SIZE)
MiniTLS 2:527a66d0a1a9 514 {
MiniTLS 2:527a66d0a1a9 515 ret = prepare_message(handshake, client_hello, buffer, HELLO_CLIENT_SIZE + handshake->tls_socket->session.session_id_length +
MiniTLS 2:527a66d0a1a9 516 HELLO_CLIENT_EXTENSIONS_HEADER_SIZE
MiniTLS 2:527a66d0a1a9 517 #if CRYPTO_ECC
MiniTLS 2:527a66d0a1a9 518 + HELLO_CLIENT_SIGNATURE_ALGORITHM_EXTENSION_SIZE + HELLO_CLIENT_SUPPORTED_ECC_CURVES_SIZE
MiniTLS 2:527a66d0a1a9 519 #endif
MiniTLS 2:527a66d0a1a9 520 + HELLO_CLIENT_MAX_FRAGMENT_EXTENSION_SIZE);
MiniTLS 2:527a66d0a1a9 521 }
MiniTLS 2:527a66d0a1a9 522 else
MiniTLS 2:527a66d0a1a9 523 {
MiniTLS 2:527a66d0a1a9 524 ret = prepare_message(handshake, client_hello, buffer, HELLO_CLIENT_SIZE + handshake->tls_socket->session.session_id_length +
MiniTLS 2:527a66d0a1a9 525 HELLO_CLIENT_EXTENSIONS_HEADER_SIZE
MiniTLS 2:527a66d0a1a9 526 #if CRYPTO_ECC
MiniTLS 2:527a66d0a1a9 527 + HELLO_CLIENT_SIGNATURE_ALGORITHM_EXTENSION_SIZE + HELLO_CLIENT_SUPPORTED_ECC_CURVES_SIZE
MiniTLS 2:527a66d0a1a9 528 #endif
MiniTLS 2:527a66d0a1a9 529 );
MiniTLS 2:527a66d0a1a9 530 }
MiniTLS 2:527a66d0a1a9 531 if(ret)
MiniTLS 2:527a66d0a1a9 532 {
MiniTLS 2:527a66d0a1a9 533 return ret;
MiniTLS 2:527a66d0a1a9 534 }
MiniTLS 2:527a66d0a1a9 535
MiniTLS 2:527a66d0a1a9 536 //Generate 28-bytes long random
MiniTLS 2:527a66d0a1a9 537 crypto_prng_get(handshake->tls_socket->minitls->prng, handshake->random_client, HANDSHAKE_RANDOM_SIZE);
MiniTLS 2:527a66d0a1a9 538
MiniTLS 2:527a66d0a1a9 539 //Write most recent protocol version supported
MiniTLS 2:527a66d0a1a9 540 #if MINITLS_CFG_PROTOCOL_TLS_1_2
MiniTLS 2:527a66d0a1a9 541 buffer_nu8_write(buffer, TLS_1_2_VERSION_MAJOR);
MiniTLS 2:527a66d0a1a9 542 buffer_nu8_write(buffer, TLS_1_2_VERSION_MINOR);
MiniTLS 2:527a66d0a1a9 543 #elif MINITLS_CFG_PROTOCOL_TLS_1_1
MiniTLS 2:527a66d0a1a9 544 buffer_nu8_write(buffer, TLS_1_1_VERSION_MAJOR);
MiniTLS 2:527a66d0a1a9 545 buffer_nu8_write(buffer, TLS_1_1_VERSION_MINOR);
MiniTLS 2:527a66d0a1a9 546 #elif MINITLS_CFG_PROTOCOL_TLS_1_0
MiniTLS 2:527a66d0a1a9 547 buffer_nu8_write(buffer, TLS_1_0_VERSION_MAJOR);
MiniTLS 2:527a66d0a1a9 548 buffer_nu8_write(buffer, TLS_1_0_VERSION_MINOR);
MiniTLS 2:527a66d0a1a9 549 #elif MINITLS_CFG_PROTOCOL_SSL_3
MiniTLS 2:527a66d0a1a9 550 buffer_nu8_write(buffer, SSL_3_VERSION_MAJOR);
MiniTLS 2:527a66d0a1a9 551 buffer_nu8_write(buffer, SSL_3_VERSION_MINOR);
MiniTLS 2:527a66d0a1a9 552 #else
MiniTLS 2:527a66d0a1a9 553 #error No SSL/TLS protocol version enabled
MiniTLS 2:527a66d0a1a9 554 #endif
MiniTLS 2:527a66d0a1a9 555
MiniTLS 2:527a66d0a1a9 556 //Write random
MiniTLS 2:527a66d0a1a9 557 //buffer_nu32_write(buffer, 0); //UNIX Timestamp -- not mandatory, write 0s -- Don't do this, just use a 32bytes long random
MiniTLS 2:527a66d0a1a9 558 buffer_nbytes_write(buffer, handshake->random_client, HANDSHAKE_RANDOM_SIZE);
MiniTLS 2:527a66d0a1a9 559 //Write session ID
MiniTLS 2:527a66d0a1a9 560 buffer_nu8_write(buffer, handshake->tls_socket->session.session_id_length);
MiniTLS 2:527a66d0a1a9 561 buffer_nbytes_write(buffer, handshake->tls_socket->session.session_id, handshake->tls_socket->session.session_id_length);
MiniTLS 2:527a66d0a1a9 562 //Write the one cipher suite we support
MiniTLS 3:eb324ffffd2b 563 #if CRYPTO_ECC
MiniTLS 2:527a66d0a1a9 564 buffer_nu16_write(buffer, 2); //2 bytes long
MiniTLS 2:527a66d0a1a9 565 buffer_nbytes_write(buffer, TLS_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 2);
MiniTLS 2:527a66d0a1a9 566 #elif CRYPTO_RSA
MiniTLS 3:eb324ffffd2b 567 buffer_nu16_write(buffer, (CRYPTO_AES_128 + CRYPTO_ARC4)*2); //2 or 4 bytes long
MiniTLS 3:eb324ffffd2b 568 #if CRYPTO_AES_128
MiniTLS 2:527a66d0a1a9 569 buffer_nbytes_write(buffer, TLS_CIPHERSUITE_RSA_WITH_AES_128_CBC_SHA, 2);
MiniTLS 3:eb324ffffd2b 570 #endif
MiniTLS 3:eb324ffffd2b 571 #if CRYPTO_ARC4
MiniTLS 3:eb324ffffd2b 572 buffer_nbytes_write(buffer, TLS_CIPHERSUITE_RSA_WITH_ARC4_SHA, 2);
MiniTLS 3:eb324ffffd2b 573 #endif
MiniTLS 2:527a66d0a1a9 574 #else
MiniTLS 2:527a66d0a1a9 575 #error You must enable one cipher suite
MiniTLS 2:527a66d0a1a9 576 #endif
MiniTLS 2:527a66d0a1a9 577 //Write the one compression method we support (null)
MiniTLS 2:527a66d0a1a9 578 buffer_nu8_write(buffer, 1); //1 byte long
MiniTLS 2:527a66d0a1a9 579 buffer_nu8_write(buffer, TLS_COMPRESSION_METHOD_NULL);
MiniTLS 2:527a66d0a1a9 580
MiniTLS 2:527a66d0a1a9 581 if(handshake->tls_socket->record.max_fragment_size < TLS_DEFAULT_MAX_FRAGMENT_SIZE)
MiniTLS 2:527a66d0a1a9 582 {
MiniTLS 2:527a66d0a1a9 583 //3 extensions (ECC) / 1 (RSA)
MiniTLS 2:527a66d0a1a9 584 buffer_nu16_write(buffer,
MiniTLS 2:527a66d0a1a9 585 #if CRYPTO_ECC
MiniTLS 2:527a66d0a1a9 586 + HELLO_CLIENT_SIGNATURE_ALGORITHM_EXTENSION_SIZE + HELLO_CLIENT_SUPPORTED_ECC_CURVES_SIZE
MiniTLS 2:527a66d0a1a9 587 #endif
MiniTLS 2:527a66d0a1a9 588 + HELLO_CLIENT_MAX_FRAGMENT_EXTENSION_SIZE);
MiniTLS 2:527a66d0a1a9 589 }
MiniTLS 2:527a66d0a1a9 590 else
MiniTLS 2:527a66d0a1a9 591 {
MiniTLS 2:527a66d0a1a9 592 //2 (ECC) extensions / 0 (RSA)
MiniTLS 2:527a66d0a1a9 593 buffer_nu16_write(buffer, 0
MiniTLS 2:527a66d0a1a9 594 #if CRYPTO_ECC
MiniTLS 2:527a66d0a1a9 595 + HELLO_CLIENT_SIGNATURE_ALGORITHM_EXTENSION_SIZE + HELLO_CLIENT_SUPPORTED_ECC_CURVES_SIZE
MiniTLS 2:527a66d0a1a9 596 #endif
MiniTLS 2:527a66d0a1a9 597 );
MiniTLS 2:527a66d0a1a9 598 }
MiniTLS 2:527a66d0a1a9 599 #if CRYPTO_ECC
MiniTLS 2:527a66d0a1a9 600 //Use signature algorithm extension
MiniTLS 2:527a66d0a1a9 601 buffer_nu16_write(buffer, TLS_EXTENSION_TYPE_SIGNATURE_ALGORITHM);
MiniTLS 2:527a66d0a1a9 602 /*
MiniTLS 2:527a66d0a1a9 603 enum {
MiniTLS 2:527a66d0a1a9 604 none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
MiniTLS 2:527a66d0a1a9 605 sha512(6), (255)
MiniTLS 2:527a66d0a1a9 606 } HashAlgorithm;
MiniTLS 2:527a66d0a1a9 607
MiniTLS 2:527a66d0a1a9 608 enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
MiniTLS 2:527a66d0a1a9 609 SignatureAlgorithm;
MiniTLS 2:527a66d0a1a9 610
MiniTLS 2:527a66d0a1a9 611 struct {
MiniTLS 2:527a66d0a1a9 612 HashAlgorithm hash;
MiniTLS 2:527a66d0a1a9 613 SignatureAlgorithm signature;
MiniTLS 2:527a66d0a1a9 614 } SignatureAndHashAlgorithm;
MiniTLS 2:527a66d0a1a9 615
MiniTLS 2:527a66d0a1a9 616 SignatureAndHashAlgorithm
MiniTLS 2:527a66d0a1a9 617 supported_signature_algorithms<2..2^16-2>;
MiniTLS 2:527a66d0a1a9 618 */
MiniTLS 2:527a66d0a1a9 619
MiniTLS 2:527a66d0a1a9 620 buffer_nu16_write(buffer, 4); //2 bytes of list length, 2 bytes of hash and signature algo
MiniTLS 2:527a66d0a1a9 621 buffer_nu16_write(buffer, 2); //2 bytes of hash and signature algo
MiniTLS 2:527a66d0a1a9 622
MiniTLS 2:527a66d0a1a9 623 //Supported algo is ECDSA-SHA1
MiniTLS 2:527a66d0a1a9 624 buffer_nu8_write(buffer, sha1);
MiniTLS 2:527a66d0a1a9 625 buffer_nu8_write(buffer, ecdsa);
MiniTLS 2:527a66d0a1a9 626
MiniTLS 2:527a66d0a1a9 627 //Use supported elliptic curves extensions
MiniTLS 2:527a66d0a1a9 628
MiniTLS 2:527a66d0a1a9 629 buffer_nu16_write(buffer, TLS_EXTENSION_TYPE_SUPPORTED_ECC_CURVES);
MiniTLS 2:527a66d0a1a9 630 /*
MiniTLS 2:527a66d0a1a9 631 struct {
MiniTLS 2:527a66d0a1a9 632 NamedCurve elliptic_curve_list<1..2^16-1>
MiniTLS 2:527a66d0a1a9 633 } EllipticCurveList;
MiniTLS 2:527a66d0a1a9 634 */
MiniTLS 2:527a66d0a1a9 635 buffer_nu16_write(buffer, 4); //2 bytes of list length, 2 bytes of curve type
MiniTLS 2:527a66d0a1a9 636 buffer_nu16_write(buffer, 2); //2 bytes of curve type
MiniTLS 2:527a66d0a1a9 637 buffer_nu16_write(buffer, secp192r1); //The one curve we support -- TODO clean this up
MiniTLS 2:527a66d0a1a9 638 #endif
MiniTLS 2:527a66d0a1a9 639
MiniTLS 2:527a66d0a1a9 640 if(handshake->tls_socket->record.max_fragment_size < TLS_DEFAULT_MAX_FRAGMENT_SIZE)
MiniTLS 2:527a66d0a1a9 641 {
MiniTLS 2:527a66d0a1a9 642 //Use MaxFragmentLength extension to decrease the maximum fragment length (RFC4366)
MiniTLS 2:527a66d0a1a9 643 buffer_nu16_write(buffer, TLS_EXTENSION_TYPE_MAX_FRAGMENT_LENGTH);
MiniTLS 2:527a66d0a1a9 644
MiniTLS 2:527a66d0a1a9 645 buffer_nu16_write(buffer, 1); //1 byte of data
MiniTLS 2:527a66d0a1a9 646 /*
MiniTLS 2:527a66d0a1a9 647 enum{
MiniTLS 2:527a66d0a1a9 648 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255)
MiniTLS 2:527a66d0a1a9 649 } MaxFragmentLength;
MiniTLS 2:527a66d0a1a9 650 */
MiniTLS 2:527a66d0a1a9 651 if( handshake->tls_socket->record.max_fragment_size >= 4096 )
MiniTLS 2:527a66d0a1a9 652 {
MiniTLS 2:527a66d0a1a9 653 buffer_nu8_write(buffer, 4);
MiniTLS 2:527a66d0a1a9 654 }
MiniTLS 2:527a66d0a1a9 655 else if( handshake->tls_socket->record.max_fragment_size >= 2048 )
MiniTLS 2:527a66d0a1a9 656 {
MiniTLS 2:527a66d0a1a9 657 buffer_nu8_write(buffer, 3);
MiniTLS 2:527a66d0a1a9 658 }
MiniTLS 2:527a66d0a1a9 659 else if( handshake->tls_socket->record.max_fragment_size >= 1024 )
MiniTLS 2:527a66d0a1a9 660 {
MiniTLS 2:527a66d0a1a9 661 buffer_nu8_write(buffer, 2);
MiniTLS 2:527a66d0a1a9 662 }
MiniTLS 2:527a66d0a1a9 663 else if( handshake->tls_socket->record.max_fragment_size >= 512 )
MiniTLS 2:527a66d0a1a9 664 {
MiniTLS 2:527a66d0a1a9 665 buffer_nu8_write(buffer, 1);
MiniTLS 2:527a66d0a1a9 666 }
MiniTLS 2:527a66d0a1a9 667 else
MiniTLS 2:527a66d0a1a9 668 {
MiniTLS 2:527a66d0a1a9 669 WARN("Fragment size is too small - using 512 bytes fragment size");
MiniTLS 2:527a66d0a1a9 670 buffer_nu8_write(buffer, 1);
MiniTLS 2:527a66d0a1a9 671 }
MiniTLS 2:527a66d0a1a9 672 }
MiniTLS 2:527a66d0a1a9 673
MiniTLS 2:527a66d0a1a9 674 ret = send_message(handshake, buffer);
MiniTLS 2:527a66d0a1a9 675 if(ret)
MiniTLS 2:527a66d0a1a9 676 {
MiniTLS 2:527a66d0a1a9 677 return ret;
MiniTLS 2:527a66d0a1a9 678 }
MiniTLS 2:527a66d0a1a9 679
MiniTLS 2:527a66d0a1a9 680 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 681 }
MiniTLS 2:527a66d0a1a9 682
MiniTLS 2:527a66d0a1a9 683 minitls_err_t parse_hello_server(tls_handshake_t* handshake, buffer_t* buffer, bool* resumed)
MiniTLS 2:527a66d0a1a9 684 {
MiniTLS 2:527a66d0a1a9 685 //Header has already been parsed
MiniTLS 2:527a66d0a1a9 686 /*
MiniTLS 2:527a66d0a1a9 687 struct {
MiniTLS 2:527a66d0a1a9 688 ProtocolVersion server_version;
MiniTLS 2:527a66d0a1a9 689 Random random;
MiniTLS 2:527a66d0a1a9 690 SessionID session_id;
MiniTLS 2:527a66d0a1a9 691 CipherSuite cipher_suite;
MiniTLS 2:527a66d0a1a9 692 CompressionMethod compression_method;
MiniTLS 2:527a66d0a1a9 693 select (extensions_present) {
MiniTLS 2:527a66d0a1a9 694 case false:
MiniTLS 2:527a66d0a1a9 695 struct {};
MiniTLS 2:527a66d0a1a9 696 case true:
MiniTLS 2:527a66d0a1a9 697 Extension extensions<0..2^16-1>;
MiniTLS 2:527a66d0a1a9 698 };
MiniTLS 2:527a66d0a1a9 699 } ServerHello;
MiniTLS 2:527a66d0a1a9 700 */
MiniTLS 2:527a66d0a1a9 701
MiniTLS 2:527a66d0a1a9 702 if( buffer_length(buffer) < 35) //protocol version + random + session_id length
MiniTLS 2:527a66d0a1a9 703 {
MiniTLS 2:527a66d0a1a9 704 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 705 }
MiniTLS 2:527a66d0a1a9 706
MiniTLS 2:527a66d0a1a9 707 tls_protocol_version_t version;
MiniTLS 2:527a66d0a1a9 708 version.major = buffer_nu8_read(buffer);
MiniTLS 2:527a66d0a1a9 709 version.minor = buffer_nu8_read(buffer);
MiniTLS 2:527a66d0a1a9 710
MiniTLS 2:527a66d0a1a9 711 //Check that version is one of the supported ones
MiniTLS 2:527a66d0a1a9 712 if(
MiniTLS 2:527a66d0a1a9 713 #if MINITLS_CFG_PROTOCOL_TLS_1_2
MiniTLS 2:527a66d0a1a9 714 ( (version.major != TLS_1_2_VERSION_MAJOR) || (version.minor != TLS_1_2_VERSION_MINOR) ) &&
MiniTLS 2:527a66d0a1a9 715 #endif
MiniTLS 2:527a66d0a1a9 716 #if MINITLS_CFG_PROTOCOL_TLS_1_1
MiniTLS 2:527a66d0a1a9 717 ( (version.major != TLS_1_1_VERSION_MAJOR) || (version.minor != TLS_1_1_VERSION_MINOR) ) &&
MiniTLS 2:527a66d0a1a9 718 #endif
MiniTLS 2:527a66d0a1a9 719 #if MINITLS_CFG_PROTOCOL_TLS_1_0
MiniTLS 2:527a66d0a1a9 720 ( (version.major != TLS_1_0_VERSION_MAJOR) || (version.minor != TLS_1_0_VERSION_MINOR) ) &&
MiniTLS 2:527a66d0a1a9 721 #endif
MiniTLS 2:527a66d0a1a9 722 #if MINITLS_CFG_PROTOCOL_SSL_3
MiniTLS 2:527a66d0a1a9 723 ( (version.major != SSL_3_VERSION_MAJOR) || (version.minor != SSL_3_VERSION_MINOR) ) &&
MiniTLS 2:527a66d0a1a9 724 #endif
MiniTLS 2:527a66d0a1a9 725 true )
MiniTLS 2:527a66d0a1a9 726 {
MiniTLS 2:527a66d0a1a9 727 ERR("Version mismatch");
MiniTLS 2:527a66d0a1a9 728 return MINITLS_ERR_PROTOCOL_VERSION;
MiniTLS 2:527a66d0a1a9 729 }
MiniTLS 2:527a66d0a1a9 730
MiniTLS 2:527a66d0a1a9 731 //Set record version accordingly
MiniTLS 2:527a66d0a1a9 732 tls_record_set_protocol_version(&handshake->tls_socket->record, version.major, version.minor);
MiniTLS 2:527a66d0a1a9 733
MiniTLS 2:527a66d0a1a9 734 //buffer_nu32_read(buffer); //UNIX Timestamp -- Don't read that, read it as part of the random
MiniTLS 2:527a66d0a1a9 735 buffer_nbytes_read(buffer, handshake->random_server, HANDSHAKE_RANDOM_SIZE);
MiniTLS 2:527a66d0a1a9 736 size_t server_session_id_length = buffer_nu8_read(buffer);
MiniTLS 2:527a66d0a1a9 737 if( buffer_length(buffer) < server_session_id_length + 3 ) //session id + cipher suite + compression mode
MiniTLS 2:527a66d0a1a9 738 {
MiniTLS 2:527a66d0a1a9 739 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; ///Will raise a "decode error" alert
MiniTLS 2:527a66d0a1a9 740 }
MiniTLS 2:527a66d0a1a9 741 if(server_session_id_length > SESSION_ID_MAX_SIZE) //Buffer overflow attack
MiniTLS 2:527a66d0a1a9 742 {
MiniTLS 2:527a66d0a1a9 743 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; ///Will raise a "decode error" alert
MiniTLS 2:527a66d0a1a9 744 }
MiniTLS 2:527a66d0a1a9 745
MiniTLS 2:527a66d0a1a9 746 uint8_t server_session_id[SESSION_ID_MAX_SIZE];
MiniTLS 2:527a66d0a1a9 747 buffer_nbytes_read(buffer, server_session_id, server_session_id_length);
MiniTLS 2:527a66d0a1a9 748
MiniTLS 2:527a66d0a1a9 749 if( (handshake->tls_socket->session.session_id_length == 0)
MiniTLS 2:527a66d0a1a9 750 || (server_session_id_length != handshake->tls_socket->session.session_id_length)
MiniTLS 2:527a66d0a1a9 751 || (memcmp(server_session_id, handshake->tls_socket->session.session_id, server_session_id_length) != 0))
MiniTLS 2:527a66d0a1a9 752 {
MiniTLS 2:527a66d0a1a9 753 //Session ID does not match, start a new one
MiniTLS 2:527a66d0a1a9 754 handshake->tls_socket->session.session_id_length = server_session_id_length;
MiniTLS 2:527a66d0a1a9 755 memcpy(handshake->tls_socket->session.session_id, server_session_id, server_session_id_length);
MiniTLS 2:527a66d0a1a9 756 *resumed = false;
MiniTLS 2:527a66d0a1a9 757 }
MiniTLS 2:527a66d0a1a9 758 else
MiniTLS 2:527a66d0a1a9 759 {
MiniTLS 2:527a66d0a1a9 760 //Resume session
MiniTLS 2:527a66d0a1a9 761 *resumed = true;
MiniTLS 2:527a66d0a1a9 762 }
MiniTLS 2:527a66d0a1a9 763
MiniTLS 2:527a66d0a1a9 764 uint8_t cipher_suite[2];
MiniTLS 2:527a66d0a1a9 765 buffer_nbytes_read(buffer, cipher_suite, 2);
MiniTLS 2:527a66d0a1a9 766 uint8_t compression_mode = buffer_nu8_read(buffer);
MiniTLS 2:527a66d0a1a9 767
MiniTLS 2:527a66d0a1a9 768 #if CRYPTO_ECC
MiniTLS 3:eb324ffffd2b 769 if(memcmp(cipher_suite, TLS_CIPHERSUITE_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 2) == 0)
MiniTLS 3:eb324ffffd2b 770 {
MiniTLS 3:eb324ffffd2b 771 handshake->target_security = TLS_SECURITY_TYPE_AES_128_CBC_SHA;
MiniTLS 3:eb324ffffd2b 772 }
MiniTLS 3:eb324ffffd2b 773 else
MiniTLS 2:527a66d0a1a9 774 #elif CRYPTO_RSA
MiniTLS 3:eb324ffffd2b 775 if(memcmp(cipher_suite, TLS_CIPHERSUITE_RSA_WITH_AES_128_CBC_SHA, 2) == 0)
MiniTLS 3:eb324ffffd2b 776 {
MiniTLS 3:eb324ffffd2b 777 handshake->target_security = TLS_SECURITY_TYPE_AES_128_CBC_SHA;
MiniTLS 3:eb324ffffd2b 778 }
MiniTLS 3:eb324ffffd2b 779 else if(memcmp(cipher_suite, TLS_CIPHERSUITE_RSA_WITH_ARC4_SHA, 2) == 0)
MiniTLS 3:eb324ffffd2b 780 {
MiniTLS 3:eb324ffffd2b 781 handshake->target_security = TLS_SECURITY_TYPE_ARC4_SHA;
MiniTLS 3:eb324ffffd2b 782 }
MiniTLS 3:eb324ffffd2b 783 else
MiniTLS 2:527a66d0a1a9 784 #else
MiniTLS 2:527a66d0a1a9 785 #error
MiniTLS 2:527a66d0a1a9 786 #endif
MiniTLS 2:527a66d0a1a9 787 {
MiniTLS 3:eb324ffffd2b 788 ERR("Unsupported cipher suite");
MiniTLS 3:eb324ffffd2b 789 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; //Protocol error as we did not advertise any other cipher suite/compression method in the hello client message
MiniTLS 3:eb324ffffd2b 790 }
MiniTLS 3:eb324ffffd2b 791
MiniTLS 3:eb324ffffd2b 792 if( compression_mode != TLS_COMPRESSION_METHOD_NULL )
MiniTLS 3:eb324ffffd2b 793 {
MiniTLS 3:eb324ffffd2b 794 ERR("Unsupported compression method");
MiniTLS 2:527a66d0a1a9 795 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; //Protocol error as we did not advertise any other cipher suite/compression method in the hello client message
MiniTLS 2:527a66d0a1a9 796 }
MiniTLS 2:527a66d0a1a9 797
MiniTLS 2:527a66d0a1a9 798 if( buffer_length(buffer) > 0 )
MiniTLS 2:527a66d0a1a9 799 {
MiniTLS 2:527a66d0a1a9 800 //Extensions are present, TODO
MiniTLS 2:527a66d0a1a9 801 DBG("Some extensions are present; ignoring them");
MiniTLS 2:527a66d0a1a9 802 }
MiniTLS 2:527a66d0a1a9 803
MiniTLS 2:527a66d0a1a9 804 DBG("Hello Server OK");
MiniTLS 2:527a66d0a1a9 805
MiniTLS 2:527a66d0a1a9 806 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 807 }
MiniTLS 2:527a66d0a1a9 808
MiniTLS 2:527a66d0a1a9 809 minitls_err_t parse_server_certificate(tls_handshake_t* handshake, buffer_t* buffer)
MiniTLS 2:527a66d0a1a9 810 {
MiniTLS 2:527a66d0a1a9 811 if( buffer_length(buffer) < 3) //Certificate list size
MiniTLS 2:527a66d0a1a9 812 {
MiniTLS 2:527a66d0a1a9 813 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 814 }
MiniTLS 2:527a66d0a1a9 815
MiniTLS 2:527a66d0a1a9 816 size_t cert_list_size = buffer_nu24_read(buffer);
MiniTLS 2:527a66d0a1a9 817
MiniTLS 2:527a66d0a1a9 818 if( buffer_length(buffer) < cert_list_size ) //Certificate list
MiniTLS 2:527a66d0a1a9 819 {
MiniTLS 2:527a66d0a1a9 820 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 821 }
MiniTLS 2:527a66d0a1a9 822
MiniTLS 2:527a66d0a1a9 823 if( buffer_length(buffer) < 3) //Certificate size
MiniTLS 2:527a66d0a1a9 824 {
MiniTLS 2:527a66d0a1a9 825 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 826 }
MiniTLS 2:527a66d0a1a9 827
MiniTLS 2:527a66d0a1a9 828 size_t cert_size = buffer_nu24_read(buffer);
MiniTLS 2:527a66d0a1a9 829
MiniTLS 2:527a66d0a1a9 830 if( (buffer_length(buffer) < cert_size) || (cert_size + 3 > cert_list_size) ) //Certificate
MiniTLS 2:527a66d0a1a9 831 {
MiniTLS 2:527a66d0a1a9 832 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 833 }
MiniTLS 2:527a66d0a1a9 834
MiniTLS 2:527a66d0a1a9 835 //Only parse first certificate in the chain, ignore others
MiniTLS 2:527a66d0a1a9 836 if( cert_size != handshake->tls_socket->minitls->certificate->certificate_size )
MiniTLS 2:527a66d0a1a9 837 {
MiniTLS 2:527a66d0a1a9 838 ERR("Certificate does not match");
MiniTLS 2:527a66d0a1a9 839 //Cannot contain certificate, return security error
MiniTLS 2:527a66d0a1a9 840 return MINITLS_ERR_WRONG_CERTIFICATE;
MiniTLS 2:527a66d0a1a9 841 }
MiniTLS 2:527a66d0a1a9 842
MiniTLS 2:527a66d0a1a9 843 //Do a plain, stupid, comparison with the certificate we have
MiniTLS 2:527a66d0a1a9 844 if( memcmp( handshake->tls_socket->minitls->certificate->certificate, buffer_current_read_position(buffer), handshake->tls_socket->minitls->certificate->certificate_size) != 0 )
MiniTLS 2:527a66d0a1a9 845 {
MiniTLS 2:527a66d0a1a9 846 ERR("Certificate does not match");
MiniTLS 2:527a66d0a1a9 847 //This is not the same certificate
MiniTLS 2:527a66d0a1a9 848 return MINITLS_ERR_WRONG_CERTIFICATE;
MiniTLS 2:527a66d0a1a9 849 }
MiniTLS 2:527a66d0a1a9 850 buffer_n_discard(buffer, handshake->tls_socket->minitls->certificate->certificate_size);
MiniTLS 2:527a66d0a1a9 851
MiniTLS 2:527a66d0a1a9 852
MiniTLS 2:527a66d0a1a9 853 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 854 }
MiniTLS 2:527a66d0a1a9 855
MiniTLS 2:527a66d0a1a9 856 minitls_err_t parse_server_key_exchange(tls_handshake_t* handshake, buffer_t* buffer)
MiniTLS 2:527a66d0a1a9 857 {
MiniTLS 2:527a66d0a1a9 858 #if CRYPTO_ECC
MiniTLS 2:527a66d0a1a9 859 //For now we only support the ECDHE_ECDSA key exchange algo, so we hardcode the recovery of ephemeral key values here
MiniTLS 2:527a66d0a1a9 860 /*
MiniTLS 2:527a66d0a1a9 861 enum { explicit_prime (1), explicit_char2 (2),
MiniTLS 2:527a66d0a1a9 862 named_curve (3), reserved(248..255) } ECCurveType;
MiniTLS 2:527a66d0a1a9 863
MiniTLS 2:527a66d0a1a9 864 enum {
MiniTLS 2:527a66d0a1a9 865 sect163k1 (1), sect163r1 (2), sect163r2 (3),
MiniTLS 2:527a66d0a1a9 866 sect193r1 (4), sect193r2 (5), sect233k1 (6),
MiniTLS 2:527a66d0a1a9 867 sect233r1 (7), sect239k1 (8), sect283k1 (9),
MiniTLS 2:527a66d0a1a9 868 sect283r1 (10), sect409k1 (11), sect409r1 (12),
MiniTLS 2:527a66d0a1a9 869 sect571k1 (13), sect571r1 (14), secp160k1 (15),
MiniTLS 2:527a66d0a1a9 870 secp160r1 (16), secp160r2 (17), secp192k1 (18),
MiniTLS 2:527a66d0a1a9 871 secp192r1 (19), secp224k1 (20), secp224r1 (21),
MiniTLS 2:527a66d0a1a9 872 secp256k1 (22), secp256r1 (23), secp384r1 (24),
MiniTLS 2:527a66d0a1a9 873 secp521r1 (25),
MiniTLS 2:527a66d0a1a9 874 reserved (0xFE00..0xFEFF),
MiniTLS 2:527a66d0a1a9 875 arbitrary_explicit_prime_curves(0xFF01),
MiniTLS 2:527a66d0a1a9 876 arbitrary_explicit_char2_curves(0xFF02),
MiniTLS 2:527a66d0a1a9 877 (0xFFFF)
MiniTLS 2:527a66d0a1a9 878 } NamedCurve;
MiniTLS 2:527a66d0a1a9 879
MiniTLS 2:527a66d0a1a9 880 struct {
MiniTLS 2:527a66d0a1a9 881 ECCurveType curve_type;
MiniTLS 2:527a66d0a1a9 882 select (curve_type) {
MiniTLS 2:527a66d0a1a9 883 case explicit_prime:
MiniTLS 2:527a66d0a1a9 884 opaque prime_p <1..2^8-1>;
MiniTLS 2:527a66d0a1a9 885 ECCurve curve;
MiniTLS 2:527a66d0a1a9 886 ECPoint base;
MiniTLS 2:527a66d0a1a9 887 opaque order <1..2^8-1>;
MiniTLS 2:527a66d0a1a9 888 opaque cofactor <1..2^8-1>;
MiniTLS 2:527a66d0a1a9 889 case explicit_char2:
MiniTLS 2:527a66d0a1a9 890 uint16 m;
MiniTLS 2:527a66d0a1a9 891 ECBasisType basis;
MiniTLS 2:527a66d0a1a9 892 select (basis) {
MiniTLS 2:527a66d0a1a9 893 case ec_trinomial:
MiniTLS 2:527a66d0a1a9 894 opaque k <1..2^8-1>;
MiniTLS 2:527a66d0a1a9 895 case ec_pentanomial:
MiniTLS 2:527a66d0a1a9 896 opaque k1 <1..2^8-1>;
MiniTLS 2:527a66d0a1a9 897 opaque k2 <1..2^8-1>;
MiniTLS 2:527a66d0a1a9 898 opaque k3 <1..2^8-1>;
MiniTLS 2:527a66d0a1a9 899 };
MiniTLS 2:527a66d0a1a9 900 ECCurve curve;
MiniTLS 2:527a66d0a1a9 901 ECPoint base;
MiniTLS 2:527a66d0a1a9 902 opaque order <1..2^8-1>;
MiniTLS 2:527a66d0a1a9 903 opaque cofactor <1..2^8-1>;
MiniTLS 2:527a66d0a1a9 904 case named_curve:
MiniTLS 2:527a66d0a1a9 905 NamedCurve namedcurve;
MiniTLS 2:527a66d0a1a9 906 };
MiniTLS 2:527a66d0a1a9 907 } ECParameters;
MiniTLS 2:527a66d0a1a9 908
MiniTLS 2:527a66d0a1a9 909 struct {
MiniTLS 2:527a66d0a1a9 910 opaque point <1..2^8-1>;
MiniTLS 2:527a66d0a1a9 911 } ECPoint;
MiniTLS 2:527a66d0a1a9 912
MiniTLS 2:527a66d0a1a9 913 struct {
MiniTLS 2:527a66d0a1a9 914 ECParameters curve_params;
MiniTLS 2:527a66d0a1a9 915 ECPoint public;
MiniTLS 2:527a66d0a1a9 916 } ServerECDHParams;
MiniTLS 2:527a66d0a1a9 917
MiniTLS 2:527a66d0a1a9 918 //signed_params - TLS1.2 specific
MiniTLS 2:527a66d0a1a9 919 struct {
MiniTLS 2:527a66d0a1a9 920 SignatureAndHashAlgorithm algorithm;
MiniTLS 2:527a66d0a1a9 921 opaque signature<0..2^16-1>;
MiniTLS 2:527a66d0a1a9 922 } DigitallySigned;
MiniTLS 2:527a66d0a1a9 923
MiniTLS 2:527a66d0a1a9 924 enum { ecdsa } SignatureAlgorithm;
MiniTLS 2:527a66d0a1a9 925
MiniTLS 2:527a66d0a1a9 926 select (SignatureAlgorithm) {
MiniTLS 2:527a66d0a1a9 927 case ecdsa:
MiniTLS 2:527a66d0a1a9 928 digitally-signed struct {
MiniTLS 2:527a66d0a1a9 929 opaque sha_hash[sha_size];
MiniTLS 2:527a66d0a1a9 930 };
MiniTLS 2:527a66d0a1a9 931 } Signature;
MiniTLS 2:527a66d0a1a9 932
MiniTLS 2:527a66d0a1a9 933
MiniTLS 2:527a66d0a1a9 934 ServerKeyExchange.signed_params.sha_hash
MiniTLS 2:527a66d0a1a9 935 SHA(ClientHello.random + ServerHello.random +
MiniTLS 2:527a66d0a1a9 936 ServerKeyExchange.params);
MiniTLS 2:527a66d0a1a9 937
MiniTLS 2:527a66d0a1a9 938 select (KeyExchangeAlgorithm) {
MiniTLS 2:527a66d0a1a9 939 case ec_diffie_hellman:
MiniTLS 2:527a66d0a1a9 940 ServerECDHParams params;
MiniTLS 2:527a66d0a1a9 941 Signature signed_params;
MiniTLS 2:527a66d0a1a9 942 } ServerKeyExchange;
MiniTLS 2:527a66d0a1a9 943 */
MiniTLS 2:527a66d0a1a9 944
MiniTLS 2:527a66d0a1a9 945 //Save position as we will have to perform a hash starting from here
MiniTLS 2:527a66d0a1a9 946 uint8_t* params_position = buffer_current_read_position(buffer);
MiniTLS 2:527a66d0a1a9 947
MiniTLS 2:527a66d0a1a9 948 //Only supporting named curves as we have no means of validating other new curves
MiniTLS 2:527a66d0a1a9 949 if( buffer_length(buffer) < 1 )
MiniTLS 2:527a66d0a1a9 950 {
MiniTLS 2:527a66d0a1a9 951 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 952 }
MiniTLS 2:527a66d0a1a9 953
MiniTLS 2:527a66d0a1a9 954 uint8_t curve_desc_type = buffer_nu8_read(buffer);
MiniTLS 2:527a66d0a1a9 955 if(curve_desc_type != 3) //Named curve
MiniTLS 2:527a66d0a1a9 956 {
MiniTLS 2:527a66d0a1a9 957 WARN("Not a named curve");
MiniTLS 2:527a66d0a1a9 958 return MINITLS_ERR_NOT_IMPLEMENTED;
MiniTLS 2:527a66d0a1a9 959 }
MiniTLS 2:527a66d0a1a9 960
MiniTLS 2:527a66d0a1a9 961 crypto_ecc_curve_type_t curve_type = buffer_nu16_read(buffer);
MiniTLS 2:527a66d0a1a9 962
MiniTLS 2:527a66d0a1a9 963 DBG("ECC Curve %d", curve_type);
MiniTLS 2:527a66d0a1a9 964
MiniTLS 2:527a66d0a1a9 965 minitls_err_t ret = crypto_ecc_curve_get(&handshake->key_exchange.ecc.curve, curve_type);
MiniTLS 2:527a66d0a1a9 966 if(ret)
MiniTLS 2:527a66d0a1a9 967 {
MiniTLS 2:527a66d0a1a9 968 ERR("Could not get curve");
MiniTLS 2:527a66d0a1a9 969 return ret;
MiniTLS 2:527a66d0a1a9 970 }
MiniTLS 2:527a66d0a1a9 971
MiniTLS 2:527a66d0a1a9 972 if( buffer_length(buffer) < 1 )
MiniTLS 2:527a66d0a1a9 973 {
MiniTLS 2:527a66d0a1a9 974 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 975 }
MiniTLS 2:527a66d0a1a9 976
MiniTLS 2:527a66d0a1a9 977 size_t point_size = buffer_nu8_read(buffer);
MiniTLS 2:527a66d0a1a9 978
MiniTLS 2:527a66d0a1a9 979 if( buffer_length(buffer) < point_size )
MiniTLS 2:527a66d0a1a9 980 {
MiniTLS 2:527a66d0a1a9 981 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 982 }
MiniTLS 2:527a66d0a1a9 983
MiniTLS 2:527a66d0a1a9 984 //Read point
MiniTLS 2:527a66d0a1a9 985 ret = crypto_ecc_ansi_x963_import(&handshake->key_exchange.ecc.server_key, handshake->key_exchange.ecc.curve, buffer_current_read_position(buffer), point_size);
MiniTLS 2:527a66d0a1a9 986 buffer_n_discard(buffer, point_size);
MiniTLS 2:527a66d0a1a9 987 if(ret)
MiniTLS 2:527a66d0a1a9 988 {
MiniTLS 2:527a66d0a1a9 989 ERR("Error decoding ANSI X9.63 key");
MiniTLS 2:527a66d0a1a9 990 return ret;
MiniTLS 2:527a66d0a1a9 991 }
MiniTLS 2:527a66d0a1a9 992
MiniTLS 2:527a66d0a1a9 993 size_t params_size = buffer_current_read_position(buffer) - params_position;
MiniTLS 2:527a66d0a1a9 994
MiniTLS 2:527a66d0a1a9 995 if( buffer_length(buffer) < 2 )
MiniTLS 2:527a66d0a1a9 996 {
MiniTLS 2:527a66d0a1a9 997 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 998 }
MiniTLS 2:527a66d0a1a9 999
MiniTLS 2:527a66d0a1a9 1000 //Check hash and signature algorithms -- this was introduced in TLS1.2
MiniTLS 2:527a66d0a1a9 1001 uint8_t hash_alg = buffer_nu8_read(buffer);
MiniTLS 2:527a66d0a1a9 1002 uint8_t sig_alg = buffer_nu8_read(buffer);
MiniTLS 2:527a66d0a1a9 1003
MiniTLS 2:527a66d0a1a9 1004 //We only support SHA1 / ECDSA so check that this is what the server is offering
MiniTLS 2:527a66d0a1a9 1005
MiniTLS 2:527a66d0a1a9 1006 if( (hash_alg != sha1) || (sig_alg != ecdsa) )
MiniTLS 2:527a66d0a1a9 1007 {
MiniTLS 2:527a66d0a1a9 1008 ERR("Unsupported hash/signature algorithms");
MiniTLS 2:527a66d0a1a9 1009 }
MiniTLS 2:527a66d0a1a9 1010
MiniTLS 2:527a66d0a1a9 1011 //Signature length is 2 bytes long
MiniTLS 2:527a66d0a1a9 1012 if( buffer_length(buffer) < 2 )
MiniTLS 2:527a66d0a1a9 1013 {
MiniTLS 2:527a66d0a1a9 1014 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 1015 }
MiniTLS 2:527a66d0a1a9 1016
MiniTLS 2:527a66d0a1a9 1017 size_t signature_length = buffer_nu16_read(buffer);
MiniTLS 2:527a66d0a1a9 1018
MiniTLS 2:527a66d0a1a9 1019 //Signature length is 2 bytes long
MiniTLS 2:527a66d0a1a9 1020 if( buffer_length(buffer) < signature_length )
MiniTLS 2:527a66d0a1a9 1021 {
MiniTLS 2:527a66d0a1a9 1022 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 1023 }
MiniTLS 2:527a66d0a1a9 1024
MiniTLS 2:527a66d0a1a9 1025 //Compute hash
MiniTLS 2:527a66d0a1a9 1026 uint8_t hash_result[SHA1_SIZE];
MiniTLS 2:527a66d0a1a9 1027 crypto_sha1_t sha1;
MiniTLS 2:527a66d0a1a9 1028 crypto_sha1_init(&sha1);
MiniTLS 2:527a66d0a1a9 1029 crypto_sha1_update(&sha1, handshake->random_client, HANDSHAKE_RANDOM_SIZE);
MiniTLS 2:527a66d0a1a9 1030 crypto_sha1_update(&sha1, handshake->random_server, HANDSHAKE_RANDOM_SIZE);
MiniTLS 2:527a66d0a1a9 1031 crypto_sha1_update(&sha1, params_position, params_size);
MiniTLS 2:527a66d0a1a9 1032 crypto_sha1_end(&sha1, hash_result);
MiniTLS 2:527a66d0a1a9 1033
MiniTLS 2:527a66d0a1a9 1034 DBG("SHA-1 Hash:");
MiniTLS 2:527a66d0a1a9 1035 DBG_BLOCK(
MiniTLS 2:527a66d0a1a9 1036 buffer_t hash_result_buf;
MiniTLS 2:527a66d0a1a9 1037 buffer_byref(&hash_result_buf, hash_result, SHA1_SIZE);
MiniTLS 2:527a66d0a1a9 1038 buffer_dump(&hash_result_buf); )
MiniTLS 2:527a66d0a1a9 1039
MiniTLS 2:527a66d0a1a9 1040 //Finally check signature
MiniTLS 2:527a66d0a1a9 1041 ret = crypto_ecc_dsa_check(&handshake->tls_socket->minitls->certificate->public_key.ecc, hash_result, SHA1_SIZE, buffer_current_read_position(buffer), signature_length);
MiniTLS 2:527a66d0a1a9 1042 buffer_n_discard(buffer, signature_length);
MiniTLS 2:527a66d0a1a9 1043 if(ret)
MiniTLS 2:527a66d0a1a9 1044 {
MiniTLS 2:527a66d0a1a9 1045 ERR("Signature check failed");
MiniTLS 2:527a66d0a1a9 1046 return ret;
MiniTLS 2:527a66d0a1a9 1047 }
MiniTLS 2:527a66d0a1a9 1048
MiniTLS 2:527a66d0a1a9 1049 DBG("Server key exchange parsed");
MiniTLS 2:527a66d0a1a9 1050
MiniTLS 2:527a66d0a1a9 1051 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1052 #else
MiniTLS 2:527a66d0a1a9 1053 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT; //Illegal for these cipher suites
MiniTLS 2:527a66d0a1a9 1054 #endif
MiniTLS 2:527a66d0a1a9 1055 }
MiniTLS 2:527a66d0a1a9 1056
MiniTLS 2:527a66d0a1a9 1057 minitls_err_t parse_client_certificate_request(tls_handshake_t* handshake, buffer_t* buffer)
MiniTLS 2:527a66d0a1a9 1058 {
MiniTLS 2:527a66d0a1a9 1059 //Ignore that, we won't offer a certificate in return anyway (or an empty one)
MiniTLS 2:527a66d0a1a9 1060 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1061 }
MiniTLS 2:527a66d0a1a9 1062
MiniTLS 2:527a66d0a1a9 1063 minitls_err_t parse_hello_done_server(tls_handshake_t* handshake, buffer_t* buffer)
MiniTLS 2:527a66d0a1a9 1064 {
MiniTLS 2:527a66d0a1a9 1065 if( buffer_length(buffer) != 0 )
MiniTLS 2:527a66d0a1a9 1066 {
MiniTLS 2:527a66d0a1a9 1067 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 1068 }
MiniTLS 2:527a66d0a1a9 1069 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1070 }
MiniTLS 2:527a66d0a1a9 1071
MiniTLS 2:527a66d0a1a9 1072 #define CLIENT_CERTIFICATE_NOCERTS_SIZE 3
MiniTLS 2:527a66d0a1a9 1073
MiniTLS 2:527a66d0a1a9 1074 minitls_err_t send_client_certificate(tls_handshake_t* handshake, buffer_t* buffer)
MiniTLS 2:527a66d0a1a9 1075 {
MiniTLS 2:527a66d0a1a9 1076 //Send a 0-length certificate structure
MiniTLS 2:527a66d0a1a9 1077
MiniTLS 2:527a66d0a1a9 1078 minitls_err_t ret;
MiniTLS 2:527a66d0a1a9 1079
MiniTLS 2:527a66d0a1a9 1080 //Write header
MiniTLS 2:527a66d0a1a9 1081 ret = prepare_message(handshake, certificate, buffer, CLIENT_CERTIFICATE_NOCERTS_SIZE);
MiniTLS 2:527a66d0a1a9 1082 if(ret)
MiniTLS 2:527a66d0a1a9 1083 {
MiniTLS 2:527a66d0a1a9 1084 return ret;
MiniTLS 2:527a66d0a1a9 1085 }
MiniTLS 2:527a66d0a1a9 1086
MiniTLS 2:527a66d0a1a9 1087 buffer_nu24_write(buffer, 0); //empty list
MiniTLS 2:527a66d0a1a9 1088
MiniTLS 2:527a66d0a1a9 1089 ret = send_message(handshake, buffer);
MiniTLS 2:527a66d0a1a9 1090 if(ret)
MiniTLS 2:527a66d0a1a9 1091 {
MiniTLS 2:527a66d0a1a9 1092 return ret;
MiniTLS 2:527a66d0a1a9 1093 }
MiniTLS 2:527a66d0a1a9 1094
MiniTLS 2:527a66d0a1a9 1095 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1096 }
MiniTLS 2:527a66d0a1a9 1097
MiniTLS 2:527a66d0a1a9 1098 #define CLIENT_KEY_EXCHANGE_BASE_SIZE 0
MiniTLS 2:527a66d0a1a9 1099
MiniTLS 2:527a66d0a1a9 1100 minitls_err_t send_client_key_exchange(tls_handshake_t* handshake, buffer_t* buffer)
MiniTLS 2:527a66d0a1a9 1101 {
MiniTLS 2:527a66d0a1a9 1102 minitls_err_t ret;
MiniTLS 2:527a66d0a1a9 1103
MiniTLS 2:527a66d0a1a9 1104 //Write header
MiniTLS 2:527a66d0a1a9 1105 ret = prepare_message(handshake, client_key_exchange, buffer, CLIENT_KEY_EXCHANGE_BASE_SIZE);
MiniTLS 2:527a66d0a1a9 1106 if(ret)
MiniTLS 2:527a66d0a1a9 1107 {
MiniTLS 2:527a66d0a1a9 1108 return ret;
MiniTLS 2:527a66d0a1a9 1109 }
MiniTLS 2:527a66d0a1a9 1110
MiniTLS 2:527a66d0a1a9 1111
MiniTLS 2:527a66d0a1a9 1112 #if CRYPTO_ECC
MiniTLS 2:527a66d0a1a9 1113 //Send a 0-length certificate structure
MiniTLS 2:527a66d0a1a9 1114
MiniTLS 2:527a66d0a1a9 1115 //Key size
MiniTLS 2:527a66d0a1a9 1116 DBG_BLOCK(
MiniTLS 2:527a66d0a1a9 1117 size_t key_size = crypto_ecc_get_key_size_for_curve(handshake->ecc_curve);
MiniTLS 2:527a66d0a1a9 1118
MiniTLS 2:527a66d0a1a9 1119 DBG("Generating ephemeral key of size %d", key_size);
MiniTLS 2:527a66d0a1a9 1120 )
MiniTLS 2:527a66d0a1a9 1121
MiniTLS 2:527a66d0a1a9 1122 //Generate client key
MiniTLS 2:527a66d0a1a9 1123 ret = crypto_ecc_generate_key(&handshake->key_exchange.ecc.client_key, handshake->key_exchange.ecc.curve, handshake->tls_socket->minitls->prng);
MiniTLS 2:527a66d0a1a9 1124 if(ret)
MiniTLS 2:527a66d0a1a9 1125 {
MiniTLS 2:527a66d0a1a9 1126 return ret;
MiniTLS 2:527a66d0a1a9 1127 }
MiniTLS 2:527a66d0a1a9 1128
MiniTLS 2:527a66d0a1a9 1129 DBG("Key generated");
MiniTLS 2:527a66d0a1a9 1130
MiniTLS 2:527a66d0a1a9 1131 //Skip key size
MiniTLS 2:527a66d0a1a9 1132 size_t point_size = 0;
MiniTLS 2:527a66d0a1a9 1133 buffer_nu8_write(buffer, point_size);
MiniTLS 2:527a66d0a1a9 1134
MiniTLS 2:527a66d0a1a9 1135 DBG("Exporting key in X9.63 format");
MiniTLS 2:527a66d0a1a9 1136
MiniTLS 2:527a66d0a1a9 1137 //Write key
MiniTLS 2:527a66d0a1a9 1138 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);
MiniTLS 2:527a66d0a1a9 1139 if(ret)
MiniTLS 2:527a66d0a1a9 1140 {
MiniTLS 2:527a66d0a1a9 1141 return ret;
MiniTLS 2:527a66d0a1a9 1142 }
MiniTLS 2:527a66d0a1a9 1143
MiniTLS 2:527a66d0a1a9 1144 buffer_n_skip(buffer, point_size);
MiniTLS 2:527a66d0a1a9 1145
MiniTLS 2:527a66d0a1a9 1146 DBG("Adjusting size");
MiniTLS 2:527a66d0a1a9 1147
MiniTLS 2:527a66d0a1a9 1148 //Rewind, write position and re-adjust
MiniTLS 2:527a66d0a1a9 1149 size_t length = buffer_length(buffer);
MiniTLS 2:527a66d0a1a9 1150 buffer_set_length(buffer, length - point_size - 1);
MiniTLS 2:527a66d0a1a9 1151
MiniTLS 2:527a66d0a1a9 1152 buffer_nu8_write(buffer, point_size);
MiniTLS 2:527a66d0a1a9 1153
MiniTLS 2:527a66d0a1a9 1154 buffer_set_length(buffer, length);
MiniTLS 2:527a66d0a1a9 1155
MiniTLS 2:527a66d0a1a9 1156 //Adjust message size
MiniTLS 2:527a66d0a1a9 1157 ret = prepare_message_adjust_size(handshake, buffer, CLIENT_KEY_EXCHANGE_BASE_SIZE + 1 + point_size);
MiniTLS 2:527a66d0a1a9 1158 if(ret)
MiniTLS 2:527a66d0a1a9 1159 {
MiniTLS 2:527a66d0a1a9 1160 return ret;
MiniTLS 2:527a66d0a1a9 1161 }
MiniTLS 2:527a66d0a1a9 1162
MiniTLS 2:527a66d0a1a9 1163 ret = send_message(handshake, buffer);
MiniTLS 2:527a66d0a1a9 1164 if(ret)
MiniTLS 2:527a66d0a1a9 1165 {
MiniTLS 2:527a66d0a1a9 1166 return ret;
MiniTLS 2:527a66d0a1a9 1167 }
MiniTLS 2:527a66d0a1a9 1168 #elif CRYPTO_RSA
MiniTLS 2:527a66d0a1a9 1169 /*
MiniTLS 2:527a66d0a1a9 1170 struct {
MiniTLS 2:527a66d0a1a9 1171 ProtocolVersion client_version;
MiniTLS 2:527a66d0a1a9 1172 opaque random[46];
MiniTLS 2:527a66d0a1a9 1173 } PreMasterSecret;
MiniTLS 2:527a66d0a1a9 1174
MiniTLS 2:527a66d0a1a9 1175 client_version
MiniTLS 2:527a66d0a1a9 1176 The latest (newest) version supported by the client. This is
MiniTLS 2:527a66d0a1a9 1177 used to detect version rollback attacks.
MiniTLS 2:527a66d0a1a9 1178
MiniTLS 2:527a66d0a1a9 1179 random
MiniTLS 2:527a66d0a1a9 1180 46 securely-generated random bytes.
MiniTLS 2:527a66d0a1a9 1181
MiniTLS 2:527a66d0a1a9 1182 struct {
MiniTLS 2:527a66d0a1a9 1183 public-key-encrypted PreMasterSecret pre_master_secret;
MiniTLS 2:527a66d0a1a9 1184 } EncryptedPreMasterSecret;
MiniTLS 2:527a66d0a1a9 1185
MiniTLS 2:527a66d0a1a9 1186 pre_master_secret
MiniTLS 2:527a66d0a1a9 1187 This random value is generated by the client and is used to
MiniTLS 2:527a66d0a1a9 1188 generate the master secret, as specified in Section 8.1.
MiniTLS 2:527a66d0a1a9 1189 */
MiniTLS 2:527a66d0a1a9 1190
MiniTLS 2:527a66d0a1a9 1191 //Premaster key is generated first
MiniTLS 2:527a66d0a1a9 1192
MiniTLS 2:527a66d0a1a9 1193 #else
MiniTLS 2:527a66d0a1a9 1194 #error
MiniTLS 2:527a66d0a1a9 1195 #endif
MiniTLS 2:527a66d0a1a9 1196
MiniTLS 2:527a66d0a1a9 1197 DBG("Generating premaster key");
MiniTLS 2:527a66d0a1a9 1198
MiniTLS 2:527a66d0a1a9 1199 uint8_t premaster_key[HANDSHAKE_MAX_PREMASTER_KEY_SIZE];
MiniTLS 2:527a66d0a1a9 1200 size_t premaster_key_size = 0;
MiniTLS 2:527a66d0a1a9 1201
MiniTLS 2:527a66d0a1a9 1202 #if CRYPTO_ECC
MiniTLS 2:527a66d0a1a9 1203 //At this point we can generate the pre-master key
MiniTLS 2:527a66d0a1a9 1204 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);
MiniTLS 2:527a66d0a1a9 1205 if(ret)
MiniTLS 2:527a66d0a1a9 1206 {
MiniTLS 2:527a66d0a1a9 1207 memset(premaster_key, 0, HANDSHAKE_MAX_PREMASTER_KEY_SIZE); //Don't want to leak this
MiniTLS 2:527a66d0a1a9 1208 return ret;
MiniTLS 2:527a66d0a1a9 1209 }
MiniTLS 2:527a66d0a1a9 1210 #elif CRYPTO_RSA
MiniTLS 2:527a66d0a1a9 1211 //The two first bytes should be the SSL/TLS version advertised in ClientHello (prevents version rollback attacks)
MiniTLS 2:527a66d0a1a9 1212 #if MINITLS_CFG_PROTOCOL_TLS_1_2
MiniTLS 2:527a66d0a1a9 1213 premaster_key[0] = TLS_1_2_VERSION_MAJOR;
MiniTLS 2:527a66d0a1a9 1214 premaster_key[1] = TLS_1_2_VERSION_MINOR;
MiniTLS 2:527a66d0a1a9 1215 #elif MINITLS_CFG_PROTOCOL_TLS_1_1
MiniTLS 2:527a66d0a1a9 1216 premaster_key[0] = TLS_1_1_VERSION_MAJOR;
MiniTLS 2:527a66d0a1a9 1217 premaster_key[1] = TLS_1_1_VERSION_MINOR;
MiniTLS 2:527a66d0a1a9 1218 #elif MINITLS_CFG_PROTOCOL_TLS_1_0
MiniTLS 2:527a66d0a1a9 1219 premaster_key[0] = TLS_1_0_VERSION_MAJOR;
MiniTLS 2:527a66d0a1a9 1220 premaster_key[1] = TLS_1_0_VERSION_MINOR;
MiniTLS 2:527a66d0a1a9 1221 #elif MINITLS_CFG_PROTOCOL_SSL_3
MiniTLS 2:527a66d0a1a9 1222 premaster_key[0] = SSL_3_VERSION_MAJOR;
MiniTLS 2:527a66d0a1a9 1223 premaster_key[1] = SSL_3_VERSION_MINOR;
MiniTLS 2:527a66d0a1a9 1224 #else
MiniTLS 2:527a66d0a1a9 1225 #error No SSL/TLS protocol version enabled
MiniTLS 2:527a66d0a1a9 1226 #endif
MiniTLS 2:527a66d0a1a9 1227
MiniTLS 2:527a66d0a1a9 1228 //Other 46 bytes are random
MiniTLS 2:527a66d0a1a9 1229 crypto_prng_get(handshake->tls_socket->minitls->prng, &premaster_key[2], HANDSHAKE_RSA_PREMASTER_KEY_SIZE - 2);
MiniTLS 2:527a66d0a1a9 1230 premaster_key_size = HANDSHAKE_RSA_PREMASTER_KEY_SIZE;
MiniTLS 2:527a66d0a1a9 1231
MiniTLS 2:527a66d0a1a9 1232 //Encrypt it using RSA
MiniTLS 3:eb324ffffd2b 1233 uint8_t encrypted_premaster_key[RSA_PREMASTER_KEY_SIZE];
MiniTLS 3:eb324ffffd2b 1234
MiniTLS 2:527a66d0a1a9 1235 size_t encrypted_premaster_key_size = 0;
MiniTLS 2:527a66d0a1a9 1236 ret = crypto_rsa_encrypt(&handshake->tls_socket->minitls->certificate->public_key.rsa,
MiniTLS 2:527a66d0a1a9 1237 premaster_key, premaster_key_size,
MiniTLS 2:527a66d0a1a9 1238 encrypted_premaster_key, sizeof(encrypted_premaster_key), &encrypted_premaster_key_size, handshake->tls_socket->minitls->prng);
MiniTLS 2:527a66d0a1a9 1239 if(ret)
MiniTLS 2:527a66d0a1a9 1240 {
MiniTLS 3:eb324ffffd2b 1241 WARN("Error %d", ret);
MiniTLS 2:527a66d0a1a9 1242 return ret;
MiniTLS 2:527a66d0a1a9 1243 }
MiniTLS 2:527a66d0a1a9 1244
MiniTLS 2:527a66d0a1a9 1245 DBG("Encrypted premaster key size: %d", encrypted_premaster_key_size);
MiniTLS 2:527a66d0a1a9 1246
MiniTLS 2:527a66d0a1a9 1247 //Now send it
MiniTLS 2:527a66d0a1a9 1248 buffer_nu16_write(buffer, encrypted_premaster_key_size);
MiniTLS 2:527a66d0a1a9 1249 buffer_nbytes_write(buffer, encrypted_premaster_key, encrypted_premaster_key_size);
MiniTLS 2:527a66d0a1a9 1250
MiniTLS 2:527a66d0a1a9 1251 //Adjust message size
MiniTLS 2:527a66d0a1a9 1252 ret = prepare_message_adjust_size(handshake, buffer, CLIENT_KEY_EXCHANGE_BASE_SIZE + 2 + encrypted_premaster_key_size);
MiniTLS 2:527a66d0a1a9 1253 if(ret)
MiniTLS 2:527a66d0a1a9 1254 {
MiniTLS 2:527a66d0a1a9 1255 return ret;
MiniTLS 2:527a66d0a1a9 1256 }
MiniTLS 2:527a66d0a1a9 1257
MiniTLS 2:527a66d0a1a9 1258 ret = send_message(handshake, buffer);
MiniTLS 2:527a66d0a1a9 1259 if(ret)
MiniTLS 2:527a66d0a1a9 1260 {
MiniTLS 2:527a66d0a1a9 1261 return ret;
MiniTLS 2:527a66d0a1a9 1262 }
MiniTLS 2:527a66d0a1a9 1263 #endif
MiniTLS 2:527a66d0a1a9 1264
MiniTLS 2:527a66d0a1a9 1265 DBG_BLOCK(
MiniTLS 2:527a66d0a1a9 1266 DBG("Premaster key size: %d", premaster_key_size);
MiniTLS 2:527a66d0a1a9 1267
MiniTLS 2:527a66d0a1a9 1268 buffer_t dump_buf;
MiniTLS 2:527a66d0a1a9 1269 DBG("Premaster key");
MiniTLS 2:527a66d0a1a9 1270 buffer_byref(&dump_buf, premaster_key, premaster_key_size);
MiniTLS 2:527a66d0a1a9 1271 buffer_dump(&dump_buf);
MiniTLS 2:527a66d0a1a9 1272
MiniTLS 2:527a66d0a1a9 1273 DBG("Random client");
MiniTLS 2:527a66d0a1a9 1274 buffer_byref(&dump_buf, handshake->random_client, HANDSHAKE_RANDOM_SIZE);
MiniTLS 2:527a66d0a1a9 1275 buffer_dump(&dump_buf);
MiniTLS 2:527a66d0a1a9 1276
MiniTLS 2:527a66d0a1a9 1277 DBG("Random server");
MiniTLS 2:527a66d0a1a9 1278 buffer_byref(&dump_buf, handshake->random_server, HANDSHAKE_RANDOM_SIZE);
MiniTLS 2:527a66d0a1a9 1279 buffer_dump(&dump_buf);
MiniTLS 2:527a66d0a1a9 1280 )
MiniTLS 2:527a66d0a1a9 1281
MiniTLS 2:527a66d0a1a9 1282
MiniTLS 2:527a66d0a1a9 1283 //Now generate the shared AES128 key
MiniTLS 2:527a66d0a1a9 1284
MiniTLS 2:527a66d0a1a9 1285 DBG("Expanding the key");
MiniTLS 2:527a66d0a1a9 1286
MiniTLS 2:527a66d0a1a9 1287 /*
MiniTLS 2:527a66d0a1a9 1288 master_secret = PRF(pre_master_secret, "master secret",
MiniTLS 2:527a66d0a1a9 1289 ClientHello.random + ServerHello.random)
MiniTLS 2:527a66d0a1a9 1290 [0..47];
MiniTLS 2:527a66d0a1a9 1291 */
MiniTLS 2:527a66d0a1a9 1292
MiniTLS 2:527a66d0a1a9 1293 ret = prf_compute(premaster_key, premaster_key_size, "master secret",
MiniTLS 2:527a66d0a1a9 1294 handshake->random_client, HANDSHAKE_RANDOM_SIZE,
MiniTLS 2:527a66d0a1a9 1295 handshake->random_server, HANDSHAKE_RANDOM_SIZE,
MiniTLS 2:527a66d0a1a9 1296 handshake->tls_socket->session.master_key, HANDSHAKE_MASTER_KEY_SIZE);
MiniTLS 2:527a66d0a1a9 1297 memset(premaster_key, 0, HANDSHAKE_MAX_PREMASTER_KEY_SIZE); //Don't want to leak this
MiniTLS 2:527a66d0a1a9 1298 if(ret)
MiniTLS 2:527a66d0a1a9 1299 {
MiniTLS 2:527a66d0a1a9 1300 return ret;
MiniTLS 2:527a66d0a1a9 1301 }
MiniTLS 2:527a66d0a1a9 1302
MiniTLS 2:527a66d0a1a9 1303 DBG_BLOCK(
MiniTLS 2:527a66d0a1a9 1304 DBG("Key expanded into master key");
MiniTLS 2:527a66d0a1a9 1305 buffer_byref(&dump_buf, handshake->tls_socket->session.master_key, HANDSHAKE_MASTER_KEY_SIZE);
MiniTLS 2:527a66d0a1a9 1306 buffer_dump(&dump_buf);
MiniTLS 2:527a66d0a1a9 1307 )
MiniTLS 2:527a66d0a1a9 1308
MiniTLS 2:527a66d0a1a9 1309 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1310 }
MiniTLS 2:527a66d0a1a9 1311
MiniTLS 2:527a66d0a1a9 1312 #define VERIFY_DATA_LENGTH 12
MiniTLS 2:527a66d0a1a9 1313 #define FINISHED_SIZE 12 // 12 bytes PRF // -- no 13 //length + 12 bytes prf
MiniTLS 2:527a66d0a1a9 1314
MiniTLS 2:527a66d0a1a9 1315 minitls_err_t send_finished(tls_handshake_t* handshake, buffer_t* buffer)
MiniTLS 2:527a66d0a1a9 1316 {
MiniTLS 2:527a66d0a1a9 1317 minitls_err_t ret;
MiniTLS 2:527a66d0a1a9 1318
MiniTLS 2:527a66d0a1a9 1319 //Write header
MiniTLS 2:527a66d0a1a9 1320 ret = prepare_message(handshake, finished, buffer, FINISHED_SIZE);
MiniTLS 2:527a66d0a1a9 1321 if(ret)
MiniTLS 2:527a66d0a1a9 1322 {
MiniTLS 2:527a66d0a1a9 1323 return ret;
MiniTLS 2:527a66d0a1a9 1324 }
MiniTLS 2:527a66d0a1a9 1325
MiniTLS 2:527a66d0a1a9 1326 crypto_sha256_t hash;
MiniTLS 2:527a66d0a1a9 1327 crypto_sha256_copy(&hash, &handshake->hash.sha256); //We need to keep the global hash to check the server's finished message
MiniTLS 2:527a66d0a1a9 1328
MiniTLS 2:527a66d0a1a9 1329 //Compute final hash
MiniTLS 2:527a66d0a1a9 1330 uint8_t result[SHA256_SIZE];
MiniTLS 2:527a66d0a1a9 1331 crypto_sha256_end(&hash, result);
MiniTLS 2:527a66d0a1a9 1332
MiniTLS 2:527a66d0a1a9 1333 /*
MiniTLS 2:527a66d0a1a9 1334 struct {
MiniTLS 2:527a66d0a1a9 1335 opaque verify_data[verify_data_length];
MiniTLS 2:527a66d0a1a9 1336 } Finished;
MiniTLS 2:527a66d0a1a9 1337
MiniTLS 2:527a66d0a1a9 1338 verify_data
MiniTLS 2:527a66d0a1a9 1339 PRF(master_secret, finished_label, Hash(handshake_messages))
MiniTLS 2:527a66d0a1a9 1340 [0..verify_data_length-1];
MiniTLS 2:527a66d0a1a9 1341 */
MiniTLS 2:527a66d0a1a9 1342
MiniTLS 2:527a66d0a1a9 1343 //buffer_nu8_write(buffer, VERIFY_DATA_LENGTH); //This is optional but anyway -- NOPE
MiniTLS 2:527a66d0a1a9 1344
MiniTLS 2:527a66d0a1a9 1345 ret = prf_compute(handshake->tls_socket->session.master_key, HANDSHAKE_MASTER_KEY_SIZE, "client finished",
MiniTLS 2:527a66d0a1a9 1346 result, SHA256_SIZE,
MiniTLS 2:527a66d0a1a9 1347 NULL, 0,
MiniTLS 2:527a66d0a1a9 1348 buffer_current_write_position(buffer), VERIFY_DATA_LENGTH);
MiniTLS 2:527a66d0a1a9 1349 buffer_n_skip(buffer, VERIFY_DATA_LENGTH);
MiniTLS 2:527a66d0a1a9 1350 if(ret)
MiniTLS 2:527a66d0a1a9 1351 {
MiniTLS 2:527a66d0a1a9 1352 return ret;
MiniTLS 2:527a66d0a1a9 1353 }
MiniTLS 2:527a66d0a1a9 1354
MiniTLS 2:527a66d0a1a9 1355 ret = send_message(handshake, buffer);
MiniTLS 2:527a66d0a1a9 1356 if(ret)
MiniTLS 2:527a66d0a1a9 1357 {
MiniTLS 2:527a66d0a1a9 1358 return ret;
MiniTLS 2:527a66d0a1a9 1359 }
MiniTLS 2:527a66d0a1a9 1360
MiniTLS 2:527a66d0a1a9 1361 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1362 }
MiniTLS 2:527a66d0a1a9 1363
MiniTLS 2:527a66d0a1a9 1364 minitls_err_t parse_finished(tls_handshake_t* handshake, buffer_t* buffer)
MiniTLS 2:527a66d0a1a9 1365 {
MiniTLS 2:527a66d0a1a9 1366 if(buffer_length(buffer) < VERIFY_DATA_LENGTH)
MiniTLS 2:527a66d0a1a9 1367 {
MiniTLS 2:527a66d0a1a9 1368 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 1369 }
MiniTLS 2:527a66d0a1a9 1370 /*
MiniTLS 2:527a66d0a1a9 1371 size_t length = VERIFY_DATA_LENGTH;
MiniTLS 2:527a66d0a1a9 1372 if(buffer_length(buffer) > VERIFY_DATA_LENGTH)
MiniTLS 2:527a66d0a1a9 1373 {
MiniTLS 2:527a66d0a1a9 1374 length = buffer_nu8_read(buffer);
MiniTLS 2:527a66d0a1a9 1375 }
MiniTLS 2:527a66d0a1a9 1376 */
MiniTLS 2:527a66d0a1a9 1377 if( (buffer_length(buffer)/*length*/ != VERIFY_DATA_LENGTH) )
MiniTLS 2:527a66d0a1a9 1378 {
MiniTLS 2:527a66d0a1a9 1379 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 1380 }
MiniTLS 2:527a66d0a1a9 1381
MiniTLS 2:527a66d0a1a9 1382 crypto_sha256_t hash;
MiniTLS 2:527a66d0a1a9 1383 crypto_sha256_copy(&hash, &handshake->hash.sha256); //We need to keep the global hash to check the server's finished message
MiniTLS 2:527a66d0a1a9 1384
MiniTLS 2:527a66d0a1a9 1385 //Compute final hash
MiniTLS 2:527a66d0a1a9 1386 uint8_t result[SHA256_SIZE];
MiniTLS 2:527a66d0a1a9 1387 crypto_sha256_end(&hash, result);
MiniTLS 2:527a66d0a1a9 1388
MiniTLS 2:527a66d0a1a9 1389 /*
MiniTLS 2:527a66d0a1a9 1390 struct {
MiniTLS 2:527a66d0a1a9 1391 opaque verify_data[verify_data_length];
MiniTLS 2:527a66d0a1a9 1392 } Finished;
MiniTLS 2:527a66d0a1a9 1393
MiniTLS 2:527a66d0a1a9 1394 verify_data
MiniTLS 2:527a66d0a1a9 1395 PRF(master_secret, finished_label, Hash(handshake_messages))
MiniTLS 2:527a66d0a1a9 1396 [0..verify_data_length-1];
MiniTLS 2:527a66d0a1a9 1397 */
MiniTLS 2:527a66d0a1a9 1398
MiniTLS 2:527a66d0a1a9 1399 uint8_t prf[VERIFY_DATA_LENGTH];
MiniTLS 2:527a66d0a1a9 1400 minitls_err_t ret = prf_compute(handshake->tls_socket->session.master_key, HANDSHAKE_MASTER_KEY_SIZE, "server finished",
MiniTLS 2:527a66d0a1a9 1401 result, SHA256_SIZE,
MiniTLS 2:527a66d0a1a9 1402 NULL, 0,
MiniTLS 2:527a66d0a1a9 1403 prf, VERIFY_DATA_LENGTH);
MiniTLS 2:527a66d0a1a9 1404 if(ret)
MiniTLS 2:527a66d0a1a9 1405 {
MiniTLS 2:527a66d0a1a9 1406 return ret;
MiniTLS 2:527a66d0a1a9 1407 }
MiniTLS 2:527a66d0a1a9 1408
MiniTLS 2:527a66d0a1a9 1409
MiniTLS 2:527a66d0a1a9 1410 if(memcmp(prf, buffer_current_read_position(buffer), VERIFY_DATA_LENGTH) != 0)
MiniTLS 2:527a66d0a1a9 1411 {
MiniTLS 2:527a66d0a1a9 1412 ERR("PRF differs; computed PRF was:");
MiniTLS 2:527a66d0a1a9 1413
MiniTLS 2:527a66d0a1a9 1414 DBG_BLOCK(
MiniTLS 2:527a66d0a1a9 1415 buffer_t computed_prf;
MiniTLS 2:527a66d0a1a9 1416 buffer_byref(&computed_prf, prf, VERIFY_DATA_LENGTH);
MiniTLS 2:527a66d0a1a9 1417 buffer_dump(&computed_prf);)
MiniTLS 2:527a66d0a1a9 1418
MiniTLS 2:527a66d0a1a9 1419 return MINITLS_ERR_WRONG_MAC;
MiniTLS 2:527a66d0a1a9 1420 }
MiniTLS 2:527a66d0a1a9 1421
MiniTLS 2:527a66d0a1a9 1422 buffer_n_discard(buffer, VERIFY_DATA_LENGTH);
MiniTLS 2:527a66d0a1a9 1423
MiniTLS 2:527a66d0a1a9 1424 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1425 }
MiniTLS 2:527a66d0a1a9 1426
MiniTLS 2:527a66d0a1a9 1427 minitls_err_t generate_record_keys(tls_handshake_t* handshake)
MiniTLS 2:527a66d0a1a9 1428 {
MiniTLS 2:527a66d0a1a9 1429 //Expand master key
MiniTLS 2:527a66d0a1a9 1430
MiniTLS 2:527a66d0a1a9 1431 /*
MiniTLS 2:527a66d0a1a9 1432 To generate the key material, compute
MiniTLS 2:527a66d0a1a9 1433
MiniTLS 2:527a66d0a1a9 1434 key_block = PRF(SecurityParameters.master_secret,
MiniTLS 2:527a66d0a1a9 1435 "key expansion",
MiniTLS 2:527a66d0a1a9 1436 SecurityParameters.server_random +
MiniTLS 2:527a66d0a1a9 1437 SecurityParameters.client_random);
MiniTLS 2:527a66d0a1a9 1438
MiniTLS 2:527a66d0a1a9 1439 until enough output has been generated. Then, the key_block is
MiniTLS 2:527a66d0a1a9 1440 partitioned as follows:
MiniTLS 2:527a66d0a1a9 1441
MiniTLS 2:527a66d0a1a9 1442 client_write_MAC_key[SecurityParameters.mac_key_length]
MiniTLS 2:527a66d0a1a9 1443 server_write_MAC_key[SecurityParameters.mac_key_length]
MiniTLS 2:527a66d0a1a9 1444 client_write_key[SecurityParameters.enc_key_length]
MiniTLS 2:527a66d0a1a9 1445 server_write_key[SecurityParameters.enc_key_length]
MiniTLS 2:527a66d0a1a9 1446 client_write_IV[SecurityParameters.fixed_iv_length]
MiniTLS 2:527a66d0a1a9 1447 server_write_IV[SecurityParameters.fixed_iv_length]
MiniTLS 2:527a66d0a1a9 1448 */
MiniTLS 2:527a66d0a1a9 1449
MiniTLS 2:527a66d0a1a9 1450 /*
MiniTLS 2:527a66d0a1a9 1451 Cipher Type Material Size Size
MiniTLS 2:527a66d0a1a9 1452 ------------ ------ -------- ---- -----
MiniTLS 2:527a66d0a1a9 1453 AES_128_CBC Block 16 16 16
MiniTLS 2:527a66d0a1a9 1454
MiniTLS 2:527a66d0a1a9 1455 MAC Algorithm mac_length mac_key_length
MiniTLS 2:527a66d0a1a9 1456 -------- ----------- ---------- --------------
MiniTLS 2:527a66d0a1a9 1457 SHA HMAC-SHA1 20 20
MiniTLS 2:527a66d0a1a9 1458 */
MiniTLS 2:527a66d0a1a9 1459
MiniTLS 2:527a66d0a1a9 1460 //For our cipher we don't need the initialization vectors
MiniTLS 2:527a66d0a1a9 1461
MiniTLS 2:527a66d0a1a9 1462 DBG("Expand master key");
MiniTLS 2:527a66d0a1a9 1463
MiniTLS 2:527a66d0a1a9 1464 //Expand key
MiniTLS 2:527a66d0a1a9 1465 uint8_t key_expansion[2*TLS_HMAC_SHA1_KEY_SIZE + 2*AES_128_KEY_SIZE];
MiniTLS 2:527a66d0a1a9 1466 minitls_err_t ret = prf_compute(handshake->tls_socket->session.master_key, HANDSHAKE_MASTER_KEY_SIZE, "key expansion",
MiniTLS 2:527a66d0a1a9 1467 handshake->random_server, HANDSHAKE_RANDOM_SIZE,
MiniTLS 2:527a66d0a1a9 1468 handshake->random_client, HANDSHAKE_RANDOM_SIZE,
MiniTLS 2:527a66d0a1a9 1469 key_expansion, 2*TLS_HMAC_SHA1_KEY_SIZE + 2*AES_128_KEY_SIZE);
MiniTLS 2:527a66d0a1a9 1470 if(ret)
MiniTLS 2:527a66d0a1a9 1471 {
MiniTLS 2:527a66d0a1a9 1472 return ret;
MiniTLS 2:527a66d0a1a9 1473 }
MiniTLS 2:527a66d0a1a9 1474
MiniTLS 2:527a66d0a1a9 1475 //Init cipher/mac
MiniTLS 3:eb324ffffd2b 1476 tls_record_set_keys(&handshake->tls_socket->record, handshake->target_security,
MiniTLS 2:527a66d0a1a9 1477 &key_expansion[0*TLS_HMAC_SHA1_KEY_SIZE + 0*AES_128_KEY_SIZE],
MiniTLS 2:527a66d0a1a9 1478 &key_expansion[1*TLS_HMAC_SHA1_KEY_SIZE + 0*AES_128_KEY_SIZE],
MiniTLS 2:527a66d0a1a9 1479 &key_expansion[2*TLS_HMAC_SHA1_KEY_SIZE + 0*AES_128_KEY_SIZE],
MiniTLS 2:527a66d0a1a9 1480 &key_expansion[2*TLS_HMAC_SHA1_KEY_SIZE + 1*AES_128_KEY_SIZE]
MiniTLS 2:527a66d0a1a9 1481 );
MiniTLS 2:527a66d0a1a9 1482
MiniTLS 2:527a66d0a1a9 1483 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1484 }
MiniTLS 2:527a66d0a1a9 1485
MiniTLS 2:527a66d0a1a9 1486 #define HANDSHAKE_HEADER_SIZE 4
MiniTLS 2:527a66d0a1a9 1487
MiniTLS 2:527a66d0a1a9 1488 minitls_err_t parse_message(tls_handshake_t* handshake, buffer_t* buffer, handshake_type_t* message_type)
MiniTLS 2:527a66d0a1a9 1489 {
MiniTLS 2:527a66d0a1a9 1490 if( buffer_length(buffer) < HANDSHAKE_HEADER_SIZE )
MiniTLS 2:527a66d0a1a9 1491 {
MiniTLS 2:527a66d0a1a9 1492 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 1493 }
MiniTLS 2:527a66d0a1a9 1494
MiniTLS 2:527a66d0a1a9 1495 //Update SHA to use in FINISHED message
MiniTLS 2:527a66d0a1a9 1496 if(handshake->state < TLS_HANDSHAKE_FINISHED_SENT) //Don't update if it is the FINISHED message sent from the server
MiniTLS 2:527a66d0a1a9 1497 {
MiniTLS 2:527a66d0a1a9 1498 //If TLS1.2 or protocol version unknown for now
MiniTLS 2:527a66d0a1a9 1499 crypto_sha256_update(&handshake->hash.sha256, buffer_current_read_position(buffer), buffer_length(buffer));
MiniTLS 2:527a66d0a1a9 1500
MiniTLS 2:527a66d0a1a9 1501 //FIXME SSL3-TLS1.1 or protocol version unknown for now
MiniTLS 2:527a66d0a1a9 1502
MiniTLS 2:527a66d0a1a9 1503 }
MiniTLS 2:527a66d0a1a9 1504
MiniTLS 2:527a66d0a1a9 1505 *message_type = (uint8_t) buffer_nu8_read(buffer);
MiniTLS 2:527a66d0a1a9 1506 size_t size = buffer_nu24_read(buffer);
MiniTLS 2:527a66d0a1a9 1507
MiniTLS 2:527a66d0a1a9 1508 if( buffer_length(buffer) != size )
MiniTLS 2:527a66d0a1a9 1509 {
MiniTLS 2:527a66d0a1a9 1510 return MINITLS_ERR_PROTOCOL_NON_CONFORMANT;
MiniTLS 2:527a66d0a1a9 1511 }
MiniTLS 2:527a66d0a1a9 1512
MiniTLS 2:527a66d0a1a9 1513 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1514 }
MiniTLS 2:527a66d0a1a9 1515
MiniTLS 2:527a66d0a1a9 1516 minitls_err_t prepare_message(tls_handshake_t* handshake, handshake_type_t message_type, buffer_t* buffer, size_t size)
MiniTLS 2:527a66d0a1a9 1517 {
MiniTLS 2:527a66d0a1a9 1518 buffer_reset(buffer);
MiniTLS 2:527a66d0a1a9 1519 if( buffer_size(buffer) < size + HANDSHAKE_HEADER_SIZE /* header size*/ )
MiniTLS 2:527a66d0a1a9 1520 {
MiniTLS 2:527a66d0a1a9 1521 ERR("Buffer too small");
MiniTLS 2:527a66d0a1a9 1522 return MINITLS_ERR_BUFFER_TOO_SMALL;
MiniTLS 2:527a66d0a1a9 1523 }
MiniTLS 2:527a66d0a1a9 1524
MiniTLS 2:527a66d0a1a9 1525 buffer_nu8_write(buffer, (uint8_t)message_type);
MiniTLS 2:527a66d0a1a9 1526 buffer_nu24_write(buffer, size);
MiniTLS 2:527a66d0a1a9 1527
MiniTLS 2:527a66d0a1a9 1528 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1529 }
MiniTLS 2:527a66d0a1a9 1530
MiniTLS 2:527a66d0a1a9 1531 minitls_err_t prepare_message_adjust_size(tls_handshake_t* handshake, buffer_t* buffer, size_t size)
MiniTLS 2:527a66d0a1a9 1532 {
MiniTLS 2:527a66d0a1a9 1533 size_t length = buffer_length(buffer);
MiniTLS 2:527a66d0a1a9 1534
MiniTLS 2:527a66d0a1a9 1535 buffer_reset(buffer);
MiniTLS 2:527a66d0a1a9 1536 if( buffer_size(buffer) < size + HANDSHAKE_HEADER_SIZE /* header size*/ )
MiniTLS 2:527a66d0a1a9 1537 {
MiniTLS 2:527a66d0a1a9 1538 return MINITLS_ERR_BUFFER_TOO_SMALL;
MiniTLS 2:527a66d0a1a9 1539 }
MiniTLS 2:527a66d0a1a9 1540
MiniTLS 2:527a66d0a1a9 1541 buffer_set_length(buffer, 1); //Skip message type
MiniTLS 2:527a66d0a1a9 1542
MiniTLS 2:527a66d0a1a9 1543 buffer_nu24_write(buffer, size);
MiniTLS 2:527a66d0a1a9 1544
MiniTLS 2:527a66d0a1a9 1545 buffer_set_length(buffer, length);
MiniTLS 2:527a66d0a1a9 1546
MiniTLS 2:527a66d0a1a9 1547 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1548 }
MiniTLS 2:527a66d0a1a9 1549
MiniTLS 2:527a66d0a1a9 1550
MiniTLS 2:527a66d0a1a9 1551 minitls_err_t send_message(tls_handshake_t* handshake, buffer_t* buffer)
MiniTLS 2:527a66d0a1a9 1552 {
MiniTLS 2:527a66d0a1a9 1553 //Update SHA to use in FINISHED messages
MiniTLS 2:527a66d0a1a9 1554 crypto_sha256_update(&handshake->hash.sha256, buffer_current_read_position(buffer), buffer_length(buffer));
MiniTLS 2:527a66d0a1a9 1555
MiniTLS 2:527a66d0a1a9 1556 //DEBUG TODO: check mismatch with length
MiniTLS 2:527a66d0a1a9 1557
MiniTLS 2:527a66d0a1a9 1558 minitls_err_t ret = tls_record_send(&handshake->tls_socket->record, TLS_HANDSHAKE, buffer);
MiniTLS 2:527a66d0a1a9 1559 if(ret)
MiniTLS 2:527a66d0a1a9 1560 {
MiniTLS 2:527a66d0a1a9 1561 ERR("Send returned %d", ret);
MiniTLS 2:527a66d0a1a9 1562 return ret;
MiniTLS 2:527a66d0a1a9 1563 }
MiniTLS 2:527a66d0a1a9 1564 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1565 }
MiniTLS 2:527a66d0a1a9 1566
MiniTLS 2:527a66d0a1a9 1567 void handle_ret(tls_handshake_t* handshake, minitls_err_t ret)
MiniTLS 2:527a66d0a1a9 1568 {
MiniTLS 2:527a66d0a1a9 1569 ERR("Will return error %d", ret);
MiniTLS 2:527a66d0a1a9 1570
MiniTLS 2:527a66d0a1a9 1571 //Make handshake fail
MiniTLS 2:527a66d0a1a9 1572 handshake->state = TLS_HANDSHAKE_FAILED;
MiniTLS 2:527a66d0a1a9 1573
MiniTLS 2:527a66d0a1a9 1574 //Send alert to other party
MiniTLS 2:527a66d0a1a9 1575 switch(ret)
MiniTLS 2:527a66d0a1a9 1576 {
MiniTLS 2:527a66d0a1a9 1577 case MINITLS_ERR_WRONG_CERTIFICATE:
MiniTLS 2:527a66d0a1a9 1578 tls_alert_send(&handshake->tls_socket->record, TLS_ALERT_FATAL, CERTIFICATE_UNKNOWN, &handshake->tls_socket->record.buffer);
MiniTLS 2:527a66d0a1a9 1579 break;
MiniTLS 2:527a66d0a1a9 1580 case MINITLS_ERR_PROTOCOL_NON_CONFORMANT:
MiniTLS 2:527a66d0a1a9 1581 tls_alert_send(&handshake->tls_socket->record, TLS_ALERT_FATAL, UNEXPECTED_MESSAGE, &handshake->tls_socket->record.buffer);
MiniTLS 2:527a66d0a1a9 1582 break;
MiniTLS 2:527a66d0a1a9 1583 case MINITLS_ERR_NOT_IMPLEMENTED:
MiniTLS 2:527a66d0a1a9 1584 default:
MiniTLS 2:527a66d0a1a9 1585 tls_alert_send(&handshake->tls_socket->record, TLS_ALERT_FATAL, HANDSHAKE_FAILURE, &handshake->tls_socket->record.buffer);
MiniTLS 2:527a66d0a1a9 1586 break;
MiniTLS 2:527a66d0a1a9 1587 }
MiniTLS 2:527a66d0a1a9 1588 }
MiniTLS 2:527a66d0a1a9 1589
MiniTLS 2:527a66d0a1a9 1590
MiniTLS 2:527a66d0a1a9 1591 minitls_err_t prf_compute(const uint8_t* secret, size_t secret_size,
MiniTLS 2:527a66d0a1a9 1592 const char* label,
MiniTLS 2:527a66d0a1a9 1593 const uint8_t* seed1, size_t seed1_size,
MiniTLS 2:527a66d0a1a9 1594 const uint8_t* seed2, size_t seed2_size,
MiniTLS 2:527a66d0a1a9 1595 uint8_t* out, size_t out_size)
MiniTLS 2:527a66d0a1a9 1596 {
MiniTLS 2:527a66d0a1a9 1597 //PRF TLS1.2
MiniTLS 2:527a66d0a1a9 1598 //TODO add PRF SSL3-TLS1.1
MiniTLS 2:527a66d0a1a9 1599
MiniTLS 2:527a66d0a1a9 1600 //DBG("PRF: Secret %p [%d] - label '%s' - Seed %p [%d] - out %p [%d]", secret, secret_size, label, seed, seed_size, out, out_size);
MiniTLS 2:527a66d0a1a9 1601 //We are using the HMAC-SHA256 MAC (non negotiable)
MiniTLS 2:527a66d0a1a9 1602
MiniTLS 2:527a66d0a1a9 1603 /*
MiniTLS 2:527a66d0a1a9 1604 P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
MiniTLS 2:527a66d0a1a9 1605 HMAC_hash(secret, A(2) + seed) +
MiniTLS 2:527a66d0a1a9 1606 HMAC_hash(secret, A(3) + seed) + ...
MiniTLS 2:527a66d0a1a9 1607
MiniTLS 2:527a66d0a1a9 1608 A(0) = seed
MiniTLS 2:527a66d0a1a9 1609 A(i) = HMAC_hash(secret, A(i-1))
MiniTLS 2:527a66d0a1a9 1610
MiniTLS 2:527a66d0a1a9 1611 PRF(secret, label, seed) = P_hash(secret, label + seed)
MiniTLS 2:527a66d0a1a9 1612
MiniTLS 2:527a66d0a1a9 1613 */
MiniTLS 2:527a66d0a1a9 1614
MiniTLS 2:527a66d0a1a9 1615 //MAC_HMAC_SHA1_SIZE
MiniTLS 2:527a66d0a1a9 1616 uint8_t mac[HMAC_SHA256_SIZE];
MiniTLS 2:527a66d0a1a9 1617 uint8_t A[HMAC_SHA256_SIZE];
MiniTLS 2:527a66d0a1a9 1618
MiniTLS 2:527a66d0a1a9 1619 //A[0] = seed
MiniTLS 2:527a66d0a1a9 1620 crypto_hmac_sha256_t hmac_sha256;
MiniTLS 2:527a66d0a1a9 1621
MiniTLS 2:527a66d0a1a9 1622 //minitls_err_t ret;
MiniTLS 2:527a66d0a1a9 1623
MiniTLS 2:527a66d0a1a9 1624 size_t current_size = 0;
MiniTLS 2:527a66d0a1a9 1625
MiniTLS 2:527a66d0a1a9 1626 while(current_size < out_size)
MiniTLS 2:527a66d0a1a9 1627 {
MiniTLS 2:527a66d0a1a9 1628 //DBG("Current size %d", current_size);
MiniTLS 2:527a66d0a1a9 1629
MiniTLS 2:527a66d0a1a9 1630 //Compute A[n]=f(A[n-1])
MiniTLS 2:527a66d0a1a9 1631 crypto_hmac_sha256_init(&hmac_sha256, secret, secret_size);
MiniTLS 2:527a66d0a1a9 1632
MiniTLS 2:527a66d0a1a9 1633 if(current_size == 0) //First iteration
MiniTLS 2:527a66d0a1a9 1634 {
MiniTLS 2:527a66d0a1a9 1635 crypto_hmac_sha256_update(&hmac_sha256, (const uint8_t*)label, strlen(label));
MiniTLS 2:527a66d0a1a9 1636
MiniTLS 2:527a66d0a1a9 1637 crypto_hmac_sha256_update(&hmac_sha256, seed1, seed1_size);
MiniTLS 2:527a66d0a1a9 1638 if(seed2 != NULL)
MiniTLS 2:527a66d0a1a9 1639 {
MiniTLS 2:527a66d0a1a9 1640 crypto_hmac_sha256_update(&hmac_sha256, seed2, seed2_size);
MiniTLS 2:527a66d0a1a9 1641 }
MiniTLS 2:527a66d0a1a9 1642 }
MiniTLS 2:527a66d0a1a9 1643 else
MiniTLS 2:527a66d0a1a9 1644 {
MiniTLS 2:527a66d0a1a9 1645 crypto_hmac_sha256_update(&hmac_sha256, A, HMAC_SHA256_SIZE);
MiniTLS 2:527a66d0a1a9 1646 }
MiniTLS 2:527a66d0a1a9 1647
MiniTLS 2:527a66d0a1a9 1648 crypto_hmac_sha256_end(&hmac_sha256, A);
MiniTLS 2:527a66d0a1a9 1649
MiniTLS 2:527a66d0a1a9 1650 //Compute HMAC_hash(secret, A[n] + seed)
MiniTLS 2:527a66d0a1a9 1651 crypto_hmac_sha256_init(&hmac_sha256, secret, secret_size);
MiniTLS 2:527a66d0a1a9 1652
MiniTLS 2:527a66d0a1a9 1653 crypto_hmac_sha256_update(&hmac_sha256, A, HMAC_SHA256_SIZE);
MiniTLS 2:527a66d0a1a9 1654
MiniTLS 2:527a66d0a1a9 1655 crypto_hmac_sha256_update(&hmac_sha256, (const uint8_t*)label, strlen(label));
MiniTLS 2:527a66d0a1a9 1656
MiniTLS 2:527a66d0a1a9 1657 crypto_hmac_sha256_update(&hmac_sha256, seed1, seed1_size);
MiniTLS 2:527a66d0a1a9 1658 if(seed2 != NULL)
MiniTLS 2:527a66d0a1a9 1659 {
MiniTLS 2:527a66d0a1a9 1660 crypto_hmac_sha256_update(&hmac_sha256, seed2, seed2_size);
MiniTLS 2:527a66d0a1a9 1661 }
MiniTLS 2:527a66d0a1a9 1662
MiniTLS 2:527a66d0a1a9 1663 crypto_hmac_sha256_end(&hmac_sha256, mac);
MiniTLS 2:527a66d0a1a9 1664
MiniTLS 2:527a66d0a1a9 1665 //Copy and truncate if needed
MiniTLS 2:527a66d0a1a9 1666 size_t append_size = MIN( out_size - current_size, HMAC_SHA256_SIZE );
MiniTLS 2:527a66d0a1a9 1667 memcpy(out + current_size, mac, append_size);
MiniTLS 2:527a66d0a1a9 1668
MiniTLS 2:527a66d0a1a9 1669 current_size += append_size;
MiniTLS 2:527a66d0a1a9 1670 }
MiniTLS 2:527a66d0a1a9 1671
MiniTLS 2:527a66d0a1a9 1672 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1673 }
MiniTLS 2:527a66d0a1a9 1674
MiniTLS 2:527a66d0a1a9 1675 minitls_err_t change_cipher_spec_request(tls_handshake_t* handshake, buffer_t* buffer)
MiniTLS 2:527a66d0a1a9 1676 {
MiniTLS 2:527a66d0a1a9 1677 /*
MiniTLS 2:527a66d0a1a9 1678 The change cipher spec protocol exists to signal transitions in
MiniTLS 2:527a66d0a1a9 1679 ciphering strategies. The protocol consists of a single message,
MiniTLS 2:527a66d0a1a9 1680 which is encrypted and compressed under the current (not the pending)
MiniTLS 2:527a66d0a1a9 1681 connection state. The message consists of a single byte of value 1.
MiniTLS 2:527a66d0a1a9 1682
MiniTLS 2:527a66d0a1a9 1683 struct {
MiniTLS 2:527a66d0a1a9 1684 enum { change_cipher_spec(1), (255) } type;
MiniTLS 2:527a66d0a1a9 1685 } ChangeCipherSpec;
MiniTLS 2:527a66d0a1a9 1686 */
MiniTLS 2:527a66d0a1a9 1687 buffer_reset(buffer);
MiniTLS 2:527a66d0a1a9 1688 if( buffer_size(buffer) < 1 )
MiniTLS 2:527a66d0a1a9 1689 {
MiniTLS 2:527a66d0a1a9 1690 return MINITLS_ERR_BUFFER_TOO_SMALL;
MiniTLS 2:527a66d0a1a9 1691 }
MiniTLS 2:527a66d0a1a9 1692
MiniTLS 2:527a66d0a1a9 1693 buffer_nu8_write(buffer, 1);
MiniTLS 2:527a66d0a1a9 1694
MiniTLS 2:527a66d0a1a9 1695 minitls_err_t ret = tls_record_send(&handshake->tls_socket->record, TLS_CHANGE_CIPHER_SPEC, buffer);
MiniTLS 2:527a66d0a1a9 1696 if(ret)
MiniTLS 2:527a66d0a1a9 1697 {
MiniTLS 2:527a66d0a1a9 1698 return ret;
MiniTLS 2:527a66d0a1a9 1699 }
MiniTLS 2:527a66d0a1a9 1700
MiniTLS 2:527a66d0a1a9 1701 return MINITLS_OK;
MiniTLS 2:527a66d0a1a9 1702 }