Added Ephemeral Elliptic Curve Diffie Hellman ciphersuites to SSL/TLS

Made all modifications to include Ephemeral Elliptic Curve Diffie
Hellman ciphersuites into the existing SSL/TLS modules. All basic
handling of the ECDHE-ciphersuites (TLS_ECDHE_RSA_WITH_NULL_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA)
has been included.
This commit is contained in:
Paul Bakker 2013-03-20 14:39:14 +01:00
parent 00c1f43743
commit 41c83d3f67
14 changed files with 676 additions and 334 deletions

View File

@ -1,6 +1,12 @@
PolarSSL ChangeLog
= Development
Features
* Elliptic Curve Cryptography module added
* Elliptic Curve Diffie Hellman module added
* Ephemeral Elliptic Curve Diffie Hellman support for SSL/TLS
(ECDHE-based ciphersuites)
Changes
* Introduced separate SSL Ciphersuites module that is based on
Cipher and MD information

View File

@ -140,6 +140,7 @@
* TLS_RSA_WITH_NULL_MD5
* TLS_RSA_WITH_NULL_SHA
* TLS_RSA_WITH_NULL_SHA256
* TLS_ECDHE_RSA_WITH_NULL_SHA
*
* Uncomment this macro to enable the NULL cipher and ciphersuites
#define POLARSSL_CIPHER_NULL_CIPHER
@ -345,6 +346,8 @@
* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
* TLS_RSA_WITH_AES_128_GCM_SHA256
* TLS_RSA_WITH_AES_256_GCM_SHA384
* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
*
* PEM uses AES for decrypting encrypted keys.
*/
@ -358,9 +361,11 @@
* Module: library/arc4.c
* Caller: library/ssl_tls.c
*
* This module enables the following ciphersuites:
* This module enables the following ciphersuites (if other requisites are
* enabled as well):
* TLS_RSA_WITH_RC4_128_MD5
* TLS_RSA_WITH_RC4_128_SHA
* TLS_ECDHE_RSA_WITH_RC4_128_SHA
*/
#define POLARSSL_ARC4_C
@ -505,6 +510,7 @@
* enabled as well):
* TLS_RSA_WITH_3DES_EDE_CBC_SHA
* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
*
* PEM uses DES/3DES for decrypting encrypted keys.
*/
@ -542,7 +548,16 @@
* Enable the elliptic curve Diffie-Hellman library.
*
* Module: library/ecdh.c
* Caller:
* Caller: library/ssl_cli.c
* library/ssl_srv.c
*
* This module enables the following ciphersuites (if other requisites are
* enabled as well):
* TLS_ECDHE_RSA_WITH_NULL_SHA
* TLS_ECDHE_RSA_WITH_RC4_128_SHA
* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
*
* Requires: POLARSSL_ECP_C
*/

View File

@ -29,6 +29,9 @@
#include "config.h"
#include "ssl.h"
#if defined(POLARSSL_ECP_C)
#include "ecp.h"
#endif
#if defined(POLARSSL_DEBUG_C)
@ -44,6 +47,9 @@
#define SSL_DEBUG_MPI( level, text, X ) \
debug_print_mpi( ssl, level, __FILE__, __LINE__, text, X );
#define SSL_DEBUG_ECP( level, text, X ) \
debug_print_ecp( ssl, level, __FILE__, __LINE__, text, X );
#define SSL_DEBUG_CRT( level, text, crt ) \
debug_print_crt( ssl, level, __FILE__, __LINE__, text, crt );
@ -53,6 +59,7 @@
#define SSL_DEBUG_RET( level, text, ret ) do { } while( 0 )
#define SSL_DEBUG_BUF( level, text, buf, len ) do { } while( 0 )
#define SSL_DEBUG_MPI( level, text, X ) do { } while( 0 )
#define SSL_DEBUG_ECP( level, text, X ) do { } while( 0 )
#define SSL_DEBUG_CRT( level, text, crt ) do { } while( 0 )
#endif
@ -78,6 +85,12 @@ void debug_print_mpi( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mpi *X );
#if defined(POLARSSL_ECP_C)
void debug_print_ecp( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, const ecp_point *X );
#endif
void debug_print_crt( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, const x509_cert *crt );

View File

