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:
Fri Jun 06 10:49:02 2014 +0000
Revision:
0:35aa5be3b78d
Initial commit

Who changed what in which revision?

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