mbed client lightswitch demo

Dependencies:   mbed Socket lwip-eth lwip-sys lwip

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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ssl_cache.c Source File

ssl_cache.c

00001 /*
00002  *  SSL session cache implementation
00003  *
00004  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
00005  *  SPDX-License-Identifier: Apache-2.0
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  *  This file is part of mbed TLS (https://tls.mbed.org)
00020  */
00021 /*
00022  * These session callbacks use a simple chained list
00023  * to store and retrieve the session information.
00024  */
00025 
00026 #if !defined(MBEDTLS_CONFIG_FILE)
00027 #include "mbedtls/config.h"
00028 #else
00029 #include MBEDTLS_CONFIG_FILE
00030 #endif
00031 
00032 #if defined(MBEDTLS_SSL_CACHE_C)
00033 
00034 #include "mbedtls/ssl_cache.h"
00035 
00036 #include <string.h>
00037 
00038 #if defined(MBEDTLS_PLATFORM_C)
00039 #include "mbedtls/platform.h"
00040 #else
00041 #include <stdlib.h>
00042 #define mbedtls_calloc    calloc
00043 #define mbedtls_free       free
00044 #endif
00045 
00046 void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache )
00047 {
00048     memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) );
00049 
00050     cache->timeout  = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT;
00051     cache->max_entries  = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES;
00052 
00053 #if defined(MBEDTLS_THREADING_C)
00054     mbedtls_mutex_init( &cache->mutex  );
00055 #endif
00056 }
00057 
00058 int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session )
00059 {
00060     int ret = 1;
00061 #if defined(MBEDTLS_HAVE_TIME)
00062     time_t t = time( NULL );
00063 #endif
00064     mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
00065     mbedtls_ssl_cache_entry *cur, *entry;
00066 
00067 #if defined(MBEDTLS_THREADING_C)
00068     if( mbedtls_mutex_lock( &cache->mutex  ) != 0 )
00069         return( 1 );
00070 #endif
00071 
00072     cur = cache->chain ;
00073     entry = NULL;
00074 
00075     while( cur != NULL )
00076     {
00077         entry = cur;
00078         cur = cur->next ;
00079 
00080 #if defined(MBEDTLS_HAVE_TIME)
00081         if( cache->timeout  != 0 &&
00082             (int) ( t - entry->timestamp  ) > cache->timeout  )
00083             continue;
00084 #endif
00085 
00086         if( session->ciphersuite != entry->session .ciphersuite ||
00087             session->compression != entry->session .compression ||
00088             session->id_len != entry->session .id_len )
00089             continue;
00090 
00091         if( memcmp( session->id, entry->session .id,
00092                     entry->session .id_len ) != 0 )
00093             continue;
00094 
00095         memcpy( session->master, entry->session .master, 48 );
00096 
00097         session->verify_result = entry->session .verify_result;
00098 
00099 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00100         /*
00101          * Restore peer certificate (without rest of the original chain)
00102          */
00103         if( entry->peer_cert .p != NULL )
00104         {
00105             if( ( session->peer_cert = mbedtls_calloc( 1,
00106                                  sizeof(mbedtls_x509_crt) ) ) == NULL )
00107             {
00108                 ret = 1;
00109                 goto exit;
00110             }
00111 
00112             mbedtls_x509_crt_init( session->peer_cert );
00113             if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert .p,
00114                                 entry->peer_cert .len ) != 0 )
00115             {
00116                 mbedtls_free( session->peer_cert );
00117                 session->peer_cert = NULL;
00118                 ret = 1;
00119                 goto exit;
00120             }
00121         }
00122 #endif /* MBEDTLS_X509_CRT_PARSE_C */
00123 
00124         ret = 0;
00125         goto exit;
00126     }
00127 
00128 exit:
00129 #if defined(MBEDTLS_THREADING_C)
00130     if( mbedtls_mutex_unlock( &cache->mutex  ) != 0 )
00131         ret = 1;
00132 #endif
00133 
00134     return( ret );
00135 }
00136 
00137 int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session )
00138 {
00139     int ret = 1;
00140 #if defined(MBEDTLS_HAVE_TIME)
00141     time_t t = time( NULL ), oldest = 0;
00142     mbedtls_ssl_cache_entry *old = NULL;
00143 #endif
00144     mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
00145     mbedtls_ssl_cache_entry *cur, *prv;
00146     int count = 0;
00147 
00148 #if defined(MBEDTLS_THREADING_C)
00149     if( ( ret = mbedtls_mutex_lock( &cache->mutex  ) ) != 0 )
00150         return( ret );
00151 #endif
00152 
00153     cur = cache->chain ;
00154     prv = NULL;
00155 
00156     while( cur != NULL )
00157     {
00158         count++;
00159 
00160 #if defined(MBEDTLS_HAVE_TIME)
00161         if( cache->timeout  != 0 &&
00162             (int) ( t - cur->timestamp  ) > cache->timeout  )
00163         {
00164             cur->timestamp  = t;
00165             break; /* expired, reuse this slot, update timestamp */
00166         }
00167 #endif
00168 
00169         if( memcmp( session->id, cur->session .id, cur->session .id_len ) == 0 )
00170             break; /* client reconnected, keep timestamp for session id */
00171 
00172 #if defined(MBEDTLS_HAVE_TIME)
00173         if( oldest == 0 || cur->timestamp  < oldest )
00174         {
00175             oldest = cur->timestamp ;
00176             old = cur;
00177         }
00178 #endif
00179 
00180         prv = cur;
00181         cur = cur->next ;
00182     }
00183 
00184     if( cur == NULL )
00185     {
00186 #if defined(MBEDTLS_HAVE_TIME)
00187         /*
00188          * Reuse oldest entry if max_entries reached
00189          */
00190         if( count >= cache->max_entries  )
00191         {
00192             if( old == NULL )
00193             {
00194                 ret = 1;
00195                 goto exit;
00196             }
00197 
00198             cur = old;
00199         }
00200 #else /* MBEDTLS_HAVE_TIME */
00201         /*
00202          * Reuse first entry in chain if max_entries reached,
00203          * but move to last place
00204          */
00205         if( count >= cache->max_entries  )
00206         {
00207             if( cache->chain  == NULL )
00208             {
00209                 ret = 1;
00210                 goto exit;
00211             }
00212 
00213             cur = cache->chain ;
00214             cache->chain  = cur->next ;
00215             cur->next  = NULL;
00216             prv->next  = cur;
00217         }
00218 #endif /* MBEDTLS_HAVE_TIME */
00219         else
00220         {
00221             /*
00222              * max_entries not reached, create new entry
00223              */
00224             cur = mbedtls_calloc( 1, sizeof(mbedtls_ssl_cache_entry) );
00225             if( cur == NULL )
00226             {
00227                 ret = 1;
00228                 goto exit;
00229             }
00230 
00231             if( prv == NULL )
00232                 cache->chain  = cur;
00233             else
00234                 prv->next  = cur;
00235         }
00236 
00237 #if defined(MBEDTLS_HAVE_TIME)
00238         cur->timestamp  = t;
00239 #endif
00240     }
00241 
00242     memcpy( &cur->session , session, sizeof( mbedtls_ssl_session ) );
00243 
00244 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00245     /*
00246      * If we're reusing an entry, free its certificate first
00247      */
00248     if( cur->peer_cert .p != NULL )
00249     {
00250         mbedtls_free( cur->peer_cert .p );
00251         memset( &cur->peer_cert , 0, sizeof(mbedtls_x509_buf) );
00252     }
00253 
00254     /*
00255      * Store peer certificate
00256      */
00257     if( session->peer_cert != NULL )
00258     {
00259         cur->peer_cert .p = mbedtls_calloc( 1, session->peer_cert->raw.len );
00260         if( cur->peer_cert .p == NULL )
00261         {
00262             ret = 1;
00263             goto exit;
00264         }
00265 
00266         memcpy( cur->peer_cert .p, session->peer_cert->raw.p,
00267                 session->peer_cert->raw.len );
00268         cur->peer_cert .len = session->peer_cert->raw.len;
00269 
00270         cur->session .peer_cert = NULL;
00271     }
00272 #endif /* MBEDTLS_X509_CRT_PARSE_C */
00273 
00274     ret = 0;
00275 
00276 exit:
00277 #if defined(MBEDTLS_THREADING_C)
00278     if( mbedtls_mutex_unlock( &cache->mutex  ) != 0 )
00279         ret = 1;
00280 #endif
00281 
00282     return( ret );
00283 }
00284 
00285 #if defined(MBEDTLS_HAVE_TIME)
00286 void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout )
00287 {
00288     if( timeout < 0 ) timeout = 0;
00289 
00290     cache->timeout  = timeout;
00291 }
00292 #endif /* MBEDTLS_HAVE_TIME */
00293 
00294 void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max )
00295 {
00296     if( max < 0 ) max = 0;
00297 
00298     cache->max_entries  = max;
00299 }
00300 
00301 void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache )
00302 {
00303     mbedtls_ssl_cache_entry *cur, *prv;
00304 
00305     cur = cache->chain ;
00306 
00307     while( cur != NULL )
00308     {
00309         prv = cur;
00310         cur = cur->next ;
00311 
00312         mbedtls_ssl_session_free( &prv->session  );
00313 
00314 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00315         mbedtls_free( prv->peer_cert .p );
00316 #endif /* MBEDTLS_X509_CRT_PARSE_C */
00317 
00318         mbedtls_free( prv );
00319     }
00320 
00321 #if defined(MBEDTLS_THREADING_C)
00322     mbedtls_mutex_free( &cache->mutex  );
00323 #endif
00324 }
00325 
00326 #endif /* MBEDTLS_SSL_CACHE_C */