@ -43,6 +43,10 @@
#include "dhm.h"
#endif
#if defined(POLARSSL_ECDH_C)
#include "ecdh.h"
#endif
#if defined(POLARSSL_ZLIB_SUPPORT)
#include "zlib.h"
#endif
@ -82,8 +86,8 @@
#define POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE -0x7B00 /**< Processing of the ServerKeyExchange handshake message failed. */
#define POLARSSL_ERR_SSL_BAD_HS_SERVER_HELLO_DONE -0x7B80 /**< Processing of the ServerHelloDone handshake message failed. */
#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE -0x7C00 /**< Processing of the ClientKeyExchange handshake message failed. */
#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_DHM_RP -0x7C80 /**< Processing of the ClientKeyExchange handshake message failed in DHM Read Public. */
#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_DHM_CS -0x7D00 /**< Processing of the ClientKeyExchange handshake message failed in DHM Calculate Secret. */
#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP -0x7C80 /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public. */
#define POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS -0x7D00 /**< Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret. */
#define POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY -0x7D80 /**< Processing of the CertificateVerify handshake message failed. */
#define POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC -0x7E00 /**< Processing of the ChangeCipherSpec handshake message failed. */
#define POLARSSL_ERR_SSL_BAD_HS_FINISHED -0x7E80 /**< Processing of the Finished handshake message failed. */
@ -140,44 +144,6 @@
#define SSL_BUFFER_LEN (SSL_MAX_CONTENT_LEN + SSL_COMPRESSION_ADD + 512)
/*
* Supported ciphersuites (Official IANA names)
*/
#define TLS_RSA_WITH_NULL_MD5 0x01 /**< Weak! */
#define TLS_RSA_WITH_NULL_SHA 0x02 /**< Weak! */
#define TLS_RSA_WITH_NULL_SHA256 0x3B /**< Weak! */
#define TLS_RSA_WITH_DES_CBC_SHA 0x09 /**< Weak! Not in TLS 1.2 */
#define TLS_DHE_RSA_WITH_DES_CBC_SHA 0x15 /**< Weak! Not in TLS 1.2 */
#define TLS_RSA_WITH_RC4_128_MD5 0x04
#define TLS_RSA_WITH_RC4_128_SHA 0x05
#define TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x0A
#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x16
#define TLS_RSA_WITH_AES_128_CBC_SHA 0x2F
#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x33
#define TLS_RSA_WITH_AES_256_CBC_SHA 0x35
#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x39
#define TLS_RSA_WITH_AES_128_CBC_SHA256 0x3C /**< TLS 1.2 */
#define TLS_RSA_WITH_AES_256_CBC_SHA256 0x3D /**< TLS 1.2 */
#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x67 /**< TLS 1.2 */
#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x6B /**< TLS 1.2 */
#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x41
#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x45
#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x84
#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x88
#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBA /**< TLS 1.2 */
#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBE /**< TLS 1.2 */
#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC0 /**< TLS 1.2 */
#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC4 /**< TLS 1.2 */
#define TLS_RSA_WITH_AES_128_GCM_SHA256 0x9C
#define TLS_RSA_WITH_AES_256_GCM_SHA384 0x9D
#define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x9E
#define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x9F
#define SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */
/*
@ -250,12 +216,15 @@
/*
* TLS extensions
*/
#define TLS_EXT_SERVERNAME 0
#define TLS_EXT_SERVERNAME_HOSTNAME 0
#define TLS_EXT_SERVERNAME 0
#define TLS_EXT_SERVERNAME_HOSTNAME 0
#define TLS_EXT_SIG_ALG 13
#define TLS_EXT_SUPPORTED_ELLIPTIC_CURVES 10
#define TLS_EXT_SUPPORTED_POINT_FORMATS 11
#define TLS_EXT_RENEGOTIATION_INFO 0xFF01
#define TLS_EXT_SIG_ALG 13
#define TLS_EXT_RENEGOTIATION_INFO 0xFF01
/*
@ -368,6 +337,13 @@ struct _ssl_handshake_params
#if defined(POLARSSL_DHM_C)
dhm_context dhm_ctx; /*!< DHM key exchange */
#endif
#if defined(POLARSSL_ECDH_C)
ecdh_context ecdh_ctx; /*!< ECDH key exchange */
#endif
#if defined(POLARSSL_ECP_C)
int ec_curve; /*!< Selected elliptic curve */
int ec_point_format; /*!< Client supported format */
#endif
/*
* Checksum contexts
@ -1114,7 +1090,7 @@ int ssl_write_change_cipher_spec( ssl_context *ssl );
int ssl_parse_finished( ssl_context *ssl );
int ssl_write_finished( ssl_context *ssl );
void ssl_optimize_checksum( ssl_context *ssl, int ciphersuite );
void ssl_optimize_checksum( ssl_context *ssl, const ssl_ciphersuite_t *ciphersuite_info );
#ifdef __cplusplus
}

View File

@ -34,15 +34,61 @@
extern "C" {
#endif
/*
* Supported ciphersuites (Official IANA names)
*/
#define TLS_RSA_WITH_NULL_MD5 0x01 /**< Weak! */
#define TLS_RSA_WITH_NULL_SHA 0x02 /**< Weak! */
#define TLS_RSA_WITH_NULL_SHA256 0x3B /**< Weak! */
#define TLS_RSA_WITH_DES_CBC_SHA 0x09 /**< Weak! Not in TLS 1.2 */
#define TLS_DHE_RSA_WITH_DES_CBC_SHA 0x15 /**< Weak! Not in TLS 1.2 */
#define TLS_RSA_WITH_RC4_128_MD5 0x04
#define TLS_RSA_WITH_RC4_128_SHA 0x05
#define TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x0A
#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x16
#define TLS_RSA_WITH_AES_128_CBC_SHA 0x2F
#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x33
#define TLS_RSA_WITH_AES_256_CBC_SHA 0x35
#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x39
#define TLS_RSA_WITH_AES_128_CBC_SHA256 0x3C /**< TLS 1.2 */
#define TLS_RSA_WITH_AES_256_CBC_SHA256 0x3D /**< TLS 1.2 */
#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x67 /**< TLS 1.2 */
#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x6B /**< TLS 1.2 */
#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA 0x41
#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x45
#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x84
#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x88
#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBA /**< TLS 1.2 */
#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBE /**< TLS 1.2 */
#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC0 /**< TLS 1.2 */
#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC4 /**< TLS 1.2 */
#define TLS_RSA_WITH_AES_128_GCM_SHA256 0x9C
#define TLS_RSA_WITH_AES_256_GCM_SHA384 0x9D
#define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x9E
#define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x9F
#define TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010
#define TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011
#define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012
#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013
#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014
typedef enum {
POLARSSL_KEY_EXCHANGE_NONE = 0,
POLARSSL_KEY_EXCHANGE_RSA,
POLARSSL_KEY_EXCHANGE_DHE_RSA
POLARSSL_KEY_EXCHANGE_DHE_RSA,
POLARSSL_KEY_EXCHANGE_ECDHE_RSA,
} key_exchange_type_t;
typedef struct _ssl_ciphersuite_t ssl_ciphersuite_t;
#define POLARSSL_CIPHERSUITE_WEAK 0x01
#define POLARSSL_CIPHERSUITE_WEAK 0x01 /*<! Weak ciphersuite flag */
#define POLARSSL_CIPHERSUITE_EC 0x02 /*<! EC-based ciphersuite flag */
/**
* \brief This structure is used for storing ciphersuite information

View File

@ -128,6 +128,28 @@ void debug_print_buf( const ssl_context *ssl, int level,
ssl->f_dbg( ssl->p_dbg, level, "\n" );
}
#if defined(POLARSSL_ECP_C)
void debug_print_ecp( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, const ecp_point *X )
{
char str[512];
int maxlen = sizeof( str ) - 1;
snprintf( str, maxlen, "%s(X)", text );
str[maxlen] = '\0';
debug_print_mpi( ssl, level, file, line, str, &X->X );
snprintf( str, maxlen, "%s(Y)", text );
str[maxlen] = '\0';
debug_print_mpi( ssl, level, file, line, str, &X->Y );
snprintf( str, maxlen, "%s(Z)", text );
str[maxlen] = '\0';
debug_print_mpi( ssl, level, file, line, str, &X->Z );
}
#endif /* POLARSSL_ECP_C */
void debug_print_mpi( const ssl_context *ssl, int level,
const char *file, int line,
const char *text, const mpi *X )

