mirror of
				https://github.com/cuberite/polarssl.git
				synced 2025-11-03 20:22:59 -05:00 
			
		
		
		
	Add new ABI-independent format for serialization
This commit is contained in:
		
							parent
							
								
									ee13a732d6
								
							
						
					
					
						commit
						f743c03ea7
					
				@ -9846,14 +9846,23 @@ const mbedtls_ssl_session *mbedtls_ssl_get_session_pointer( const mbedtls_ssl_co
 | 
			
		||||
 * Serialize a session in the following format:
 | 
			
		||||
 * (in the presentation language of TLS, RFC 8446 section 3)
 | 
			
		||||
 *
 | 
			
		||||
 *  opaque session_struct[n];       // n = sizeof(mbedtls_ssl_session)
 | 
			
		||||
 *  select (MBEDTLS_SSL_KEEP_PEER_CERTIFICATE) {
 | 
			
		||||
 *      case enabled:  opaque peer_cert<0..2^24-1>; // length 0 means no cert
 | 
			
		||||
 *      case disabled: opaque peer_cert_digest<0..2^8-1>;
 | 
			
		||||
 *  }
 | 
			
		||||
 *  opaque ticket<0..2^24-1>;       // 0 means no ticket
 | 
			
		||||
 *  uint64 start_time;
 | 
			
		||||
 *  uint8 ciphersuite[2];           // defined by the standard
 | 
			
		||||
 *  uint8 compression;              // 0 or 1
 | 
			
		||||
 *  uint8 session_id_len;           // at most 32
 | 
			
		||||
 *  opaque session_id[32];
 | 
			
		||||
 *  opaque master[48];              // fixed length in the standard
 | 
			
		||||
 *  uint32 verify_result;
 | 
			
		||||
 *  opaque peer_cert<0..2^24-1>;    // length 0 means no peer cert
 | 
			
		||||
 *  opaque ticket<0..2^24-1>;       // length 0 means no ticket
 | 
			
		||||
 *  uint32 ticket_lifetime;
 | 
			
		||||
 *  uint8 mfl_code;                 // up to 255 according to standard
 | 
			
		||||
 *  uint8 trunc_hmac;               // 0 or 1
 | 
			
		||||
 *  uint8 encrypt_then_mac;         // 0 or 1
 | 
			
		||||
 *
 | 
			
		||||
 * Only the peer's certificate is saved, not the whole chain.
 | 
			
		||||
 * The order is the same as in the definition of the structure, except
 | 
			
		||||
 * verify_result is put before peer_cert so that all mandatory fields come
 | 
			
		||||
 * together in one block.
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
 | 
			
		||||
                              unsigned char *buf,
 | 
			
		||||
@ -9862,30 +9871,69 @@ int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
 | 
			
		||||
{
 | 
			
		||||
    unsigned char *p = buf;
 | 
			
		||||
    size_t used = 0;
 | 
			
		||||
#if defined(MBEDTLS_HAVE_TIME)
 | 
			
		||||
    uint64_t start;
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
 | 
			
		||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
 | 
			
		||||
    size_t cert_len;
 | 
			
		||||
#else
 | 
			
		||||
    size_t cert_digest_len;
 | 
			
		||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 | 
			
		||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Shallow copy of the session structure
 | 
			
		||||
     */
 | 
			
		||||
    used += sizeof( mbedtls_ssl_session );
 | 
			
		||||
 | 
			
		||||
    /* This also copies the values of pointer fields in the
 | 
			
		||||
     * session to be serialized, but they'll be ignored when
 | 
			
		||||
     * loading the session through ssl_load_session(). */
 | 
			
		||||
    /*
 | 
			
		||||
     * Time
 | 
			
		||||
     */
 | 
			
		||||
#if defined(MBEDTLS_HAVE_TIME)
 | 
			
		||||
    used += 8;
 | 
			
		||||
 | 
			
		||||
    if( used <= buf_len )
 | 
			
		||||
    {
 | 
			
		||||
        memcpy( p, session, sizeof( mbedtls_ssl_session ) );
 | 
			
		||||
        p += sizeof( mbedtls_ssl_session );
 | 
			
		||||
        start = (uint64_t) session->start;
 | 
			
		||||
 | 
			
		||||
        *p++ = (unsigned char)( ( start >> 56 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( start >> 48 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( start >> 40 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( start >> 32 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( start >> 24 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( start >> 16 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( start >>  8 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( start       ) & 0xFF );
 | 
			
		||||
    }
 | 
			
		||||
#endif /* MBEDTLS_HAVE_TIME */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Basic mandatory fields
 | 
			
		||||
     */
 | 
			
		||||
    used += 2   /* ciphersuite */
 | 
			
		||||
          + 1   /* compression */
 | 
			
		||||
          + 1   /* id_len */
 | 
			
		||||
          + sizeof( session->id )
 | 
			
		||||
          + sizeof( session->master )
 | 
			
		||||
          + 4;  /* verify_result */
 | 
			
		||||
 | 
			
		||||
    if( used <= buf_len )
 | 
			
		||||
    {
 | 
			
		||||
        *p++ = (unsigned char)( ( session->ciphersuite >> 8 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( session->ciphersuite      ) & 0xFF );
 | 
			
		||||
 | 
			
		||||
        *p++ = (unsigned char)( session->compression & 0xFF );
 | 
			
		||||
 | 
			
		||||
        *p++ = (unsigned char)( session->id_len & 0xFF );
 | 
			
		||||
        memcpy( p, session->id, 32 );
 | 
			
		||||
        p += 32;
 | 
			
		||||
 | 
			
		||||
        memcpy( p, session->master, 48 );
 | 
			
		||||
        p += 48;
 | 
			
		||||
 | 
			
		||||
        *p++ = (unsigned char)( ( session->verify_result >> 24 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( session->verify_result >> 16 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( session->verify_result >>  8 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( session->verify_result       ) & 0xFF );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Copy of the peer's end-entity certificate
 | 
			
		||||
     * Peer's end-entity certificate
 | 
			
		||||
     */
 | 
			
		||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
 | 
			
		||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
 | 
			
		||||
@ -9909,30 +9957,35 @@ int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 | 
			
		||||
    if( session->peer_cert_digest == NULL )
 | 
			
		||||
        cert_digest_len = 0;
 | 
			
		||||
    else
 | 
			
		||||
        cert_digest_len = session->peer_cert_digest_len;
 | 
			
		||||
 | 
			
		||||
    used += 1 + cert_digest_len;
 | 
			
		||||
 | 
			
		||||
    if( used <= buf_len )
 | 
			
		||||
    if( session->peer_cert_digest != NULL )
 | 
			
		||||
    {
 | 
			
		||||
        *p++ = (unsigned char) cert_digest_len;
 | 
			
		||||
 | 
			
		||||
        if( session->peer_cert_digest != NULL )
 | 
			
		||||
            memcpy( p, session->peer_cert_digest, cert_digest_len );
 | 
			
		||||
 | 
			
		||||
        p += cert_digest_len;
 | 
			
		||||
        used += 1 /* type */ + 1 /* length */ + session->peer_cert_digest_len;
 | 
			
		||||
        if( used <= buf_len )
 | 
			
		||||
        {
 | 
			
		||||
            *p++ = (unsigned char) session->peer_cert_digest_type;
 | 
			
		||||
            *p++ = (unsigned char) session->peer_cert_digest_len;
 | 
			
		||||
            memcpy( p, session->peer_cert_digest,
 | 
			
		||||
                    session->peer_cert_digest_len );
 | 
			
		||||
            p += session->peer_cert_digest_len;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        used += 2;
 | 
			
		||||
        if( used <= buf_len )
 | 
			
		||||
        {
 | 
			
		||||
            *p++ = (unsigned char) MBEDTLS_MD_NONE;
 | 
			
		||||
            *p++ = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
#endif /* !MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 | 
			
		||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Copy of the session ticket if any
 | 
			
		||||
     * Session ticket if any, plus associated data
 | 
			
		||||
     */
 | 
			
		||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
 | 
			
		||||
    used += 3 + session->ticket_len;
 | 
			
		||||
    used += 3 + session->ticket_len + 4; /* len + ticket + lifetime */
 | 
			
		||||
 | 
			
		||||
    if( used <= buf_len )
 | 
			
		||||
    {
 | 
			
		||||
@ -9945,9 +9998,38 @@ int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
 | 
			
		||||
            memcpy( p, session->ticket, session->ticket_len );
 | 
			
		||||
            p += session->ticket_len;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        *p++ = (unsigned char)( ( session->ticket_lifetime >> 24 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( session->ticket_lifetime >> 16 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( session->ticket_lifetime >>  8 ) & 0xFF );
 | 
			
		||||
        *p++ = (unsigned char)( ( session->ticket_lifetime       ) & 0xFF );
 | 
			
		||||
    }
 | 
			
		||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Misc extension-related info
 | 
			
		||||
     */
 | 
			
		||||
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
 | 
			
		||||
    used += 1;
 | 
			
		||||
 | 
			
		||||
    if( used <= buf_len )
 | 
			
		||||
        *p++ = session->mfl_code;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
 | 
			
		||||
    used += 1;
 | 
			
		||||
 | 
			
		||||
    if( used <= buf_len )
 | 
			
		||||
        *p++ = (unsigned char)( ( session->trunc_hmac ) & 0xFF );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
 | 
			
		||||
    used += 1;
 | 
			
		||||
 | 
			
		||||
    if( used <= buf_len )
 | 
			
		||||
        *p++ = (unsigned char)( ( session->encrypt_then_mac ) & 0xFF );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* Done */
 | 
			
		||||
    *olen = used;
 | 
			
		||||
 | 
			
		||||
@ -9958,7 +10040,7 @@ int mbedtls_ssl_session_save( const mbedtls_ssl_session *session,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Unserialize session, see mbedtls_ssl_session_save().
 | 
			
		||||
 * Unserialize session, see mbedtls_ssl_session_save() for format.
 | 
			
		||||
 *
 | 
			
		||||
 * This internal version is wrapped by a public function that cleans up in
 | 
			
		||||
 * case of error.
 | 
			
		||||
@ -9969,25 +10051,61 @@ static int ssl_session_load( mbedtls_ssl_session *session,
 | 
			
		||||
{
 | 
			
		||||
    const unsigned char *p = buf;
 | 
			
		||||
    const unsigned char * const end = buf + len;
 | 
			
		||||
#if defined(MBEDTLS_HAVE_TIME)
 | 
			
		||||
    uint64_t start;
 | 
			
		||||
#endif
 | 
			
		||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
 | 
			
		||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
 | 
			
		||||
    size_t cert_len;
 | 
			
		||||
#else
 | 
			
		||||
    size_t cert_digest_len;
 | 
			
		||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 | 
			
		||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Shallow session structure
 | 
			
		||||
     * Time
 | 
			
		||||
     */
 | 
			
		||||
    if( sizeof( mbedtls_ssl_session ) > (size_t)( end - p ) )
 | 
			
		||||
#if defined(MBEDTLS_HAVE_TIME)
 | 
			
		||||
    if( 8 > (size_t)( end - p ) )
 | 
			
		||||
        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 | 
			
		||||
 | 
			
		||||
    memcpy( session, p, sizeof( mbedtls_ssl_session ) );
 | 
			
		||||
    p += sizeof( mbedtls_ssl_session );
 | 
			
		||||
    start = ( (uint64_t) p[0] << 56 ) |
 | 
			
		||||
            ( (uint64_t) p[1] << 48 ) |
 | 
			
		||||
            ( (uint64_t) p[2] << 40 ) |
 | 
			
		||||
            ( (uint64_t) p[3] << 32 ) |
 | 
			
		||||
            ( (uint64_t) p[4] << 24 ) |
 | 
			
		||||
            ( (uint64_t) p[5] << 16 ) |
 | 
			
		||||
            ( (uint64_t) p[6] <<  8 ) |
 | 
			
		||||
            ( (uint64_t) p[7]       );
 | 
			
		||||
    p += 8;
 | 
			
		||||
 | 
			
		||||
    /* Non-NULL pointer fields of `session` are meaningless
 | 
			
		||||
     * and potentially harmful. Zeroize them for safety. */
 | 
			
		||||
    session->start = (time_t) start;
 | 
			
		||||
#endif /* MBEDTLS_HAVE_TIME */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Basic mandatory fields
 | 
			
		||||
     */
 | 
			
		||||
    if( 2 + 1 + 1 + 32 + 48 + 4 > (size_t)( end - p ) )
 | 
			
		||||
        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 | 
			
		||||
 | 
			
		||||
    session->ciphersuite = ( p[0] << 8 ) | p[1];
 | 
			
		||||
    p += 2;
 | 
			
		||||
 | 
			
		||||
    session->compression = *p++;
 | 
			
		||||
 | 
			
		||||
    session->id_len = *p++;
 | 
			
		||||
    memcpy( session->id, p, 32 );
 | 
			
		||||
    p += 32;
 | 
			
		||||
 | 
			
		||||
    memcpy( session->master, p, 48 );
 | 
			
		||||
    p += 48;
 | 
			
		||||
 | 
			
		||||
    session->verify_result = ( (uint32_t) p[0] << 24 ) |
 | 
			
		||||
                             ( (uint32_t) p[1] << 16 ) |
 | 
			
		||||
                             ( (uint32_t) p[2] <<  8 ) |
 | 
			
		||||
                             ( (uint32_t) p[3]       );
 | 
			
		||||
    p += 4;
 | 
			
		||||
 | 
			
		||||
    /* Immediately clear invalid pointer values that have been read, in case
 | 
			
		||||
     * we exit early before we replaced them with valid ones. */
 | 
			
		||||
#if defined(MBEDTLS_X509_CRT_PARSE_C)
 | 
			
		||||
#if defined(MBEDTLS_SSL_KEEP_PEER_CERTIFICATE)
 | 
			
		||||
    session->peer_cert = NULL;
 | 
			
		||||
@ -10038,32 +10156,38 @@ static int ssl_session_load( mbedtls_ssl_session *session,
 | 
			
		||||
    }
 | 
			
		||||
#else /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 | 
			
		||||
    /* Deserialize CRT digest from the end of the ticket. */
 | 
			
		||||
    if( 1 > (size_t)( end - p ) )
 | 
			
		||||
    if( 2 > (size_t)( end - p ) )
 | 
			
		||||
        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 | 
			
		||||
 | 
			
		||||
    cert_digest_len = (size_t) p[0];
 | 
			
		||||
    p++;
 | 
			
		||||
    session->peer_cert_digest_type = (mbedtls_md_type_t) *p++;
 | 
			
		||||
    session->peer_cert_digest_len  = (size_t) *p++;
 | 
			
		||||
 | 
			
		||||
    if( cert_digest_len != 0 )
 | 
			
		||||
    if( session->peer_cert_digest_len != 0 )
 | 
			
		||||
    {
 | 
			
		||||
        if( cert_digest_len > (size_t)( end - p ) ||
 | 
			
		||||
            cert_digest_len != session->peer_cert_digest_len )
 | 
			
		||||
        {
 | 
			
		||||
        const mbedtls_md_info_t *md_info =
 | 
			
		||||
            mbedtls_md_info_from_type( session->peer_cert_digest_type );
 | 
			
		||||
        if( md_info == NULL )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 | 
			
		||||
        if( session->peer_cert_digest_len != mbedtls_md_get_size( md_info ) )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        session->peer_cert_digest = mbedtls_calloc( 1, cert_digest_len );
 | 
			
		||||
        if( session->peer_cert_digest_len > (size_t)( end - p ) )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 | 
			
		||||
 | 
			
		||||
        session->peer_cert_digest =
 | 
			
		||||
            mbedtls_calloc( 1, session->peer_cert_digest_len );
 | 
			
		||||
        if( session->peer_cert_digest == NULL )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_ALLOC_FAILED );
 | 
			
		||||
 | 
			
		||||
        memcpy( session->peer_cert_digest, p, cert_digest_len );
 | 
			
		||||
        p += cert_digest_len;
 | 
			
		||||
        memcpy( session->peer_cert_digest, p,
 | 
			
		||||
                session->peer_cert_digest_len );
 | 
			
		||||
        p += session->peer_cert_digest_len;
 | 
			
		||||
    }
 | 
			
		||||
#endif /* MBEDTLS_SSL_KEEP_PEER_CERTIFICATE */
 | 
			
		||||
#endif /* MBEDTLS_X509_CRT_PARSE_C */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Session ticket
 | 
			
		||||
     * Session ticket and associated data
 | 
			
		||||
     */
 | 
			
		||||
#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C)
 | 
			
		||||
    if( 3 > (size_t)( end - p ) )
 | 
			
		||||
@ -10084,8 +10208,41 @@ static int ssl_session_load( mbedtls_ssl_session *session,
 | 
			
		||||
        memcpy( session->ticket, p, session->ticket_len );
 | 
			
		||||
        p += session->ticket_len;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( 4 > (size_t)( end - p ) )
 | 
			
		||||
        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 | 
			
		||||
 | 
			
		||||
    session->ticket_lifetime = ( (uint32_t) p[0] << 24 ) |
 | 
			
		||||
                               ( (uint32_t) p[1] << 16 ) |
 | 
			
		||||
                               ( (uint32_t) p[2] <<  8 ) |
 | 
			
		||||
                               ( (uint32_t) p[3]       );
 | 
			
		||||
    p += 4;
 | 
			
		||||
#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Misc extension-related info
 | 
			
		||||
     */
 | 
			
		||||
#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH)
 | 
			
		||||
    if( 1 > (size_t)( end - p ) )
 | 
			
		||||
        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 | 
			
		||||
 | 
			
		||||
    session->mfl_code = *p++;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(MBEDTLS_SSL_TRUNCATED_HMAC)
 | 
			
		||||
    if( 1 > (size_t)( end - p ) )
 | 
			
		||||
        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 | 
			
		||||
 | 
			
		||||
    session->trunc_hmac = *p++;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC)
 | 
			
		||||
    if( 1 > (size_t)( end - p ) )
 | 
			
		||||
        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 | 
			
		||||
 | 
			
		||||
    session->encrypt_then_mac = *p++;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* Done, should have consumed entire buffer */
 | 
			
		||||
    if( p != end )
 | 
			
		||||
        return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA );
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user