Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

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