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:
Mon Jun 09 14:57:54 2014 +0000
Revision:
2:527a66d0a1a9
Child:
3:eb324ffffd2b
Change name to MiniTLS and added doc

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