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.c
Sergunb 0:8918a71cdbe9 3 * @brief TLS (Transport Layer Security)
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 * @section Description
Sergunb 0:8918a71cdbe9 26 *
Sergunb 0:8918a71cdbe9 27 * The TLS protocol provides communications security over the Internet. The
Sergunb 0:8918a71cdbe9 28 * protocol allows client/server applications to communicate in a way that
Sergunb 0:8918a71cdbe9 29 * is designed to prevent eavesdropping, tampering, or message forgery
Sergunb 0:8918a71cdbe9 30 *
Sergunb 0:8918a71cdbe9 31 * @author Oryx Embedded SARL (www.oryx-embedded.com)
Sergunb 0:8918a71cdbe9 32 * @version 1.7.6
Sergunb 0:8918a71cdbe9 33 **/
Sergunb 0:8918a71cdbe9 34
Sergunb 0:8918a71cdbe9 35 //Switch to the appropriate trace level
Sergunb 0:8918a71cdbe9 36 #define TRACE_LEVEL TLS_TRACE_LEVEL
Sergunb 0:8918a71cdbe9 37
Sergunb 0:8918a71cdbe9 38 //Dependencies
Sergunb 0:8918a71cdbe9 39 #include <string.h>
Sergunb 0:8918a71cdbe9 40 #include <ctype.h>
Sergunb 0:8918a71cdbe9 41 #include "tls.h"
Sergunb 0:8918a71cdbe9 42 #include "tls_client.h"
Sergunb 0:8918a71cdbe9 43 #include "tls_server.h"
Sergunb 0:8918a71cdbe9 44 #include "tls_common.h"
Sergunb 0:8918a71cdbe9 45 #include "tls_record.h"
Sergunb 0:8918a71cdbe9 46 #include "tls_misc.h"
Sergunb 0:8918a71cdbe9 47 #include "x509.h"
Sergunb 0:8918a71cdbe9 48 #include "pem.h"
Sergunb 0:8918a71cdbe9 49 #include "debug.h"
Sergunb 0:8918a71cdbe9 50
Sergunb 0:8918a71cdbe9 51 //Check SSL library configuration
Sergunb 0:8918a71cdbe9 52 #if (TLS_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 53
Sergunb 0:8918a71cdbe9 54
Sergunb 0:8918a71cdbe9 55 /**
Sergunb 0:8918a71cdbe9 56 * @brief TLS context initialization
Sergunb 0:8918a71cdbe9 57 * @return Handle referencing the fully initialized TLS context
Sergunb 0:8918a71cdbe9 58 **/
Sergunb 0:8918a71cdbe9 59
Sergunb 0:8918a71cdbe9 60 TlsContext *tlsInit(void)
Sergunb 0:8918a71cdbe9 61 {
Sergunb 0:8918a71cdbe9 62 TlsContext *context;
Sergunb 0:8918a71cdbe9 63
Sergunb 0:8918a71cdbe9 64 //Allocate a memory buffer to hold the TLS context
Sergunb 0:8918a71cdbe9 65 context = tlsAllocMem(sizeof(TlsContext));
Sergunb 0:8918a71cdbe9 66
Sergunb 0:8918a71cdbe9 67 //Successful memory allocation?
Sergunb 0:8918a71cdbe9 68 if(context != NULL)
Sergunb 0:8918a71cdbe9 69 {
Sergunb 0:8918a71cdbe9 70 //Clear TLS context
Sergunb 0:8918a71cdbe9 71 memset(context, 0, sizeof(TlsContext));
Sergunb 0:8918a71cdbe9 72
Sergunb 0:8918a71cdbe9 73 //Default state
Sergunb 0:8918a71cdbe9 74 context->state = TLS_STATE_INIT;
Sergunb 0:8918a71cdbe9 75 //Default operation mode
Sergunb 0:8918a71cdbe9 76 context->entity = TLS_CONNECTION_END_CLIENT;
Sergunb 0:8918a71cdbe9 77 //Default TLS version
Sergunb 0:8918a71cdbe9 78 context->version = TLS_MIN_VERSION;
Sergunb 0:8918a71cdbe9 79 //Default client authentication mode
Sergunb 0:8918a71cdbe9 80 context->clientAuthMode = TLS_CLIENT_AUTH_NONE;
Sergunb 0:8918a71cdbe9 81
Sergunb 0:8918a71cdbe9 82 #if (TLS_DH_ANON_SUPPORT == ENABLED || TLS_DHE_RSA_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 83 TLS_DHE_DSS_SUPPORT == ENABLED || TLS_DHE_PSK_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 84 //Initialize Diffie-Hellman context
Sergunb 0:8918a71cdbe9 85 dhInit(&context->dhContext);
Sergunb 0:8918a71cdbe9 86 #endif
Sergunb 0:8918a71cdbe9 87
Sergunb 0:8918a71cdbe9 88 #if (TLS_ECDH_ANON_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 89 TLS_ECDHE_ECDSA_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 90 //Initialize ECDH context
Sergunb 0:8918a71cdbe9 91 ecdhInit(&context->ecdhContext);
Sergunb 0:8918a71cdbe9 92 #endif
Sergunb 0:8918a71cdbe9 93
Sergunb 0:8918a71cdbe9 94 #if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_RSA_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 95 TLS_DHE_RSA_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 96 //Initialize peer's RSA public key
Sergunb 0:8918a71cdbe9 97 rsaInitPublicKey(&context->peerRsaPublicKey);
Sergunb 0:8918a71cdbe9 98 #endif
Sergunb 0:8918a71cdbe9 99
Sergunb 0:8918a71cdbe9 100 #if (TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_DHE_DSS_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 101 //Initialize peer's DSA public key
Sergunb 0:8918a71cdbe9 102 dsaInitPublicKey(&context->peerDsaPublicKey);
Sergunb 0:8918a71cdbe9 103 #endif
Sergunb 0:8918a71cdbe9 104
Sergunb 0:8918a71cdbe9 105 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_ECDHE_ECDSA_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 106 //Initialize peer's EC domain parameters
Sergunb 0:8918a71cdbe9 107 ecInitDomainParameters(&context->peerEcParams);
Sergunb 0:8918a71cdbe9 108 //Initialize peer's EC public key
Sergunb 0:8918a71cdbe9 109 ecInit(&context->peerEcPublicKey);
Sergunb 0:8918a71cdbe9 110 #endif
Sergunb 0:8918a71cdbe9 111
Sergunb 0:8918a71cdbe9 112 //Set the maximum fragment length for outgoing TLS records
Sergunb 0:8918a71cdbe9 113 context->txRecordMaxLen = TLS_MAX_RECORD_LENGTH;
Sergunb 0:8918a71cdbe9 114
Sergunb 0:8918a71cdbe9 115 //Compute the corresponding buffer size
Sergunb 0:8918a71cdbe9 116 context->txBufferSize = TLS_MAX_RECORD_LENGTH +
Sergunb 0:8918a71cdbe9 117 sizeof(TlsRecord) + TLS_MAX_RECORD_OVERHEAD;
Sergunb 0:8918a71cdbe9 118
Sergunb 0:8918a71cdbe9 119 //Save the maximum fragment length for incoming TLS records
Sergunb 0:8918a71cdbe9 120 context->rxRecordMaxLen = TLS_MAX_RECORD_LENGTH;
Sergunb 0:8918a71cdbe9 121
Sergunb 0:8918a71cdbe9 122 //Compute the corresponding buffer size
Sergunb 0:8918a71cdbe9 123 context->rxBufferSize = TLS_MAX_RECORD_LENGTH +
Sergunb 0:8918a71cdbe9 124 sizeof(TlsRecord) + TLS_MAX_RECORD_OVERHEAD;
Sergunb 0:8918a71cdbe9 125 }
Sergunb 0:8918a71cdbe9 126
Sergunb 0:8918a71cdbe9 127 //Return a pointer to the freshly created TLS context
Sergunb 0:8918a71cdbe9 128 return context;
Sergunb 0:8918a71cdbe9 129 }
Sergunb 0:8918a71cdbe9 130
Sergunb 0:8918a71cdbe9 131
Sergunb 0:8918a71cdbe9 132 /**
Sergunb 0:8918a71cdbe9 133 * @brief Set send and receive callbacks (I/O abstraction layer)
Sergunb 0:8918a71cdbe9 134 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 135 * @param[in] handle Handle for I/O operations
Sergunb 0:8918a71cdbe9 136 * @param[in] sendCallback Send callback function
Sergunb 0:8918a71cdbe9 137 * @param[in] receiveCallback Receive callback function
Sergunb 0:8918a71cdbe9 138 * @return Error code
Sergunb 0:8918a71cdbe9 139 **/
Sergunb 0:8918a71cdbe9 140
Sergunb 0:8918a71cdbe9 141 error_t tlsSetIoCallbacks(TlsContext *context, TlsIoHandle handle,
Sergunb 0:8918a71cdbe9 142 TlsIoSendCallback sendCallback, TlsIoReceiveCallback receiveCallback)
Sergunb 0:8918a71cdbe9 143 {
Sergunb 0:8918a71cdbe9 144 //Check parameters
Sergunb 0:8918a71cdbe9 145 if(context == NULL || sendCallback == NULL || receiveCallback == NULL)
Sergunb 0:8918a71cdbe9 146 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 147
Sergunb 0:8918a71cdbe9 148 //Save I/O handle
Sergunb 0:8918a71cdbe9 149 context->handle = handle;
Sergunb 0:8918a71cdbe9 150
Sergunb 0:8918a71cdbe9 151 //Save send and receive callback functions
Sergunb 0:8918a71cdbe9 152 context->sendCallback = sendCallback;
Sergunb 0:8918a71cdbe9 153 context->receiveCallback = receiveCallback;
Sergunb 0:8918a71cdbe9 154
Sergunb 0:8918a71cdbe9 155 //Successful processing
Sergunb 0:8918a71cdbe9 156 return NO_ERROR;
Sergunb 0:8918a71cdbe9 157 }
Sergunb 0:8918a71cdbe9 158
Sergunb 0:8918a71cdbe9 159
Sergunb 0:8918a71cdbe9 160 /**
Sergunb 0:8918a71cdbe9 161 * @brief Set operation mode (client or server)
Sergunb 0:8918a71cdbe9 162 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 163 * @param[in] entity Specifies whether this entity is considered a client or a server
Sergunb 0:8918a71cdbe9 164 * @return Error code
Sergunb 0:8918a71cdbe9 165 **/
Sergunb 0:8918a71cdbe9 166
Sergunb 0:8918a71cdbe9 167 error_t tlsSetConnectionEnd(TlsContext *context, TlsConnectionEnd entity)
Sergunb 0:8918a71cdbe9 168 {
Sergunb 0:8918a71cdbe9 169 //Invalid TLS context?
Sergunb 0:8918a71cdbe9 170 if(context == NULL)
Sergunb 0:8918a71cdbe9 171 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 172 //Invalid parameter?
Sergunb 0:8918a71cdbe9 173 if(entity != TLS_CONNECTION_END_CLIENT && entity != TLS_CONNECTION_END_SERVER)
Sergunb 0:8918a71cdbe9 174 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 175
Sergunb 0:8918a71cdbe9 176 //Check whether TLS operates as a client or a server
Sergunb 0:8918a71cdbe9 177 context->entity = entity;
Sergunb 0:8918a71cdbe9 178
Sergunb 0:8918a71cdbe9 179 //Successful processing
Sergunb 0:8918a71cdbe9 180 return NO_ERROR;
Sergunb 0:8918a71cdbe9 181 }
Sergunb 0:8918a71cdbe9 182
Sergunb 0:8918a71cdbe9 183
Sergunb 0:8918a71cdbe9 184 /**
Sergunb 0:8918a71cdbe9 185 * @brief Set the pseudo-random number generator to be used
Sergunb 0:8918a71cdbe9 186 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 187 * @param[in] prngAlgo PRNG algorithm
Sergunb 0:8918a71cdbe9 188 * @param[in] prngContext Pointer to the PRNG context
Sergunb 0:8918a71cdbe9 189 * @return Error code
Sergunb 0:8918a71cdbe9 190 **/
Sergunb 0:8918a71cdbe9 191
Sergunb 0:8918a71cdbe9 192 error_t tlsSetPrng(TlsContext *context, const PrngAlgo *prngAlgo, void *prngContext)
Sergunb 0:8918a71cdbe9 193 {
Sergunb 0:8918a71cdbe9 194 //Invalid TLS context?
Sergunb 0:8918a71cdbe9 195 if(context == NULL)
Sergunb 0:8918a71cdbe9 196 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 197 //Invalid parameters?
Sergunb 0:8918a71cdbe9 198 if(prngAlgo == NULL || prngContext == NULL)
Sergunb 0:8918a71cdbe9 199 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 200
Sergunb 0:8918a71cdbe9 201 //PRNG algorithm that will be used to generate random numbers
Sergunb 0:8918a71cdbe9 202 context->prngAlgo = prngAlgo;
Sergunb 0:8918a71cdbe9 203 //PRNG context
Sergunb 0:8918a71cdbe9 204 context->prngContext = prngContext;
Sergunb 0:8918a71cdbe9 205
Sergunb 0:8918a71cdbe9 206 //Successful processing
Sergunb 0:8918a71cdbe9 207 return NO_ERROR;
Sergunb 0:8918a71cdbe9 208 }
Sergunb 0:8918a71cdbe9 209
Sergunb 0:8918a71cdbe9 210
Sergunb 0:8918a71cdbe9 211 /**
Sergunb 0:8918a71cdbe9 212 * @brief Set the name of the remote server
Sergunb 0:8918a71cdbe9 213 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 214 * @param[in] serverName Fully qualified domain name of the server
Sergunb 0:8918a71cdbe9 215 * @return Error code
Sergunb 0:8918a71cdbe9 216 **/
Sergunb 0:8918a71cdbe9 217
Sergunb 0:8918a71cdbe9 218 error_t tlsSetServerName(TlsContext *context, const char_t *serverName)
Sergunb 0:8918a71cdbe9 219 {
Sergunb 0:8918a71cdbe9 220 size_t i;
Sergunb 0:8918a71cdbe9 221 size_t length;
Sergunb 0:8918a71cdbe9 222
Sergunb 0:8918a71cdbe9 223 //Invalid parameters?
Sergunb 0:8918a71cdbe9 224 if(context == NULL || serverName == NULL)
Sergunb 0:8918a71cdbe9 225 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 226
Sergunb 0:8918a71cdbe9 227 //Retrieve the length of the server name
Sergunb 0:8918a71cdbe9 228 length = strlen(serverName);
Sergunb 0:8918a71cdbe9 229
Sergunb 0:8918a71cdbe9 230 //Check whether the server name has already been configured
Sergunb 0:8918a71cdbe9 231 if(context->serverName != NULL)
Sergunb 0:8918a71cdbe9 232 {
Sergunb 0:8918a71cdbe9 233 //Release memory
Sergunb 0:8918a71cdbe9 234 tlsFreeMem(context->serverName);
Sergunb 0:8918a71cdbe9 235 context->serverName = NULL;
Sergunb 0:8918a71cdbe9 236 }
Sergunb 0:8918a71cdbe9 237
Sergunb 0:8918a71cdbe9 238 //Valid server name?
Sergunb 0:8918a71cdbe9 239 if(length > 0)
Sergunb 0:8918a71cdbe9 240 {
Sergunb 0:8918a71cdbe9 241 //Allocate a memory block to hold the hostname
Sergunb 0:8918a71cdbe9 242 context->serverName = tlsAllocMem(length + 1);
Sergunb 0:8918a71cdbe9 243 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 244 if(context->serverName == NULL)
Sergunb 0:8918a71cdbe9 245 return ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 246
Sergunb 0:8918a71cdbe9 247 //Convert the hostname into lowercase
Sergunb 0:8918a71cdbe9 248 for(i = 0; i < length; i++)
Sergunb 0:8918a71cdbe9 249 context->serverName[i] = tolower((uint8_t) serverName[i]);
Sergunb 0:8918a71cdbe9 250
Sergunb 0:8918a71cdbe9 251 //Properly terminate the string with a NULL character
Sergunb 0:8918a71cdbe9 252 context->serverName[length] = '\0';
Sergunb 0:8918a71cdbe9 253 }
Sergunb 0:8918a71cdbe9 254
Sergunb 0:8918a71cdbe9 255 //Successful processing
Sergunb 0:8918a71cdbe9 256 return NO_ERROR;
Sergunb 0:8918a71cdbe9 257 }
Sergunb 0:8918a71cdbe9 258
Sergunb 0:8918a71cdbe9 259
Sergunb 0:8918a71cdbe9 260 /**
Sergunb 0:8918a71cdbe9 261 * @brief Set session cache
Sergunb 0:8918a71cdbe9 262 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 263 * @param[in] cache Session cache that will be used to save/resume TLS sessions
Sergunb 0:8918a71cdbe9 264 * @return Error code
Sergunb 0:8918a71cdbe9 265 **/
Sergunb 0:8918a71cdbe9 266
Sergunb 0:8918a71cdbe9 267 error_t tlsSetCache(TlsContext *context, TlsCache *cache)
Sergunb 0:8918a71cdbe9 268 {
Sergunb 0:8918a71cdbe9 269 //Check parameters
Sergunb 0:8918a71cdbe9 270 if(context == NULL || cache == NULL)
Sergunb 0:8918a71cdbe9 271 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 272
Sergunb 0:8918a71cdbe9 273 //The cache will be used to save/resume TLS sessions
Sergunb 0:8918a71cdbe9 274 context->cache = cache;
Sergunb 0:8918a71cdbe9 275
Sergunb 0:8918a71cdbe9 276 //Successful processing
Sergunb 0:8918a71cdbe9 277 return NO_ERROR;
Sergunb 0:8918a71cdbe9 278 }
Sergunb 0:8918a71cdbe9 279
Sergunb 0:8918a71cdbe9 280
Sergunb 0:8918a71cdbe9 281 /**
Sergunb 0:8918a71cdbe9 282 * @brief Set client authentication mode
Sergunb 0:8918a71cdbe9 283 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 284 * @param[in] mode Client authentication mode
Sergunb 0:8918a71cdbe9 285 * @return Error code
Sergunb 0:8918a71cdbe9 286 **/
Sergunb 0:8918a71cdbe9 287
Sergunb 0:8918a71cdbe9 288 error_t tlsSetClientAuthMode(TlsContext *context, TlsClientAuthMode mode)
Sergunb 0:8918a71cdbe9 289 {
Sergunb 0:8918a71cdbe9 290 //Invalid TLS context?
Sergunb 0:8918a71cdbe9 291 if(context == NULL)
Sergunb 0:8918a71cdbe9 292 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 293
Sergunb 0:8918a71cdbe9 294 //Save client authentication mode
Sergunb 0:8918a71cdbe9 295 context->clientAuthMode = mode;
Sergunb 0:8918a71cdbe9 296
Sergunb 0:8918a71cdbe9 297 //Successful processing
Sergunb 0:8918a71cdbe9 298 return NO_ERROR;
Sergunb 0:8918a71cdbe9 299 }
Sergunb 0:8918a71cdbe9 300
Sergunb 0:8918a71cdbe9 301
Sergunb 0:8918a71cdbe9 302 /**
Sergunb 0:8918a71cdbe9 303 * @brief Set TLS buffer size
Sergunb 0:8918a71cdbe9 304 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 305 * @param[in] txBufferSize TX buffer size
Sergunb 0:8918a71cdbe9 306 * @param[in] rxBufferSize RX buffer size
Sergunb 0:8918a71cdbe9 307 * @return Error code
Sergunb 0:8918a71cdbe9 308 **/
Sergunb 0:8918a71cdbe9 309
Sergunb 0:8918a71cdbe9 310 error_t tlsSetBufferSize(TlsContext *context,
Sergunb 0:8918a71cdbe9 311 size_t txBufferSize, size_t rxBufferSize)
Sergunb 0:8918a71cdbe9 312 {
Sergunb 0:8918a71cdbe9 313 //Invalid TLS context?
Sergunb 0:8918a71cdbe9 314 if(context == NULL)
Sergunb 0:8918a71cdbe9 315 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 316 //Check parameters
Sergunb 0:8918a71cdbe9 317 if(txBufferSize < 512 || rxBufferSize < 512)
Sergunb 0:8918a71cdbe9 318 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 319
Sergunb 0:8918a71cdbe9 320 //Save the maximum fragment length for outgoing TLS records
Sergunb 0:8918a71cdbe9 321 context->txRecordMaxLen = txBufferSize;
Sergunb 0:8918a71cdbe9 322
Sergunb 0:8918a71cdbe9 323 //Compute the corresponding buffer size
Sergunb 0:8918a71cdbe9 324 context->txBufferSize = txBufferSize +
Sergunb 0:8918a71cdbe9 325 sizeof(TlsRecord) + TLS_MAX_RECORD_OVERHEAD;
Sergunb 0:8918a71cdbe9 326
Sergunb 0:8918a71cdbe9 327 //Save the maximum fragment length for incoming TLS records
Sergunb 0:8918a71cdbe9 328 context->rxRecordMaxLen = rxBufferSize;
Sergunb 0:8918a71cdbe9 329
Sergunb 0:8918a71cdbe9 330 //Compute the corresponding buffer size
Sergunb 0:8918a71cdbe9 331 context->rxBufferSize = rxBufferSize +
Sergunb 0:8918a71cdbe9 332 sizeof(TlsRecord) + TLS_MAX_RECORD_OVERHEAD;
Sergunb 0:8918a71cdbe9 333
Sergunb 0:8918a71cdbe9 334 //Successful processing
Sergunb 0:8918a71cdbe9 335 return NO_ERROR;
Sergunb 0:8918a71cdbe9 336 }
Sergunb 0:8918a71cdbe9 337
Sergunb 0:8918a71cdbe9 338
Sergunb 0:8918a71cdbe9 339 /**
Sergunb 0:8918a71cdbe9 340 * @brief Specify the list of allowed cipher suites
Sergunb 0:8918a71cdbe9 341 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 342 * @param[in] cipherSuites Pointer to the cipher suite list
Sergunb 0:8918a71cdbe9 343 * @param[in] length Number of cipher suites in the list
Sergunb 0:8918a71cdbe9 344 * @return Error code
Sergunb 0:8918a71cdbe9 345 **/
Sergunb 0:8918a71cdbe9 346
Sergunb 0:8918a71cdbe9 347 error_t tlsSetCipherSuites(TlsContext *context,
Sergunb 0:8918a71cdbe9 348 const uint16_t *cipherSuites, uint_t length)
Sergunb 0:8918a71cdbe9 349 {
Sergunb 0:8918a71cdbe9 350 //Invalid TLS context?
Sergunb 0:8918a71cdbe9 351 if(context == NULL)
Sergunb 0:8918a71cdbe9 352 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 353 //Check parameters
Sergunb 0:8918a71cdbe9 354 if(cipherSuites == NULL && length != 0)
Sergunb 0:8918a71cdbe9 355 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 356
Sergunb 0:8918a71cdbe9 357 //Restrict the cipher suites that can be used
Sergunb 0:8918a71cdbe9 358 context->cipherSuites = cipherSuites;
Sergunb 0:8918a71cdbe9 359 context->numCipherSuites = length;
Sergunb 0:8918a71cdbe9 360
Sergunb 0:8918a71cdbe9 361 //Successful processing
Sergunb 0:8918a71cdbe9 362 return NO_ERROR;
Sergunb 0:8918a71cdbe9 363 }
Sergunb 0:8918a71cdbe9 364
Sergunb 0:8918a71cdbe9 365
Sergunb 0:8918a71cdbe9 366 /**
Sergunb 0:8918a71cdbe9 367 * @brief Import Diffie-Hellman parameters
Sergunb 0:8918a71cdbe9 368 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 369 * @param[in] params PEM structure that holds Diffie-Hellman parameters
Sergunb 0:8918a71cdbe9 370 * @param[in] length Total length of the DER structure
Sergunb 0:8918a71cdbe9 371 * @return Error code
Sergunb 0:8918a71cdbe9 372 **/
Sergunb 0:8918a71cdbe9 373
Sergunb 0:8918a71cdbe9 374 error_t tlsSetDhParameters(TlsContext *context,
Sergunb 0:8918a71cdbe9 375 const char_t *params, size_t length)
Sergunb 0:8918a71cdbe9 376 {
Sergunb 0:8918a71cdbe9 377 #if (TLS_DH_ANON_SUPPORT == ENABLED || TLS_DHE_RSA_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 378 TLS_DHE_DSS_SUPPORT == ENABLED || TLS_DHE_PSK_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 379 //Invalid TLS context?
Sergunb 0:8918a71cdbe9 380 if(context == NULL)
Sergunb 0:8918a71cdbe9 381 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 382 //Check parameters
Sergunb 0:8918a71cdbe9 383 if(params == NULL && length != 0)
Sergunb 0:8918a71cdbe9 384 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 385
Sergunb 0:8918a71cdbe9 386 //Decode the PEM structure that holds Diffie-Hellman parameters
Sergunb 0:8918a71cdbe9 387 return pemReadDhParameters(params, length, &context->dhContext.params);
Sergunb 0:8918a71cdbe9 388 #else
Sergunb 0:8918a71cdbe9 389 //Diffie-Hellman is not implemented
Sergunb 0:8918a71cdbe9 390 return ERROR_NOT_IMPLEMENTED;
Sergunb 0:8918a71cdbe9 391 #endif
Sergunb 0:8918a71cdbe9 392 }
Sergunb 0:8918a71cdbe9 393
Sergunb 0:8918a71cdbe9 394
Sergunb 0:8918a71cdbe9 395 /**
Sergunb 0:8918a71cdbe9 396 * @brief Set the list of supported ALPN protocols
Sergunb 0:8918a71cdbe9 397 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 398 * @param[in] protocolList Comma-delimited list of supported protocols
Sergunb 0:8918a71cdbe9 399 * @return Error code
Sergunb 0:8918a71cdbe9 400 **/
Sergunb 0:8918a71cdbe9 401
Sergunb 0:8918a71cdbe9 402 error_t tlsSetAlpnProtocolList(TlsContext *context, const char_t *protocolList)
Sergunb 0:8918a71cdbe9 403 {
Sergunb 0:8918a71cdbe9 404 #if (TLS_ALPN_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 405 size_t length;
Sergunb 0:8918a71cdbe9 406
Sergunb 0:8918a71cdbe9 407 //Invalid parameters?
Sergunb 0:8918a71cdbe9 408 if(context == NULL || protocolList == NULL)
Sergunb 0:8918a71cdbe9 409 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 410
Sergunb 0:8918a71cdbe9 411 //Retrieve the length of the list
Sergunb 0:8918a71cdbe9 412 length = strlen(protocolList);
Sergunb 0:8918a71cdbe9 413
Sergunb 0:8918a71cdbe9 414 //Check whether the list of supported protocols has already been configured
Sergunb 0:8918a71cdbe9 415 if(context->protocolList != NULL)
Sergunb 0:8918a71cdbe9 416 {
Sergunb 0:8918a71cdbe9 417 //Release memory
Sergunb 0:8918a71cdbe9 418 tlsFreeMem(context->protocolList);
Sergunb 0:8918a71cdbe9 419 context->protocolList = NULL;
Sergunb 0:8918a71cdbe9 420 }
Sergunb 0:8918a71cdbe9 421
Sergunb 0:8918a71cdbe9 422 //Check whether the list of protocols is valid
Sergunb 0:8918a71cdbe9 423 if(length > 0)
Sergunb 0:8918a71cdbe9 424 {
Sergunb 0:8918a71cdbe9 425 //Allocate a memory block to hold the list
Sergunb 0:8918a71cdbe9 426 context->protocolList = tlsAllocMem(length + 1);
Sergunb 0:8918a71cdbe9 427 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 428 if(context->protocolList == NULL)
Sergunb 0:8918a71cdbe9 429 return ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 430
Sergunb 0:8918a71cdbe9 431 //Save the list of supported protocols
Sergunb 0:8918a71cdbe9 432 strcpy(context->protocolList, protocolList);
Sergunb 0:8918a71cdbe9 433 }
Sergunb 0:8918a71cdbe9 434
Sergunb 0:8918a71cdbe9 435 //Successful processing
Sergunb 0:8918a71cdbe9 436 return NO_ERROR;
Sergunb 0:8918a71cdbe9 437 #else
Sergunb 0:8918a71cdbe9 438 //ALPN is not implemented
Sergunb 0:8918a71cdbe9 439 return ERROR_NOT_IMPLEMENTED;
Sergunb 0:8918a71cdbe9 440 #endif
Sergunb 0:8918a71cdbe9 441 }
Sergunb 0:8918a71cdbe9 442
Sergunb 0:8918a71cdbe9 443
Sergunb 0:8918a71cdbe9 444 /**
Sergunb 0:8918a71cdbe9 445 * @brief Get the name of the negotiated ALPN protocol
Sergunb 0:8918a71cdbe9 446 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 447 * @return Pointer to the protocol name
Sergunb 0:8918a71cdbe9 448 **/
Sergunb 0:8918a71cdbe9 449
Sergunb 0:8918a71cdbe9 450 const char_t *tlsGetAlpnProtocol(TlsContext *context)
Sergunb 0:8918a71cdbe9 451 {
Sergunb 0:8918a71cdbe9 452 //Not implemented
Sergunb 0:8918a71cdbe9 453 return NULL;
Sergunb 0:8918a71cdbe9 454 }
Sergunb 0:8918a71cdbe9 455
Sergunb 0:8918a71cdbe9 456
Sergunb 0:8918a71cdbe9 457 /**
Sergunb 0:8918a71cdbe9 458 * @brief Set the pre-shared key to be used
Sergunb 0:8918a71cdbe9 459 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 460 * @param[in] psk Pointer to the pre-shared key
Sergunb 0:8918a71cdbe9 461 * @param[in] pskLength Length of the pre-shared key, in bytes
Sergunb 0:8918a71cdbe9 462 * @return Error code
Sergunb 0:8918a71cdbe9 463 **/
Sergunb 0:8918a71cdbe9 464
Sergunb 0:8918a71cdbe9 465 error_t tlsSetPsk(TlsContext *context, const uint8_t *psk, size_t pskLength)
Sergunb 0:8918a71cdbe9 466 {
Sergunb 0:8918a71cdbe9 467 #if (TLS_PSK_SUPPORT == ENABLED || TLS_RSA_PSK_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 468 TLS_DHE_PSK_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 469 //Invalid TLS context?
Sergunb 0:8918a71cdbe9 470 if(context == NULL)
Sergunb 0:8918a71cdbe9 471 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 472 //Check parameters
Sergunb 0:8918a71cdbe9 473 if(psk == NULL && pskLength != 0)
Sergunb 0:8918a71cdbe9 474 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 475
Sergunb 0:8918a71cdbe9 476 //Check whether the pre-shared key has already been configured
Sergunb 0:8918a71cdbe9 477 if(context->psk != NULL)
Sergunb 0:8918a71cdbe9 478 {
Sergunb 0:8918a71cdbe9 479 //Release memory
Sergunb 0:8918a71cdbe9 480 memset(context->psk, 0, context->pskLen);
Sergunb 0:8918a71cdbe9 481 tlsFreeMem(context->psk);
Sergunb 0:8918a71cdbe9 482 //Re-initialize length
Sergunb 0:8918a71cdbe9 483 context->pskLen = 0;
Sergunb 0:8918a71cdbe9 484 }
Sergunb 0:8918a71cdbe9 485
Sergunb 0:8918a71cdbe9 486 //Valid PSK?
Sergunb 0:8918a71cdbe9 487 if(pskLength > 0)
Sergunb 0:8918a71cdbe9 488 {
Sergunb 0:8918a71cdbe9 489 //Allocate a memory block to hold the pre-shared key
Sergunb 0:8918a71cdbe9 490 context->psk = tlsAllocMem(pskLength);
Sergunb 0:8918a71cdbe9 491 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 492 if(context->psk == NULL)
Sergunb 0:8918a71cdbe9 493 return ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 494
Sergunb 0:8918a71cdbe9 495 //Save the pre-shared key
Sergunb 0:8918a71cdbe9 496 memcpy(context->psk, psk, pskLength);
Sergunb 0:8918a71cdbe9 497 //Save the length of the key
Sergunb 0:8918a71cdbe9 498 context->pskLen = pskLength;
Sergunb 0:8918a71cdbe9 499 }
Sergunb 0:8918a71cdbe9 500
Sergunb 0:8918a71cdbe9 501 //Successful processing
Sergunb 0:8918a71cdbe9 502 return NO_ERROR;
Sergunb 0:8918a71cdbe9 503 #else
Sergunb 0:8918a71cdbe9 504 //PSK key exchange is not implemented
Sergunb 0:8918a71cdbe9 505 return ERROR_NOT_IMPLEMENTED;
Sergunb 0:8918a71cdbe9 506 #endif
Sergunb 0:8918a71cdbe9 507 }
Sergunb 0:8918a71cdbe9 508
Sergunb 0:8918a71cdbe9 509
Sergunb 0:8918a71cdbe9 510 /**
Sergunb 0:8918a71cdbe9 511 * @brief Set the PSK identity to be used by the client
Sergunb 0:8918a71cdbe9 512 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 513 * @param[in] pskIdentity NULL-terminated string that contains the PSK identity
Sergunb 0:8918a71cdbe9 514 * @return Error code
Sergunb 0:8918a71cdbe9 515 **/
Sergunb 0:8918a71cdbe9 516
Sergunb 0:8918a71cdbe9 517 error_t tlsSetPskIdentity(TlsContext *context, const char_t *pskIdentity)
Sergunb 0:8918a71cdbe9 518 {
Sergunb 0:8918a71cdbe9 519 #if (TLS_PSK_SUPPORT == ENABLED || TLS_RSA_PSK_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 520 TLS_DHE_PSK_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 521 size_t length;
Sergunb 0:8918a71cdbe9 522
Sergunb 0:8918a71cdbe9 523 //Invalid parameters?
Sergunb 0:8918a71cdbe9 524 if(context == NULL || pskIdentity == NULL)
Sergunb 0:8918a71cdbe9 525 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 526
Sergunb 0:8918a71cdbe9 527 //Retrieve the length of the PSK identity
Sergunb 0:8918a71cdbe9 528 length = strlen(pskIdentity);
Sergunb 0:8918a71cdbe9 529
Sergunb 0:8918a71cdbe9 530 //Check whether the PSK identity has already been configured
Sergunb 0:8918a71cdbe9 531 if(context->pskIdentity != NULL)
Sergunb 0:8918a71cdbe9 532 {
Sergunb 0:8918a71cdbe9 533 //Release memory
Sergunb 0:8918a71cdbe9 534 tlsFreeMem(context->pskIdentity);
Sergunb 0:8918a71cdbe9 535 context->pskIdentity = NULL;
Sergunb 0:8918a71cdbe9 536 }
Sergunb 0:8918a71cdbe9 537
Sergunb 0:8918a71cdbe9 538 //Valid PSK identity?
Sergunb 0:8918a71cdbe9 539 if(length > 0)
Sergunb 0:8918a71cdbe9 540 {
Sergunb 0:8918a71cdbe9 541 //Allocate a memory block to hold the PSK identity
Sergunb 0:8918a71cdbe9 542 context->pskIdentity = tlsAllocMem(length + 1);
Sergunb 0:8918a71cdbe9 543 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 544 if(context->pskIdentity == NULL)
Sergunb 0:8918a71cdbe9 545 return ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 546
Sergunb 0:8918a71cdbe9 547 //Save the PSK identity
Sergunb 0:8918a71cdbe9 548 strcpy(context->pskIdentity, pskIdentity);
Sergunb 0:8918a71cdbe9 549 }
Sergunb 0:8918a71cdbe9 550
Sergunb 0:8918a71cdbe9 551 //Successful processing
Sergunb 0:8918a71cdbe9 552 return NO_ERROR;
Sergunb 0:8918a71cdbe9 553 #else
Sergunb 0:8918a71cdbe9 554 //PSK key exchange is not implemented
Sergunb 0:8918a71cdbe9 555 return ERROR_NOT_IMPLEMENTED;
Sergunb 0:8918a71cdbe9 556 #endif
Sergunb 0:8918a71cdbe9 557 }
Sergunb 0:8918a71cdbe9 558
Sergunb 0:8918a71cdbe9 559
Sergunb 0:8918a71cdbe9 560 /**
Sergunb 0:8918a71cdbe9 561 * @brief Set the PSK identity hint to be used by the server
Sergunb 0:8918a71cdbe9 562 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 563 * @param[in] pskIdentityHint NULL-terminated string that contains the PSK identity hint
Sergunb 0:8918a71cdbe9 564 * @return Error code
Sergunb 0:8918a71cdbe9 565 **/
Sergunb 0:8918a71cdbe9 566
Sergunb 0:8918a71cdbe9 567 error_t tlsSetPskIdentityHint(TlsContext *context, const char_t *pskIdentityHint)
Sergunb 0:8918a71cdbe9 568 {
Sergunb 0:8918a71cdbe9 569 #if (TLS_PSK_SUPPORT == ENABLED || TLS_RSA_PSK_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 570 TLS_DHE_PSK_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 571 size_t length;
Sergunb 0:8918a71cdbe9 572
Sergunb 0:8918a71cdbe9 573 //Invalid parameters?
Sergunb 0:8918a71cdbe9 574 if(context == NULL || pskIdentityHint == NULL)
Sergunb 0:8918a71cdbe9 575 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 576
Sergunb 0:8918a71cdbe9 577 //Retrieve the length of the PSK identity hint
Sergunb 0:8918a71cdbe9 578 length = strlen(pskIdentityHint);
Sergunb 0:8918a71cdbe9 579
Sergunb 0:8918a71cdbe9 580 //Check whether the PSK identity hint has already been configured
Sergunb 0:8918a71cdbe9 581 if(context->pskIdentityHint != NULL)
Sergunb 0:8918a71cdbe9 582 {
Sergunb 0:8918a71cdbe9 583 //Release memory
Sergunb 0:8918a71cdbe9 584 tlsFreeMem(context->pskIdentityHint);
Sergunb 0:8918a71cdbe9 585 context->pskIdentityHint = NULL;
Sergunb 0:8918a71cdbe9 586 }
Sergunb 0:8918a71cdbe9 587
Sergunb 0:8918a71cdbe9 588 //Valid PSK identity hint?
Sergunb 0:8918a71cdbe9 589 if(length > 0)
Sergunb 0:8918a71cdbe9 590 {
Sergunb 0:8918a71cdbe9 591 //Allocate a memory block to hold the PSK identity hint
Sergunb 0:8918a71cdbe9 592 context->pskIdentityHint = tlsAllocMem(length + 1);
Sergunb 0:8918a71cdbe9 593 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 594 if(context->pskIdentityHint == NULL)
Sergunb 0:8918a71cdbe9 595 return ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 596
Sergunb 0:8918a71cdbe9 597 //Save the PSK identity hint
Sergunb 0:8918a71cdbe9 598 strcpy(context->pskIdentityHint, pskIdentityHint);
Sergunb 0:8918a71cdbe9 599 }
Sergunb 0:8918a71cdbe9 600
Sergunb 0:8918a71cdbe9 601 //Successful processing
Sergunb 0:8918a71cdbe9 602 return NO_ERROR;
Sergunb 0:8918a71cdbe9 603 #else
Sergunb 0:8918a71cdbe9 604 //PSK key exchange is not implemented
Sergunb 0:8918a71cdbe9 605 return ERROR_NOT_IMPLEMENTED;
Sergunb 0:8918a71cdbe9 606 #endif
Sergunb 0:8918a71cdbe9 607 }
Sergunb 0:8918a71cdbe9 608
Sergunb 0:8918a71cdbe9 609
Sergunb 0:8918a71cdbe9 610 /**
Sergunb 0:8918a71cdbe9 611 * @brief Register the PSK callback function
Sergunb 0:8918a71cdbe9 612 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 613 * @param[in] pskCallback PSK callback function
Sergunb 0:8918a71cdbe9 614 * @return Error code
Sergunb 0:8918a71cdbe9 615 **/
Sergunb 0:8918a71cdbe9 616
Sergunb 0:8918a71cdbe9 617 error_t tlsSetPskCallback(TlsContext *context, TlsPskCallback pskCallback)
Sergunb 0:8918a71cdbe9 618 {
Sergunb 0:8918a71cdbe9 619 #if (TLS_PSK_SUPPORT == ENABLED || TLS_RSA_PSK_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 620 TLS_DHE_PSK_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 621 //Invalid parameters?
Sergunb 0:8918a71cdbe9 622 if(context == NULL || pskCallback == NULL)
Sergunb 0:8918a71cdbe9 623 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 624
Sergunb 0:8918a71cdbe9 625 //Save the PSK callback function
Sergunb 0:8918a71cdbe9 626 context->pskCallback = pskCallback;
Sergunb 0:8918a71cdbe9 627
Sergunb 0:8918a71cdbe9 628 //Successful processing
Sergunb 0:8918a71cdbe9 629 return NO_ERROR;
Sergunb 0:8918a71cdbe9 630 #else
Sergunb 0:8918a71cdbe9 631 //PSK key exchange is not implemented
Sergunb 0:8918a71cdbe9 632 return ERROR_NOT_IMPLEMENTED;
Sergunb 0:8918a71cdbe9 633 #endif
Sergunb 0:8918a71cdbe9 634 }
Sergunb 0:8918a71cdbe9 635
Sergunb 0:8918a71cdbe9 636
Sergunb 0:8918a71cdbe9 637 /**
Sergunb 0:8918a71cdbe9 638 * @brief Import a trusted CA list
Sergunb 0:8918a71cdbe9 639 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 640 * @param[in] trustedCaList List of trusted CA (PEM format)
Sergunb 0:8918a71cdbe9 641 * @param[in] length Total length of the list
Sergunb 0:8918a71cdbe9 642 * @return Error code
Sergunb 0:8918a71cdbe9 643 **/
Sergunb 0:8918a71cdbe9 644
Sergunb 0:8918a71cdbe9 645 error_t tlsSetTrustedCaList(TlsContext *context,
Sergunb 0:8918a71cdbe9 646 const char_t *trustedCaList, size_t length)
Sergunb 0:8918a71cdbe9 647 {
Sergunb 0:8918a71cdbe9 648 //Invalid TLS context?
Sergunb 0:8918a71cdbe9 649 if(context == NULL)
Sergunb 0:8918a71cdbe9 650 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 651 //Check parameters
Sergunb 0:8918a71cdbe9 652 if(trustedCaList == NULL && length != 0)
Sergunb 0:8918a71cdbe9 653 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 654
Sergunb 0:8918a71cdbe9 655 //Save the certificate chain
Sergunb 0:8918a71cdbe9 656 context->trustedCaList = trustedCaList;
Sergunb 0:8918a71cdbe9 657 context->trustedCaListLen = length;
Sergunb 0:8918a71cdbe9 658
Sergunb 0:8918a71cdbe9 659 //Successful processing
Sergunb 0:8918a71cdbe9 660 return NO_ERROR;
Sergunb 0:8918a71cdbe9 661 }
Sergunb 0:8918a71cdbe9 662
Sergunb 0:8918a71cdbe9 663
Sergunb 0:8918a71cdbe9 664 /**
Sergunb 0:8918a71cdbe9 665 * @brief Import a certificate and the corresponding private key
Sergunb 0:8918a71cdbe9 666 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 667 * @param[in] certChain Certificate chain (PEM format)
Sergunb 0:8918a71cdbe9 668 * @param[in] certChainLength Total length of the certificate chain
Sergunb 0:8918a71cdbe9 669 * @param[in] privateKey Private key (PEM format)
Sergunb 0:8918a71cdbe9 670 * @param[in] privateKeyLength Total length of the private key
Sergunb 0:8918a71cdbe9 671 * @return Error code
Sergunb 0:8918a71cdbe9 672 **/
Sergunb 0:8918a71cdbe9 673
Sergunb 0:8918a71cdbe9 674 error_t tlsAddCertificate(TlsContext *context, const char_t *certChain,
Sergunb 0:8918a71cdbe9 675 size_t certChainLength, const char_t *privateKey, size_t privateKeyLength)
Sergunb 0:8918a71cdbe9 676 {
Sergunb 0:8918a71cdbe9 677 error_t error;
Sergunb 0:8918a71cdbe9 678 const char_t *p;
Sergunb 0:8918a71cdbe9 679 size_t n;
Sergunb 0:8918a71cdbe9 680 uint8_t *derCert;
Sergunb 0:8918a71cdbe9 681 size_t derCertSize;
Sergunb 0:8918a71cdbe9 682 size_t derCertLength;
Sergunb 0:8918a71cdbe9 683 X509CertificateInfo *certInfo;
Sergunb 0:8918a71cdbe9 684 TlsCertificateType certType;
Sergunb 0:8918a71cdbe9 685 TlsSignatureAlgo certSignAlgo;
Sergunb 0:8918a71cdbe9 686 TlsHashAlgo certHashAlgo;
Sergunb 0:8918a71cdbe9 687 TlsEcNamedCurve namedCurve;
Sergunb 0:8918a71cdbe9 688
Sergunb 0:8918a71cdbe9 689 //Invalid TLS context?
Sergunb 0:8918a71cdbe9 690 if(context == NULL)
Sergunb 0:8918a71cdbe9 691 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 692
Sergunb 0:8918a71cdbe9 693 //Check parameters
Sergunb 0:8918a71cdbe9 694 if(certChain == NULL || certChainLength == 0)
Sergunb 0:8918a71cdbe9 695 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 696 if(privateKey == NULL || privateKeyLength == 0)
Sergunb 0:8918a71cdbe9 697 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 698
Sergunb 0:8918a71cdbe9 699 //Make sure there is enough room to add the certificate
Sergunb 0:8918a71cdbe9 700 if(context->numCerts >= TLS_MAX_CERTIFICATES)
Sergunb 0:8918a71cdbe9 701 return ERROR_OUT_OF_RESOURCES;
Sergunb 0:8918a71cdbe9 702
Sergunb 0:8918a71cdbe9 703 //Allocate a memory buffer to store X.509 certificate info
Sergunb 0:8918a71cdbe9 704 certInfo = tlsAllocMem(sizeof(X509CertificateInfo));
Sergunb 0:8918a71cdbe9 705 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 706 if(certInfo == NULL)
Sergunb 0:8918a71cdbe9 707 return ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 708
Sergunb 0:8918a71cdbe9 709 //Point to the beginning of the certificate chain
Sergunb 0:8918a71cdbe9 710 p = certChain;
Sergunb 0:8918a71cdbe9 711 n = certChainLength;
Sergunb 0:8918a71cdbe9 712
Sergunb 0:8918a71cdbe9 713 //DER encoded certificate
Sergunb 0:8918a71cdbe9 714 derCert = NULL;
Sergunb 0:8918a71cdbe9 715 derCertSize = 0;
Sergunb 0:8918a71cdbe9 716 derCertLength = 0;
Sergunb 0:8918a71cdbe9 717
Sergunb 0:8918a71cdbe9 718 //Start of exception handling block
Sergunb 0:8918a71cdbe9 719 do
Sergunb 0:8918a71cdbe9 720 {
Sergunb 0:8918a71cdbe9 721 //Decode end entity certificate
Sergunb 0:8918a71cdbe9 722 error = pemReadCertificate(&p, &n, &derCert, &derCertSize, &derCertLength);
Sergunb 0:8918a71cdbe9 723 //Any error to report?
Sergunb 0:8918a71cdbe9 724 if(error)
Sergunb 0:8918a71cdbe9 725 break;
Sergunb 0:8918a71cdbe9 726
Sergunb 0:8918a71cdbe9 727 //Parse X.509 certificate
Sergunb 0:8918a71cdbe9 728 error = x509ParseCertificate(derCert, derCertLength, certInfo);
Sergunb 0:8918a71cdbe9 729 //Failed to parse the X.509 certificate?
Sergunb 0:8918a71cdbe9 730 if(error)
Sergunb 0:8918a71cdbe9 731 break;
Sergunb 0:8918a71cdbe9 732
Sergunb 0:8918a71cdbe9 733 //Retrieve the signature algorithm that has been used to sign the certificate
Sergunb 0:8918a71cdbe9 734 error = tlsGetCertificateType(certInfo, &certType,
Sergunb 0:8918a71cdbe9 735 &certSignAlgo, &certHashAlgo, &namedCurve);
Sergunb 0:8918a71cdbe9 736 //The specified signature algorithm is not supported?
Sergunb 0:8918a71cdbe9 737 if(error)
Sergunb 0:8918a71cdbe9 738 break;
Sergunb 0:8918a71cdbe9 739
Sergunb 0:8918a71cdbe9 740 //End of exception handling block
Sergunb 0:8918a71cdbe9 741 } while(0);
Sergunb 0:8918a71cdbe9 742
Sergunb 0:8918a71cdbe9 743 //Check whether the certificate is acceptable
Sergunb 0:8918a71cdbe9 744 if(!error)
Sergunb 0:8918a71cdbe9 745 {
Sergunb 0:8918a71cdbe9 746 //Point to the structure that describes the certificate
Sergunb 0:8918a71cdbe9 747 TlsCertDesc *cert = &context->certs[context->numCerts];
Sergunb 0:8918a71cdbe9 748
Sergunb 0:8918a71cdbe9 749 //Save the certificate chain and the corresponding private key
Sergunb 0:8918a71cdbe9 750 cert->certChain = certChain;
Sergunb 0:8918a71cdbe9 751 cert->certChainLength = certChainLength;
Sergunb 0:8918a71cdbe9 752 cert->privateKey = privateKey;
Sergunb 0:8918a71cdbe9 753 cert->privateKeyLength = privateKeyLength;
Sergunb 0:8918a71cdbe9 754 cert->type = certType;
Sergunb 0:8918a71cdbe9 755 cert->signAlgo = certSignAlgo;
Sergunb 0:8918a71cdbe9 756 cert->hashAlgo = certHashAlgo;
Sergunb 0:8918a71cdbe9 757 cert->namedCurve = namedCurve;
Sergunb 0:8918a71cdbe9 758
Sergunb 0:8918a71cdbe9 759 //Update the number of certificates
Sergunb 0:8918a71cdbe9 760 context->numCerts++;
Sergunb 0:8918a71cdbe9 761 }
Sergunb 0:8918a71cdbe9 762
Sergunb 0:8918a71cdbe9 763 //Release previously allocated memory
Sergunb 0:8918a71cdbe9 764 tlsFreeMem(derCert);
Sergunb 0:8918a71cdbe9 765 tlsFreeMem(certInfo);
Sergunb 0:8918a71cdbe9 766
Sergunb 0:8918a71cdbe9 767 //Return status code
Sergunb 0:8918a71cdbe9 768 return error;
Sergunb 0:8918a71cdbe9 769 }
Sergunb 0:8918a71cdbe9 770
Sergunb 0:8918a71cdbe9 771
Sergunb 0:8918a71cdbe9 772 /**
Sergunb 0:8918a71cdbe9 773 * @brief Initiate the TLS handshake
Sergunb 0:8918a71cdbe9 774 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 775 * @return Error code
Sergunb 0:8918a71cdbe9 776 **/
Sergunb 0:8918a71cdbe9 777
Sergunb 0:8918a71cdbe9 778 error_t tlsConnect(TlsContext *context)
Sergunb 0:8918a71cdbe9 779 {
Sergunb 0:8918a71cdbe9 780 error_t error;
Sergunb 0:8918a71cdbe9 781
Sergunb 0:8918a71cdbe9 782 //Invalid TLS context?
Sergunb 0:8918a71cdbe9 783 if(context == NULL)
Sergunb 0:8918a71cdbe9 784 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 785
Sergunb 0:8918a71cdbe9 786 //Ensure the I/O callback functions are properly registered
Sergunb 0:8918a71cdbe9 787 if(context->sendCallback == NULL || context->receiveCallback == NULL)
Sergunb 0:8918a71cdbe9 788 return ERROR_NOT_CONFIGURED;
Sergunb 0:8918a71cdbe9 789
Sergunb 0:8918a71cdbe9 790 //Verify that the PRNG is properly set
Sergunb 0:8918a71cdbe9 791 if(context->prngAlgo == NULL || context->prngContext == NULL)
Sergunb 0:8918a71cdbe9 792 return ERROR_NOT_CONFIGURED;
Sergunb 0:8918a71cdbe9 793
Sergunb 0:8918a71cdbe9 794 //Check current state
Sergunb 0:8918a71cdbe9 795 if(context->state == TLS_STATE_INIT)
Sergunb 0:8918a71cdbe9 796 {
Sergunb 0:8918a71cdbe9 797 //Allocate send buffer if necessary
Sergunb 0:8918a71cdbe9 798 if(context->txBuffer == NULL)
Sergunb 0:8918a71cdbe9 799 {
Sergunb 0:8918a71cdbe9 800 //Allocate TX buffer
Sergunb 0:8918a71cdbe9 801 context->txBuffer = tlsAllocMem(context->txBufferSize);
Sergunb 0:8918a71cdbe9 802
Sergunb 0:8918a71cdbe9 803 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 804 if(context->txBuffer == NULL)
Sergunb 0:8918a71cdbe9 805 return ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 806
Sergunb 0:8918a71cdbe9 807 //Clear TX buffer
Sergunb 0:8918a71cdbe9 808 memset(context->txBuffer, 0, context->txBufferSize);
Sergunb 0:8918a71cdbe9 809 }
Sergunb 0:8918a71cdbe9 810
Sergunb 0:8918a71cdbe9 811 //Allocate receive buffer if necessary
Sergunb 0:8918a71cdbe9 812 if(context->rxBuffer == NULL)
Sergunb 0:8918a71cdbe9 813 {
Sergunb 0:8918a71cdbe9 814 //Allocate RX buffer
Sergunb 0:8918a71cdbe9 815 context->rxBuffer = tlsAllocMem(context->rxBufferSize);
Sergunb 0:8918a71cdbe9 816
Sergunb 0:8918a71cdbe9 817 //Failed to allocate memory?
Sergunb 0:8918a71cdbe9 818 if(context->rxBuffer == NULL)
Sergunb 0:8918a71cdbe9 819 {
Sergunb 0:8918a71cdbe9 820 //Clean up side effects
Sergunb 0:8918a71cdbe9 821 tlsFreeMem(context->txBuffer);
Sergunb 0:8918a71cdbe9 822 context->txBuffer = NULL;
Sergunb 0:8918a71cdbe9 823 //Report an error
Sergunb 0:8918a71cdbe9 824 return ERROR_OUT_OF_MEMORY;
Sergunb 0:8918a71cdbe9 825 }
Sergunb 0:8918a71cdbe9 826
Sergunb 0:8918a71cdbe9 827 //Clear RX buffer
Sergunb 0:8918a71cdbe9 828 memset(context->rxBuffer, 0, context->rxBufferSize);
Sergunb 0:8918a71cdbe9 829 }
Sergunb 0:8918a71cdbe9 830 }
Sergunb 0:8918a71cdbe9 831
Sergunb 0:8918a71cdbe9 832 //Perform TLS handshake
Sergunb 0:8918a71cdbe9 833 error = tlsHandshake(context);
Sergunb 0:8918a71cdbe9 834 //Return status code
Sergunb 0:8918a71cdbe9 835 return error;
Sergunb 0:8918a71cdbe9 836 }
Sergunb 0:8918a71cdbe9 837
Sergunb 0:8918a71cdbe9 838
Sergunb 0:8918a71cdbe9 839 /**
Sergunb 0:8918a71cdbe9 840 * @brief Send application data to the remote host using TLS
Sergunb 0:8918a71cdbe9 841 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 842 * @param[in] data Pointer to a buffer containing the data to be transmitted
Sergunb 0:8918a71cdbe9 843 * @param[in] length Number of bytes to be transmitted
Sergunb 0:8918a71cdbe9 844 * @param[out] written Actual number of bytes written (optional parameter)
Sergunb 0:8918a71cdbe9 845 * @param[in] flags Set of flags that influences the behavior of this function
Sergunb 0:8918a71cdbe9 846 * @return Error code
Sergunb 0:8918a71cdbe9 847 **/
Sergunb 0:8918a71cdbe9 848
Sergunb 0:8918a71cdbe9 849 error_t tlsWrite(TlsContext *context, const void *data,
Sergunb 0:8918a71cdbe9 850 size_t length, size_t *written, uint_t flags)
Sergunb 0:8918a71cdbe9 851 {
Sergunb 0:8918a71cdbe9 852 error_t error;
Sergunb 0:8918a71cdbe9 853 size_t n;
Sergunb 0:8918a71cdbe9 854 size_t totalLength;
Sergunb 0:8918a71cdbe9 855
Sergunb 0:8918a71cdbe9 856 //Invalid TLS context?
Sergunb 0:8918a71cdbe9 857 if(context == NULL)
Sergunb 0:8918a71cdbe9 858 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 859
Sergunb 0:8918a71cdbe9 860 //Check parameters
Sergunb 0:8918a71cdbe9 861 if(data == NULL && length != 0)
Sergunb 0:8918a71cdbe9 862 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 863
Sergunb 0:8918a71cdbe9 864 //Ensure the I/O callback functions are properly registered
Sergunb 0:8918a71cdbe9 865 if(context->sendCallback == NULL || context->receiveCallback == NULL)
Sergunb 0:8918a71cdbe9 866 return ERROR_NOT_CONFIGURED;
Sergunb 0:8918a71cdbe9 867
Sergunb 0:8918a71cdbe9 868 //Initialize status code
Sergunb 0:8918a71cdbe9 869 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 870
Sergunb 0:8918a71cdbe9 871 //Actual number of bytes written
Sergunb 0:8918a71cdbe9 872 totalLength = 0;
Sergunb 0:8918a71cdbe9 873
Sergunb 0:8918a71cdbe9 874 //Send as much data as possible
Sergunb 0:8918a71cdbe9 875 while(totalLength < length)
Sergunb 0:8918a71cdbe9 876 {
Sergunb 0:8918a71cdbe9 877 //Check current state
Sergunb 0:8918a71cdbe9 878 if(context->state == TLS_STATE_APPLICATION_DATA)
Sergunb 0:8918a71cdbe9 879 {
Sergunb 0:8918a71cdbe9 880 //Calculate the number of bytes to write at a time
Sergunb 0:8918a71cdbe9 881 n = MIN(length - totalLength, context->txRecordMaxLen);
Sergunb 0:8918a71cdbe9 882 //The record length must not exceed 16384 bytes
Sergunb 0:8918a71cdbe9 883 n = MIN(n, TLS_MAX_RECORD_LENGTH);
Sergunb 0:8918a71cdbe9 884
Sergunb 0:8918a71cdbe9 885 //Send application data
Sergunb 0:8918a71cdbe9 886 error = tlsWriteProtocolData(context, data, n, TLS_TYPE_APPLICATION_DATA);
Sergunb 0:8918a71cdbe9 887
Sergunb 0:8918a71cdbe9 888 //Check status code
Sergunb 0:8918a71cdbe9 889 if(!error)
Sergunb 0:8918a71cdbe9 890 {
Sergunb 0:8918a71cdbe9 891 //Advance data pointer
Sergunb 0:8918a71cdbe9 892 data = (uint8_t *) data + n;
Sergunb 0:8918a71cdbe9 893 //Update byte counter
Sergunb 0:8918a71cdbe9 894 totalLength += n;
Sergunb 0:8918a71cdbe9 895 }
Sergunb 0:8918a71cdbe9 896 else
Sergunb 0:8918a71cdbe9 897 {
Sergunb 0:8918a71cdbe9 898 //Send an alert message to the peer, if applicable
Sergunb 0:8918a71cdbe9 899 tlsProcessError(context, error);
Sergunb 0:8918a71cdbe9 900 }
Sergunb 0:8918a71cdbe9 901 }
Sergunb 0:8918a71cdbe9 902 else
Sergunb 0:8918a71cdbe9 903 {
Sergunb 0:8918a71cdbe9 904 //The connection has not yet been established
Sergunb 0:8918a71cdbe9 905 error = ERROR_NOT_CONNECTED;
Sergunb 0:8918a71cdbe9 906 }
Sergunb 0:8918a71cdbe9 907
Sergunb 0:8918a71cdbe9 908 //Any error to report?
Sergunb 0:8918a71cdbe9 909 if(error)
Sergunb 0:8918a71cdbe9 910 break;
Sergunb 0:8918a71cdbe9 911 }
Sergunb 0:8918a71cdbe9 912
Sergunb 0:8918a71cdbe9 913 //Total number of data that have been written
Sergunb 0:8918a71cdbe9 914 if(written != NULL)
Sergunb 0:8918a71cdbe9 915 *written = totalLength;
Sergunb 0:8918a71cdbe9 916
Sergunb 0:8918a71cdbe9 917 //Return status code
Sergunb 0:8918a71cdbe9 918 return error;
Sergunb 0:8918a71cdbe9 919 }
Sergunb 0:8918a71cdbe9 920
Sergunb 0:8918a71cdbe9 921
Sergunb 0:8918a71cdbe9 922 /**
Sergunb 0:8918a71cdbe9 923 * @brief Receive application data from a the remote host using TLS
Sergunb 0:8918a71cdbe9 924 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 925 * @param[out] data Buffer into which received data will be placed
Sergunb 0:8918a71cdbe9 926 * @param[in] size Maximum number of bytes that can be received
Sergunb 0:8918a71cdbe9 927 * @param[out] received Number of bytes that have been received
Sergunb 0:8918a71cdbe9 928 * @param[in] flags Set of flags that influences the behavior of this function
Sergunb 0:8918a71cdbe9 929 * @return Error code
Sergunb 0:8918a71cdbe9 930 **/
Sergunb 0:8918a71cdbe9 931
Sergunb 0:8918a71cdbe9 932 error_t tlsRead(TlsContext *context, void *data,
Sergunb 0:8918a71cdbe9 933 size_t size, size_t *received, uint_t flags)
Sergunb 0:8918a71cdbe9 934 {
Sergunb 0:8918a71cdbe9 935 error_t error;
Sergunb 0:8918a71cdbe9 936 size_t i;
Sergunb 0:8918a71cdbe9 937 size_t n;
Sergunb 0:8918a71cdbe9 938 uint8_t *p;
Sergunb 0:8918a71cdbe9 939 TlsContentType contentType;
Sergunb 0:8918a71cdbe9 940
Sergunb 0:8918a71cdbe9 941 //Invalid TLS context?
Sergunb 0:8918a71cdbe9 942 if(context == NULL)
Sergunb 0:8918a71cdbe9 943 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 944
Sergunb 0:8918a71cdbe9 945 //Check parameters
Sergunb 0:8918a71cdbe9 946 if(data == NULL && received == NULL)
Sergunb 0:8918a71cdbe9 947 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 948
Sergunb 0:8918a71cdbe9 949 //Ensure the I/O callback functions are properly registered
Sergunb 0:8918a71cdbe9 950 if(context->sendCallback == NULL || context->receiveCallback == NULL)
Sergunb 0:8918a71cdbe9 951 return ERROR_NOT_CONFIGURED;
Sergunb 0:8918a71cdbe9 952
Sergunb 0:8918a71cdbe9 953 //Initialize status code
Sergunb 0:8918a71cdbe9 954 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 955
Sergunb 0:8918a71cdbe9 956 //No data has been read yet
Sergunb 0:8918a71cdbe9 957 *received = 0;
Sergunb 0:8918a71cdbe9 958
Sergunb 0:8918a71cdbe9 959 //Read as much data as possible
Sergunb 0:8918a71cdbe9 960 while(*received < size)
Sergunb 0:8918a71cdbe9 961 {
Sergunb 0:8918a71cdbe9 962 //Check current state
Sergunb 0:8918a71cdbe9 963 if(context->state == TLS_STATE_APPLICATION_DATA)
Sergunb 0:8918a71cdbe9 964 {
Sergunb 0:8918a71cdbe9 965 //The TLS record layer receives uninterpreted data from higher layers
Sergunb 0:8918a71cdbe9 966 error = tlsReadProtocolData(context, (void **) &p, &n, &contentType);
Sergunb 0:8918a71cdbe9 967
Sergunb 0:8918a71cdbe9 968 //Check status code
Sergunb 0:8918a71cdbe9 969 if(!error)
Sergunb 0:8918a71cdbe9 970 {
Sergunb 0:8918a71cdbe9 971 //Application data received?
Sergunb 0:8918a71cdbe9 972 if(contentType == TLS_TYPE_APPLICATION_DATA)
Sergunb 0:8918a71cdbe9 973 {
Sergunb 0:8918a71cdbe9 974 //Limit the number of bytes to read at a time
Sergunb 0:8918a71cdbe9 975 n = MIN(n, size - *received);
Sergunb 0:8918a71cdbe9 976
Sergunb 0:8918a71cdbe9 977 //The TLS_FLAG_BREAK_CHAR flag causes the function to stop reading
Sergunb 0:8918a71cdbe9 978 //data as soon as the specified break character is encountered
Sergunb 0:8918a71cdbe9 979 if(flags & TLS_FLAG_BREAK_CHAR)
Sergunb 0:8918a71cdbe9 980 {
Sergunb 0:8918a71cdbe9 981 //Retrieve the break character code
Sergunb 0:8918a71cdbe9 982 char_t c = LSB(flags);
Sergunb 0:8918a71cdbe9 983
Sergunb 0:8918a71cdbe9 984 //Search for the specified break character
Sergunb 0:8918a71cdbe9 985 for(i = 0; i < n && p[i] != c; i++);
Sergunb 0:8918a71cdbe9 986 //Adjust the number of data to read
Sergunb 0:8918a71cdbe9 987 n = MIN(n, i + 1);
Sergunb 0:8918a71cdbe9 988
Sergunb 0:8918a71cdbe9 989 //Copy data to user buffer
Sergunb 0:8918a71cdbe9 990 memcpy(data, p, n);
Sergunb 0:8918a71cdbe9 991 //Total number of data that have been read
Sergunb 0:8918a71cdbe9 992 *received += n;
Sergunb 0:8918a71cdbe9 993
Sergunb 0:8918a71cdbe9 994 //Advance data pointer
Sergunb 0:8918a71cdbe9 995 context->rxBufferPos += n;
Sergunb 0:8918a71cdbe9 996 //Number of bytes still pending in the receive buffer
Sergunb 0:8918a71cdbe9 997 context->rxBufferLen -= n;
Sergunb 0:8918a71cdbe9 998
Sergunb 0:8918a71cdbe9 999 //Check whether a break character has been found
Sergunb 0:8918a71cdbe9 1000 if(n > 0 && p[n - 1] == c)
Sergunb 0:8918a71cdbe9 1001 break;
Sergunb 0:8918a71cdbe9 1002 }
Sergunb 0:8918a71cdbe9 1003 else
Sergunb 0:8918a71cdbe9 1004 {
Sergunb 0:8918a71cdbe9 1005 //Copy data to user buffer
Sergunb 0:8918a71cdbe9 1006 memcpy(data, p, n);
Sergunb 0:8918a71cdbe9 1007 //Total number of data that have been read
Sergunb 0:8918a71cdbe9 1008 *received += n;
Sergunb 0:8918a71cdbe9 1009
Sergunb 0:8918a71cdbe9 1010 //Advance data pointer
Sergunb 0:8918a71cdbe9 1011 context->rxBufferPos += n;
Sergunb 0:8918a71cdbe9 1012 //Number of bytes still pending in the receive buffer
Sergunb 0:8918a71cdbe9 1013 context->rxBufferLen -= n;
Sergunb 0:8918a71cdbe9 1014
Sergunb 0:8918a71cdbe9 1015 //The TLS_FLAG_WAIT_ALL flag causes the function to return
Sergunb 0:8918a71cdbe9 1016 //only when the requested number of bytes have been read
Sergunb 0:8918a71cdbe9 1017 if(!(flags & TLS_FLAG_WAIT_ALL))
Sergunb 0:8918a71cdbe9 1018 break;
Sergunb 0:8918a71cdbe9 1019 }
Sergunb 0:8918a71cdbe9 1020
Sergunb 0:8918a71cdbe9 1021 //Advance data pointer
Sergunb 0:8918a71cdbe9 1022 data = (uint8_t *) data + n;
Sergunb 0:8918a71cdbe9 1023 }
Sergunb 0:8918a71cdbe9 1024 //Alert message received?
Sergunb 0:8918a71cdbe9 1025 else if(contentType == TLS_TYPE_ALERT)
Sergunb 0:8918a71cdbe9 1026 {
Sergunb 0:8918a71cdbe9 1027 //Parse Alert message
Sergunb 0:8918a71cdbe9 1028 error = tlsParseAlert(context, (TlsAlert *) p, n);
Sergunb 0:8918a71cdbe9 1029
Sergunb 0:8918a71cdbe9 1030 //Advance data pointer
Sergunb 0:8918a71cdbe9 1031 context->rxBufferPos += n;
Sergunb 0:8918a71cdbe9 1032 //Number of bytes still pending in the receive buffer
Sergunb 0:8918a71cdbe9 1033 context->rxBufferLen -= n;
Sergunb 0:8918a71cdbe9 1034 }
Sergunb 0:8918a71cdbe9 1035 //An inappropriate message was received?
Sergunb 0:8918a71cdbe9 1036 else
Sergunb 0:8918a71cdbe9 1037 {
Sergunb 0:8918a71cdbe9 1038 //Report an error
Sergunb 0:8918a71cdbe9 1039 error = ERROR_UNEXPECTED_MESSAGE;
Sergunb 0:8918a71cdbe9 1040 }
Sergunb 0:8918a71cdbe9 1041 }
Sergunb 0:8918a71cdbe9 1042
Sergunb 0:8918a71cdbe9 1043 //Any error to report?
Sergunb 0:8918a71cdbe9 1044 if(error)
Sergunb 0:8918a71cdbe9 1045 {
Sergunb 0:8918a71cdbe9 1046 //Send an alert message to the peer, if applicable
Sergunb 0:8918a71cdbe9 1047 tlsProcessError(context, error);
Sergunb 0:8918a71cdbe9 1048 }
Sergunb 0:8918a71cdbe9 1049 }
Sergunb 0:8918a71cdbe9 1050 else if(context->state == TLS_STATE_CLOSING ||
Sergunb 0:8918a71cdbe9 1051 context->state == TLS_STATE_CLOSED)
Sergunb 0:8918a71cdbe9 1052 {
Sergunb 0:8918a71cdbe9 1053 //Check whether a fatal alert message has been sent or received
Sergunb 0:8918a71cdbe9 1054 if(context->fatalAlertSent || context->fatalAlertReceived)
Sergunb 0:8918a71cdbe9 1055 {
Sergunb 0:8918a71cdbe9 1056 //Alert messages with a level of fatal result in the immediate
Sergunb 0:8918a71cdbe9 1057 //termination of the connection
Sergunb 0:8918a71cdbe9 1058 error = ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 1059 }
Sergunb 0:8918a71cdbe9 1060 else
Sergunb 0:8918a71cdbe9 1061 {
Sergunb 0:8918a71cdbe9 1062 //The user must be satisfied with data already on hand
Sergunb 0:8918a71cdbe9 1063 if(*received > 0)
Sergunb 0:8918a71cdbe9 1064 {
Sergunb 0:8918a71cdbe9 1065 //Some data are pending in the receive buffer
Sergunb 0:8918a71cdbe9 1066 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 1067 break;
Sergunb 0:8918a71cdbe9 1068 }
Sergunb 0:8918a71cdbe9 1069 else
Sergunb 0:8918a71cdbe9 1070 {
Sergunb 0:8918a71cdbe9 1071 //The receive buffer is empty
Sergunb 0:8918a71cdbe9 1072 error = ERROR_END_OF_STREAM;
Sergunb 0:8918a71cdbe9 1073 }
Sergunb 0:8918a71cdbe9 1074 }
Sergunb 0:8918a71cdbe9 1075 }
Sergunb 0:8918a71cdbe9 1076 else
Sergunb 0:8918a71cdbe9 1077 {
Sergunb 0:8918a71cdbe9 1078 //The connection has not yet been established
Sergunb 0:8918a71cdbe9 1079 error = ERROR_NOT_CONNECTED;
Sergunb 0:8918a71cdbe9 1080 }
Sergunb 0:8918a71cdbe9 1081
Sergunb 0:8918a71cdbe9 1082 //Any error to report?
Sergunb 0:8918a71cdbe9 1083 if(error)
Sergunb 0:8918a71cdbe9 1084 break;
Sergunb 0:8918a71cdbe9 1085 }
Sergunb 0:8918a71cdbe9 1086
Sergunb 0:8918a71cdbe9 1087 //Return status code
Sergunb 0:8918a71cdbe9 1088 return error;
Sergunb 0:8918a71cdbe9 1089 }
Sergunb 0:8918a71cdbe9 1090
Sergunb 0:8918a71cdbe9 1091
Sergunb 0:8918a71cdbe9 1092 /**
Sergunb 0:8918a71cdbe9 1093 * @brief Gracefully close TLS session
Sergunb 0:8918a71cdbe9 1094 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 1095 **/
Sergunb 0:8918a71cdbe9 1096
Sergunb 0:8918a71cdbe9 1097 error_t tlsShutdown(TlsContext *context)
Sergunb 0:8918a71cdbe9 1098 {
Sergunb 0:8918a71cdbe9 1099 //Either party may initiate a close by sending a close_notify alert
Sergunb 0:8918a71cdbe9 1100 return tlsShutdownEx(context, FALSE);
Sergunb 0:8918a71cdbe9 1101 }
Sergunb 0:8918a71cdbe9 1102
Sergunb 0:8918a71cdbe9 1103
Sergunb 0:8918a71cdbe9 1104 /**
Sergunb 0:8918a71cdbe9 1105 * @brief Gracefully close TLS session
Sergunb 0:8918a71cdbe9 1106 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 1107 * @param[in] waitForCloseNotify Wait for the close notify alert from the peer
Sergunb 0:8918a71cdbe9 1108 **/
Sergunb 0:8918a71cdbe9 1109
Sergunb 0:8918a71cdbe9 1110 error_t tlsShutdownEx(TlsContext *context, bool_t waitForCloseNotify)
Sergunb 0:8918a71cdbe9 1111 {
Sergunb 0:8918a71cdbe9 1112 error_t error;
Sergunb 0:8918a71cdbe9 1113 size_t n;
Sergunb 0:8918a71cdbe9 1114 uint8_t *p;
Sergunb 0:8918a71cdbe9 1115 TlsContentType contentType;
Sergunb 0:8918a71cdbe9 1116
Sergunb 0:8918a71cdbe9 1117 //Invalid TLS context?
Sergunb 0:8918a71cdbe9 1118 if(context == NULL)
Sergunb 0:8918a71cdbe9 1119 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 1120
Sergunb 0:8918a71cdbe9 1121 //Ensure the I/O callback functions are properly registered
Sergunb 0:8918a71cdbe9 1122 if(context->sendCallback == NULL || context->receiveCallback == NULL)
Sergunb 0:8918a71cdbe9 1123 return ERROR_NOT_CONFIGURED;
Sergunb 0:8918a71cdbe9 1124
Sergunb 0:8918a71cdbe9 1125 //Initialize status code
Sergunb 0:8918a71cdbe9 1126 error = NO_ERROR;
Sergunb 0:8918a71cdbe9 1127
Sergunb 0:8918a71cdbe9 1128 //Wait for the TLS session to be closed
Sergunb 0:8918a71cdbe9 1129 while(context->state != TLS_STATE_CLOSED)
Sergunb 0:8918a71cdbe9 1130 {
Sergunb 0:8918a71cdbe9 1131 //Check current state
Sergunb 0:8918a71cdbe9 1132 if(context->state == TLS_STATE_APPLICATION_DATA)
Sergunb 0:8918a71cdbe9 1133 {
Sergunb 0:8918a71cdbe9 1134 //Flush send buffer
Sergunb 0:8918a71cdbe9 1135 error = tlsWriteProtocolData(context, NULL, 0, TLS_TYPE_NONE);
Sergunb 0:8918a71cdbe9 1136
Sergunb 0:8918a71cdbe9 1137 //Check status code
Sergunb 0:8918a71cdbe9 1138 if(!error)
Sergunb 0:8918a71cdbe9 1139 {
Sergunb 0:8918a71cdbe9 1140 //Either party may initiate a close by sending a close_notify alert
Sergunb 0:8918a71cdbe9 1141 context->state = TLS_STATE_CLOSING;
Sergunb 0:8918a71cdbe9 1142 }
Sergunb 0:8918a71cdbe9 1143 }
Sergunb 0:8918a71cdbe9 1144 if(context->state == TLS_STATE_CLOSING)
Sergunb 0:8918a71cdbe9 1145 {
Sergunb 0:8918a71cdbe9 1146 //Flush send buffer
Sergunb 0:8918a71cdbe9 1147 error = tlsWriteProtocolData(context, NULL, 0, TLS_TYPE_NONE);
Sergunb 0:8918a71cdbe9 1148
Sergunb 0:8918a71cdbe9 1149 //Check status code
Sergunb 0:8918a71cdbe9 1150 if(!error)
Sergunb 0:8918a71cdbe9 1151 {
Sergunb 0:8918a71cdbe9 1152 //Unless some other fatal alert has been transmitted, each party
Sergunb 0:8918a71cdbe9 1153 //is required to send a close_notify alert before closing the
Sergunb 0:8918a71cdbe9 1154 //write side of the connection
Sergunb 0:8918a71cdbe9 1155 if(context->fatalAlertSent || context->fatalAlertReceived)
Sergunb 0:8918a71cdbe9 1156 {
Sergunb 0:8918a71cdbe9 1157 //Close the connection immediately
Sergunb 0:8918a71cdbe9 1158 context->state = TLS_STATE_CLOSED;
Sergunb 0:8918a71cdbe9 1159 }
Sergunb 0:8918a71cdbe9 1160 else if(!context->closeNotifySent)
Sergunb 0:8918a71cdbe9 1161 {
Sergunb 0:8918a71cdbe9 1162 //Notifies the recipient that the sender will not send any
Sergunb 0:8918a71cdbe9 1163 //more messages on this connection
Sergunb 0:8918a71cdbe9 1164 error = tlsSendAlert(context, TLS_ALERT_LEVEL_WARNING,
Sergunb 0:8918a71cdbe9 1165 TLS_ALERT_CLOSE_NOTIFY);
Sergunb 0:8918a71cdbe9 1166 }
Sergunb 0:8918a71cdbe9 1167 else if(!context->closeNotifyReceived && waitForCloseNotify)
Sergunb 0:8918a71cdbe9 1168 {
Sergunb 0:8918a71cdbe9 1169 //Wait for the responding close_notify alert
Sergunb 0:8918a71cdbe9 1170 error = tlsReadProtocolData(context, (void **) &p, &n, &contentType);
Sergunb 0:8918a71cdbe9 1171
Sergunb 0:8918a71cdbe9 1172 //Check status code
Sergunb 0:8918a71cdbe9 1173 if(!error)
Sergunb 0:8918a71cdbe9 1174 {
Sergunb 0:8918a71cdbe9 1175 //Application data received?
Sergunb 0:8918a71cdbe9 1176 if(contentType == TLS_TYPE_APPLICATION_DATA)
Sergunb 0:8918a71cdbe9 1177 {
Sergunb 0:8918a71cdbe9 1178 //Advance data pointer
Sergunb 0:8918a71cdbe9 1179 context->rxBufferPos += n;
Sergunb 0:8918a71cdbe9 1180 //Number of bytes still pending in the receive buffer
Sergunb 0:8918a71cdbe9 1181 context->rxBufferLen -= n;
Sergunb 0:8918a71cdbe9 1182 }
Sergunb 0:8918a71cdbe9 1183 //Alert message received?
Sergunb 0:8918a71cdbe9 1184 else if(contentType == TLS_TYPE_ALERT)
Sergunb 0:8918a71cdbe9 1185 {
Sergunb 0:8918a71cdbe9 1186 //Parse Alert message
Sergunb 0:8918a71cdbe9 1187 error = tlsParseAlert(context, (TlsAlert *) p, n);
Sergunb 0:8918a71cdbe9 1188
Sergunb 0:8918a71cdbe9 1189 //Advance data pointer
Sergunb 0:8918a71cdbe9 1190 context->rxBufferPos += n;
Sergunb 0:8918a71cdbe9 1191 //Number of bytes still pending in the receive buffer
Sergunb 0:8918a71cdbe9 1192 context->rxBufferLen -= n;
Sergunb 0:8918a71cdbe9 1193 }
Sergunb 0:8918a71cdbe9 1194 //An inappropriate message was received?
Sergunb 0:8918a71cdbe9 1195 else
Sergunb 0:8918a71cdbe9 1196 {
Sergunb 0:8918a71cdbe9 1197 //Report an error
Sergunb 0:8918a71cdbe9 1198 error = ERROR_UNEXPECTED_MESSAGE;
Sergunb 0:8918a71cdbe9 1199 }
Sergunb 0:8918a71cdbe9 1200 }
Sergunb 0:8918a71cdbe9 1201 }
Sergunb 0:8918a71cdbe9 1202 else
Sergunb 0:8918a71cdbe9 1203 {
Sergunb 0:8918a71cdbe9 1204 //The connection is closed
Sergunb 0:8918a71cdbe9 1205 context->state = TLS_STATE_CLOSED;
Sergunb 0:8918a71cdbe9 1206 }
Sergunb 0:8918a71cdbe9 1207 }
Sergunb 0:8918a71cdbe9 1208 }
Sergunb 0:8918a71cdbe9 1209 else
Sergunb 0:8918a71cdbe9 1210 {
Sergunb 0:8918a71cdbe9 1211 //Report an error
Sergunb 0:8918a71cdbe9 1212 error = ERROR_NOT_CONNECTED;
Sergunb 0:8918a71cdbe9 1213 }
Sergunb 0:8918a71cdbe9 1214
Sergunb 0:8918a71cdbe9 1215 //Any error to report?
Sergunb 0:8918a71cdbe9 1216 if(error)
Sergunb 0:8918a71cdbe9 1217 break;
Sergunb 0:8918a71cdbe9 1218 }
Sergunb 0:8918a71cdbe9 1219
Sergunb 0:8918a71cdbe9 1220 //Return status code
Sergunb 0:8918a71cdbe9 1221 return error;
Sergunb 0:8918a71cdbe9 1222 }
Sergunb 0:8918a71cdbe9 1223
Sergunb 0:8918a71cdbe9 1224
Sergunb 0:8918a71cdbe9 1225 /**
Sergunb 0:8918a71cdbe9 1226 * @brief Release TLS context
Sergunb 0:8918a71cdbe9 1227 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 1228 **/
Sergunb 0:8918a71cdbe9 1229
Sergunb 0:8918a71cdbe9 1230 void tlsFree(TlsContext *context)
Sergunb 0:8918a71cdbe9 1231 {
Sergunb 0:8918a71cdbe9 1232 //Valid TLS context?
Sergunb 0:8918a71cdbe9 1233 if(context != NULL)
Sergunb 0:8918a71cdbe9 1234 {
Sergunb 0:8918a71cdbe9 1235 //Release server name
Sergunb 0:8918a71cdbe9 1236 if(context->serverName != NULL)
Sergunb 0:8918a71cdbe9 1237 tlsFreeMem(context->serverName);
Sergunb 0:8918a71cdbe9 1238
Sergunb 0:8918a71cdbe9 1239 #if (TLS_ALPN_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 1240 //Release the list of supported protocols
Sergunb 0:8918a71cdbe9 1241 if(context->protocolList != NULL)
Sergunb 0:8918a71cdbe9 1242 tlsFreeMem(context->protocolList);
Sergunb 0:8918a71cdbe9 1243 #endif
Sergunb 0:8918a71cdbe9 1244
Sergunb 0:8918a71cdbe9 1245 #if (TLS_PSK_SUPPORT == ENABLED || TLS_RSA_PSK_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 1246 TLS_DHE_PSK_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 1247 //Release the pre-shared key
Sergunb 0:8918a71cdbe9 1248 if(context->psk != NULL)
Sergunb 0:8918a71cdbe9 1249 {
Sergunb 0:8918a71cdbe9 1250 memset(context->psk, 0, context->pskLen);
Sergunb 0:8918a71cdbe9 1251 tlsFreeMem(context->psk);
Sergunb 0:8918a71cdbe9 1252 }
Sergunb 0:8918a71cdbe9 1253
Sergunb 0:8918a71cdbe9 1254 //Release the PSK identity
Sergunb 0:8918a71cdbe9 1255 if(context->pskIdentity != NULL)
Sergunb 0:8918a71cdbe9 1256 tlsFreeMem(context->pskIdentity);
Sergunb 0:8918a71cdbe9 1257
Sergunb 0:8918a71cdbe9 1258 //Release the PSK identity hint
Sergunb 0:8918a71cdbe9 1259 if(context->pskIdentityHint != NULL)
Sergunb 0:8918a71cdbe9 1260 tlsFreeMem(context->pskIdentityHint);
Sergunb 0:8918a71cdbe9 1261 #endif
Sergunb 0:8918a71cdbe9 1262
Sergunb 0:8918a71cdbe9 1263 #if (TLS_DH_ANON_SUPPORT == ENABLED || TLS_DHE_RSA_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 1264 TLS_DHE_DSS_SUPPORT == ENABLED || TLS_DHE_PSK_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 1265 //Release Diffie-Hellman context
Sergunb 0:8918a71cdbe9 1266 dhFree(&context->dhContext);
Sergunb 0:8918a71cdbe9 1267 #endif
Sergunb 0:8918a71cdbe9 1268
Sergunb 0:8918a71cdbe9 1269 #if (TLS_ECDH_ANON_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 1270 TLS_ECDHE_ECDSA_SUPPORT == ENABLED || TLS_ECDHE_PSK_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 1271 //Release ECDH context
Sergunb 0:8918a71cdbe9 1272 ecdhFree(&context->ecdhContext);
Sergunb 0:8918a71cdbe9 1273 #endif
Sergunb 0:8918a71cdbe9 1274
Sergunb 0:8918a71cdbe9 1275 #if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_RSA_SUPPORT == ENABLED || \
Sergunb 0:8918a71cdbe9 1276 TLS_DHE_RSA_SUPPORT == ENABLED || TLS_ECDHE_RSA_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 1277 //Release peer's RSA public key
Sergunb 0:8918a71cdbe9 1278 rsaFreePublicKey(&context->peerRsaPublicKey);
Sergunb 0:8918a71cdbe9 1279 #endif
Sergunb 0:8918a71cdbe9 1280
Sergunb 0:8918a71cdbe9 1281 #if (TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_DHE_DSS_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 1282 //Release peer's DSA public key
Sergunb 0:8918a71cdbe9 1283 dsaFreePublicKey(&context->peerDsaPublicKey);
Sergunb 0:8918a71cdbe9 1284 #endif
Sergunb 0:8918a71cdbe9 1285
Sergunb 0:8918a71cdbe9 1286 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_ECDHE_ECDSA_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 1287 //Release peer's EC domain parameters
Sergunb 0:8918a71cdbe9 1288 ecFreeDomainParameters(&context->peerEcParams);
Sergunb 0:8918a71cdbe9 1289 //Release peer's EC public key
Sergunb 0:8918a71cdbe9 1290 ecFree(&context->peerEcPublicKey);
Sergunb 0:8918a71cdbe9 1291 #endif
Sergunb 0:8918a71cdbe9 1292
Sergunb 0:8918a71cdbe9 1293 //Release send buffer
Sergunb 0:8918a71cdbe9 1294 if(context->txBuffer != NULL)
Sergunb 0:8918a71cdbe9 1295 {
Sergunb 0:8918a71cdbe9 1296 memset(context->txBuffer, 0, context->txBufferSize);
Sergunb 0:8918a71cdbe9 1297 tlsFreeMem(context->txBuffer);
Sergunb 0:8918a71cdbe9 1298 }
Sergunb 0:8918a71cdbe9 1299
Sergunb 0:8918a71cdbe9 1300 //Release receive buffer
Sergunb 0:8918a71cdbe9 1301 if(context->rxBuffer != NULL)
Sergunb 0:8918a71cdbe9 1302 {
Sergunb 0:8918a71cdbe9 1303 memset(context->rxBuffer, 0, context->rxBufferSize);
Sergunb 0:8918a71cdbe9 1304 tlsFreeMem(context->rxBuffer);
Sergunb 0:8918a71cdbe9 1305 }
Sergunb 0:8918a71cdbe9 1306
Sergunb 0:8918a71cdbe9 1307 //Release the MD5 context used to compute verify data
Sergunb 0:8918a71cdbe9 1308 if(context->handshakeMd5Context != NULL)
Sergunb 0:8918a71cdbe9 1309 {
Sergunb 0:8918a71cdbe9 1310 memset(context->handshakeMd5Context, 0, sizeof(Md5Context));
Sergunb 0:8918a71cdbe9 1311 tlsFreeMem(context->handshakeMd5Context);
Sergunb 0:8918a71cdbe9 1312 }
Sergunb 0:8918a71cdbe9 1313
Sergunb 0:8918a71cdbe9 1314 //Release the SHA-1 context used to compute verify data
Sergunb 0:8918a71cdbe9 1315 if(context->handshakeSha1Context != NULL)
Sergunb 0:8918a71cdbe9 1316 {
Sergunb 0:8918a71cdbe9 1317 memset(context->handshakeSha1Context, 0, sizeof(Sha1Context));
Sergunb 0:8918a71cdbe9 1318 tlsFreeMem(context->handshakeSha1Context);
Sergunb 0:8918a71cdbe9 1319 }
Sergunb 0:8918a71cdbe9 1320
Sergunb 0:8918a71cdbe9 1321 //Release the hash context used to compute verify data (TLS 1.2)
Sergunb 0:8918a71cdbe9 1322 if(context->handshakeHashContext != NULL)
Sergunb 0:8918a71cdbe9 1323 {
Sergunb 0:8918a71cdbe9 1324 memset(context->handshakeHashContext, 0, context->prfHashAlgo->contextSize);
Sergunb 0:8918a71cdbe9 1325 tlsFreeMem(context->handshakeHashContext);
Sergunb 0:8918a71cdbe9 1326 }
Sergunb 0:8918a71cdbe9 1327
Sergunb 0:8918a71cdbe9 1328 //Release the encryption context (TX path)
Sergunb 0:8918a71cdbe9 1329 if(context->writeCipherContext != NULL)
Sergunb 0:8918a71cdbe9 1330 {
Sergunb 0:8918a71cdbe9 1331 memset(context->writeCipherContext, 0, context->cipherAlgo->contextSize);
Sergunb 0:8918a71cdbe9 1332 tlsFreeMem(context->writeCipherContext);
Sergunb 0:8918a71cdbe9 1333 }
Sergunb 0:8918a71cdbe9 1334
Sergunb 0:8918a71cdbe9 1335 //Release the encryption context (RX path)
Sergunb 0:8918a71cdbe9 1336 if(context->readCipherContext != NULL)
Sergunb 0:8918a71cdbe9 1337 {
Sergunb 0:8918a71cdbe9 1338 memset(context->readCipherContext, 0, context->cipherAlgo->contextSize);
Sergunb 0:8918a71cdbe9 1339 tlsFreeMem(context->readCipherContext);
Sergunb 0:8918a71cdbe9 1340 }
Sergunb 0:8918a71cdbe9 1341
Sergunb 0:8918a71cdbe9 1342 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
Sergunb 0:8918a71cdbe9 1343 //Release the GCM context (TX path)
Sergunb 0:8918a71cdbe9 1344 if(context->writeGcmContext != NULL)
Sergunb 0:8918a71cdbe9 1345 {
Sergunb 0:8918a71cdbe9 1346 memset(context->writeGcmContext, 0, sizeof(GcmContext));
Sergunb 0:8918a71cdbe9 1347 tlsFreeMem(context->writeGcmContext);
Sergunb 0:8918a71cdbe9 1348 }
Sergunb 0:8918a71cdbe9 1349
Sergunb 0:8918a71cdbe9 1350 //Release the GCM context (RX path)
Sergunb 0:8918a71cdbe9 1351 if(context->readGcmContext != NULL)
Sergunb 0:8918a71cdbe9 1352 {
Sergunb 0:8918a71cdbe9 1353 memset(context->readGcmContext, 0, sizeof(GcmContext));
Sergunb 0:8918a71cdbe9 1354 tlsFreeMem(context->readGcmContext);
Sergunb 0:8918a71cdbe9 1355 }
Sergunb 0:8918a71cdbe9 1356 #endif
Sergunb 0:8918a71cdbe9 1357
Sergunb 0:8918a71cdbe9 1358 //Clear the TLS context before freeing memory
Sergunb 0:8918a71cdbe9 1359 memset(context, 0, sizeof(TlsContext));
Sergunb 0:8918a71cdbe9 1360 tlsFreeMem(context);
Sergunb 0:8918a71cdbe9 1361 }
Sergunb 0:8918a71cdbe9 1362 }
Sergunb 0:8918a71cdbe9 1363
Sergunb 0:8918a71cdbe9 1364
Sergunb 0:8918a71cdbe9 1365 /**
Sergunb 0:8918a71cdbe9 1366 * @brief Save TLS session
Sergunb 0:8918a71cdbe9 1367 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 1368 * @param[out] session Buffer where to store the current session parameters
Sergunb 0:8918a71cdbe9 1369 * @return Error code
Sergunb 0:8918a71cdbe9 1370 **/
Sergunb 0:8918a71cdbe9 1371
Sergunb 0:8918a71cdbe9 1372 error_t tlsSaveSession(const TlsContext *context, TlsSession *session)
Sergunb 0:8918a71cdbe9 1373 {
Sergunb 0:8918a71cdbe9 1374 //Check parameters
Sergunb 0:8918a71cdbe9 1375 if(context == NULL || session == NULL)
Sergunb 0:8918a71cdbe9 1376 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 1377
Sergunb 0:8918a71cdbe9 1378 //Invalid session parameters?
Sergunb 0:8918a71cdbe9 1379 if(!context->sessionIdLen || !context->cipherSuite)
Sergunb 0:8918a71cdbe9 1380 return ERROR_FAILURE;
Sergunb 0:8918a71cdbe9 1381
Sergunb 0:8918a71cdbe9 1382 //Save session identifier
Sergunb 0:8918a71cdbe9 1383 memcpy(session->id, context->sessionId, context->sessionIdLen);
Sergunb 0:8918a71cdbe9 1384 session->idLength = context->sessionIdLen;
Sergunb 0:8918a71cdbe9 1385
Sergunb 0:8918a71cdbe9 1386 //Get current time
Sergunb 0:8918a71cdbe9 1387 session->timestamp = osGetSystemTime();
Sergunb 0:8918a71cdbe9 1388
Sergunb 0:8918a71cdbe9 1389 //Negotiated cipher suite and compression method
Sergunb 0:8918a71cdbe9 1390 session->cipherSuite = context->cipherSuite;
Sergunb 0:8918a71cdbe9 1391 session->compressionMethod = context->compressionMethod;
Sergunb 0:8918a71cdbe9 1392
Sergunb 0:8918a71cdbe9 1393 //Save master secret
Sergunb 0:8918a71cdbe9 1394 memcpy(session->masterSecret, context->masterSecret, 48);
Sergunb 0:8918a71cdbe9 1395
Sergunb 0:8918a71cdbe9 1396 //Successful processing
Sergunb 0:8918a71cdbe9 1397 return NO_ERROR;
Sergunb 0:8918a71cdbe9 1398 }
Sergunb 0:8918a71cdbe9 1399
Sergunb 0:8918a71cdbe9 1400
Sergunb 0:8918a71cdbe9 1401 /**
Sergunb 0:8918a71cdbe9 1402 * @brief Restore TLS session
Sergunb 0:8918a71cdbe9 1403 * @param[in] context Pointer to the TLS context
Sergunb 0:8918a71cdbe9 1404 * @param[in] session Pointer to the session to be restored
Sergunb 0:8918a71cdbe9 1405 * @return Error code
Sergunb 0:8918a71cdbe9 1406 **/
Sergunb 0:8918a71cdbe9 1407
Sergunb 0:8918a71cdbe9 1408 error_t tlsRestoreSession(TlsContext *context, const TlsSession *session)
Sergunb 0:8918a71cdbe9 1409 {
Sergunb 0:8918a71cdbe9 1410 //Check parameters
Sergunb 0:8918a71cdbe9 1411 if(context == NULL || session == NULL)
Sergunb 0:8918a71cdbe9 1412 return ERROR_INVALID_PARAMETER;
Sergunb 0:8918a71cdbe9 1413
Sergunb 0:8918a71cdbe9 1414 //Restore session identifier
Sergunb 0:8918a71cdbe9 1415 memcpy(context->sessionId, session->id, session->idLength);
Sergunb 0:8918a71cdbe9 1416 context->sessionIdLen = session->idLength;
Sergunb 0:8918a71cdbe9 1417
Sergunb 0:8918a71cdbe9 1418 //Negotiated cipher suite and compression method
Sergunb 0:8918a71cdbe9 1419 context->cipherSuite = session->cipherSuite;
Sergunb 0:8918a71cdbe9 1420 context->compressionMethod = session->compressionMethod;
Sergunb 0:8918a71cdbe9 1421
Sergunb 0:8918a71cdbe9 1422 //Restore master secret
Sergunb 0:8918a71cdbe9 1423 memcpy(context->masterSecret, session->masterSecret, 48);
Sergunb 0:8918a71cdbe9 1424
Sergunb 0:8918a71cdbe9 1425 //Successful processing
Sergunb 0:8918a71cdbe9 1426 return NO_ERROR;
Sergunb 0:8918a71cdbe9 1427 }
Sergunb 0:8918a71cdbe9 1428
Sergunb 0:8918a71cdbe9 1429 #endif
Sergunb 0:8918a71cdbe9 1430