joey shelton / LED_Demo

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

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 #if defined(MBEDTLS_PLATFORM_C)
00035 #include "mbedtls/platform.h"
00036 #else
00037 #include <stdlib.h>
00038 #define mbedtls_calloc    calloc
00039 #define mbedtls_free      free
00040 #define mbedtls_time      time
00041 #define mbedtls_time_t    time_t
00042 #endif
00043 
00044 #include "mbedtls/ssl_cache.h"
00045 
00046 #include <string.h>
00047 
00048 void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache )
00049 {
00050     memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) );
00051 
00052     cache->timeout  = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT;
00053     cache->max_entries  = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES;
00054 
00055 #if defined(MBEDTLS_THREADING_C)
00056     mbedtls_mutex_init( &cache->mutex  );
00057 #endif
00058 }
00059 
00060 int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session )
00061 {
00062     int ret = 1;
00063 #if defined(MBEDTLS_HAVE_TIME)
00064     mbedtls_time_t t = mbedtls_time( NULL );
00065 #endif
00066     mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
00067     mbedtls_ssl_cache_entry *cur, *entry;
00068 
00069 #if defined(MBEDTLS_THREADING_C)
00070     if( mbedtls_mutex_lock( &cache->mutex  ) != 0 )
00071         return( 1 );
00072 #endif
00073 
00074     cur = cache->chain ;
00075     entry = NULL;
00076 
00077     while( cur != NULL )
00078     {
00079         entry = cur;
00080         cur = cur->next ;
00081 
00082 #if defined(MBEDTLS_HAVE_TIME)
00083         if( cache->timeout  != 0 &&
00084             (int) ( t - entry->timestamp  ) > cache->timeout  )
00085             continue;
00086 #endif
00087 
00088         if( session->ciphersuite != entry->session .ciphersuite ||
00089             session->compression != entry->session .compression ||
00090             session->id_len != entry->session .id_len )
00091             continue;
00092 
00093         if( memcmp( session->id, entry->session .id,
00094                     entry->session .id_len ) != 0 )
00095             continue;
00096 
00097         memcpy( session->master, entry->session .master, 48 );
00098 
00099         session->verify_result = entry->session .verify_result;
00100 
00101 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00102         /*
00103          * Restore peer certificate (without rest of the original chain)
00104          */
00105         if( entry->peer_cert .p != NULL )
00106         {
00107             if( ( session->peer_cert = mbedtls_calloc( 1,
00108                                  sizeof(mbedtls_x509_crt) ) ) == NULL )
00109             {
00110                 ret = 1;
00111                 goto exit;
00112             }
00113 
00114             mbedtls_x509_crt_init( session->peer_cert );
00115             if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert .p,
00116                                 entry->peer_cert .len ) != 0 )
00117             {
00118                 mbedtls_free( session->peer_cert );
00119                 session->peer_cert = NULL;
00120                 ret = 1;
00121                 goto exit;
00122             }
00123         }
00124 #endif /* MBEDTLS_X509_CRT_PARSE_C */
00125 
00126         ret = 0;
00127         goto exit;
00128     }
00129 
00130 exit:
00131 #if defined(MBEDTLS_THREADING_C)
00132     if( mbedtls_mutex_unlock( &cache->mutex  ) != 0 )
00133         ret = 1;
00134 #endif
00135 
00136     return( ret );
00137 }
00138 
00139 int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session )
00140 {
00141     int ret = 1;
00142 #if defined(MBEDTLS_HAVE_TIME)
00143     mbedtls_time_t t = time( NULL ), oldest = 0;
00144     mbedtls_ssl_cache_entry *old = NULL;
00145 #endif
00146     mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data;
00147     mbedtls_ssl_cache_entry *cur, *prv;
00148     int count = 0;
00149 
00150 #if defined(MBEDTLS_THREADING_C)
00151     if( ( ret = mbedtls_mutex_lock( &cache->mutex  ) ) != 0 )
00152         return( ret );
00153 #endif
00154 
00155     cur = cache->chain ;
00156     prv = NULL;
00157 
00158     while( cur != NULL )
00159     {
00160         count++;
00161 
00162 #if defined(MBEDTLS_HAVE_TIME)
00163         if( cache->timeout  != 0 &&
00164             (int) ( t - cur->timestamp  ) > cache->timeout  )
00165         {
00166             cur->timestamp  = t;
00167             break; /* expired, reuse this slot, update timestamp */
00168         }
00169 #endif
00170 
00171         if( memcmp( session->id, cur->session .id, cur->session .id_len ) == 0 )
00172             break; /* client reconnected, keep timestamp for session id */
00173 
00174 #if defined(MBEDTLS_HAVE_TIME)
00175         if( oldest == 0 || cur->timestamp  < oldest )
00176         {
00177             oldest = cur->timestamp ;
00178             old = cur;
00179         }
00180 #endif
00181 
00182         prv = cur;
00183         cur = cur->next ;
00184     }
00185 
00186     if( cur == NULL )
00187     {
00188 #if defined(MBEDTLS_HAVE_TIME)
00189         /*
00190          * Reuse oldest entry if max_entries reached
00191          */
00192         if( count >= cache->max_entries  )
00193         {
00194             if( old == NULL )
00195             {
00196                 ret = 1;
00197                 goto exit;
00198             }
00199 
00200             cur = old;
00201         }
00202 #else /* MBEDTLS_HAVE_TIME */
00203         /*
00204          * Reuse first entry in chain if max_entries reached,
00205          * but move to last place
00206          */
00207         if( count >= cache->max_entries  )
00208         {
00209             if( cache->chain  == NULL )
00210             {
00211                 ret = 1;
00212                 goto exit;
00213             }
00214 
00215             cur = cache->chain ;
00216             cache->chain  = cur->next ;
00217             cur->next  = NULL;
00218             prv->next  = cur;
00219         }
00220 #endif /* MBEDTLS_HAVE_TIME */
00221         else
00222         {
00223             /*
00224              * max_entries not reached, create new entry
00225              */
00226             cur = mbedtls_calloc( 1, sizeof(mbedtls_ssl_cache_entry) );
00227             if( cur == NULL )
00228             {
00229                 ret = 1;
00230                 goto exit;
00231             }
00232 
00233             if( prv == NULL )
00234                 cache->chain  = cur;
00235             else
00236                 prv->next  = cur;
00237         }
00238 
00239 #if defined(MBEDTLS_HAVE_TIME)
00240         cur->timestamp  = t;
00241 #endif
00242     }
00243 
00244     memcpy( &cur->session , session, sizeof( mbedtls_ssl_session ) );
00245 
00246 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00247     /*
00248      * If we're reusing an entry, free its certificate first
00249      */
00250     if( cur->peer_cert .p != NULL )
00251     {
00252         mbedtls_free( cur->peer_cert .p );
00253         memset( &cur->peer_cert , 0, sizeof(mbedtls_x509_buf) );
00254     }
00255 
00256     /*
00257      * Store peer certificate
00258      */
00259     if( session->peer_cert != NULL )
00260     {
00261         cur->peer_cert .p = mbedtls_calloc( 1, session->peer_cert->raw.len );
00262         if( cur->peer_cert .p == NULL )
00263         {
00264             ret = 1;
00265             goto exit;
00266         }
00267 
00268         memcpy( cur->peer_cert .p, session->peer_cert->raw.p,
00269                 session->peer_cert->raw.len );
00270         cur->peer_cert .len = session->peer_cert->raw.len;
00271 
00272         cur->session .peer_cert = NULL;
00273     }
00274 #endif /* MBEDTLS_X509_CRT_PARSE_C */
00275 
00276     ret = 0;
00277 
00278 exit:
00279 #if defined(MBEDTLS_THREADING_C)
00280     if( mbedtls_mutex_unlock( &cache->mutex  ) != 0 )
00281         ret = 1;
00282 #endif
00283 
00284     return( ret );
00285 }
00286 
00287 #if defined(MBEDTLS_HAVE_TIME)
00288 void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout )
00289 {
00290     if( timeout < 0 ) timeout = 0;
00291 
00292     cache->timeout  = timeout;
00293 }
00294 #endif /* MBEDTLS_HAVE_TIME */
00295 
00296 void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max )
00297 {
00298     if( max < 0 ) max = 0;
00299 
00300     cache->max_entries  = max;
00301 }
00302 
00303 void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache )
00304 {
00305     mbedtls_ssl_cache_entry *cur, *prv;
00306 
00307     cur = cache->chain ;
00308 
00309     while( cur != NULL )
00310     {
00311         prv = cur;
00312         cur = cur->next ;
00313 
00314         mbedtls_ssl_session_free( &prv->session  );
00315 
00316 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00317         mbedtls_free( prv->peer_cert .p );
00318 #endif /* MBEDTLS_X509_CRT_PARSE_C */
00319 
00320         mbedtls_free( prv );
00321     }
00322 
00323 #if defined(MBEDTLS_THREADING_C)
00324     mbedtls_mutex_free( &cache->mutex  );
00325 #endif
00326 }
00327 
00328 #endif /* MBEDTLS_SSL_CACHE_C */