View File

@ -212,8 +212,11 @@ int ecdh_calc_secret( ecdh_context *ctx, size_t *olen,
!= 0 )
return( ret );
*olen = mpi_size( &ctx->z );
return mpi_write_binary( &ctx->z, buf, blen );
if( mpi_size( &ctx->z ) > blen )
return( POLARSSL_ERR_ECP_BAD_INPUT_DATA );
*olen = ctx->grp.nbits / 8 + ( ( ctx->grp.nbits % 8 ) != 0 );
return mpi_write_binary( &ctx->z, buf, *olen );
}

View File

@ -189,6 +189,8 @@ void error_strerror( int ret, char *buf, size_t buflen )
#if defined(POLARSSL_ECP_C)
if( use_ret == -(POLARSSL_ERR_ECP_BAD_INPUT_DATA) )
snprintf( buf, buflen, "ECP - Bad input parameters to function" );
if( use_ret == -(POLARSSL_ERR_ECP_BUFFER_TOO_SMALL) )
snprintf( buf, buflen, "ECP - The buffer is too small to write to" );
if( use_ret == -(POLARSSL_ERR_ECP_GENERIC) )
snprintf( buf, buflen, "ECP - Generic ECP error" );
#endif /* POLARSSL_ECP_C */
@ -296,10 +298,10 @@ void error_strerror( int ret, char *buf, size_t buflen )
snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) )
snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_DHM_RP) )
snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM Read Public" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_DHM_CS) )
snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM Calculate Secret" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) )
snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) )
snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) )
snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) )

View File

