ON Semiconductor / mbed-os

Dependents:   mbed-TFT-example-NCS36510 mbed-Accelerometer-example-NCS36510 mbed-Accelerometer-example-NCS36510

Committer:
group-onsemi
Date:
Wed Jan 25 20:34:15 2017 +0000
Revision:
0:098463de4c5d
Initial commit

Who changed what in which revision?

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