mbed client lightswitch demo

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

Fork of mbed-client-classic-example-lwip by Austin Blackstone

Committer:
mbedAustin
Date:
Thu Jun 09 17:08:36 2016 +0000
Revision:
11:cada08fc8a70
Commit for public Consumption

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbedAustin 11:cada08fc8a70 1 /*
mbedAustin 11:cada08fc8a70 2 * SSL session cache implementation
mbedAustin 11:cada08fc8a70 3 *
mbedAustin 11:cada08fc8a70 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
mbedAustin 11:cada08fc8a70 5 * SPDX-License-Identifier: Apache-2.0
mbedAustin 11:cada08fc8a70 6 *
mbedAustin 11:cada08fc8a70 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
mbedAustin 11:cada08fc8a70 8 * not use this file except in compliance with the License.
mbedAustin 11:cada08fc8a70 9 * You may obtain a copy of the License at
mbedAustin 11:cada08fc8a70 10 *
mbedAustin 11:cada08fc8a70 11 * http://www.apache.org/licenses/LICENSE-2.0
mbedAustin 11:cada08fc8a70 12 *
mbedAustin 11:cada08fc8a70 13 * Unless required by applicable law or agreed to in writing, software
mbedAustin 11:cada08fc8a70 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
mbedAustin 11:cada08fc8a70 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbedAustin 11:cada08fc8a70 16 * See the License for the specific language governing permissions and
mbedAustin 11:cada08fc8a70 17 * limitations under the License.
mbedAustin 11:cada08fc8a70 18 *
mbedAustin 11:cada08fc8a70 19 * This file is part of mbed TLS (https://tls.mbed.org)
mbedAustin 11:cada08fc8a70 20 */
mbedAustin 11:cada08fc8a70 21 /*
mbedAustin 11:cada08fc8a70 22 * These session callbacks use a simple chained list
mbedAustin 11:cada08fc8a70 23 * to store and retrieve the session information.
mbedAustin 11:cada08fc8a70 24 */
mbedAustin 11:cada08fc8a70 25
mbedAustin 11:cada08fc8a70 26 #if !defined(MBEDTLS_CONFIG_FILE)
mbedAustin 11:cada08fc8a70 27 #include "mbedtls/config.h"
mbedAustin 11:cada08fc8a70 28 #else
mbedAustin 11:cada08fc8a70 29 #include MBEDTLS_CONFIG_FILE
mbedAustin 11:cada08fc8a70 30 #endif
mbedAustin 11:cada08fc8a70 31
mbedAustin 11:cada08fc8a70 32 #if defined(MBEDTLS_SSL_CACHE_C)
mbedAustin 11:cada08fc8a70 33
mbedAustin 11:cada08fc8a70 34 #include "mbedtls/ssl_cache.h"
mbedAustin 11:cada08fc8a70 35
mbedAustin 11:cada08fc8a70 36 #include <string.h>
mbedAustin 11:cada08fc8a70 37
mbedAustin 11:cada08fc8a70 38 #if defined(MBEDTLS_PLATFORM_C)
mbedAustin 11:cada08fc8a70 39 #include "mbedtls/platform.h"
mbedAustin 11:cada08fc8a70 40 #else
mbedAustin 11:cada08fc8a70 41 #include <stdlib.h>
mbedAustin 11:cada08fc8a70 42 #define mbedtls_calloc calloc
mbedAustin 11:cada08fc8a70 43 #define mbedtls_free free
mbedAustin 11:cada08fc8a70 44 #endif
mbedAustin 11:cada08fc8a70 45
mbedAustin 11:cada08fc8a70 46 void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache )
mbedAustin 11:cada08fc8a70 47 {
mbedAustin 11:cada08fc8a70 48 memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) );
mbedAustin 11:cada08fc8a70 49
mbedAustin 11:cada08fc8a70 50 cache->timeout = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT;
mbedAustin 11:cada08fc8a70 51 cache->max_entries = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES;
mbedAustin 11:cada08fc8a70 52
mbedAustin 11:cada08fc8a70 53 #if defined(MBEDTLS_THREADING_C)
mbedAustin 11:cada08fc8a70 54 mbedtls_mutex_init( &cache->mutex );
mbedAustin 11:cada08fc8a70 55 #endif
mbedAustin 11:cada08fc8a70 56 }
mbedAustin 11:cada08fc8a70 57
mbedAustin 11:cada08fc8a70 58 int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session )
mbedAustin 11:cada08fc8a70 59 {
mbedAustin 11:cada08fc8a70 60 int ret = 1;
mbedAustin 11:cada08fc8a70 61 #if defined(MBEDTLS_HAVE_TIME)
mbedAustin 11:cada08fc8a70 62 time_t t = time( NULL );
mbedAustin 11:cada08fc8a70 63 #endif
mbedAustin 11:cada08fc8a70 64 mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
mbedAustin 11:cada08fc8a70 65 mbedtls_ssl_cache_entry *cur, *entry;
mbedAustin 11:cada08fc8a70 66
mbedAustin 11:cada08fc8a70 67 #if defined(MBEDTLS_THREADING_C)
mbedAustin 11:cada08fc8a70 68 if( mbedtls_mutex_lock( &cache->mutex ) != 0 )
mbedAustin 11:cada08fc8a70 69 return( 1 );
mbedAustin 11:cada08fc8a70 70 #endif
mbedAustin 11:cada08fc8a70 71
mbedAustin 11:cada08fc8a70 72 cur = cache->chain;
mbedAustin 11:cada08fc8a70 73 entry = NULL;
mbedAustin 11:cada08fc8a70 74
mbedAustin 11:cada08fc8a70 75 while( cur != NULL )
mbedAustin 11:cada08fc8a70 76 {
mbedAustin 11:cada08fc8a70 77 entry = cur;
mbedAustin 11:cada08fc8a70 78 cur = cur->next;
mbedAustin 11:cada08fc8a70 79
mbedAustin 11:cada08fc8a70 80 #if defined(MBEDTLS_HAVE_TIME)
mbedAustin 11:cada08fc8a70 81 if( cache->timeout != 0 &&
mbedAustin 11:cada08fc8a70 82 (int) ( t - entry->timestamp ) > cache->timeout )
mbedAustin 11:cada08fc8a70 83 continue;
mbedAustin 11:cada08fc8a70 84 #endif
mbedAustin 11:cada08fc8a70 85
mbedAustin 11:cada08fc8a70 86 if( session->ciphersuite != entry->session.ciphersuite ||
mbedAustin 11:cada08fc8a70 87 session->compression != entry->session.compression ||
mbedAustin 11:cada08fc8a70 88 session->id_len != entry->session.id_len )
mbedAustin 11:cada08fc8a70 89 continue;
mbedAustin 11:cada08fc8a70 90
mbedAustin 11:cada08fc8a70 91 if( memcmp( session->id, entry->session.id,
mbedAustin 11:cada08fc8a70 92 entry->session.id_len ) != 0 )
mbedAustin 11:cada08fc8a70 93 continue;
mbedAustin 11:cada08fc8a70 94
mbedAustin 11:cada08fc8a70 95 memcpy( session->master, entry->session.master, 48 );
mbedAustin 11:cada08fc8a70 96
mbedAustin 11:cada08fc8a70 97 session->verify_result = entry->session.verify_result;
mbedAustin 11:cada08fc8a70 98
mbedAustin 11:cada08fc8a70 99 #if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedAustin 11:cada08fc8a70 100 /*
mbedAustin 11:cada08fc8a70 101 * Restore peer certificate (without rest of the original chain)
mbedAustin 11:cada08fc8a70 102 */
mbedAustin 11:cada08fc8a70 103 if( entry->peer_cert.p != NULL )
mbedAustin 11:cada08fc8a70 104 {
mbedAustin 11:cada08fc8a70 105 if( ( session->peer_cert = mbedtls_calloc( 1,
mbedAustin 11:cada08fc8a70 106 sizeof(mbedtls_x509_crt) ) ) == NULL )
mbedAustin 11:cada08fc8a70 107 {
mbedAustin 11:cada08fc8a70 108 ret = 1;
mbedAustin 11:cada08fc8a70 109 goto exit;
mbedAustin 11:cada08fc8a70 110 }
mbedAustin 11:cada08fc8a70 111
mbedAustin 11:cada08fc8a70 112 mbedtls_x509_crt_init( session->peer_cert );
mbedAustin 11:cada08fc8a70 113 if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert.p,
mbedAustin 11:cada08fc8a70 114 entry->peer_cert.len ) != 0 )
mbedAustin 11:cada08fc8a70 115 {
mbedAustin 11:cada08fc8a70 116 mbedtls_free( session->peer_cert );
mbedAustin 11:cada08fc8a70 117 session->peer_cert = NULL;
mbedAustin 11:cada08fc8a70 118 ret = 1;
mbedAustin 11:cada08fc8a70 119 goto exit;
mbedAustin 11:cada08fc8a70 120 }
mbedAustin 11:cada08fc8a70 121 }
mbedAustin 11:cada08fc8a70 122 #endif /* MBEDTLS_X509_CRT_PARSE_C */
mbedAustin 11:cada08fc8a70 123
mbedAustin 11:cada08fc8a70 124 ret = 0;
mbedAustin 11:cada08fc8a70 125 goto exit;
mbedAustin 11:cada08fc8a70 126 }
mbedAustin 11:cada08fc8a70 127
mbedAustin 11:cada08fc8a70 128 exit:
mbedAustin 11:cada08fc8a70 129 #if defined(MBEDTLS_THREADING_C)
mbedAustin 11:cada08fc8a70 130 if( mbedtls_mutex_unlock( &cache->mutex ) != 0 )
mbedAustin 11:cada08fc8a70 131 ret = 1;
mbedAustin 11:cada08fc8a70 132 #endif
mbedAustin 11:cada08fc8a70 133
mbedAustin 11:cada08fc8a70 134 return( ret );
mbedAustin 11:cada08fc8a70 135 }
mbedAustin 11:cada08fc8a70 136
mbedAustin 11:cada08fc8a70 137 int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session )
mbedAustin 11:cada08fc8a70 138 {
mbedAustin 11:cada08fc8a70 139 int ret = 1;
mbedAustin 11:cada08fc8a70 140 #if defined(MBEDTLS_HAVE_TIME)
mbedAustin 11:cada08fc8a70 141 time_t t = time( NULL ), oldest = 0;
mbedAustin 11:cada08fc8a70 142 mbedtls_ssl_cache_entry *old = NULL;
mbedAustin 11:cada08fc8a70 143 #endif
mbedAustin 11:cada08fc8a70 144 mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
mbedAustin 11:cada08fc8a70 145 mbedtls_ssl_cache_entry *cur, *prv;
mbedAustin 11:cada08fc8a70 146 int count = 0;
mbedAustin 11:cada08fc8a70 147
mbedAustin 11:cada08fc8a70 148 #if defined(MBEDTLS_THREADING_C)
mbedAustin 11:cada08fc8a70 149 if( ( ret = mbedtls_mutex_lock( &cache->mutex ) ) != 0 )
mbedAustin 11:cada08fc8a70 150 return( ret );
mbedAustin 11:cada08fc8a70 151 #endif
mbedAustin 11:cada08fc8a70 152
mbedAustin 11:cada08fc8a70 153 cur = cache->chain;
mbedAustin 11:cada08fc8a70 154 prv = NULL;
mbedAustin 11:cada08fc8a70 155
mbedAustin 11:cada08fc8a70 156 while( cur != NULL )
mbedAustin 11:cada08fc8a70 157 {
mbedAustin 11:cada08fc8a70 158 count++;
mbedAustin 11:cada08fc8a70 159
mbedAustin 11:cada08fc8a70 160 #if defined(MBEDTLS_HAVE_TIME)
mbedAustin 11:cada08fc8a70 161 if( cache->timeout != 0 &&
mbedAustin 11:cada08fc8a70 162 (int) ( t - cur->timestamp ) > cache->timeout )
mbedAustin 11:cada08fc8a70 163 {
mbedAustin 11:cada08fc8a70 164 cur->timestamp = t;
mbedAustin 11:cada08fc8a70 165 break; /* expired, reuse this slot, update timestamp */
mbedAustin 11:cada08fc8a70 166 }
mbedAustin 11:cada08fc8a70 167 #endif
mbedAustin 11:cada08fc8a70 168
mbedAustin 11:cada08fc8a70 169 if( memcmp( session->id, cur->session.id, cur->session.id_len ) == 0 )
mbedAustin 11:cada08fc8a70 170 break; /* client reconnected, keep timestamp for session id */
mbedAustin 11:cada08fc8a70 171
mbedAustin 11:cada08fc8a70 172 #if defined(MBEDTLS_HAVE_TIME)
mbedAustin 11:cada08fc8a70 173 if( oldest == 0 || cur->timestamp < oldest )
mbedAustin 11:cada08fc8a70 174 {
mbedAustin 11:cada08fc8a70 175 oldest = cur->timestamp;
mbedAustin 11:cada08fc8a70 176 old = cur;
mbedAustin 11:cada08fc8a70 177 }
mbedAustin 11:cada08fc8a70 178 #endif
mbedAustin 11:cada08fc8a70 179
mbedAustin 11:cada08fc8a70 180 prv = cur;
mbedAustin 11:cada08fc8a70 181 cur = cur->next;
mbedAustin 11:cada08fc8a70 182 }
mbedAustin 11:cada08fc8a70 183
mbedAustin 11:cada08fc8a70 184 if( cur == NULL )
mbedAustin 11:cada08fc8a70 185 {
mbedAustin 11:cada08fc8a70 186 #if defined(MBEDTLS_HAVE_TIME)
mbedAustin 11:cada08fc8a70 187 /*
mbedAustin 11:cada08fc8a70 188 * Reuse oldest entry if max_entries reached
mbedAustin 11:cada08fc8a70 189 */
mbedAustin 11:cada08fc8a70 190 if( count >= cache->max_entries )
mbedAustin 11:cada08fc8a70 191 {
mbedAustin 11:cada08fc8a70 192 if( old == NULL )
mbedAustin 11:cada08fc8a70 193 {
mbedAustin 11:cada08fc8a70 194 ret = 1;
mbedAustin 11:cada08fc8a70 195 goto exit;
mbedAustin 11:cada08fc8a70 196 }
mbedAustin 11:cada08fc8a70 197
mbedAustin 11:cada08fc8a70 198 cur = old;
mbedAustin 11:cada08fc8a70 199 }
mbedAustin 11:cada08fc8a70 200 #else /* MBEDTLS_HAVE_TIME */
mbedAustin 11:cada08fc8a70 201 /*
mbedAustin 11:cada08fc8a70 202 * Reuse first entry in chain if max_entries reached,
mbedAustin 11:cada08fc8a70 203 * but move to last place
mbedAustin 11:cada08fc8a70 204 */
mbedAustin 11:cada08fc8a70 205 if( count >= cache->max_entries )
mbedAustin 11:cada08fc8a70 206 {
mbedAustin 11:cada08fc8a70 207 if( cache->chain == NULL )
mbedAustin 11:cada08fc8a70 208 {
mbedAustin 11:cada08fc8a70 209 ret = 1;
mbedAustin 11:cada08fc8a70 210 goto exit;
mbedAustin 11:cada08fc8a70 211 }
mbedAustin 11:cada08fc8a70 212
mbedAustin 11:cada08fc8a70 213 cur = cache->chain;
mbedAustin 11:cada08fc8a70 214 cache->chain = cur->next;
mbedAustin 11:cada08fc8a70 215 cur->next = NULL;
mbedAustin 11:cada08fc8a70 216 prv->next = cur;
mbedAustin 11:cada08fc8a70 217 }
mbedAustin 11:cada08fc8a70 218 #endif /* MBEDTLS_HAVE_TIME */
mbedAustin 11:cada08fc8a70 219 else
mbedAustin 11:cada08fc8a70 220 {
mbedAustin 11:cada08fc8a70 221 /*
mbedAustin 11:cada08fc8a70 222 * max_entries not reached, create new entry
mbedAustin 11:cada08fc8a70 223 */
mbedAustin 11:cada08fc8a70 224 cur = mbedtls_calloc( 1, sizeof(mbedtls_ssl_cache_entry) );
mbedAustin 11:cada08fc8a70 225 if( cur == NULL )
mbedAustin 11:cada08fc8a70 226 {
mbedAustin 11:cada08fc8a70 227 ret = 1;
mbedAustin 11:cada08fc8a70 228 goto exit;
mbedAustin 11:cada08fc8a70 229 }
mbedAustin 11:cada08fc8a70 230
mbedAustin 11:cada08fc8a70 231 if( prv == NULL )
mbedAustin 11:cada08fc8a70 232 cache->chain = cur;
mbedAustin 11:cada08fc8a70 233 else
mbedAustin 11:cada08fc8a70 234 prv->next = cur;
mbedAustin 11:cada08fc8a70 235 }
mbedAustin 11:cada08fc8a70 236
mbedAustin 11:cada08fc8a70 237 #if defined(MBEDTLS_HAVE_TIME)
mbedAustin 11:cada08fc8a70 238 cur->timestamp = t;
mbedAustin 11:cada08fc8a70 239 #endif
mbedAustin 11:cada08fc8a70 240 }
mbedAustin 11:cada08fc8a70 241
mbedAustin 11:cada08fc8a70 242 memcpy( &cur->session, session, sizeof( mbedtls_ssl_session ) );
mbedAustin 11:cada08fc8a70 243
mbedAustin 11:cada08fc8a70 244 #if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedAustin 11:cada08fc8a70 245 /*
mbedAustin 11:cada08fc8a70 246 * If we're reusing an entry, free its certificate first
mbedAustin 11:cada08fc8a70 247 */
mbedAustin 11:cada08fc8a70 248 if( cur->peer_cert.p != NULL )
mbedAustin 11:cada08fc8a70 249 {
mbedAustin 11:cada08fc8a70 250 mbedtls_free( cur->peer_cert.p );
mbedAustin 11:cada08fc8a70 251 memset( &cur->peer_cert, 0, sizeof(mbedtls_x509_buf) );
mbedAustin 11:cada08fc8a70 252 }
mbedAustin 11:cada08fc8a70 253
mbedAustin 11:cada08fc8a70 254 /*
mbedAustin 11:cada08fc8a70 255 * Store peer certificate
mbedAustin 11:cada08fc8a70 256 */
mbedAustin 11:cada08fc8a70 257 if( session->peer_cert != NULL )
mbedAustin 11:cada08fc8a70 258 {
mbedAustin 11:cada08fc8a70 259 cur->peer_cert.p = mbedtls_calloc( 1, session->peer_cert->raw.len );
mbedAustin 11:cada08fc8a70 260 if( cur->peer_cert.p == NULL )
mbedAustin 11:cada08fc8a70 261 {
mbedAustin 11:cada08fc8a70 262 ret = 1;
mbedAustin 11:cada08fc8a70 263 goto exit;
mbedAustin 11:cada08fc8a70 264 }
mbedAustin 11:cada08fc8a70 265
mbedAustin 11:cada08fc8a70 266 memcpy( cur->peer_cert.p, session->peer_cert->raw.p,
mbedAustin 11:cada08fc8a70 267 session->peer_cert->raw.len );
mbedAustin 11:cada08fc8a70 268 cur->peer_cert.len = session->peer_cert->raw.len;
mbedAustin 11:cada08fc8a70 269
mbedAustin 11:cada08fc8a70 270 cur->session.peer_cert = NULL;
mbedAustin 11:cada08fc8a70 271 }
mbedAustin 11:cada08fc8a70 272 #endif /* MBEDTLS_X509_CRT_PARSE_C */
mbedAustin 11:cada08fc8a70 273
mbedAustin 11:cada08fc8a70 274 ret = 0;
mbedAustin 11:cada08fc8a70 275
mbedAustin 11:cada08fc8a70 276 exit:
mbedAustin 11:cada08fc8a70 277 #if defined(MBEDTLS_THREADING_C)
mbedAustin 11:cada08fc8a70 278 if( mbedtls_mutex_unlock( &cache->mutex ) != 0 )
mbedAustin 11:cada08fc8a70 279 ret = 1;
mbedAustin 11:cada08fc8a70 280 #endif
mbedAustin 11:cada08fc8a70 281
mbedAustin 11:cada08fc8a70 282 return( ret );
mbedAustin 11:cada08fc8a70 283 }
mbedAustin 11:cada08fc8a70 284
mbedAustin 11:cada08fc8a70 285 #if defined(MBEDTLS_HAVE_TIME)
mbedAustin 11:cada08fc8a70 286 void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout )
mbedAustin 11:cada08fc8a70 287 {
mbedAustin 11:cada08fc8a70 288 if( timeout < 0 ) timeout = 0;
mbedAustin 11:cada08fc8a70 289
mbedAustin 11:cada08fc8a70 290 cache->timeout = timeout;
mbedAustin 11:cada08fc8a70 291 }
mbedAustin 11:cada08fc8a70 292 #endif /* MBEDTLS_HAVE_TIME */
mbedAustin 11:cada08fc8a70 293
mbedAustin 11:cada08fc8a70 294 void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max )
mbedAustin 11:cada08fc8a70 295 {
mbedAustin 11:cada08fc8a70 296 if( max < 0 ) max = 0;
mbedAustin 11:cada08fc8a70 297
mbedAustin 11:cada08fc8a70 298 cache->max_entries = max;
mbedAustin 11:cada08fc8a70 299 }
mbedAustin 11:cada08fc8a70 300
mbedAustin 11:cada08fc8a70 301 void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache )
mbedAustin 11:cada08fc8a70 302 {
mbedAustin 11:cada08fc8a70 303 mbedtls_ssl_cache_entry *cur, *prv;
mbedAustin 11:cada08fc8a70 304
mbedAustin 11:cada08fc8a70 305 cur = cache->chain;
mbedAustin 11:cada08fc8a70 306
mbedAustin 11:cada08fc8a70 307 while( cur != NULL )
mbedAustin 11:cada08fc8a70 308 {
mbedAustin 11:cada08fc8a70 309 prv = cur;
mbedAustin 11:cada08fc8a70 310 cur = cur->next;
mbedAustin 11:cada08fc8a70 311
mbedAustin 11:cada08fc8a70 312 mbedtls_ssl_session_free( &prv->session );
mbedAustin 11:cada08fc8a70 313
mbedAustin 11:cada08fc8a70 314 #if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedAustin 11:cada08fc8a70 315 mbedtls_free( prv->peer_cert.p );
mbedAustin 11:cada08fc8a70 316 #endif /* MBEDTLS_X509_CRT_PARSE_C */
mbedAustin 11:cada08fc8a70 317
mbedAustin 11:cada08fc8a70 318 mbedtls_free( prv );
mbedAustin 11:cada08fc8a70 319 }
mbedAustin 11:cada08fc8a70 320
mbedAustin 11:cada08fc8a70 321 #if defined(MBEDTLS_THREADING_C)
mbedAustin 11:cada08fc8a70 322 mbedtls_mutex_free( &cache->mutex );
mbedAustin 11:cada08fc8a70 323 #endif
mbedAustin 11:cada08fc8a70 324 }
mbedAustin 11:cada08fc8a70 325
mbedAustin 11:cada08fc8a70 326 #endif /* MBEDTLS_SSL_CACHE_C */