@ -34,107 +34,100 @@
#include <stdlib.h>
const int supported_ciphersuites[] =
/*
* Ordered from most preferred to least preferred in terms of security.
*/
static const int ciphersuite_preference[] =
{
#if defined(POLARSSL_DHM_C)
#if defined(POLARSSL_AES_C)
#if defined(POLARSSL_SHA2_C)
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA4_C)
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
#endif
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
#if defined(POLARSSL_SHA2_C)
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA2_C)
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
#endif
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
#endif /* POLARSSL_AES_C */
#if defined(POLARSSL_CAMELLIA_C)
#if defined(POLARSSL_SHA2_C)
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
#if defined(POLARSSL_SHA2_C)
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
#endif /* POLARSSL_CAMELLIA_C */
#if defined(POLARSSL_DES_C)
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
#endif
#endif /* POLARSSL_DHM_C */
#if defined(POLARSSL_AES_C)
#if defined(POLARSSL_SHA2_C)
TLS_ECDHE_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_AES_256_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA4_C)
TLS_RSA_WITH_AES_256_GCM_SHA384,
#endif
TLS_RSA_WITH_AES_256_CBC_SHA,
#endif /* POLARSSL_AES_C */
#if defined(POLARSSL_CAMELLIA_C)
#if defined(POLARSSL_SHA2_C)
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
#endif /* POLARSSL_CAMELLIA_C */
#if defined(POLARSSL_AES_C)
#if defined(POLARSSL_SHA2_C)
TLS_RSA_WITH_AES_128_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA2_C)
TLS_RSA_WITH_AES_128_GCM_SHA256,
#endif /* POLARSSL_SHA2_C */
TLS_RSA_WITH_AES_128_CBC_SHA,
#endif /* POLARSSL_AES_C */
#if defined(POLARSSL_CAMELLIA_C)
#if defined(POLARSSL_SHA2_C)
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
#endif /* POLARSSL_CAMELLIA_C */
#if defined(POLARSSL_DES_C)
TLS_RSA_WITH_3DES_EDE_CBC_SHA,
#endif /* POLARSSL_DES_C */
#if defined(POLARSSL_ARC4_C)
TLS_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_RC4_128_MD5,
#endif /* POLARSSL_ARC4_C */
#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
#if defined(POLARSSL_DES_C)
#if defined(POLARSSL_DHM_C)
TLS_DHE_RSA_WITH_DES_CBC_SHA,
#endif /* POLARSSL_DHM_C */
TLS_RSA_WITH_DES_CBC_SHA,
#endif /* POLARSSL_DES_C */
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
#if defined(POLARSSL_SHA2_C)
TLS_ECDHE_RSA_WITH_NULL_SHA,
TLS_RSA_WITH_NULL_SHA256,
#endif
TLS_RSA_WITH_NULL_SHA,
TLS_RSA_WITH_NULL_MD5,
#endif /* POLARSSL_CIPHER_NULL_CIPHER */
#endif /* POLARSSL_ENABLE_WEAK_CIPHERSUITES */
0
};
#define MAX_CIPHERSUITES 60
static int supported_ciphersuites[MAX_CIPHERSUITES];
static int supported_init = 0;
static const ssl_ciphersuite_t ciphersuite_definitions[] =
{
#if defined(POLARSSL_ECDH_C)
#if defined(POLARSSL_AES_C)
{ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA",
POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_RSA,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
POLARSSL_CIPHERSUITE_EC },
{ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA",
POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_RSA,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
POLARSSL_CIPHERSUITE_EC },
#endif
#if defined(POLARSSL_DES_C)
{ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA",
POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_RSA,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
POLARSSL_CIPHERSUITE_EC },
#endif /* POLARSSL_DES_C */
#if defined(POLARSSL_ARC4_C)
{ TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS-ECDHE-RSA-WITH-RC4-128-SHA",
POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_RSA,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
POLARSSL_CIPHERSUITE_EC },
#endif
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
{ TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS-ECDHE-RSA-WITH-NULL-SHA",
POLARSSL_CIPHER_NULL, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_ECDHE_RSA,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_1,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
POLARSSL_CIPHERSUITE_EC | POLARSSL_CIPHERSUITE_WEAK },
#endif
#endif
#if defined(POLARSSL_ARC4_C)
{ TLS_RSA_WITH_RC4_128_MD5, "TLS-RSA-WITH-RC4-128-MD5",
POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_MD5, POLARSSL_KEY_EXCHANGE_RSA,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
{ TLS_RSA_WITH_RC4_128_SHA, "TLS-RSA-WITH-RC4-128-SHA",
POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
#endif /* POLARSSL_ARC4_C */
@ -345,6 +338,27 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
const int *ssl_list_ciphersuites( void )
{
/*
* On initial call filter out all ciphersuites not supported by current
* build based on presence in the ciphersuite_definitions.
*/
if( supported_init == 0 )
{
const int *p = ciphersuite_preference;
int *q = supported_ciphersuites;
memset( supported_ciphersuites, 0x00, sizeof(supported_ciphersuites) );
while( *p != 0 )
{
if( ssl_ciphersuite_from_id( *p ) != NULL )
*(q++) = *p;
p++;
}
supported_init = 1;
}
return supported_ciphersuites;
};

View File

@ -47,6 +47,10 @@ static int ssl_write_client_hello( ssl_context *ssl )
time_t t;
unsigned char sig_alg_list[20];
size_t sig_alg_len = 0;
#if defined(POLARSSL_ECDH_C)
unsigned char elliptic_curve_list[20];
size_t elliptic_curve_len = 0;
#endif
SSL_DEBUG_MSG( 2, ( "=> write client hello" ) );
@ -203,6 +207,26 @@ static int ssl_write_client_hello( ssl_context *ssl )
ext_len += 6 + sig_alg_len;
}
#if defined(POLARSSL_ECDH_C)
SSL_DEBUG_MSG( 3, ( "client hello, prepping for supported elliptic curves extension" ) );
elliptic_curve_list[elliptic_curve_len++] = 0x00;
elliptic_curve_list[elliptic_curve_len++] = POLARSSL_ECP_DP_SECP521R1;
elliptic_curve_list[elliptic_curve_len++] = 0x00;
elliptic_curve_list[elliptic_curve_len++] = POLARSSL_ECP_DP_SECP384R1;
elliptic_curve_list[elliptic_curve_len++] = 0x00;
elliptic_curve_list[elliptic_curve_len++] = POLARSSL_ECP_DP_SECP256R1;
elliptic_curve_list[elliptic_curve_len++] = 0x00;
elliptic_curve_list[elliptic_curve_len++] = POLARSSL_ECP_DP_SECP224R1;
elliptic_curve_list[elliptic_curve_len++] = 0x00;
elliptic_curve_list[elliptic_curve_len++] = POLARSSL_ECP_DP_SECP192R1;
ext_len += 6 + elliptic_curve_len;
SSL_DEBUG_MSG( 3, ( "client hello, prepping for supported point formats extension" ) );
ext_len += 7;
#endif
SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d",
ext_len ) );
@ -302,6 +326,35 @@ static int ssl_write_client_hello( ssl_context *ssl )
p += sig_alg_len;
}
#if defined(POLARSSL_ECDH_C)
SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) );
*p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF );
*p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF );
*p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF );
memcpy( p, elliptic_curve_list, elliptic_curve_len );
p+= elliptic_curve_len;
SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) );
*p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF );
*p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF );
*p++ = 0x00;
*p++ = 3;
*p++ = 2;
*p++ = POLARSSL_ECP_PF_COMPRESSED;
*p++ = POLARSSL_ECP_PF_UNCOMPRESSED;
#endif
ssl->out_msglen = p - buf;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_CLIENT_HELLO;
@ -472,8 +525,8 @@ static int ssl_parse_server_hello( ssl_context *ssl )
/*
* Initialize update checksum functions
*/
ssl_optimize_checksum( ssl, i );
ssl->transform_negotiate->ciphersuite_info = ssl_ciphersuite_from_id( i );
ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
if( ssl->transform_negotiate->ciphersuite_info == NULL )
{
@ -629,9 +682,17 @@ static int ssl_parse_server_hello( ssl_context *ssl )
return( 0 );
}
#if !defined(POLARSSL_DHM_C) && !defined(POLARSSL_ECDH_C)
static int ssl_parse_server_key_exchange( ssl_context *ssl )
{
SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
ssl->state++;
return( 0 );
}
#else
static int ssl_parse_server_key_exchange( ssl_context *ssl )
{
#if defined(POLARSSL_DHM_C)
int ret;
size_t n;
unsigned char *p, *end;
@ -640,22 +701,19 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
sha1_context sha1;
int hash_id = SIG_RSA_RAW;
unsigned int hashlen = 0;
#endif
const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
POLARSSL_KEY_EXCHANGE_DHE_RSA )
if( ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_DHE_RSA &&
ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
{
SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
ssl->state++;
return( 0 );
}
#if !defined(POLARSSL_DHM_C)
SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
#else
if( ( ret = ssl_read_record( ssl ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ssl_read_record", ret );
@ -676,24 +734,55 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
SSL_DEBUG_BUF( 3, "server key exchange", ssl->in_msg + 4, ssl->in_hslen - 4 );
/*
* Ephemeral DH parameters:
*
* struct {
* opaque dh_p<1..2^16-1>;
* opaque dh_g<1..2^16-1>;
* opaque dh_Ys<1..2^16-1>;
* } ServerDHParams;
*/
p = ssl->in_msg + 4;
end = ssl->in_msg + ssl->in_hslen;
if( ( ret = dhm_read_params( &ssl->handshake->dhm_ctx, &p, end ) ) != 0 )
#if defined(POLARSSL_DHM_C)
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA )
{
SSL_DEBUG_MSG( 2, ( "DHM Read Params returned -0x%x", -ret ) );
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
/*
* Ephemeral DH parameters:
*
* struct {
* opaque dh_p<1..2^16-1>;
* opaque dh_g<1..2^16-1>;
* opaque dh_Ys<1..2^16-1>;
* } ServerDHParams;
*/
p = ssl->in_msg + 4;
end = ssl->in_msg + ssl->in_hslen;
if( ( ret = dhm_read_params( &ssl->handshake->dhm_ctx, &p, end ) ) != 0 )
{
SSL_DEBUG_MSG( 2, ( "DHM Read Params returned -0x%x", -ret ) );
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
}
#endif /* POLARSSL_DHM_C */
#if defined(POLARSSL_ECDH_C)
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
{
/*
* Ephemeral ECDH parameters:
*
* struct {
* ECParameters curve_params;
* ECPoint public;
* } ServerECDHParams;
*/
ecdh_init( &ssl->handshake->ecdh_ctx );
p = ssl->in_msg + 4;
end = ssl->in_msg + ssl->in_hslen;
if( ( ret = ecdh_read_params( &ssl->handshake->ecdh_ctx,
(const unsigned char **) &p, end ) ) != 0 )
{
SSL_DEBUG_MSG( 2, ( "ECDH Read Params returned -0x%x", -ret ) );
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
}
#endif /* POLARSSL_ECDH_C */
if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
{
@ -759,15 +848,35 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
if( ssl->handshake->dhm_ctx.len < 64 || ssl->handshake->dhm_ctx.len > 512 )
#if defined(POLARSSL_DHM_C)
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA )
{
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
if( ssl->handshake->dhm_ctx.len < 64 ||
ssl->handshake->dhm_ctx.len > 512 )
{
SSL_DEBUG_MSG( 1, ( "bad server key exchange message (DHM length)" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
}
#endif
#if defined(POLARSSL_ECDH_C)
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
{
if( ssl->handshake->ecdh_ctx.grp.nbits < 163 ||
ssl->handshake->ecdh_ctx.grp.nbits > 521 )
{
SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDH length)" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp );
}
#endif
if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
{
@ -885,8 +994,8 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
return( 0 );
#endif
}
#endif /* POLARSSL_DHM_C || POLARSSL_ECDH_C */
static int ssl_parse_certificate_request( ssl_context *ssl )
{
@ -1039,16 +1148,15 @@ static int ssl_write_client_key_exchange( ssl_context *ssl )
{
int ret;
size_t i, n;
#if defined(POLARSSL_DHM_C) || defined(POLARSSL_ECDH_C)
const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
#endif
SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) );
if( ssl->transform_negotiate->ciphersuite_info->key_exchange ==
POLARSSL_KEY_EXCHANGE_DHE_RSA )
#if defined(POLARSSL_DHM_C)
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA )
{
#if !defined(POLARSSL_DHM_C)
SSL_DEBUG_MSG( 1, ( "support for dhm in not available" ) );
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
#else
/*
* DHM key exchange -- send G^X mod P
*/
@ -1082,9 +1190,42 @@ static int ssl_write_client_key_exchange( ssl_context *ssl )
}
SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
#endif
}
else
#endif /* POLARSSL_DHM_C */
#if defined(POLARSSL_ECDH_C)
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
{
/*
* ECDH key exchange -- send client public value
*/
i = 4;
ret = ecdh_make_public( &ssl->handshake->ecdh_ctx,
&n,
&ssl->out_msg[i], 1000,
ssl->f_rng, ssl->p_rng );
if( ret != 0 )
{
SSL_DEBUG_RET( 1, "ecdh_make_public", ret );
return( ret );
}
SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q );
if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
&ssl->handshake->pmslen,
ssl->handshake->premaster,
POLARSSL_MPI_MAX_SIZE ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret );
return( ret );
}
SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z );
}
else
#endif /* POLARSSL_ECDH_C */
{
/*
* RSA key exchange -- send rsa_public(pkcs1 v1.5(premaster))
@ -1206,8 +1347,8 @@ static int ssl_write_certificate_verify( ssl_context *ssl )
* Reason: Otherwise we should have running hashes for SHA512 and SHA224
* in order to satisfy 'weird' needs from the server side.
*/
if( ssl->session_negotiate->ciphersuite == TLS_RSA_WITH_AES_256_GCM_SHA384 ||
ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 )
if( ssl->transform_negotiate->ciphersuite_info->cipher ==
POLARSSL_CIPHER_AES_256_GCM )
{
hash_id = SIG_RSA_SHA384;
hashlen = 48;

View File

@ -29,6 +29,9 @@
#include "polarssl/debug.h"
#include "polarssl/ssl.h"
#if defined(POLARSSL_ECP_C)
#include "polarssl/ecp.h"
#endif
#include <stdlib.h>
#include <stdio.h>
@ -191,6 +194,75 @@ static int ssl_parse_signature_algorithms_ext( ssl_context *ssl,
return( 0 );
}
#if defined(POLARSSL_ECP_C)
int ssl_parse_supported_elliptic_curves( ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
size_t list_size;
const unsigned char *p;
list_size = ( ( buf[0] << 8 ) | ( buf[1] ) );
if( list_size + 2 != len ||
list_size % 2 != 0 )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
p = buf + 2;
while( list_size > 0 )
{
if( p[0] == 0x00 && (
p[1] == POLARSSL_ECP_DP_SECP192R1 ||
p[1] == POLARSSL_ECP_DP_SECP224R1 ||
p[1] == POLARSSL_ECP_DP_SECP256R1 ||
p[1] == POLARSSL_ECP_DP_SECP384R1 ||
p[1] == POLARSSL_ECP_DP_SECP521R1 ) )
{
ssl->handshake->ec_curve = p[1];
return( 0 );
}
list_size -= 2;
p += 2;
}
return( 0 );
}
int ssl_parse_supported_point_formats( ssl_context *ssl,
const unsigned char *buf,
size_t len )
{
size_t list_size;
const unsigned char *p;
list_size = buf[0];
if( list_size + 1 != len )
{
SSL_DEBUG_MSG( 1, ( "bad client hello message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
p = buf + 2;
while( list_size > 0 )
{
if( p[0] == POLARSSL_ECP_PF_UNCOMPRESSED ||
p[0] == POLARSSL_ECP_PF_COMPRESSED )
{
ssl->handshake->ec_point_format = p[0];
return( 0 );
}
list_size--;
p++;
}
return( 0 );
}
#endif /* POLARSSL_ECP_C */
#if defined(POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO)
static int ssl_parse_client_hello_v2( ssl_context *ssl )
{
@ -363,9 +435,12 @@ static int ssl_parse_client_hello_v2( ssl_context *ssl )
{
for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 )
{
// Only allow non-ECC ciphersuites as we do not have extensions
//
if( p[0] == 0 &&
p[1] == 0 &&
p[2] == ssl->ciphersuites[i] )
( ( ssl->ciphersuites[i] >> 8 ) & 0xFF ) == 0 &&
p[2] == ( ssl->ciphersuites[i] & 0xFF ) )
goto have_ciphersuite_v2;
}
}
@ -376,7 +451,7 @@ static int ssl_parse_client_hello_v2( ssl_context *ssl )
have_ciphersuite_v2:
ssl->session_negotiate->ciphersuite = ssl->ciphersuites[i];
ssl_optimize_checksum( ssl, ssl->session_negotiate->ciphersuite );
ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
/*
* SSLv2 Client Hello relevant renegotiation security checks
@ -412,6 +487,7 @@ static int ssl_parse_client_hello( ssl_context *ssl )
unsigned char *buf, *p, *ext;
int renegotiation_info_seen = 0;
int handshake_failure = 0;
const ssl_ciphersuite_t *ciphersuite_info;
SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) );
@ -639,37 +715,6 @@ static int ssl_parse_client_hello( ssl_context *ssl )
}
}
/*
* Search for a matching ciphersuite
*/
for( i = 0; ssl->ciphersuites[i] != 0; i++ )
{
for( j = 0, p = buf + 41 + sess_len; j < ciph_len;
j += 2, p += 2 )
{
if( p[0] == 0 && p[1] == ssl->ciphersuites[i] )
goto have_ciphersuite;
}
}
SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN );
have_ciphersuite:
ssl->session_negotiate->ciphersuite = ssl->ciphersuites[i];
ssl->transform_negotiate->ciphersuite_info =
ssl_ciphersuite_from_id( ssl->ciphersuites[i] );
if( ssl->transform_negotiate->ciphersuite_info == NULL )
{
SSL_DEBUG_MSG( 1, ( "ciphersuite info for %02x not found",
ssl->ciphersuites[i] ) );
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
}
ssl_optimize_checksum( ssl, ssl->session_negotiate->ciphersuite );
ext = buf + 44 + sess_len + ciph_len + comp_len;
while( ext_len )
@ -715,6 +760,24 @@ have_ciphersuite:
return( ret );
break;
#if defined(POLARSSL_ECP_C)
case TLS_EXT_SUPPORTED_ELLIPTIC_CURVES:
SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) );
ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
case TLS_EXT_SUPPORTED_POINT_FORMATS:
SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) );
ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size );
if( ret != 0 )
return( ret );
break;
#endif /* POLARSSL_ECP_C */
default:
SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)",
ext_id ) );
@ -769,6 +832,48 @@ have_ciphersuite:
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
/*
* Search for a matching ciphersuite
* (At the end because we need information from the EC-based extensions)
*/
for( i = 0; ssl->ciphersuites[i] != 0; i++ )
{
for( j = 0, p = buf + 41 + sess_len; j < ciph_len;
j += 2, p += 2 )
{
if( p[0] == ( ( ssl->ciphersuites[i] >> 8 ) & 0xFF ) &&
p[1] == ( ( ssl->ciphersuites[i] ) & 0xFF ) )
{
ciphersuite_info = ssl_ciphersuite_from_id( ssl->ciphersuites[i] );
if( ciphersuite_info == NULL )
{
SSL_DEBUG_MSG( 1, ( "ciphersuite info for %02x not found",
ssl->ciphersuites[i] ) );
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
}
if( ( ciphersuite_info->flags & POLARSSL_CIPHERSUITE_EC ) &&
ssl->handshake->ec_curve == 0 )
continue;
goto have_ciphersuite;
}
}
}
SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) );
if( ( ret = ssl_send_fatal_handshake_failure( ssl ) ) != 0 )
return( ret );
return( POLARSSL_ERR_SSL_NO_CIPHER_CHOSEN );
have_ciphersuite:
ssl->session_negotiate->ciphersuite = ssl->ciphersuites[i];
ssl->transform_negotiate->ciphersuite_info = ciphersuite_info;
ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info );
ssl->in_left = 0;
ssl->state++;
@ -963,8 +1068,8 @@ static int ssl_write_certificate_request( ssl_context *ssl )
*p++ = 0;
*p++ = 2;
if( ssl->session_negotiate->ciphersuite == TLS_RSA_WITH_AES_256_GCM_SHA384 ||
ssl->session_negotiate->ciphersuite == TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 )
if( ssl->transform_negotiate->ciphersuite_info->cipher ==
POLARSSL_CIPHER_AES_256_GCM )
{
ssl->handshake->verify_sig_alg = SSL_HASH_SHA384;
}
@ -1009,30 +1114,36 @@ static int ssl_write_certificate_request( ssl_context *ssl )
return( ret );
}
#if !defined(POLARSSL_DHM_C) && !defined(POLARSSL_ECDH_C)
static int ssl_write_server_key_exchange( ssl_context *ssl )
{
SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
ssl->state++;
return( 0 );
}
#else
static int ssl_write_server_key_exchange( ssl_context *ssl )
{
#if defined(POLARSSL_DHM_C)
int ret;
size_t n, rsa_key_len = 0;
unsigned char hash[64];
int hash_id = 0;
unsigned int hashlen = 0;
#endif
const ssl_ciphersuite_t *ciphersuite_info;
ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) );
if( ssl->transform_negotiate->ciphersuite_info->key_exchange !=
POLARSSL_KEY_EXCHANGE_DHE_RSA )
if( ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_DHE_RSA &&
ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
{
SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) );
ssl->state++;
return( 0 );
}
#if !defined(POLARSSL_DHM_C)
SSL_DEBUG_MSG( 1, ( "support for dhm is not available" ) );
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
#else
if( ssl->rsa_key == NULL )
{
@ -1040,35 +1151,72 @@ static int ssl_write_server_key_exchange( ssl_context *ssl )
return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
}
/*
* Ephemeral DH parameters:
*
* struct {
* opaque dh_p<1..2^16-1>;
* opaque dh_g<1..2^16-1>;
* opaque dh_Ys<1..2^16-1>;
* } ServerDHParams;
*/
if( ( ret = mpi_copy( &ssl->handshake->dhm_ctx.P, &ssl->dhm_P ) ) != 0 ||
( ret = mpi_copy( &ssl->handshake->dhm_ctx.G, &ssl->dhm_G ) ) != 0 )
#if defined(POLARSSL_DHM_C)
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA )
{
SSL_DEBUG_RET( 1, "mpi_copy", ret );
return( ret );
}
/*
* Ephemeral DH parameters:
*
* struct {
* opaque dh_p<1..2^16-1>;
* opaque dh_g<1..2^16-1>;
* opaque dh_Ys<1..2^16-1>;
* } ServerDHParams;
*/
if( ( ret = mpi_copy( &ssl->handshake->dhm_ctx.P, &ssl->dhm_P ) ) != 0 ||
( ret = mpi_copy( &ssl->handshake->dhm_ctx.G, &ssl->dhm_G ) ) != 0 )
{
SSL_DEBUG_RET( 1, "mpi_copy", ret );
return( ret );
}
if( ( ret = dhm_make_params( &ssl->handshake->dhm_ctx,
mpi_size( &ssl->handshake->dhm_ctx.P ),
ssl->out_msg + 4,
&n, ssl->f_rng, ssl->p_rng ) ) != 0 )
if( ( ret = dhm_make_params( &ssl->handshake->dhm_ctx,
mpi_size( &ssl->handshake->dhm_ctx.P ),
ssl->out_msg + 4,
&n, ssl->f_rng, ssl->p_rng ) ) != 0 )
{
SSL_DEBUG_RET( 1, "dhm_make_params", ret );
return( ret );
}
SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
}
#endif /* POLARSSL_DHM_C */
#if defined(POLARSSL_ECDH_C)
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
{
SSL_DEBUG_RET( 1, "dhm_make_params", ret );
return( ret );
}
/*
* Ephemeral ECDH parameters:
*
* struct {
* ECParameters curve_params;
* ECPoint public;
* } ServerECDHParams;
*/
ecdh_init( &ssl->handshake->ecdh_ctx );
if( ( ret = ecp_use_known_dp( &ssl->handshake->ecdh_ctx.grp,
ssl->handshake->ec_curve ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ecp_use_known_dp", ret );
return( ret );
}
SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X );
SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P );
SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G );
SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX );
if( ( ret = ecdh_make_params( &ssl->handshake->ecdh_ctx,
&n,
ssl->out_msg + 4,
1000, ssl->f_rng, ssl->p_rng ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ecdh_make_params", ret );
return( ret );
}
SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q );
}
#endif /* POLARSSL_ECDH_INIT */
if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
{
@ -1237,8 +1385,8 @@ static int ssl_write_server_key_exchange( ssl_context *ssl )
SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) );
return( 0 );
#endif
}
#endif /* POLARSSL_DHM_C || POLARSSL_ECDH_C */
static int ssl_write_server_hello_done( ssl_context *ssl )
{
@ -1267,6 +1415,10 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl )
{
int ret;
size_t i, n = 0;
#if defined(POLARSSL_DHM_C) || defined(POLARSSL_ECDH_C)
const ssl_ciphersuite_t *ciphersuite_info;
ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
#endif
SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) );
@ -1288,13 +1440,9 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl )
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
if( ssl->transform_negotiate->ciphersuite_info->key_exchange ==
POLARSSL_KEY_EXCHANGE_DHE_RSA )
#if defined(POLARSSL_DHM_C)
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA )
{
#if !defined(POLARSSL_DHM_C)
SSL_DEBUG_MSG( 1, ( "support for dhm is not available" ) );
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
#else
/*
* Receive G^Y mod P, premaster = (G^Y)^X mod P
*/
@ -1311,7 +1459,7 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl )
ssl->in_msg + 6, n ) ) != 0 )
{
SSL_DEBUG_RET( 1, "dhm_read_public", ret );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_DHM_RP );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
}
SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY );
@ -1323,13 +1471,50 @@ static int ssl_parse_client_key_exchange( ssl_context *ssl )
&ssl->handshake->pmslen ) ) != 0 )
{
SSL_DEBUG_RET( 1, "dhm_calc_secret", ret );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_DHM_CS );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
}
SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K );
#endif
}
else
#endif
#if defined(POLARSSL_ECDH_C)
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
{
/*
* Receive client public key and calculate premaster
*/
n = ssl->in_msg[3];
if( n < 1 || n > mpi_size( &ssl->handshake->ecdh_ctx.grp.P ) * 2 + 2 ||
n + 4 != ssl->in_hslen )
{
SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE );
}
if( ( ret = ecdh_read_public( &ssl->handshake->ecdh_ctx,
ssl->in_msg + 4, n ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ecdh_read_public", ret );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP );
}
SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp );
if( ( ret = ecdh_calc_secret( &ssl->handshake->ecdh_ctx,
&ssl->handshake->pmslen,
ssl->handshake->premaster,
POLARSSL_MPI_MAX_SIZE ) ) != 0 )
{
SSL_DEBUG_RET( 1, "ecdh_calc_secret", ret );
return( POLARSSL_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS );
}
SSL_DEBUG_MPI( 3, "ECDH: z ", &ssl->handshake->ecdh_ctx.z );
}
else
#endif
{
if( ssl->rsa_key == NULL )
{

View File

@ -346,8 +346,8 @@ int ssl_derive_keys( ssl_context *ssl )
handshake->calc_finished = ssl_calc_finished_tls;
}
#if defined(POLARSSL_SHA4_C)
else if( session->ciphersuite == TLS_RSA_WITH_AES_256_GCM_SHA384 ||
session->ciphersuite == TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 )
else if( transform->ciphersuite_info->cipher ==
POLARSSL_CIPHER_AES_256_GCM )
{
handshake->tls_prf = tls_prf_sha384;
handshake->calc_verify = ssl_calc_verify_tls_sha384;
@ -2151,7 +2151,8 @@ int ssl_parse_change_cipher_spec( ssl_context *ssl )
return( 0 );
}
void ssl_optimize_checksum( ssl_context *ssl, int ciphersuite )
void ssl_optimize_checksum( ssl_context *ssl,
const ssl_ciphersuite_t *ciphersuite_info )
{
#if !defined(POLARSSL_SHA4_C)
((void) ciphersuite);
@ -2160,8 +2161,7 @@ void ssl_optimize_checksum( ssl_context *ssl, int ciphersuite )
if( ssl->minor_ver < SSL_MINOR_VERSION_3 )
ssl->handshake->update_checksum = ssl_update_checksum_md5sha1;
#if defined(POLARSSL_SHA4_C)
else if ( ciphersuite == TLS_RSA_WITH_AES_256_GCM_SHA384 ||
ciphersuite == TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 )
else if( ciphersuite_info->cipher == POLARSSL_CIPHER_AES_256_GCM )
{
ssl->handshake->update_checksum = ssl_update_checksum_sha384;
}

View File

@ -94,96 +94,6 @@ void my_debug( void *ctx, int level, const char *str )
}
}
/*
* Sorted by order of preference
*/
int my_ciphersuites[] =
{
#if defined(POLARSSL_DHM_C)
#if defined(POLARSSL_AES_C)
#if defined(POLARSSL_SHA2_C)
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA4_C)
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
#endif
TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
#if defined(POLARSSL_SHA2_C)
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
#endif
#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA2_C)
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
#endif
TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
#endif
#if defined(POLARSSL_CAMELLIA_C)
#if defined(POLARSSL_SHA2_C)
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
#if defined(POLARSSL_SHA2_C)
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
#endif
#if defined(POLARSSL_DES_C)
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
#endif
#endif
#if defined(POLARSSL_AES_C)
#if defined(POLARSSL_SHA2_C)
TLS_RSA_WITH_AES_256_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA4_C)
TLS_RSA_WITH_AES_256_GCM_SHA384,
#endif /* POLARSSL_SHA2_C */
TLS_RSA_WITH_AES_256_CBC_SHA,
#endif
#if defined(POLARSSL_CAMELLIA_C)
#if defined(POLARSSL_SHA2_C)
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,
#endif
#if defined(POLARSSL_AES_C)
#if defined(POLARSSL_SHA2_C)
TLS_RSA_WITH_AES_128_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
#if defined(POLARSSL_GCM_C) && defined(POLARSSL_SHA2_C)
TLS_RSA_WITH_AES_128_GCM_SHA256,
#endif /* POLARSSL_SHA2_C */
TLS_RSA_WITH_AES_128_CBC_SHA,
#endif
#if defined(POLARSSL_CAMELLIA_C)
#if defined(POLARSSL_SHA2_C)
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256,
#endif /* POLARSSL_SHA2_C */
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA,
#endif
#if defined(POLARSSL_DES_C)
TLS_RSA_WITH_3DES_EDE_CBC_SHA,
#endif
#if defined(POLARSSL_ARC4_C)
TLS_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_RC4_128_MD5,
#endif
#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
#if defined(POLARSSL_DES_C)
TLS_DHE_RSA_WITH_DES_CBC_SHA,
TLS_RSA_WITH_DES_CBC_SHA,
#endif
#if defined(POLARSSL_CIPHER_NULL_CIPHER)
TLS_RSA_WITH_NULL_MD5,
TLS_RSA_WITH_NULL_SHA,
TLS_RSA_WITH_NULL_SHA256,
#endif
#endif
0
};
#if defined(POLARSSL_FS_IO)
#define USAGE_IO \
" ca_file=%%s The single file containing the top-level CA(s) you fully trust\n" \
@ -503,9 +413,7 @@ int main( int argc, char *argv[] )
ssl_cache_set, &cache );
#endif
if( opt.force_ciphersuite[0] == DFL_FORCE_CIPHER )
ssl_set_ciphersuites( &ssl, my_ciphersuites );
else
if( opt.force_ciphersuite[0] != DFL_FORCE_CIPHER )
ssl_set_ciphersuites( &ssl, opt.force_ciphersuite );
ssl_set_renegotiation( &ssl, opt.renegotiation );

View File

@ -36,6 +36,12 @@ P_CIPHERS=" \
TLS-RSA-WITH-NULL-SHA \
TLS-RSA-WITH-DES-CBC-SHA \
TLS-DHE-RSA-WITH-DES-CBC-SHA \
TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA \
TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA \
TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA \
TLS-ECDHE-RSA-WITH-RC4-128-SHA \
TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA \
TLS-ECDHE-RSA-WITH-NULL-SHA \
"
O_CIPHERS=" \
@ -55,6 +61,11 @@ O_CIPHERS=" \
NULL-SHA \
DES-CBC-SHA \
EDH-RSA-DES-CBC-SHA \
ECDHE-RSA-AES256-SHA \
ECDHE-RSA-AES128-SHA \
ECDHE-RSA-DES-CBC3-SHA \
ECDHE-RSA-RC4-SHA \
ECDHE-RSA-NULL-SHA \
"
# Also add SHA256 ciphersuites