Webserver+3d print

Dependents:   Nucleo

Committer:
Sergunb
Date:
Sat Feb 04 18:15:49 2017 +0000
Revision:
0:8918a71cdbe9
nothing else

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sergunb 0:8918a71cdbe9 1 /**
Sergunb 0:8918a71cdbe9 2 * @file tls_common.c
Sergunb 0:8918a71cdbe9 3 * @brief Handshake message processing (TLS client and server)
Sergunb 0:8918a71cdbe9 4 *
Sergunb 0:8918a71cdbe9 5 * @section License
Sergunb 0:8918a71cdbe9 6 *
Sergunb 0:8918a71cdbe9 7 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved.
Sergunb 0:8918a71cdbe9 8 *
Sergunb 0:8918a71cdbe9 9 * This file is part of CycloneSSL Open.
Sergunb 0:8918a71cdbe9 10 *
Sergunb 0:8918a71cdbe9 11 * This program is free software; you can redistribute it and/or
Sergunb 0:8918a71cdbe9 12 * modify it under the terms of the GNU General Public License
Sergunb 0:8918a71cdbe9 13 * as published by the Free Software Foundation; either version 2
Sergunb 0:8918a71cdbe9 14 * of the License, or (at your option) any later version.
Sergunb 0:8918a71cdbe9 15 *
Sergunb 0:8918a71cdbe9 16 * This program is distributed in the hope that it will be useful,
Sergunb 0:8918a71cdbe9 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Sergunb 0:8918a71cdbe9 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Sergunb 0:8918a71cdbe9 19 * GNU General Public License for more details.
Sergunb 0:8918a71cdbe9 20 *
Sergunb 0:8918a71cdbe9 21 * You should have received a copy of the GNU General Public License
Sergunb 0:8918a71cdbe9 22 * along with this program; if not, write to the Free Software Foundation,
Sergunb 0:8918a71cdbe9 23 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Sergunb 0:8918a71cdbe9 24 *
Sergunb 0:8918a71cdbe9 25 * @author Oryx Embedded SARL (www.oryx-embedded.com)
Sergunb 0:8918a71cdbe9 26 * @version 1.7.6
Sergunb 0:8918a71cdbe9 27 **/
Sergunb 0:8918a71cdbe9 28
Sergunb 0:8918a71cdbe9 29 //Switch to the appropriate trace level
Sergunb 0:8918a71cdbe9 30 #define TRACE_LEVEL TLS_TRACE_LEVEL
Sergunb 0:8918a71cdbe9 31
Sergunb 0:8918a71cdbe9 32 //Dependencies
Sergunb 0:8918a71cdbe9 33 #include <string.h>
Sergunb 0:8918a71cdbe9 34 #include <ctype.h>
Sergunb 0:8918a71cdbe9 35 #include "tls.h"
Sergunb 0:8918a71cdbe9 36 #include "tls_cipher_suites.h"
Sergunb 0:8918a71cdbe9 37 #include "tls_client.h"
Sergunb 0:8918a71cdbe9 38 #include "tls_server.h"
Sergunb 0:8918a71cdbe9 39 #include "tls_common.h"
Sergunb 0:8918a71cdbe9 40 #include "tls_record.h"
Sergunb 0:8918a71cdbe9 41 #include "tls_cache.h"
Sergunb 0:8918a71cdbe9 42 #include "tls_misc.h"
Sergunb 0:8918a71cdbe9 43 #include "asn1.h"
Sergunb 0:8918a71cdbe9 44 #include "oid.h"
Sergunb 0:8918a71cdbe9 45 #include "x509.h"
Sergunb 0:8918a71cdbe9 46 #include "pem.h"
Sergunb 0:8918a71cdbe9 47 #include "debug.h"
Sergunb 0:8918a71cdbe9 48
Sergunb 0:8918a71cdbe9 49 //Check SSL library configuration
Sergunb 0:8918a71cdbe9 50 #if (TLS_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 51
Sergunb 0:8918a71cdbe9 52
Sergunb 0:8918a71cdbe9 53 /**
Sergunb 0:8918a71cdbe9 54 * @brief Perform TLS handshake
Sergunb 0:8918a71cdbe9 55 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 56 * @return Error code
Sergunb 0:8918a71cdbe9 57 **/
Sergunb 0:8918a71cdbe9 58
Sergunb 0:8918a71cdbe9 59 error_t tlsHandshake(TlsContext *context)
Sergunb 0:8918a71cdbe9 60 {
Sergunb 0:8918a71cdbe9 61 error_t error;
Sergunb 0:8918a71cdbe9 62
Sergunb 0:8918a71cdbe9 63 #if (TLS_CLIENT_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 64 //TLS operates as a client?
Sergunb 0:8918a71cdbe9 65 if(context->entity == TLS_CONNECTION_END_CLIENT)
Sergunb 0:8918a71cdbe9 66 {
Sergunb 0:8918a71cdbe9 67 //Initiate TLS handshake with the remote server
Sergunb 0:8918a71cdbe9 68 error = tlsClientHandshake(context);
Sergunb 0:8918a71cdbe9 69 }
Sergunb 0:8918a71cdbe9 70 else
Sergunb 0:8918a71cdbe9 71 #endif
Sergunb 0:8918a71cdbe9 72 #if (TLS_SERVER_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 73 //TLS operates as a server?
Sergunb 0:8918a71cdbe9 74 if(context->entity == TLS_CONNECTION_END_SERVER)
Sergunb 0:8918a71cdbe9 75 {
Sergunb 0:8918a71cdbe9 76 //Initiate TLS handshake with the remote client
Sergunb 0:8918a71cdbe9 77 error = tlsServerHandshake(context);
Sergunb 0:8918a71cdbe9 78 }
Sergunb 0:8918a71cdbe9 79 else
Sergunb 0:8918a71cdbe9 80 #endif
Sergunb 0:8918a71cdbe9 81 //Unsupported mode of operation?
Sergunb 0:8918a71cdbe9 82 {
Sergunb 0:8918a71cdbe9 83 //Cannot establish a secure session between the server and the client
Sergunb 0:8918a71cdbe9 84 error = ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 85 }
Sergunb 0:8918a71cdbe9 86
Sergunb 0:8918a71cdbe9 87 //Return status code
Sergunb 0:8918a71cdbe9 88 return error;
Sergunb 0:8918a71cdbe9 89 }
Sergunb 0:8918a71cdbe9 90
Sergunb 0:8918a71cdbe9 91
Sergunb 0:8918a71cdbe9 92 /**
Sergunb 0:8918a71cdbe9 93 * @brief Send Certificate message
Sergunb 0:8918a71cdbe9 94 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 95 * @return Error code
Sergunb 0:8918a71cdbe9 96 **/
Sergunb 0:8918a71cdbe9 97
Sergunb 0:8918a71cdbe9 98 error_t tlsSendCertificate(TlsContext *context)
Sergunb 0:8918a71cdbe9 99 {
Sergunb 0:8918a71cdbe9 100 error_t error;
Sergunb 0:8918a71cdbe9 101 size_t length;
Sergunb 0:8918a71cdbe9 102 void *message;
Sergunb 0:8918a71cdbe9 103
Sergunb 0:8918a71cdbe9 104 //Initialize status code
Sergunb 0:8918a71cdbe9 105 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 106
Sergunb 0:8918a71cdbe9 107 //Point to the buffer where to format the message
Sergunb 0:8918a71cdbe9 108 message = (void *) context->txBuffer;
Sergunb 0:8918a71cdbe9 109
Sergunb 0:8918a71cdbe9 110 #if (TLS_CLIENT_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 111 //TLS operates as a client?
Sergunb 0:8918a71cdbe9 112 if(context->entity == TLS_CONNECTION_END_CLIENT)
Sergunb 0:8918a71cdbe9 113 {
Sergunb 0:8918a71cdbe9 114 //The client must send a Certificate message if the server requests it
Sergunb 0:8918a71cdbe9 115 if(context->clientCertRequested)
Sergunb 0:8918a71cdbe9 116 {
Sergunb 0:8918a71cdbe9 117 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= SSL_VERSION_3_0)
Sergunb 0:8918a71cdbe9 118 //No suitable certificate available?
Sergunb 0:8918a71cdbe9 119 if(context->cert == NULL && context->version == SSL_VERSION_3_0)
Sergunb 0:8918a71cdbe9 120 {
Sergunb 0:8918a71cdbe9 121 //The client should send a no_certificate alert instead
Sergunb 0:8918a71cdbe9 122 error = tlsFormatAlert(context, TLS_ALERT_LEVEL_WARNING,
Sergunb 0:8918a71cdbe9 123 TLS_ALERT_NO_CERTIFICATE, message, &length);
Sergunb 0:8918a71cdbe9 124
Sergunb 0:8918a71cdbe9 125 //Check status code
Sergunb 0:8918a71cdbe9 126 if(!error)
Sergunb 0:8918a71cdbe9 127 {
Sergunb 0:8918a71cdbe9 128 //Debug message
Sergunb 0:8918a71cdbe9 129 TRACE_INFO("Sending Alert message (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 130 TRACE_INFO_ARRAY(" ", message, length);
Sergunb 0:8918a71cdbe9 131
Sergunb 0:8918a71cdbe9 132 //Send Alert message
Sergunb 0:8918a71cdbe9 133 error = tlsWriteProtocolData(context, message, length, TLS_TYPE_ALERT);
Sergunb 0:8918a71cdbe9 134 }
Sergunb 0:8918a71cdbe9 135 }
Sergunb 0:8918a71cdbe9 136 else
Sergunb 0:8918a71cdbe9 137 #endif
Sergunb 0:8918a71cdbe9 138 {
Sergunb 0:8918a71cdbe9 139 //Format Certificate message
Sergunb 0:8918a71cdbe9 140 error = tlsFormatCertificate(context, message, &length);
Sergunb 0:8918a71cdbe9 141
Sergunb 0:8918a71cdbe9 142 //Check status code
Sergunb 0:8918a71cdbe9 143 if(!error)
Sergunb 0:8918a71cdbe9 144 {
Sergunb 0:8918a71cdbe9 145 //Debug message
Sergunb 0:8918a71cdbe9 146 TRACE_INFO("Sending Certificate message (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 147 TRACE_DEBUG_ARRAY(" ", message, length);
Sergunb 0:8918a71cdbe9 148
Sergunb 0:8918a71cdbe9 149 //Send handshake message
Sergunb 0:8918a71cdbe9 150 error = tlsWriteProtocolData(context, message, length, TLS_TYPE_HANDSHAKE);
Sergunb 0:8918a71cdbe9 151 }
Sergunb 0:8918a71cdbe9 152 }
Sergunb 0:8918a71cdbe9 153 }
Sergunb 0:8918a71cdbe9 154 }
Sergunb 0:8918a71cdbe9 155 else
Sergunb 0:8918a71cdbe9 156 #endif
Sergunb 0:8918a71cdbe9 157 #if (TLS_SERVER_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 158 //TLS operates as a server?
Sergunb 0:8918a71cdbe9 159 if(context->entity == TLS_CONNECTION_END_SERVER)
Sergunb 0:8918a71cdbe9 160 {
Sergunb 0:8918a71cdbe9 161 //The server must send a Certificate message whenever the agreed-upon
Sergunb 0:8918a71cdbe9 162 //key exchange method uses certificates for authentication
Sergunb 0:8918a71cdbe9 163 if(context->cert != NULL)
Sergunb 0:8918a71cdbe9 164 {
Sergunb 0:8918a71cdbe9 165 //Format Certificate message
Sergunb 0:8918a71cdbe9 166 error = tlsFormatCertificate(context, message, &length);
Sergunb 0:8918a71cdbe9 167
Sergunb 0:8918a71cdbe9 168 //Check status code
Sergunb 0:8918a71cdbe9 169 if(!error)
Sergunb 0:8918a71cdbe9 170 {
Sergunb 0:8918a71cdbe9 171 //Debug message
Sergunb 0:8918a71cdbe9 172 TRACE_INFO("Sending Certificate message (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 173 TRACE_DEBUG_ARRAY(" ", message, length);
Sergunb 0:8918a71cdbe9 174
Sergunb 0:8918a71cdbe9 175 //Send handshake message
Sergunb 0:8918a71cdbe9 176 error = tlsWriteProtocolData(context, message, length, TLS_TYPE_HANDSHAKE);
Sergunb 0:8918a71cdbe9 177 }
Sergunb 0:8918a71cdbe9 178 }
Sergunb 0:8918a71cdbe9 179 }
Sergunb 0:8918a71cdbe9 180 else
Sergunb 0:8918a71cdbe9 181 #endif
Sergunb 0:8918a71cdbe9 182 //Unsupported mode of operation?
Sergunb 0:8918a71cdbe9 183 {
Sergunb 0:8918a71cdbe9 184 //Report an error
Sergunb 0:8918a71cdbe9 185 error = ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 186 }
Sergunb 0:8918a71cdbe9 187
Sergunb 0:8918a71cdbe9 188 //Check status code
Sergunb 0:8918a71cdbe9 189 if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
Sergunb 0:8918a71cdbe9 190 {
Sergunb 0:8918a71cdbe9 191 //Update FSM state
Sergunb 0:8918a71cdbe9 192 if(context->entity == TLS_CONNECTION_END_CLIENT)
Sergunb 0:8918a71cdbe9 193 context->state = TLS_STATE_CLIENT_KEY_EXCHANGE;
Sergunb 0:8918a71cdbe9 194 else
Sergunb 0:8918a71cdbe9 195 context->state = TLS_STATE_SERVER_KEY_EXCHANGE;
Sergunb 0:8918a71cdbe9 196 }
Sergunb 0:8918a71cdbe9 197
Sergunb 0:8918a71cdbe9 198 //Return status code
Sergunb 0:8918a71cdbe9 199 return error;
Sergunb 0:8918a71cdbe9 200 }
Sergunb 0:8918a71cdbe9 201
Sergunb 0:8918a71cdbe9 202
Sergunb 0:8918a71cdbe9 203 /**
Sergunb 0:8918a71cdbe9 204 * @brief Send ChangeCipherSpec message
Sergunb 0:8918a71cdbe9 205 *
Sergunb 0:8918a71cdbe9 206 * The change cipher spec message is sent by both the client and the
Sergunb 0:8918a71cdbe9 207 * server to notify the receiving party that subsequent records will be
Sergunb 0:8918a71cdbe9 208 * protected under the newly negotiated CipherSpec and keys
Sergunb 0:8918a71cdbe9 209 *
Sergunb 0:8918a71cdbe9 210 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 211 * @return Error code
Sergunb 0:8918a71cdbe9 212 **/
Sergunb 0:8918a71cdbe9 213
Sergunb 0:8918a71cdbe9 214 error_t tlsSendChangeCipherSpec(TlsContext *context)
Sergunb 0:8918a71cdbe9 215 {
Sergunb 0:8918a71cdbe9 216 error_t error;
Sergunb 0:8918a71cdbe9 217 size_t length;
Sergunb 0:8918a71cdbe9 218 TlsChangeCipherSpec *message;
Sergunb 0:8918a71cdbe9 219
Sergunb 0:8918a71cdbe9 220 //Point to the buffer where to format the message
Sergunb 0:8918a71cdbe9 221 message = (TlsChangeCipherSpec *) context->txBuffer;
Sergunb 0:8918a71cdbe9 222
Sergunb 0:8918a71cdbe9 223 //Format ChangeCipherSpec message
Sergunb 0:8918a71cdbe9 224 error = tlsFormatChangeCipherSpec(context, message, &length);
Sergunb 0:8918a71cdbe9 225
Sergunb 0:8918a71cdbe9 226 //Check status code
Sergunb 0:8918a71cdbe9 227 if(!error)
Sergunb 0:8918a71cdbe9 228 {
Sergunb 0:8918a71cdbe9 229 //Debug message
Sergunb 0:8918a71cdbe9 230 TRACE_INFO("Sending ChangeCipherSpec message (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 231 TRACE_DEBUG_ARRAY(" ", message, length);
Sergunb 0:8918a71cdbe9 232
Sergunb 0:8918a71cdbe9 233 //Send ChangeCipherSpec message
Sergunb 0:8918a71cdbe9 234 error = tlsWriteProtocolData(context, message, length, TLS_TYPE_CHANGE_CIPHER_SPEC);
Sergunb 0:8918a71cdbe9 235 }
Sergunb 0:8918a71cdbe9 236
Sergunb 0:8918a71cdbe9 237 //Check status code
Sergunb 0:8918a71cdbe9 238 if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
Sergunb 0:8918a71cdbe9 239 {
Sergunb 0:8918a71cdbe9 240 //Initialize encryption engine
Sergunb 0:8918a71cdbe9 241 error = tlsInitEncryptionEngine(context);
Sergunb 0:8918a71cdbe9 242 }
Sergunb 0:8918a71cdbe9 243
Sergunb 0:8918a71cdbe9 244 //Check status code
Sergunb 0:8918a71cdbe9 245 if(!error)
Sergunb 0:8918a71cdbe9 246 {
Sergunb 0:8918a71cdbe9 247 //Inform the record layer that subsequent records will be protected
Sergunb 0:8918a71cdbe9 248 //under the newly negotiated encryption algorithm
Sergunb 0:8918a71cdbe9 249 context->changeCipherSpecSent = TRUE;
Sergunb 0:8918a71cdbe9 250
Sergunb 0:8918a71cdbe9 251 //Prepare to send a Finished message to the peer...
Sergunb 0:8918a71cdbe9 252 if(context->entity == TLS_CONNECTION_END_CLIENT)
Sergunb 0:8918a71cdbe9 253 context->state = TLS_STATE_CLIENT_FINISHED;
Sergunb 0:8918a71cdbe9 254 else
Sergunb 0:8918a71cdbe9 255 context->state = TLS_STATE_SERVER_FINISHED;
Sergunb 0:8918a71cdbe9 256 }
Sergunb 0:8918a71cdbe9 257
Sergunb 0:8918a71cdbe9 258 //Return status code
Sergunb 0:8918a71cdbe9 259 return error;
Sergunb 0:8918a71cdbe9 260 }
Sergunb 0:8918a71cdbe9 261
Sergunb 0:8918a71cdbe9 262
Sergunb 0:8918a71cdbe9 263 /**
Sergunb 0:8918a71cdbe9 264 * @brief Send Finished message
Sergunb 0:8918a71cdbe9 265 *
Sergunb 0:8918a71cdbe9 266 * A Finished message is always sent immediately after a change
Sergunb 0:8918a71cdbe9 267 * cipher spec message to verify that the key exchange and
Sergunb 0:8918a71cdbe9 268 * authentication processes were successful. It is essential that a
Sergunb 0:8918a71cdbe9 269 * change cipher spec message be received between the other handshake
Sergunb 0:8918a71cdbe9 270 * messages and the Finished message
Sergunb 0:8918a71cdbe9 271 *
Sergunb 0:8918a71cdbe9 272 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 273 * @return Error code
Sergunb 0:8918a71cdbe9 274 **/
Sergunb 0:8918a71cdbe9 275
Sergunb 0:8918a71cdbe9 276 error_t tlsSendFinished(TlsContext *context)
Sergunb 0:8918a71cdbe9 277 {
Sergunb 0:8918a71cdbe9 278 error_t error;
Sergunb 0:8918a71cdbe9 279 size_t length;
Sergunb 0:8918a71cdbe9 280 TlsFinished *message;
Sergunb 0:8918a71cdbe9 281
Sergunb 0:8918a71cdbe9 282 //Point to the buffer where to format the message
Sergunb 0:8918a71cdbe9 283 message = (TlsFinished *) context->txBuffer;
Sergunb 0:8918a71cdbe9 284
Sergunb 0:8918a71cdbe9 285 //The verify data is generated from all messages in this handshake
Sergunb 0:8918a71cdbe9 286 //up to but not including the Finished message
Sergunb 0:8918a71cdbe9 287 error = tlsComputeVerifyData(context, context->entity);
Sergunb 0:8918a71cdbe9 288
Sergunb 0:8918a71cdbe9 289 //Check status code
Sergunb 0:8918a71cdbe9 290 if(!error)
Sergunb 0:8918a71cdbe9 291 {
Sergunb 0:8918a71cdbe9 292 //Format Finished message
Sergunb 0:8918a71cdbe9 293 error = tlsFormatFinished(context, message, &length);
Sergunb 0:8918a71cdbe9 294 }
Sergunb 0:8918a71cdbe9 295
Sergunb 0:8918a71cdbe9 296 //Check status code
Sergunb 0:8918a71cdbe9 297 if(!error)
Sergunb 0:8918a71cdbe9 298 {
Sergunb 0:8918a71cdbe9 299 //Debug message
Sergunb 0:8918a71cdbe9 300 TRACE_INFO("Sending Finished message (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 301 TRACE_DEBUG_ARRAY(" ", message, length);
Sergunb 0:8918a71cdbe9 302
Sergunb 0:8918a71cdbe9 303 //Send handshake message
Sergunb 0:8918a71cdbe9 304 error = tlsWriteProtocolData(context, message, length, TLS_TYPE_HANDSHAKE);
Sergunb 0:8918a71cdbe9 305 }
Sergunb 0:8918a71cdbe9 306
Sergunb 0:8918a71cdbe9 307 //Check status code
Sergunb 0:8918a71cdbe9 308 if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
Sergunb 0:8918a71cdbe9 309 {
Sergunb 0:8918a71cdbe9 310 //TLS operates as a client or a server?
Sergunb 0:8918a71cdbe9 311 if(context->entity == TLS_CONNECTION_END_CLIENT)
Sergunb 0:8918a71cdbe9 312 {
Sergunb 0:8918a71cdbe9 313 //Use abbreviated or full handshake?
Sergunb 0:8918a71cdbe9 314 if(context->resume)
Sergunb 0:8918a71cdbe9 315 context->state = TLS_STATE_APPLICATION_DATA;
Sergunb 0:8918a71cdbe9 316 else
Sergunb 0:8918a71cdbe9 317 context->state = TLS_STATE_SERVER_CHANGE_CIPHER_SPEC;
Sergunb 0:8918a71cdbe9 318 }
Sergunb 0:8918a71cdbe9 319 else
Sergunb 0:8918a71cdbe9 320 {
Sergunb 0:8918a71cdbe9 321 //Use abbreviated or full handshake?
Sergunb 0:8918a71cdbe9 322 if(context->resume)
Sergunb 0:8918a71cdbe9 323 context->state = TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC;
Sergunb 0:8918a71cdbe9 324 else
Sergunb 0:8918a71cdbe9 325 context->state = TLS_STATE_APPLICATION_DATA;
Sergunb 0:8918a71cdbe9 326 }
Sergunb 0:8918a71cdbe9 327 }
Sergunb 0:8918a71cdbe9 328
Sergunb 0:8918a71cdbe9 329 //Return status code
Sergunb 0:8918a71cdbe9 330 return error;
Sergunb 0:8918a71cdbe9 331 }
Sergunb 0:8918a71cdbe9 332
Sergunb 0:8918a71cdbe9 333
Sergunb 0:8918a71cdbe9 334 /**
Sergunb 0:8918a71cdbe9 335 * @brief Send Alert message
Sergunb 0:8918a71cdbe9 336 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 337 * @param[in] level Severity of the message (warning or fatal)
Sergunb 0:8918a71cdbe9 338 * @param[in] description Description of the alert
Sergunb 0:8918a71cdbe9 339 * @return Error code
Sergunb 0:8918a71cdbe9 340 **/
Sergunb 0:8918a71cdbe9 341
Sergunb 0:8918a71cdbe9 342 error_t tlsSendAlert(TlsContext *context, uint8_t level, uint8_t description)
Sergunb 0:8918a71cdbe9 343 {
Sergunb 0:8918a71cdbe9 344 error_t error;
Sergunb 0:8918a71cdbe9 345 size_t length;
Sergunb 0:8918a71cdbe9 346 TlsAlert *message;
Sergunb 0:8918a71cdbe9 347
Sergunb 0:8918a71cdbe9 348 //Point to the buffer where to format the message
Sergunb 0:8918a71cdbe9 349 message = (TlsAlert *) context->txBuffer;
Sergunb 0:8918a71cdbe9 350
Sergunb 0:8918a71cdbe9 351 //Format Alert message
Sergunb 0:8918a71cdbe9 352 error = tlsFormatAlert(context, level, description, message, &length);
Sergunb 0:8918a71cdbe9 353
Sergunb 0:8918a71cdbe9 354 //Check status code
Sergunb 0:8918a71cdbe9 355 if(!error)
Sergunb 0:8918a71cdbe9 356 {
Sergunb 0:8918a71cdbe9 357 //Debug message
Sergunb 0:8918a71cdbe9 358 TRACE_INFO("Sending Alert message (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 359 TRACE_INFO_ARRAY(" ", message, length);
Sergunb 0:8918a71cdbe9 360
Sergunb 0:8918a71cdbe9 361 //Send Alert message
Sergunb 0:8918a71cdbe9 362 error = tlsWriteProtocolData(context, message, length, TLS_TYPE_ALERT);
Sergunb 0:8918a71cdbe9 363 }
Sergunb 0:8918a71cdbe9 364
Sergunb 0:8918a71cdbe9 365 //Alert messages convey the severity of the message
Sergunb 0:8918a71cdbe9 366 if(level == TLS_ALERT_LEVEL_WARNING)
Sergunb 0:8918a71cdbe9 367 {
Sergunb 0:8918a71cdbe9 368 //If an alert with a level of warning is sent, generally the
Sergunb 0:8918a71cdbe9 369 //connection can continue normally
Sergunb 0:8918a71cdbe9 370 if(description == TLS_ALERT_CLOSE_NOTIFY)
Sergunb 0:8918a71cdbe9 371 {
Sergunb 0:8918a71cdbe9 372 //Either party may initiate a close by sending a close_notify alert
Sergunb 0:8918a71cdbe9 373 context->closeNotifySent = TRUE;
Sergunb 0:8918a71cdbe9 374
Sergunb 0:8918a71cdbe9 375 //Update FSM state
Sergunb 0:8918a71cdbe9 376 context->state = TLS_STATE_CLOSING;
Sergunb 0:8918a71cdbe9 377 }
Sergunb 0:8918a71cdbe9 378 }
Sergunb 0:8918a71cdbe9 379 else if(level == TLS_ALERT_LEVEL_FATAL)
Sergunb 0:8918a71cdbe9 380 {
Sergunb 0:8918a71cdbe9 381 //Alert messages with a level of fatal result in the immediate
Sergunb 0:8918a71cdbe9 382 //termination of the connection
Sergunb 0:8918a71cdbe9 383 context->fatalAlertSent = TRUE;
Sergunb 0:8918a71cdbe9 384
Sergunb 0:8918a71cdbe9 385 //Any connection terminated with a fatal alert must not be resumed
Sergunb 0:8918a71cdbe9 386 if(context->entity == TLS_CONNECTION_END_SERVER)
Sergunb 0:8918a71cdbe9 387 tlsRemoveFromCache(context);
Sergunb 0:8918a71cdbe9 388
Sergunb 0:8918a71cdbe9 389 //Servers and clients must forget any session identifiers
Sergunb 0:8918a71cdbe9 390 memset(context->sessionId, 0, 32);
Sergunb 0:8918a71cdbe9 391 context->sessionIdLen = 0;
Sergunb 0:8918a71cdbe9 392
Sergunb 0:8918a71cdbe9 393 //Update FSM state
Sergunb 0:8918a71cdbe9 394 context->state = TLS_STATE_CLOSING;
Sergunb 0:8918a71cdbe9 395 }
Sergunb 0:8918a71cdbe9 396
Sergunb 0:8918a71cdbe9 397 //Return status code
Sergunb 0:8918a71cdbe9 398 return error;
Sergunb 0:8918a71cdbe9 399 }
Sergunb 0:8918a71cdbe9 400
Sergunb 0:8918a71cdbe9 401
Sergunb 0:8918a71cdbe9 402 /**
Sergunb 0:8918a71cdbe9 403 * @brief Format Certificate message
Sergunb 0:8918a71cdbe9 404 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 405 * @param[out] message Buffer where to format the Certificate message
Sergunb 0:8918a71cdbe9 406 * @param[out] length Length of the resulting Certificate message
Sergunb 0:8918a71cdbe9 407 * @return Error code
Sergunb 0:8918a71cdbe9 408 **/
Sergunb 0:8918a71cdbe9 409
Sergunb 0:8918a71cdbe9 410 error_t tlsFormatCertificate(TlsContext *context,
Sergunb 0:8918a71cdbe9 411 TlsCertificate *message, size_t *length)
Sergunb 0:8918a71cdbe9 412 {
Sergunb 0:8918a71cdbe9 413 error_t error;
Sergunb 0:8918a71cdbe9 414 uint8_t *p;
Sergunb 0:8918a71cdbe9 415 const char_t *pemCert;
Sergunb 0:8918a71cdbe9 416 size_t pemCertLength;
Sergunb 0:8918a71cdbe9 417 uint8_t *derCert;
Sergunb 0:8918a71cdbe9 418 size_t derCertSize;
Sergunb 0:8918a71cdbe9 419 size_t derCertLength;
Sergunb 0:8918a71cdbe9 420
Sergunb 0:8918a71cdbe9 421 //Initialize status code
Sergunb 0:8918a71cdbe9 422 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 423
Sergunb 0:8918a71cdbe9 424 //Handshake message type
Sergunb 0:8918a71cdbe9 425 message->msgType = TLS_TYPE_CERTIFICATE;
Sergunb 0:8918a71cdbe9 426
Sergunb 0:8918a71cdbe9 427 //Point to the first certificate of the list
Sergunb 0:8918a71cdbe9 428 p = message->certificateList;
Sergunb 0:8918a71cdbe9 429 //Length of the certificate list in bytes
Sergunb 0:8918a71cdbe9 430 *length = 0;
Sergunb 0:8918a71cdbe9 431
Sergunb 0:8918a71cdbe9 432 //Check whether a certificate is available
Sergunb 0:8918a71cdbe9 433 if(context->cert != NULL)
Sergunb 0:8918a71cdbe9 434 {
Sergunb 0:8918a71cdbe9 435 //Point to the certificate chain
Sergunb 0:8918a71cdbe9 436 pemCert = context->cert->certChain;
Sergunb 0:8918a71cdbe9 437 //Get the total length, in bytes, of the certificate chain
Sergunb 0:8918a71cdbe9 438 pemCertLength = context->cert->certChainLength;
Sergunb 0:8918a71cdbe9 439 }
Sergunb 0:8918a71cdbe9 440 else
Sergunb 0:8918a71cdbe9 441 {
Sergunb 0:8918a71cdbe9 442 //If no suitable certificate is available, the message
Sergunb 0:8918a71cdbe9 443 //contains an empty certificate list
Sergunb 0:8918a71cdbe9 444 pemCert = NULL;
Sergunb 0:8918a71cdbe9 445 pemCertLength = 0;
Sergunb 0:8918a71cdbe9 446 }
Sergunb 0:8918a71cdbe9 447
Sergunb 0:8918a71cdbe9 448 //DER encoded certificate
Sergunb 0:8918a71cdbe9 449 derCert = NULL;
Sergunb 0:8918a71cdbe9 450 derCertSize = 0;
Sergunb 0:8918a71cdbe9 451 derCertLength = 0;
Sergunb 0:8918a71cdbe9 452
Sergunb 0:8918a71cdbe9 453 //Parse the certificate chain
Sergunb 0:8918a71cdbe9 454 while(pemCertLength > 0)
Sergunb 0:8918a71cdbe9 455 {
Sergunb 0:8918a71cdbe9 456 //Decode PEM certificate
Sergunb 0:8918a71cdbe9 457 error = pemReadCertificate(&pemCert, &pemCertLength,
Sergunb 0:8918a71cdbe9 458 &derCert, &derCertSize, &derCertLength);
Sergunb 0:8918a71cdbe9 459
Sergunb 0:8918a71cdbe9 460 //Any error to report?
Sergunb 0:8918a71cdbe9 461 if(error)
Sergunb 0:8918a71cdbe9 462 {
Sergunb 0:8918a71cdbe9 463 //End of file detected
Sergunb 0:8918a71cdbe9 464 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 465 break;
Sergunb 0:8918a71cdbe9 466 }
Sergunb 0:8918a71cdbe9 467
Sergunb 0:8918a71cdbe9 468 //Total length of the certificate list
Sergunb 0:8918a71cdbe9 469 *length += derCertLength + 3;
Sergunb 0:8918a71cdbe9 470
Sergunb 0:8918a71cdbe9 471 //Prevent the buffer from overflowing
Sergunb 0:8918a71cdbe9 472 if((*length + sizeof(TlsCertificate)) > context->txRecordMaxLen)
Sergunb 0:8918a71cdbe9 473 {
Sergunb 0:8918a71cdbe9 474 //Report an error
Sergunb 0:8918a71cdbe9 475 error = ERROR_MESSAGE_TOO_LONG;
Sergunb 0:8918a71cdbe9 476 break;
Sergunb 0:8918a71cdbe9 477 }
Sergunb 0:8918a71cdbe9 478
Sergunb 0:8918a71cdbe9 479 //Each certificate is preceded by a 3-byte length field
Sergunb 0:8918a71cdbe9 480 STORE24BE(derCertLength, p);
Sergunb 0:8918a71cdbe9 481 //Copy the current certificate
Sergunb 0:8918a71cdbe9 482 memcpy(p + 3, derCert, derCertLength);
Sergunb 0:8918a71cdbe9 483
Sergunb 0:8918a71cdbe9 484 //Advance data pointer
Sergunb 0:8918a71cdbe9 485 p += derCertLength + 3;
Sergunb 0:8918a71cdbe9 486 }
Sergunb 0:8918a71cdbe9 487
Sergunb 0:8918a71cdbe9 488 //Free previously allocated memory
Sergunb 0:8918a71cdbe9 489 tlsFreeMem(derCert);
Sergunb 0:8918a71cdbe9 490
Sergunb 0:8918a71cdbe9 491 //A 3-byte length field shall precede the certificate list
Sergunb 0:8918a71cdbe9 492 STORE24BE(*length, message->certificateListLength);
Sergunb 0:8918a71cdbe9 493 //Consider the 3-byte length field
Sergunb 0:8918a71cdbe9 494 *length += 3;
Sergunb 0:8918a71cdbe9 495
Sergunb 0:8918a71cdbe9 496 //Fix the length field
Sergunb 0:8918a71cdbe9 497 STORE24BE(*length, message->length);
Sergunb 0:8918a71cdbe9 498 //Length of the complete handshake message
Sergunb 0:8918a71cdbe9 499 *length += sizeof(TlsHandshake);
Sergunb 0:8918a71cdbe9 500
Sergunb 0:8918a71cdbe9 501 //Return status code
Sergunb 0:8918a71cdbe9 502 return error;
Sergunb 0:8918a71cdbe9 503 }
Sergunb 0:8918a71cdbe9 504
Sergunb 0:8918a71cdbe9 505
Sergunb 0:8918a71cdbe9 506 /**
Sergunb 0:8918a71cdbe9 507 * @brief Format ChangeCipherSpec message
Sergunb 0:8918a71cdbe9 508 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 509 * @param[out] message Buffer where to format the ChangeCipherSpec message
Sergunb 0:8918a71cdbe9 510 * @param[out] length Length of the resulting ChangeCipherSpec message
Sergunb 0:8918a71cdbe9 511 * @return Error code
Sergunb 0:8918a71cdbe9 512 **/
Sergunb 0:8918a71cdbe9 513
Sergunb 0:8918a71cdbe9 514 error_t tlsFormatChangeCipherSpec(TlsContext *context,
Sergunb 0:8918a71cdbe9 515 TlsChangeCipherSpec *message, size_t *length)
Sergunb 0:8918a71cdbe9 516 {
Sergunb 0:8918a71cdbe9 517 //The ChangeCipherSpec message consists of a single byte of value 1
Sergunb 0:8918a71cdbe9 518 message->type = 1;
Sergunb 0:8918a71cdbe9 519
Sergunb 0:8918a71cdbe9 520 //Length of the ChangeCipherSpec message
Sergunb 0:8918a71cdbe9 521 *length = sizeof(TlsChangeCipherSpec);
Sergunb 0:8918a71cdbe9 522
Sergunb 0:8918a71cdbe9 523 //Successful processing
Sergunb 0:8918a71cdbe9 524 return NO_ERROR;
Sergunb 0:8918a71cdbe9 525 }
Sergunb 0:8918a71cdbe9 526
Sergunb 0:8918a71cdbe9 527
Sergunb 0:8918a71cdbe9 528 /**
Sergunb 0:8918a71cdbe9 529 * @brief Format Finished message
Sergunb 0:8918a71cdbe9 530 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 531 * @param[out] message Buffer where to format the Finished message
Sergunb 0:8918a71cdbe9 532 * @param[out] length Length of the resulting Finished message
Sergunb 0:8918a71cdbe9 533 * @return Error code
Sergunb 0:8918a71cdbe9 534 **/
Sergunb 0:8918a71cdbe9 535
Sergunb 0:8918a71cdbe9 536 error_t tlsFormatFinished(TlsContext *context,
Sergunb 0:8918a71cdbe9 537 TlsFinished *message, size_t *length)
Sergunb 0:8918a71cdbe9 538 {
Sergunb 0:8918a71cdbe9 539 //Handshake message type
Sergunb 0:8918a71cdbe9 540 message->msgType = TLS_TYPE_FINISHED;
Sergunb 0:8918a71cdbe9 541
Sergunb 0:8918a71cdbe9 542 //The length of the verify data depends on the cipher suite
Sergunb 0:8918a71cdbe9 543 STORE24BE(context->verifyDataLen, message->length);
Sergunb 0:8918a71cdbe9 544
Sergunb 0:8918a71cdbe9 545 //Copy the verify data
Sergunb 0:8918a71cdbe9 546 memcpy(message->verifyData, context->verifyData, context->verifyDataLen);
Sergunb 0:8918a71cdbe9 547
Sergunb 0:8918a71cdbe9 548 //Length of the complete handshake message
Sergunb 0:8918a71cdbe9 549 *length = context->verifyDataLen + sizeof(TlsHandshake);
Sergunb 0:8918a71cdbe9 550
Sergunb 0:8918a71cdbe9 551 //Successful processing
Sergunb 0:8918a71cdbe9 552 return NO_ERROR;
Sergunb 0:8918a71cdbe9 553 }
Sergunb 0:8918a71cdbe9 554
Sergunb 0:8918a71cdbe9 555
Sergunb 0:8918a71cdbe9 556 /**
Sergunb 0:8918a71cdbe9 557 * @brief Format Alert message
Sergunb 0:8918a71cdbe9 558 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 559 * @param[in] level Severity of the message (warning or fatal)
Sergunb 0:8918a71cdbe9 560 * @param[in] description Description of the alert
Sergunb 0:8918a71cdbe9 561 * @param[out] message Buffer where to format the Alert message
Sergunb 0:8918a71cdbe9 562 * @param[out] length Length of the resulting Alert message
Sergunb 0:8918a71cdbe9 563 * @return Error code
Sergunb 0:8918a71cdbe9 564 **/
Sergunb 0:8918a71cdbe9 565
Sergunb 0:8918a71cdbe9 566 error_t tlsFormatAlert(TlsContext *context, uint8_t level,
Sergunb 0:8918a71cdbe9 567 uint8_t description, TlsAlert *message, size_t *length)
Sergunb 0:8918a71cdbe9 568 {
Sergunb 0:8918a71cdbe9 569 //Severity of the message
Sergunb 0:8918a71cdbe9 570 message->level = level;
Sergunb 0:8918a71cdbe9 571 //Description of the alert
Sergunb 0:8918a71cdbe9 572 message->description = description;
Sergunb 0:8918a71cdbe9 573
Sergunb 0:8918a71cdbe9 574 //Length of the Alert message
Sergunb 0:8918a71cdbe9 575 *length = sizeof(TlsAlert);
Sergunb 0:8918a71cdbe9 576
Sergunb 0:8918a71cdbe9 577 //Successful processing
Sergunb 0:8918a71cdbe9 578 return NO_ERROR;
Sergunb 0:8918a71cdbe9 579 }
Sergunb 0:8918a71cdbe9 580
Sergunb 0:8918a71cdbe9 581
Sergunb 0:8918a71cdbe9 582 /**
Sergunb 0:8918a71cdbe9 583 * @brief Parse Certificate message
Sergunb 0:8918a71cdbe9 584 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 585 * @param[in] message Incoming Certificate message to parse
Sergunb 0:8918a71cdbe9 586 * @param[in] length Message length
Sergunb 0:8918a71cdbe9 587 * @return Error code
Sergunb 0:8918a71cdbe9 588 **/
Sergunb 0:8918a71cdbe9 589
Sergunb 0:8918a71cdbe9 590 error_t tlsParseCertificate(TlsContext *context, const TlsCertificate *message, size_t length)
Sergunb 0:8918a71cdbe9 591 {
Sergunb 0:8918a71cdbe9 592 error_t error;
Sergunb 0:8918a71cdbe9 593 const uint8_t *p;
Sergunb 0:8918a71cdbe9 594 size_t n;
Sergunb 0:8918a71cdbe9 595 const char_t *pemCert;
Sergunb 0:8918a71cdbe9 596 size_t pemCertLength;
Sergunb 0:8918a71cdbe9 597 uint8_t *derCert;
Sergunb 0:8918a71cdbe9 598 size_t derCertSize;
Sergunb 0:8918a71cdbe9 599 size_t derCertLength;
Sergunb 0:8918a71cdbe9 600
Sergunb 0:8918a71cdbe9 601 //X.509 certificates
Sergunb 0:8918a71cdbe9 602 X509CertificateInfo *certInfo = NULL;
Sergunb 0:8918a71cdbe9 603 X509CertificateInfo *issuerCertInfo = NULL;
Sergunb 0:8918a71cdbe9 604
Sergunb 0:8918a71cdbe9 605 //Debug message
Sergunb 0:8918a71cdbe9 606 TRACE_INFO("Certificate message received (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 607 TRACE_DEBUG_ARRAY(" ", message, length);
Sergunb 0:8918a71cdbe9 608
Sergunb 0:8918a71cdbe9 609 //Check the length of the Certificate message
Sergunb 0:8918a71cdbe9 610 if(length < sizeof(TlsCertificate))
Sergunb 0:8918a71cdbe9 611 return ERROR_DECODING_FAILED;
Sergunb 0:8918a71cdbe9 612
Sergunb 0:8918a71cdbe9 613 //TLS operates as a client or a server?
Sergunb 0:8918a71cdbe9 614 if(context->entity == TLS_CONNECTION_END_CLIENT)
Sergunb 0:8918a71cdbe9 615 {
Sergunb 0:8918a71cdbe9 616 //Check current state
Sergunb 0:8918a71cdbe9 617 if(context->state != TLS_STATE_SERVER_CERTIFICATE)
Sergunb 0:8918a71cdbe9 618 return ERROR_UNEXPECTED_MESSAGE;
Sergunb 0:8918a71cdbe9 619 }
Sergunb 0:8918a71cdbe9 620 else
Sergunb 0:8918a71cdbe9 621 {
Sergunb 0:8918a71cdbe9 622 //Check current state
Sergunb 0:8918a71cdbe9 623 if(context->state != TLS_STATE_CLIENT_CERTIFICATE)
Sergunb 0:8918a71cdbe9 624 return ERROR_UNEXPECTED_MESSAGE;
Sergunb 0:8918a71cdbe9 625 }
Sergunb 0:8918a71cdbe9 626
Sergunb 0:8918a71cdbe9 627 //Update the hash value with the incoming handshake message
Sergunb 0:8918a71cdbe9 628 tlsUpdateHandshakeHash(context, message, length);
Sergunb 0:8918a71cdbe9 629
Sergunb 0:8918a71cdbe9 630 //Get the size occupied by the certificate list
Sergunb 0:8918a71cdbe9 631 n = LOAD24BE(message->certificateListLength);
Sergunb 0:8918a71cdbe9 632 //Remaining bytes to process
Sergunb 0:8918a71cdbe9 633 length -= sizeof(TlsCertificate);
Sergunb 0:8918a71cdbe9 634
Sergunb 0:8918a71cdbe9 635 //Ensure that the chain of certificates is valid
Sergunb 0:8918a71cdbe9 636 if(n > length)
Sergunb 0:8918a71cdbe9 637 return ERROR_DECODING_FAILED;
Sergunb 0:8918a71cdbe9 638
Sergunb 0:8918a71cdbe9 639 //Compute the length of the certificate list
Sergunb 0:8918a71cdbe9 640 length = n;
Sergunb 0:8918a71cdbe9 641
Sergunb 0:8918a71cdbe9 642 //The sender's certificate must come first in the list
Sergunb 0:8918a71cdbe9 643 p = message->certificateList;
Sergunb 0:8918a71cdbe9 644
Sergunb 0:8918a71cdbe9 645 //Start of exception handling block
Sergunb 0:8918a71cdbe9 646 do
Sergunb 0:8918a71cdbe9 647 {
Sergunb 0:8918a71cdbe9 648 //Assume an error...
Sergunb 0:8918a71cdbe9 649 error = ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 650
Sergunb 0:8918a71cdbe9 651 //Allocate a memory buffer to store X.509 certificate info
Sergunb 0:8918a71cdbe9 652 certInfo = tlsAllocMem(sizeof(X509CertificateInfo));
Sergunb 0:8918a71cdbe9 653 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 654 if(certInfo == NULL)
Sergunb 0:8918a71cdbe9 655 break;
Sergunb 0:8918a71cdbe9 656
Sergunb 0:8918a71cdbe9 657 //Allocate a memory buffer to store the parent certificate
Sergunb 0:8918a71cdbe9 658 issuerCertInfo = tlsAllocMem(sizeof(X509CertificateInfo));
Sergunb 0:8918a71cdbe9 659 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 660 if(issuerCertInfo == NULL)
Sergunb 0:8918a71cdbe9 661 break;
Sergunb 0:8918a71cdbe9 662
Sergunb 0:8918a71cdbe9 663 //TLS operates as a server?
Sergunb 0:8918a71cdbe9 664 if(context->entity == TLS_CONNECTION_END_SERVER)
Sergunb 0:8918a71cdbe9 665 {
Sergunb 0:8918a71cdbe9 666 //Empty certificate list?
Sergunb 0:8918a71cdbe9 667 if(!length)
Sergunb 0:8918a71cdbe9 668 {
Sergunb 0:8918a71cdbe9 669 //Check whether mutual authentication is required
Sergunb 0:8918a71cdbe9 670 if(context->clientAuthMode == TLS_CLIENT_AUTH_REQUIRED)
Sergunb 0:8918a71cdbe9 671 {
Sergunb 0:8918a71cdbe9 672 //If client authentication is required by the server for the handshake
Sergunb 0:8918a71cdbe9 673 //to continue, it may respond with a fatal handshake failure alert
Sergunb 0:8918a71cdbe9 674 error = ERROR_HANDSHAKE_FAILED;
Sergunb 0:8918a71cdbe9 675 break;
Sergunb 0:8918a71cdbe9 676 }
Sergunb 0:8918a71cdbe9 677 else
Sergunb 0:8918a71cdbe9 678 {
Sergunb 0:8918a71cdbe9 679 //Client authentication is optional
Sergunb 0:8918a71cdbe9 680 context->peerCertType = TLS_CERT_NONE;
Sergunb 0:8918a71cdbe9 681 //Exit immediately
Sergunb 0:8918a71cdbe9 682 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 683 break;
Sergunb 0:8918a71cdbe9 684 }
Sergunb 0:8918a71cdbe9 685 }
Sergunb 0:8918a71cdbe9 686 }
Sergunb 0:8918a71cdbe9 687
Sergunb 0:8918a71cdbe9 688 //Each certificate is preceded by a 3-byte length field
Sergunb 0:8918a71cdbe9 689 if(length < 3)
Sergunb 0:8918a71cdbe9 690 {
Sergunb 0:8918a71cdbe9 691 //Report an error
Sergunb 0:8918a71cdbe9 692 error = ERROR_DECODING_FAILED;
Sergunb 0:8918a71cdbe9 693 break;
Sergunb 0:8918a71cdbe9 694 }
Sergunb 0:8918a71cdbe9 695
Sergunb 0:8918a71cdbe9 696 //Get the size occupied by the certificate
Sergunb 0:8918a71cdbe9 697 n = LOAD24BE(p);
Sergunb 0:8918a71cdbe9 698 //Jump to the beginning of the DER encoded certificate
Sergunb 0:8918a71cdbe9 699 p += 3;
Sergunb 0:8918a71cdbe9 700 length -= 3;
Sergunb 0:8918a71cdbe9 701
Sergunb 0:8918a71cdbe9 702 //Make sure that the certificate is valid
Sergunb 0:8918a71cdbe9 703 if(n > length)
Sergunb 0:8918a71cdbe9 704 {
Sergunb 0:8918a71cdbe9 705 //Report an error
Sergunb 0:8918a71cdbe9 706 error = ERROR_DECODING_FAILED;
Sergunb 0:8918a71cdbe9 707 break;
Sergunb 0:8918a71cdbe9 708 }
Sergunb 0:8918a71cdbe9 709
Sergunb 0:8918a71cdbe9 710 //Display ASN.1 structure
Sergunb 0:8918a71cdbe9 711 error = asn1DumpObject(p, n, 0);
Sergunb 0:8918a71cdbe9 712 //Any error to report?
Sergunb 0:8918a71cdbe9 713 if(error)
Sergunb 0:8918a71cdbe9 714 break;
Sergunb 0:8918a71cdbe9 715
Sergunb 0:8918a71cdbe9 716 //Parse X.509 certificate
Sergunb 0:8918a71cdbe9 717 error = x509ParseCertificate(p, n, certInfo);
Sergunb 0:8918a71cdbe9 718 //Failed to parse the X.509 certificate?
Sergunb 0:8918a71cdbe9 719 if(error)
Sergunb 0:8918a71cdbe9 720 break;
Sergunb 0:8918a71cdbe9 721
Sergunb 0:8918a71cdbe9 722 #if (TLS_CLIENT_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 723 //TLS operates as a client?
Sergunb 0:8918a71cdbe9 724 if(context->entity == TLS_CONNECTION_END_CLIENT)
Sergunb 0:8918a71cdbe9 725 {
Sergunb 0:8918a71cdbe9 726 //Check if the hostname must be verified
Sergunb 0:8918a71cdbe9 727 if(context->serverName != NULL)
Sergunb 0:8918a71cdbe9 728 {
Sergunb 0:8918a71cdbe9 729 int_t i;
Sergunb 0:8918a71cdbe9 730 int_t j;
Sergunb 0:8918a71cdbe9 731
Sergunb 0:8918a71cdbe9 732 //Point to the last character of the common name
Sergunb 0:8918a71cdbe9 733 i = certInfo->subject.commonNameLen - 1;
Sergunb 0:8918a71cdbe9 734 //Point to the last character of the hostname
Sergunb 0:8918a71cdbe9 735 j = strlen(context->serverName) - 1;
Sergunb 0:8918a71cdbe9 736
Sergunb 0:8918a71cdbe9 737 //Check the common name in the server certificate against
Sergunb 0:8918a71cdbe9 738 //the actual hostname that is being requested
Sergunb 0:8918a71cdbe9 739 while(i >= 0 && j >= 0)
Sergunb 0:8918a71cdbe9 740 {
Sergunb 0:8918a71cdbe9 741 //Wildcard certificate found?
Sergunb 0:8918a71cdbe9 742 if(certInfo->subject.commonName[i] == '*' && i == 0)
Sergunb 0:8918a71cdbe9 743 {
Sergunb 0:8918a71cdbe9 744 //The CN is acceptable
Sergunb 0:8918a71cdbe9 745 j = 0;
Sergunb 0:8918a71cdbe9 746 }
Sergunb 0:8918a71cdbe9 747 //Perform case insensitive character comparison
Sergunb 0:8918a71cdbe9 748 else if(tolower((uint8_t) certInfo->subject.commonName[i]) != context->serverName[j])
Sergunb 0:8918a71cdbe9 749 {
Sergunb 0:8918a71cdbe9 750 break;
Sergunb 0:8918a71cdbe9 751 }
Sergunb 0:8918a71cdbe9 752
Sergunb 0:8918a71cdbe9 753 //Compare previous characters
Sergunb 0:8918a71cdbe9 754 i--;
Sergunb 0:8918a71cdbe9 755 j--;
Sergunb 0:8918a71cdbe9 756 }
Sergunb 0:8918a71cdbe9 757
Sergunb 0:8918a71cdbe9 758 //If the host names do not match, reject the certificate
Sergunb 0:8918a71cdbe9 759 if(i >= 0 || j >= 0)
Sergunb 0:8918a71cdbe9 760 {
Sergunb 0:8918a71cdbe9 761 //Debug message
Sergunb 0:8918a71cdbe9 762 TRACE_WARNING("Server name mismatch!\r\n");
Sergunb 0:8918a71cdbe9 763 //Report an error
Sergunb 0:8918a71cdbe9 764 error = ERROR_BAD_CERTIFICATE;
Sergunb 0:8918a71cdbe9 765 break;
Sergunb 0:8918a71cdbe9 766 }
Sergunb 0:8918a71cdbe9 767 }
Sergunb 0:8918a71cdbe9 768 }
Sergunb 0:8918a71cdbe9 769 #endif
Sergunb 0:8918a71cdbe9 770
Sergunb 0:8918a71cdbe9 771 #if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_RSA_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 772 TLS_DHE_RSA_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 773 //The certificate contains a valid RSA public key?
Sergunb 0:8918a71cdbe9 774 if(!oidComp(certInfo->subjectPublicKeyInfo.oid, certInfo->subjectPublicKeyInfo.oidLen,
Sergunb 0:8918a71cdbe9 775 RSA_ENCRYPTION_OID, sizeof(RSA_ENCRYPTION_OID)))
Sergunb 0:8918a71cdbe9 776 {
Sergunb 0:8918a71cdbe9 777 uint_t k;
Sergunb 0:8918a71cdbe9 778
Sergunb 0:8918a71cdbe9 779 //Retrieve the RSA public key
Sergunb 0:8918a71cdbe9 780 error = x509ReadRsaPublicKey(certInfo, &context->peerRsaPublicKey);
Sergunb 0:8918a71cdbe9 781 //Any error to report
Sergunb 0:8918a71cdbe9 782 if(error)
Sergunb 0:8918a71cdbe9 783 break;
Sergunb 0:8918a71cdbe9 784
Sergunb 0:8918a71cdbe9 785 //Get the length of the modulus, in bits
Sergunb 0:8918a71cdbe9 786 k = mpiGetBitLength(&context->peerRsaPublicKey.n);
Sergunb 0:8918a71cdbe9 787
Sergunb 0:8918a71cdbe9 788 //Make sure the modulus is acceptable
Sergunb 0:8918a71cdbe9 789 if(k < TLS_MIN_RSA_MODULUS_SIZE || k > TLS_MAX_RSA_MODULUS_SIZE)
Sergunb 0:8918a71cdbe9 790 {
Sergunb 0:8918a71cdbe9 791 //Report an error
Sergunb 0:8918a71cdbe9 792 error = ERROR_BAD_CERTIFICATE;
Sergunb 0:8918a71cdbe9 793 break;
Sergunb 0:8918a71cdbe9 794 }
Sergunb 0:8918a71cdbe9 795
Sergunb 0:8918a71cdbe9 796 //Save the certificate type
Sergunb 0:8918a71cdbe9 797 context->peerCertType = TLS_CERT_RSA_SIGN;
Sergunb 0:8918a71cdbe9 798 }
Sergunb 0:8918a71cdbe9 799 else
Sergunb 0:8918a71cdbe9 800 #endif
Sergunb 0:8918a71cdbe9 801 #if (TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_DHE_DSS_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 802 //The certificate contains a valid DSA public key?
Sergunb 0:8918a71cdbe9 803 if(!oidComp(certInfo->subjectPublicKeyInfo.oid, certInfo->subjectPublicKeyInfo.oidLen,
Sergunb 0:8918a71cdbe9 804 DSA_OID, sizeof(DSA_OID)))
Sergunb 0:8918a71cdbe9 805 {
Sergunb 0:8918a71cdbe9 806 uint_t k;
Sergunb 0:8918a71cdbe9 807
Sergunb 0:8918a71cdbe9 808 //Retrieve the DSA public key
Sergunb 0:8918a71cdbe9 809 error = x509ReadDsaPublicKey(certInfo, &context->peerDsaPublicKey);
Sergunb 0:8918a71cdbe9 810 //Any error to report
Sergunb 0:8918a71cdbe9 811 if(error)
Sergunb 0:8918a71cdbe9 812 break;
Sergunb 0:8918a71cdbe9 813
Sergunb 0:8918a71cdbe9 814 //Get the length of the prime modulus, in bits
Sergunb 0:8918a71cdbe9 815 k = mpiGetBitLength(&context->peerDsaPublicKey.p);
Sergunb 0:8918a71cdbe9 816
Sergunb 0:8918a71cdbe9 817 //Make sure the prime modulus is acceptable
Sergunb 0:8918a71cdbe9 818 if(k < TLS_MIN_DSA_MODULUS_SIZE || k > TLS_MAX_DSA_MODULUS_SIZE)
Sergunb 0:8918a71cdbe9 819 {
Sergunb 0:8918a71cdbe9 820 //Report an error
Sergunb 0:8918a71cdbe9 821 error = ERROR_BAD_CERTIFICATE;
Sergunb 0:8918a71cdbe9 822 break;
Sergunb 0:8918a71cdbe9 823 }
Sergunb 0:8918a71cdbe9 824
Sergunb 0:8918a71cdbe9 825 //Save the certificate type
Sergunb 0:8918a71cdbe9 826 context->peerCertType = TLS_CERT_DSS_SIGN;
Sergunb 0:8918a71cdbe9 827 }
Sergunb 0:8918a71cdbe9 828 else
Sergunb 0:8918a71cdbe9 829 #endif
Sergunb 0:8918a71cdbe9 830 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_ECDHE_ECDSA_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 831 //The certificate contains a valid EC public key?
Sergunb 0:8918a71cdbe9 832 if(!oidComp(certInfo->subjectPublicKeyInfo.oid, certInfo->subjectPublicKeyInfo.oidLen,
Sergunb 0:8918a71cdbe9 833 EC_PUBLIC_KEY_OID, sizeof(EC_PUBLIC_KEY_OID)))
Sergunb 0:8918a71cdbe9 834 {
Sergunb 0:8918a71cdbe9 835 const EcCurveInfo *curveInfo;
Sergunb 0:8918a71cdbe9 836
Sergunb 0:8918a71cdbe9 837 //Retrieve EC domain parameters
Sergunb 0:8918a71cdbe9 838 curveInfo = ecGetCurveInfo(certInfo->subjectPublicKeyInfo.ecParams.namedCurve,
Sergunb 0:8918a71cdbe9 839 certInfo->subjectPublicKeyInfo.ecParams.namedCurveLen);
Sergunb 0:8918a71cdbe9 840
Sergunb 0:8918a71cdbe9 841 //Make sure the specified elliptic curve is supported
Sergunb 0:8918a71cdbe9 842 if(curveInfo == NULL)
Sergunb 0:8918a71cdbe9 843 {
Sergunb 0:8918a71cdbe9 844 //Report an error
Sergunb 0:8918a71cdbe9 845 error = ERROR_BAD_CERTIFICATE;
Sergunb 0:8918a71cdbe9 846 //Exit immediately
Sergunb 0:8918a71cdbe9 847 break;
Sergunb 0:8918a71cdbe9 848 }
Sergunb 0:8918a71cdbe9 849
Sergunb 0:8918a71cdbe9 850 //Load EC domain parameters
Sergunb 0:8918a71cdbe9 851 error = ecLoadDomainParameters(&context->peerEcParams, curveInfo);
Sergunb 0:8918a71cdbe9 852 //Any error to report?
Sergunb 0:8918a71cdbe9 853 if(error)
Sergunb 0:8918a71cdbe9 854 break;
Sergunb 0:8918a71cdbe9 855
Sergunb 0:8918a71cdbe9 856 //Retrieve the EC public key
Sergunb 0:8918a71cdbe9 857 error = ecImport(&context->peerEcParams, &context->peerEcPublicKey,
Sergunb 0:8918a71cdbe9 858 certInfo->subjectPublicKeyInfo.ecPublicKey.q, certInfo->subjectPublicKeyInfo.ecPublicKey.qLen);
Sergunb 0:8918a71cdbe9 859 //Any error to report
Sergunb 0:8918a71cdbe9 860 if(error)
Sergunb 0:8918a71cdbe9 861 break;
Sergunb 0:8918a71cdbe9 862
Sergunb 0:8918a71cdbe9 863 //Save the certificate type
Sergunb 0:8918a71cdbe9 864 context->peerCertType = TLS_CERT_ECDSA_SIGN;
Sergunb 0:8918a71cdbe9 865 }
Sergunb 0:8918a71cdbe9 866 else
Sergunb 0:8918a71cdbe9 867 #endif
Sergunb 0:8918a71cdbe9 868 //The certificate does not contain any valid public key?
Sergunb 0:8918a71cdbe9 869 {
Sergunb 0:8918a71cdbe9 870 //Report an error
Sergunb 0:8918a71cdbe9 871 error = ERROR_BAD_CERTIFICATE;
Sergunb 0:8918a71cdbe9 872 break;
Sergunb 0:8918a71cdbe9 873 }
Sergunb 0:8918a71cdbe9 874
Sergunb 0:8918a71cdbe9 875 //Next certificate
Sergunb 0:8918a71cdbe9 876 p += n;
Sergunb 0:8918a71cdbe9 877 length -= n;
Sergunb 0:8918a71cdbe9 878
Sergunb 0:8918a71cdbe9 879 //PKIX path validation
Sergunb 0:8918a71cdbe9 880 while(length > 0)
Sergunb 0:8918a71cdbe9 881 {
Sergunb 0:8918a71cdbe9 882 //Each certificate is preceded by a 3-byte length field
Sergunb 0:8918a71cdbe9 883 if(length < 3)
Sergunb 0:8918a71cdbe9 884 {
Sergunb 0:8918a71cdbe9 885 //Report an error
Sergunb 0:8918a71cdbe9 886 error = ERROR_DECODING_FAILED;
Sergunb 0:8918a71cdbe9 887 break;
Sergunb 0:8918a71cdbe9 888 }
Sergunb 0:8918a71cdbe9 889
Sergunb 0:8918a71cdbe9 890 //Get the size occupied by the certificate
Sergunb 0:8918a71cdbe9 891 n = LOAD24BE(p);
Sergunb 0:8918a71cdbe9 892 //Jump to the beginning of the DER encoded certificate
Sergunb 0:8918a71cdbe9 893 p += 3;
Sergunb 0:8918a71cdbe9 894 length -= 3;
Sergunb 0:8918a71cdbe9 895
Sergunb 0:8918a71cdbe9 896 //Ensure that the certificate is valid
Sergunb 0:8918a71cdbe9 897 if(n > length)
Sergunb 0:8918a71cdbe9 898 {
Sergunb 0:8918a71cdbe9 899 //Report an error
Sergunb 0:8918a71cdbe9 900 error = ERROR_DECODING_FAILED;
Sergunb 0:8918a71cdbe9 901 break;
Sergunb 0:8918a71cdbe9 902 }
Sergunb 0:8918a71cdbe9 903
Sergunb 0:8918a71cdbe9 904 //Display ASN.1 structure
Sergunb 0:8918a71cdbe9 905 error = asn1DumpObject(p, n, 0);
Sergunb 0:8918a71cdbe9 906 //Any error to report?
Sergunb 0:8918a71cdbe9 907 if(error)
Sergunb 0:8918a71cdbe9 908 break;
Sergunb 0:8918a71cdbe9 909
Sergunb 0:8918a71cdbe9 910 //Parse X.509 certificate
Sergunb 0:8918a71cdbe9 911 error = x509ParseCertificate(p, n, issuerCertInfo);
Sergunb 0:8918a71cdbe9 912 //Failed to parse the X.509 certificate?
Sergunb 0:8918a71cdbe9 913 if(error)
Sergunb 0:8918a71cdbe9 914 break;
Sergunb 0:8918a71cdbe9 915
Sergunb 0:8918a71cdbe9 916 //Valid trusted CA list?
Sergunb 0:8918a71cdbe9 917 if(context->trustedCaListLen > 0)
Sergunb 0:8918a71cdbe9 918 {
Sergunb 0:8918a71cdbe9 919 //Validate current certificate
Sergunb 0:8918a71cdbe9 920 error = x509ValidateCertificate(certInfo, issuerCertInfo);
Sergunb 0:8918a71cdbe9 921 //Certificate validation failed?
Sergunb 0:8918a71cdbe9 922 if(error)
Sergunb 0:8918a71cdbe9 923 break;
Sergunb 0:8918a71cdbe9 924 }
Sergunb 0:8918a71cdbe9 925
Sergunb 0:8918a71cdbe9 926 //Keep track of the issuer certificate
Sergunb 0:8918a71cdbe9 927 memcpy(certInfo, issuerCertInfo, sizeof(X509CertificateInfo));
Sergunb 0:8918a71cdbe9 928
Sergunb 0:8918a71cdbe9 929 //Next certificate
Sergunb 0:8918a71cdbe9 930 p += n;
Sergunb 0:8918a71cdbe9 931 length -= n;
Sergunb 0:8918a71cdbe9 932 }
Sergunb 0:8918a71cdbe9 933
Sergunb 0:8918a71cdbe9 934 //Propagate exception if necessary...
Sergunb 0:8918a71cdbe9 935 if(error)
Sergunb 0:8918a71cdbe9 936 break;
Sergunb 0:8918a71cdbe9 937
Sergunb 0:8918a71cdbe9 938 //Point to the first trusted CA certificate
Sergunb 0:8918a71cdbe9 939 pemCert = context->trustedCaList;
Sergunb 0:8918a71cdbe9 940 //Get the total length, in bytes, of the trusted CA list
Sergunb 0:8918a71cdbe9 941 pemCertLength = context->trustedCaListLen;
Sergunb 0:8918a71cdbe9 942
Sergunb 0:8918a71cdbe9 943 //DER encoded certificate
Sergunb 0:8918a71cdbe9 944 derCert = NULL;
Sergunb 0:8918a71cdbe9 945 derCertSize = 0;
Sergunb 0:8918a71cdbe9 946 derCertLength = 0;
Sergunb 0:8918a71cdbe9 947
Sergunb 0:8918a71cdbe9 948 //Loop through the list
Sergunb 0:8918a71cdbe9 949 while(pemCertLength > 0)
Sergunb 0:8918a71cdbe9 950 {
Sergunb 0:8918a71cdbe9 951 //Decode PEM certificate
Sergunb 0:8918a71cdbe9 952 error = pemReadCertificate(&pemCert, &pemCertLength,
Sergunb 0:8918a71cdbe9 953 &derCert, &derCertSize, &derCertLength);
Sergunb 0:8918a71cdbe9 954 //Any error to report?
Sergunb 0:8918a71cdbe9 955 if(error)
Sergunb 0:8918a71cdbe9 956 break;
Sergunb 0:8918a71cdbe9 957
Sergunb 0:8918a71cdbe9 958 //Parse X.509 certificate
Sergunb 0:8918a71cdbe9 959 error = x509ParseCertificate(derCert, derCertLength, issuerCertInfo);
Sergunb 0:8918a71cdbe9 960 //Failed to parse the X.509 certificate?
Sergunb 0:8918a71cdbe9 961 if(error)
Sergunb 0:8918a71cdbe9 962 break;
Sergunb 0:8918a71cdbe9 963
Sergunb 0:8918a71cdbe9 964 //Validate the certificate with the current trusted CA
Sergunb 0:8918a71cdbe9 965 error = x509ValidateCertificate(certInfo, issuerCertInfo);
Sergunb 0:8918a71cdbe9 966 //Certificate validation succeeded?
Sergunb 0:8918a71cdbe9 967 if(!error)
Sergunb 0:8918a71cdbe9 968 break;
Sergunb 0:8918a71cdbe9 969 }
Sergunb 0:8918a71cdbe9 970
Sergunb 0:8918a71cdbe9 971 //The certificate could not be matched with a known, trusted CA?
Sergunb 0:8918a71cdbe9 972 if(error == ERROR_END_OF_FILE)
Sergunb 0:8918a71cdbe9 973 error = ERROR_UNKNOWN_CA;
Sergunb 0:8918a71cdbe9 974
Sergunb 0:8918a71cdbe9 975 //Free previously allocated memory
Sergunb 0:8918a71cdbe9 976 tlsFreeMem(derCert);
Sergunb 0:8918a71cdbe9 977
Sergunb 0:8918a71cdbe9 978 //End of exception handling block
Sergunb 0:8918a71cdbe9 979 } while(0);
Sergunb 0:8918a71cdbe9 980
Sergunb 0:8918a71cdbe9 981 //Free previously allocated memory
Sergunb 0:8918a71cdbe9 982 tlsFreeMem(certInfo);
Sergunb 0:8918a71cdbe9 983 tlsFreeMem(issuerCertInfo);
Sergunb 0:8918a71cdbe9 984
Sergunb 0:8918a71cdbe9 985 //Clean up side effects
Sergunb 0:8918a71cdbe9 986 if(error)
Sergunb 0:8918a71cdbe9 987 {
Sergunb 0:8918a71cdbe9 988 #if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_RSA_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 989 TLS_DHE_RSA_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 990 //Release peer's RSA public key
Sergunb 0:8918a71cdbe9 991 rsaFreePublicKey(&context->peerRsaPublicKey);
Sergunb 0:8918a71cdbe9 992 #endif
Sergunb 0:8918a71cdbe9 993 #if (TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_DHE_DSS_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 994 //Release peer's DSA public key
Sergunb 0:8918a71cdbe9 995 dsaFreePublicKey(&context->peerDsaPublicKey);
Sergunb 0:8918a71cdbe9 996 #endif
Sergunb 0:8918a71cdbe9 997 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_ECDHE_ECDSA_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 998 //Release peer's EC domain parameters
Sergunb 0:8918a71cdbe9 999 ecFreeDomainParameters(&context->peerEcParams);
Sergunb 0:8918a71cdbe9 1000 //Release peer's EC public key
Sergunb 0:8918a71cdbe9 1001 ecFree(&context->peerEcPublicKey);
Sergunb 0:8918a71cdbe9 1002 #endif
Sergunb 0:8918a71cdbe9 1003 }
Sergunb 0:8918a71cdbe9 1004
Sergunb 0:8918a71cdbe9 1005 //TLS operates as a client or a server?
Sergunb 0:8918a71cdbe9 1006 if(context->entity == TLS_CONNECTION_END_CLIENT)
Sergunb 0:8918a71cdbe9 1007 {
Sergunb 0:8918a71cdbe9 1008 //Update FSM state
Sergunb 0:8918a71cdbe9 1009 if(context->keyExchMethod == TLS_KEY_EXCH_RSA)
Sergunb 0:8918a71cdbe9 1010 context->state = TLS_STATE_CERTIFICATE_REQUEST;
Sergunb 0:8918a71cdbe9 1011 else
Sergunb 0:8918a71cdbe9 1012 context->state = TLS_STATE_SERVER_KEY_EXCHANGE;
Sergunb 0:8918a71cdbe9 1013 }
Sergunb 0:8918a71cdbe9 1014 else
Sergunb 0:8918a71cdbe9 1015 {
Sergunb 0:8918a71cdbe9 1016 //Prepare to receive ClientKeyExchange message...
Sergunb 0:8918a71cdbe9 1017 context->state = TLS_STATE_CLIENT_KEY_EXCHANGE;
Sergunb 0:8918a71cdbe9 1018 }
Sergunb 0:8918a71cdbe9 1019
Sergunb 0:8918a71cdbe9 1020 //Return status code
Sergunb 0:8918a71cdbe9 1021 return error;
Sergunb 0:8918a71cdbe9 1022 }
Sergunb 0:8918a71cdbe9 1023
Sergunb 0:8918a71cdbe9 1024
Sergunb 0:8918a71cdbe9 1025 /**
Sergunb 0:8918a71cdbe9 1026 * @brief Parse ChangeCipherSpec message
Sergunb 0:8918a71cdbe9 1027 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 1028 * @param[in] message Incoming ChangeCipherSpec message to parse
Sergunb 0:8918a71cdbe9 1029 * @param[in] length Message length
Sergunb 0:8918a71cdbe9 1030 * @return Error code
Sergunb 0:8918a71cdbe9 1031 **/
Sergunb 0:8918a71cdbe9 1032
Sergunb 0:8918a71cdbe9 1033 error_t tlsParseChangeCipherSpec(TlsContext *context, const TlsChangeCipherSpec *message, size_t length)
Sergunb 0:8918a71cdbe9 1034 {
Sergunb 0:8918a71cdbe9 1035 error_t error;
Sergunb 0:8918a71cdbe9 1036
Sergunb 0:8918a71cdbe9 1037 //Debug message
Sergunb 0:8918a71cdbe9 1038 TRACE_INFO("ChangeCipherSpec message received (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 1039 TRACE_DEBUG_ARRAY(" ", message, length);
Sergunb 0:8918a71cdbe9 1040
Sergunb 0:8918a71cdbe9 1041 //Check the length of the ChangeCipherSpec message
Sergunb 0:8918a71cdbe9 1042 if(length < sizeof(TlsChangeCipherSpec))
Sergunb 0:8918a71cdbe9 1043 return ERROR_DECODING_FAILED;
Sergunb 0:8918a71cdbe9 1044
Sergunb 0:8918a71cdbe9 1045 //TLS operates as a client or a server?
Sergunb 0:8918a71cdbe9 1046 if(context->entity == TLS_CONNECTION_END_CLIENT)
Sergunb 0:8918a71cdbe9 1047 {
Sergunb 0:8918a71cdbe9 1048 //Check current state
Sergunb 0:8918a71cdbe9 1049 if(context->state != TLS_STATE_SERVER_CHANGE_CIPHER_SPEC)
Sergunb 0:8918a71cdbe9 1050 return ERROR_UNEXPECTED_MESSAGE;
Sergunb 0:8918a71cdbe9 1051 }
Sergunb 0:8918a71cdbe9 1052 else
Sergunb 0:8918a71cdbe9 1053 {
Sergunb 0:8918a71cdbe9 1054 //Check current state
Sergunb 0:8918a71cdbe9 1055 if(context->state != TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC)
Sergunb 0:8918a71cdbe9 1056 return ERROR_UNEXPECTED_MESSAGE;
Sergunb 0:8918a71cdbe9 1057 }
Sergunb 0:8918a71cdbe9 1058
Sergunb 0:8918a71cdbe9 1059 //Initialize decryption engine
Sergunb 0:8918a71cdbe9 1060 error = tlsInitDecryptionEngine(context);
Sergunb 0:8918a71cdbe9 1061 //Any error to report?
Sergunb 0:8918a71cdbe9 1062 if(error)
Sergunb 0:8918a71cdbe9 1063 return error;
Sergunb 0:8918a71cdbe9 1064
Sergunb 0:8918a71cdbe9 1065 //Inform the record layer that subsequent records will be protected
Sergunb 0:8918a71cdbe9 1066 //under the newly negotiated encryption algorithm
Sergunb 0:8918a71cdbe9 1067 context->changeCipherSpecReceived = TRUE;
Sergunb 0:8918a71cdbe9 1068
Sergunb 0:8918a71cdbe9 1069 //Prepare to receive a Finished message from the peer...
Sergunb 0:8918a71cdbe9 1070 if(context->entity == TLS_CONNECTION_END_CLIENT)
Sergunb 0:8918a71cdbe9 1071 context->state = TLS_STATE_SERVER_FINISHED;
Sergunb 0:8918a71cdbe9 1072 else
Sergunb 0:8918a71cdbe9 1073 context->state = TLS_STATE_CLIENT_FINISHED;
Sergunb 0:8918a71cdbe9 1074
Sergunb 0:8918a71cdbe9 1075 //Successful processing
Sergunb 0:8918a71cdbe9 1076 return NO_ERROR;
Sergunb 0:8918a71cdbe9 1077 }
Sergunb 0:8918a71cdbe9 1078
Sergunb 0:8918a71cdbe9 1079
Sergunb 0:8918a71cdbe9 1080 /**
Sergunb 0:8918a71cdbe9 1081 * @brief Parse Finished message
Sergunb 0:8918a71cdbe9 1082 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 1083 * @param[in] message Incoming Finished message to parse
Sergunb 0:8918a71cdbe9 1084 * @param[in] length Message length
Sergunb 0:8918a71cdbe9 1085 * @return Error code
Sergunb 0:8918a71cdbe9 1086 **/
Sergunb 0:8918a71cdbe9 1087
Sergunb 0:8918a71cdbe9 1088 error_t tlsParseFinished(TlsContext *context, const TlsFinished *message, size_t length)
Sergunb 0:8918a71cdbe9 1089 {
Sergunb 0:8918a71cdbe9 1090 error_t error;
Sergunb 0:8918a71cdbe9 1091
Sergunb 0:8918a71cdbe9 1092 //Debug message
Sergunb 0:8918a71cdbe9 1093 TRACE_INFO("Finished message received (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 1094 TRACE_DEBUG_ARRAY(" ", message, length);
Sergunb 0:8918a71cdbe9 1095
Sergunb 0:8918a71cdbe9 1096 //Check the length of the Finished message
Sergunb 0:8918a71cdbe9 1097 if(length < sizeof(TlsFinished))
Sergunb 0:8918a71cdbe9 1098 return ERROR_DECODING_FAILED;
Sergunb 0:8918a71cdbe9 1099
Sergunb 0:8918a71cdbe9 1100 //TLS operates as a client or a server?
Sergunb 0:8918a71cdbe9 1101 if(context->entity == TLS_CONNECTION_END_CLIENT)
Sergunb 0:8918a71cdbe9 1102 {
Sergunb 0:8918a71cdbe9 1103 //Check current state
Sergunb 0:8918a71cdbe9 1104 if(context->state != TLS_STATE_SERVER_FINISHED)
Sergunb 0:8918a71cdbe9 1105 return ERROR_UNEXPECTED_MESSAGE;
Sergunb 0:8918a71cdbe9 1106
Sergunb 0:8918a71cdbe9 1107 //The verify data is generated from all messages in this
Sergunb 0:8918a71cdbe9 1108 //handshake up to but not including the Finished message
Sergunb 0:8918a71cdbe9 1109 error = tlsComputeVerifyData(context, TLS_CONNECTION_END_SERVER);
Sergunb 0:8918a71cdbe9 1110 }
Sergunb 0:8918a71cdbe9 1111 else
Sergunb 0:8918a71cdbe9 1112 {
Sergunb 0:8918a71cdbe9 1113 //Check current state
Sergunb 0:8918a71cdbe9 1114 if(context->state != TLS_STATE_CLIENT_FINISHED)
Sergunb 0:8918a71cdbe9 1115 return ERROR_UNEXPECTED_MESSAGE;
Sergunb 0:8918a71cdbe9 1116
Sergunb 0:8918a71cdbe9 1117 //The verify data is generated from all messages in this
Sergunb 0:8918a71cdbe9 1118 //handshake up to but not including the Finished message
Sergunb 0:8918a71cdbe9 1119 error = tlsComputeVerifyData(context, TLS_CONNECTION_END_CLIENT);
Sergunb 0:8918a71cdbe9 1120 }
Sergunb 0:8918a71cdbe9 1121
Sergunb 0:8918a71cdbe9 1122 //Unable to generate the verify data?
Sergunb 0:8918a71cdbe9 1123 if(error)
Sergunb 0:8918a71cdbe9 1124 return error;
Sergunb 0:8918a71cdbe9 1125
Sergunb 0:8918a71cdbe9 1126 //Check message length
Sergunb 0:8918a71cdbe9 1127 if(LOAD24BE(message->length) != context->verifyDataLen)
Sergunb 0:8918a71cdbe9 1128 return ERROR_DECODING_FAILED;
Sergunb 0:8918a71cdbe9 1129
Sergunb 0:8918a71cdbe9 1130 //Check the resulting verify data
Sergunb 0:8918a71cdbe9 1131 if(memcmp(message->verifyData, context->verifyData, context->verifyDataLen))
Sergunb 0:8918a71cdbe9 1132 return ERROR_INVALID_SIGNATURE;
Sergunb 0:8918a71cdbe9 1133
Sergunb 0:8918a71cdbe9 1134 //Update the hash value with the incoming handshake message
Sergunb 0:8918a71cdbe9 1135 tlsUpdateHandshakeHash(context, message, length);
Sergunb 0:8918a71cdbe9 1136
Sergunb 0:8918a71cdbe9 1137 //TLS operates as a client or a server?
Sergunb 0:8918a71cdbe9 1138 if(context->entity == TLS_CONNECTION_END_CLIENT)
Sergunb 0:8918a71cdbe9 1139 {
Sergunb 0:8918a71cdbe9 1140 //Use abbreviated or full handshake?
Sergunb 0:8918a71cdbe9 1141 if(context->resume)
Sergunb 0:8918a71cdbe9 1142 context->state = TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC;
Sergunb 0:8918a71cdbe9 1143 else
Sergunb 0:8918a71cdbe9 1144 context->state = TLS_STATE_APPLICATION_DATA;
Sergunb 0:8918a71cdbe9 1145 }
Sergunb 0:8918a71cdbe9 1146 else
Sergunb 0:8918a71cdbe9 1147 {
Sergunb 0:8918a71cdbe9 1148 //Use abbreviated or full handshake?
Sergunb 0:8918a71cdbe9 1149 if(context->resume)
Sergunb 0:8918a71cdbe9 1150 context->state = TLS_STATE_APPLICATION_DATA;
Sergunb 0:8918a71cdbe9 1151 else
Sergunb 0:8918a71cdbe9 1152 context->state = TLS_STATE_SERVER_CHANGE_CIPHER_SPEC;
Sergunb 0:8918a71cdbe9 1153 }
Sergunb 0:8918a71cdbe9 1154
Sergunb 0:8918a71cdbe9 1155 //Successful processing
Sergunb 0:8918a71cdbe9 1156 return NO_ERROR;
Sergunb 0:8918a71cdbe9 1157 }
Sergunb 0:8918a71cdbe9 1158
Sergunb 0:8918a71cdbe9 1159
Sergunb 0:8918a71cdbe9 1160 /**
Sergunb 0:8918a71cdbe9 1161 * @brief Parse Alert message
Sergunb 0:8918a71cdbe9 1162 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 1163 * @param[in] message Incoming Alert message to parse
Sergunb 0:8918a71cdbe9 1164 * @param[in] length Message length
Sergunb 0:8918a71cdbe9 1165 * @return Error code
Sergunb 0:8918a71cdbe9 1166 **/
Sergunb 0:8918a71cdbe9 1167
Sergunb 0:8918a71cdbe9 1168 error_t tlsParseAlert(TlsContext *context, const TlsAlert *message, size_t length)
Sergunb 0:8918a71cdbe9 1169 {
Sergunb 0:8918a71cdbe9 1170 //Debug message
Sergunb 0:8918a71cdbe9 1171 TRACE_INFO("Alert message received (%" PRIuSIZE " bytes)...\r\n", length);
Sergunb 0:8918a71cdbe9 1172 TRACE_INFO_ARRAY(" ", message, length);
Sergunb 0:8918a71cdbe9 1173
Sergunb 0:8918a71cdbe9 1174 //Check message length
Sergunb 0:8918a71cdbe9 1175 if(length != sizeof(TlsAlert))
Sergunb 0:8918a71cdbe9 1176 return ERROR_INVALID_LENGTH;
Sergunb 0:8918a71cdbe9 1177
Sergunb 0:8918a71cdbe9 1178 //Debug message
Sergunb 0:8918a71cdbe9 1179 TRACE_DEBUG(" Level = %" PRIu8 "\r\n", message->level);
Sergunb 0:8918a71cdbe9 1180 TRACE_DEBUG(" Description = %" PRIu8 "\r\n", message->description);
Sergunb 0:8918a71cdbe9 1181
Sergunb 0:8918a71cdbe9 1182 //Alert messages convey the severity of the message
Sergunb 0:8918a71cdbe9 1183 if(message->level == TLS_ALERT_LEVEL_WARNING)
Sergunb 0:8918a71cdbe9 1184 {
Sergunb 0:8918a71cdbe9 1185 //Closure alert received?
Sergunb 0:8918a71cdbe9 1186 if(message->description == TLS_ALERT_CLOSE_NOTIFY)
Sergunb 0:8918a71cdbe9 1187 {
Sergunb 0:8918a71cdbe9 1188 //A closure alert has been received
Sergunb 0:8918a71cdbe9 1189 context->closeNotifyReceived = TRUE;
Sergunb 0:8918a71cdbe9 1190
Sergunb 0:8918a71cdbe9 1191 //Close down the connection immediately
Sergunb 0:8918a71cdbe9 1192 if(context->state == TLS_STATE_APPLICATION_DATA)
Sergunb 0:8918a71cdbe9 1193 context->state = TLS_STATE_CLOSING;
Sergunb 0:8918a71cdbe9 1194 }
Sergunb 0:8918a71cdbe9 1195 }
Sergunb 0:8918a71cdbe9 1196 else if(message->level == TLS_ALERT_LEVEL_FATAL)
Sergunb 0:8918a71cdbe9 1197 {
Sergunb 0:8918a71cdbe9 1198 //A fatal alert message has been received
Sergunb 0:8918a71cdbe9 1199 context->fatalAlertReceived = TRUE;
Sergunb 0:8918a71cdbe9 1200
Sergunb 0:8918a71cdbe9 1201 //Any connection terminated with a fatal alert must not be resumed
Sergunb 0:8918a71cdbe9 1202 if(context->entity == TLS_CONNECTION_END_SERVER)
Sergunb 0:8918a71cdbe9 1203 tlsRemoveFromCache(context);
Sergunb 0:8918a71cdbe9 1204
Sergunb 0:8918a71cdbe9 1205 //Servers and clients must forget any session identifiers
Sergunb 0:8918a71cdbe9 1206 memset(context->sessionId, 0, 32);
Sergunb 0:8918a71cdbe9 1207 context->sessionIdLen = 0;
Sergunb 0:8918a71cdbe9 1208
Sergunb 0:8918a71cdbe9 1209 //Alert messages with a level of fatal result in the immediate
Sergunb 0:8918a71cdbe9 1210 //termination of the connection
Sergunb 0:8918a71cdbe9 1211 context->state = TLS_STATE_CLOSED;
Sergunb 0:8918a71cdbe9 1212 }
Sergunb 0:8918a71cdbe9 1213 else
Sergunb 0:8918a71cdbe9 1214 {
Sergunb 0:8918a71cdbe9 1215 //Report an error
Sergunb 0:8918a71cdbe9 1216 return ERROR_ILLEGAL_PARAMETER;
Sergunb 0:8918a71cdbe9 1217 }
Sergunb 0:8918a71cdbe9 1218
Sergunb 0:8918a71cdbe9 1219 //Successful processing
Sergunb 0:8918a71cdbe9 1220 return NO_ERROR;
Sergunb 0:8918a71cdbe9 1221 }
Sergunb 0:8918a71cdbe9 1222
Sergunb 0:8918a71cdbe9 1223 #endif
Sergunb 0:8918a71cdbe9 1224