Added pre-shared key handling for the client side of SSL / TLS

Client side handling of the pure PSK ciphersuites is now in the base
code.
This commit is contained in:
Paul Bakker 2013-04-16 18:05:29 +02:00
parent f7abd422dc
commit d4a56ec6bf
7 changed files with 381 additions and 26 deletions

View File

@ -161,6 +161,21 @@
#define POLARSSL_ENABLE_WEAK_CIPHERSUITES #define POLARSSL_ENABLE_WEAK_CIPHERSUITES
*/ */
/**
* \def POLARSSL_KEY_EXCHANGE_PSK_ENABLED
*
* Enable the PSK based ciphersuite modes in SSL / TLS
* In combination with POLARSSL_RSA_C it also enables RSA_PSK ciphersuites
* and in combination with POLARSSL_DHM_C it enables the DHE_PSK ciphersuites
*
* This enables the following ciphersuites:
* TLS_PSK_WITH_RC4_128_SHA
* TLS_PSK_WITH_3DES_EDE_CBC_SHA
* TLS_PSK_WITH_AES_128_CBC_SHA
* TLS_PSK_WITH_AES_256_CBC_SHA
*/
#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED
/** /**
* \def POLARSSL_ERROR_STRERROR_DUMMY * \def POLARSSL_ERROR_STRERROR_DUMMY
* *
@ -348,6 +363,8 @@
* TLS_RSA_WITH_AES_256_GCM_SHA384 * TLS_RSA_WITH_AES_256_GCM_SHA384
* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
* TLS_PSK_WITH_AES_128_CBC_SHA
* TLS_PSK_WITH_AES_256_CBC_SHA
* *
* PEM uses AES for decrypting encrypted keys. * PEM uses AES for decrypting encrypted keys.
*/ */
@ -366,6 +383,7 @@
* TLS_RSA_WITH_RC4_128_MD5 * TLS_RSA_WITH_RC4_128_MD5
* TLS_RSA_WITH_RC4_128_SHA * TLS_RSA_WITH_RC4_128_SHA
* TLS_ECDHE_RSA_WITH_RC4_128_SHA * TLS_ECDHE_RSA_WITH_RC4_128_SHA
* TLS_PSK_WITH_RC4_128_SHA
*/ */
#define POLARSSL_ARC4_C #define POLARSSL_ARC4_C
@ -511,6 +529,7 @@
* TLS_RSA_WITH_3DES_EDE_CBC_SHA * TLS_RSA_WITH_3DES_EDE_CBC_SHA
* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
* TLS_PSK_WITH_3DES_EDE_CBC_SHA
* *
* PEM uses DES/3DES for decrypting encrypted keys. * PEM uses DES/3DES for decrypting encrypted keys.
*/ */

View File

@ -201,6 +201,7 @@
#define SSL_ALERT_MSG_NO_RENEGOTIATION 100 /* 0x64 */ #define SSL_ALERT_MSG_NO_RENEGOTIATION 100 /* 0x64 */
#define SSL_ALERT_MSG_UNSUPPORTED_EXT 110 /* 0x6E */ #define SSL_ALERT_MSG_UNSUPPORTED_EXT 110 /* 0x6E */
#define SSL_ALERT_MSG_UNRECOGNIZED_NAME 112 /* 0x70 */ #define SSL_ALERT_MSG_UNRECOGNIZED_NAME 112 /* 0x70 */
#define SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY 115 /* 0x73 */
#define SSL_HS_HELLO_REQUEST 0 #define SSL_HS_HELLO_REQUEST 0
#define SSL_HS_CLIENT_HELLO 1 #define SSL_HS_CLIENT_HELLO 1
@ -226,7 +227,6 @@
#define TLS_EXT_RENEGOTIATION_INFO 0xFF01 #define TLS_EXT_RENEGOTIATION_INFO 0xFF01
/* /*
* Generic function pointers for allowing external RSA private key * Generic function pointers for allowing external RSA private key
* implementations. * implementations.
@ -441,6 +441,7 @@ struct _ssl_context
size_t in_hslen; /*!< current handshake message length */ size_t in_hslen; /*!< current handshake message length */
int nb_zero; /*!< # of 0-length encrypted messages */ int nb_zero; /*!< # of 0-length encrypted messages */
int record_read; /*!< record is already present */
/* /*
* Record layer (outgoing data) * Record layer (outgoing data)
@ -483,6 +484,16 @@ struct _ssl_context
mpi dhm_G; /*!< generator for DHM */ mpi dhm_G; /*!< generator for DHM */
#endif #endif
#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
/*
* PSK values
*/
const unsigned char *psk;
size_t psk_len;
const unsigned char *psk_identity;
size_t psk_identity_len;
#endif
/* /*
* TLS extensions * TLS extensions
*/ */
@ -780,6 +791,21 @@ void ssl_set_own_cert_alt( ssl_context *ssl, x509_cert *own_cert,
rsa_sign_func rsa_sign, rsa_sign_func rsa_sign,
rsa_key_len_func rsa_key_len ); rsa_key_len_func rsa_key_len );
#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
/**
* \brief Set the Pre Shared Key (PSK) and the identity name connected
* to it. The PSK is used in all PSK-based ciphersuites.
*
* \param ssl SSL context
* \param psk pointer to the pre-shared key
* \param psk_len pre-shared key length
* \param psk_identity pointer to the pre-shared key identity
* \param psk_identity_len identity key length
*/
void ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len,
const unsigned char *psk_identity, size_t psk_identity_len );
#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */
#if defined(POLARSSL_DHM_C) #if defined(POLARSSL_DHM_C)
/** /**
* \brief Set the Diffie-Hellman public P and G values, * \brief Set the Diffie-Hellman public P and G values,

View File

@ -53,6 +53,7 @@ extern "C" {
#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x33 #define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x33
#define TLS_RSA_WITH_AES_256_CBC_SHA 0x35 #define TLS_RSA_WITH_AES_256_CBC_SHA 0x35
#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x39 #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_128_CBC_SHA256 0x3C /**< TLS 1.2 */
#define TLS_RSA_WITH_AES_256_CBC_SHA256 0x3D /**< 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_128_CBC_SHA256 0x67 /**< TLS 1.2 */
@ -62,6 +63,22 @@ extern "C" {
#define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x45 #define TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x45
#define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x84 #define TLS_RSA_WITH_CAMELLIA_256_CBC_SHA 0x84
#define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x88 #define TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x88
#define TLS_PSK_WITH_RC4_128_SHA 0x8A
#define TLS_PSK_WITH_3DES_EDE_CBC_SHA 0x8B
#define TLS_PSK_WITH_AES_128_CBC_SHA 0x8C
#define TLS_PSK_WITH_AES_256_CBC_SHA 0x8D
#define TLS_DHE_PSK_WITH_RC4_128_SHA 0x8E
#define TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA 0x8F
#define TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x90
#define TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x91
#define TLS_RSA_PSK_WITH_RC4_128_SHA 0x92
#define TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA 0x93
#define TLS_RSA_PSK_WITH_AES_128_CBC_SHA 0x94
#define TLS_RSA_PSK_WITH_AES_256_CBC_SHA 0x95
#define TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 0xBA /**< TLS 1.2 */ #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_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_RSA_WITH_CAMELLIA_256_CBC_SHA256 0xC0 /**< TLS 1.2 */
@ -91,6 +108,9 @@ typedef enum {
POLARSSL_KEY_EXCHANGE_RSA, POLARSSL_KEY_EXCHANGE_RSA,
POLARSSL_KEY_EXCHANGE_DHE_RSA, POLARSSL_KEY_EXCHANGE_DHE_RSA,
POLARSSL_KEY_EXCHANGE_ECDHE_RSA, POLARSSL_KEY_EXCHANGE_ECDHE_RSA,
POLARSSL_KEY_EXCHANGE_PSK,
POLARSSL_KEY_EXCHANGE_DHE_PSK,
POLARSSL_KEY_EXCHANGE_RSA_PSK,
} key_exchange_type_t; } key_exchange_type_t;
typedef struct _ssl_ciphersuite_t ssl_ciphersuite_t; typedef struct _ssl_ciphersuite_t ssl_ciphersuite_t;

View File

@ -70,6 +70,12 @@ static const int ciphersuite_preference[] =
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
/* The PSK ephemeral suites */
TLS_DHE_PSK_WITH_AES_256_CBC_SHA,
TLS_DHE_PSK_WITH_AES_128_CBC_SHA,
TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA,
TLS_DHE_PSK_WITH_RC4_128_SHA,
/* All AES-256 suites */ /* All AES-256 suites */
TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384,
@ -93,6 +99,18 @@ static const int ciphersuite_preference[] =
TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_RC4_128_SHA,
TLS_RSA_WITH_RC4_128_MD5, TLS_RSA_WITH_RC4_128_MD5,
/* The RSA PSK suites */
TLS_RSA_PSK_WITH_AES_256_CBC_SHA,
TLS_RSA_PSK_WITH_AES_128_CBC_SHA,
TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA,
TLS_RSA_PSK_WITH_RC4_128_SHA,
/* The PSK suites */
TLS_PSK_WITH_AES_256_CBC_SHA,
TLS_PSK_WITH_AES_128_CBC_SHA,
TLS_PSK_WITH_3DES_EDE_CBC_SHA,
TLS_PSK_WITH_RC4_128_SHA,
/* Weak or NULL suites */ /* Weak or NULL suites */
TLS_DHE_RSA_WITH_DES_CBC_SHA, TLS_DHE_RSA_WITH_DES_CBC_SHA,
TLS_RSA_WITH_DES_CBC_SHA, TLS_RSA_WITH_DES_CBC_SHA,
@ -370,6 +388,100 @@ static const ssl_ciphersuite_t ciphersuite_definitions[] =
0 }, 0 },
#endif /* POLARSSL_DES_C */ #endif /* POLARSSL_DES_C */
#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
#if defined(POLARSSL_AES_C)
{ TLS_PSK_WITH_AES_128_CBC_SHA, "TLS-PSK-WITH-AES-128-CBC-SHA",
POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_PSK,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
{ TLS_PSK_WITH_AES_256_CBC_SHA, "TLS-PSK-WITH-AES-256-CBC-SHA",
POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_PSK,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
#endif /* POLARSSL_AES_C */
#if defined(POLARSSL_DES_C)
{ TLS_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-PSK-WITH-3DES-EDE-CBC-SHA",
POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_PSK,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
#endif /* POLARSSL_DES_C */
#if defined(POLARSSL_ARC4_C)
{ TLS_PSK_WITH_RC4_128_SHA, "TLS-PSK-WITH-RC4-128-SHA",
POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_PSK,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
#endif /* POLARSSL_ARC4_C */
#if defined(POLARSSL_DHM_C)
#if defined(POLARSSL_AES_C)
{ TLS_DHE_PSK_WITH_AES_128_CBC_SHA, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA",
POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_PSK,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
{ TLS_DHE_PSK_WITH_AES_256_CBC_SHA, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA",
POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_PSK,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
#endif /* POLARSSL_AES_C */
#if defined(POLARSSL_DES_C)
{ TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA",
POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_PSK,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
#endif /* POLARSSL_DES_C */
#if defined(POLARSSL_ARC4_C)
{ TLS_DHE_PSK_WITH_RC4_128_SHA, "TLS-DHE-PSK-WITH-RC4-128-SHA",
POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_DHE_PSK,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
#endif /* POLARSSL_ARC4_C */
#endif /* POLARSSL_DHM_C */
#if defined(POLARSSL_AES_C)
{ TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA",
POLARSSL_CIPHER_AES_128_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
{ TLS_RSA_PSK_WITH_AES_256_CBC_SHA, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA",
POLARSSL_CIPHER_AES_256_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
#endif /* POLARSSL_AES_C */
#if defined(POLARSSL_DES_C)
{ TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA",
POLARSSL_CIPHER_DES_EDE3_CBC, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
#endif /* POLARSSL_DES_C */
#if defined(POLARSSL_ARC4_C)
{ TLS_RSA_PSK_WITH_RC4_128_SHA, "TLS-RSA-PSK-WITH-RC4-128-SHA",
POLARSSL_CIPHER_ARC4_128, POLARSSL_MD_SHA1, POLARSSL_KEY_EXCHANGE_RSA_PSK,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_0,
SSL_MAJOR_VERSION_3, SSL_MINOR_VERSION_3,
0 },
#endif /* POLARSSL_ARC4_C */
#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */
#if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES) #if defined(POLARSSL_ENABLE_WEAK_CIPHERSUITES)
#if defined(POLARSSL_CIPHER_NULL_CIPHER) #if defined(POLARSSL_CIPHER_NULL_CIPHER)
{ TLS_RSA_WITH_NULL_MD5, "TLS-RSA-WITH-NULL-MD5", { TLS_RSA_WITH_NULL_MD5, "TLS-RSA-WITH-NULL-MD5",

View File

@ -727,7 +727,8 @@ static int ssl_parse_server_hello( ssl_context *ssl )
return( 0 ); return( 0 );
} }
#if !defined(POLARSSL_DHM_C) && !defined(POLARSSL_ECDH_C) #if !defined(POLARSSL_DHM_C) && !defined(POLARSSL_ECDH_C) && \
!defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
static int ssl_parse_server_key_exchange( ssl_context *ssl ) static int ssl_parse_server_key_exchange( ssl_context *ssl )
{ {
SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
@ -809,6 +810,36 @@ static int ssl_parse_server_ecdh_params( ssl_context *ssl,
return( ret ); return( ret );
} }
static int ssl_parse_server_psk_hint( ssl_context *ssl,
unsigned char **p,
unsigned char *end )
{
int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
size_t len;
/*
* PSK parameters:
*
* opaque psk_identity_hint<0..2^16-1>;
*/
len = (*p)[1] << 8 | (*p)[0];
if( (*p) + len > end )
{
SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
// TODO: Retrieve PSK identity hint and callback to app
//
*p += len;
#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */
return( ret );
}
static int ssl_parse_signature_algorithm( ssl_context *ssl, static int ssl_parse_signature_algorithm( ssl_context *ssl,
unsigned char **p, unsigned char **p,
unsigned char *end, unsigned char *end,
@ -822,7 +853,6 @@ static int ssl_parse_signature_algorithm( ssl_context *ssl,
if( (*p)[1] != SSL_SIG_RSA ) if( (*p)[1] != SSL_SIG_RSA )
{ {
SSL_DEBUG_MSG( 2, ( "server used unsupported SignatureAlgorithm %d", (*p)[1] ) ); SSL_DEBUG_MSG( 2, ( "server used unsupported SignatureAlgorithm %d", (*p)[1] ) );
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
@ -880,7 +910,8 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) );
if( 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 ) ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_ECDHE_RSA &&
ciphersuite_info->key_exchange != POLARSSL_KEY_EXCHANGE_PSK )
{ {
SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) );
ssl->state++; ssl->state++;
@ -901,8 +932,8 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
if( ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE ) if( ssl->in_msg[0] != SSL_HS_SERVER_KEY_EXCHANGE )
{ {
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); ssl->record_read = 1;
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); goto exit;
} }
SSL_DEBUG_BUF( 3, "server key exchange", ssl->in_msg + 4, ssl->in_hslen - 4 ); SSL_DEBUG_BUF( 3, "server key exchange", ssl->in_msg + 4, ssl->in_hslen - 4 );
@ -913,15 +944,22 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA ) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_DHE_RSA )
{ {
if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 ) if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 )
{
SSL_DEBUG_MSG( 1, ( "failed to parsebad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
}
}
else if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
{
if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 )
{ {
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
} }
else if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK )
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_ECDHE_RSA )
{ {
if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 ) if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 )
{ {
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
@ -1028,6 +1066,7 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
} }
} }
exit:
ssl->state++; ssl->state++;
SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) ); SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) );
@ -1057,6 +1096,8 @@ static int ssl_parse_certificate_request( ssl_context *ssl )
* n+4 .. ... Distinguished Name #1 * n+4 .. ... Distinguished Name #1
* ... .. ... length of DN 2, etc. * ... .. ... length of DN 2, etc.
*/ */
if( ssl->record_read == 0 )
{
if( ( ret = ssl_read_record( ssl ) ) != 0 ) if( ( ret = ssl_read_record( ssl ) ) != 0 )
{ {
SSL_DEBUG_RET( 1, "ssl_read_record", ret ); SSL_DEBUG_RET( 1, "ssl_read_record", ret );
@ -1069,6 +1110,9 @@ static int ssl_parse_certificate_request( ssl_context *ssl )
return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
} }
ssl->record_read = 1;
}
ssl->client_auth = 0; ssl->client_auth = 0;
ssl->state++; ssl->state++;
@ -1081,6 +1125,8 @@ static int ssl_parse_certificate_request( ssl_context *ssl )
if( ssl->client_auth == 0 ) if( ssl->client_auth == 0 )
goto exit; goto exit;
ssl->record_read = 0;
// TODO: handshake_failure alert for an anonymous server to request // TODO: handshake_failure alert for an anonymous server to request
// client authentication // client authentication
@ -1154,7 +1200,7 @@ static int ssl_parse_server_hello_done( ssl_context *ssl )
SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) ); SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) );
if( ssl->client_auth != 0 ) if( ssl->record_read == 0 )
{ {
if( ( ret = ssl_read_record( ssl ) ) != 0 ) if( ( ret = ssl_read_record( ssl ) ) != 0 )
{ {
@ -1168,6 +1214,7 @@ static int ssl_parse_server_hello_done( ssl_context *ssl )
return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE ); return( POLARSSL_ERR_SSL_UNEXPECTED_MESSAGE );
} }
} }
ssl->record_read = 0;
if( ssl->in_hslen != 4 || if( ssl->in_hslen != 4 ||
ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE ) ssl->in_msg[0] != SSL_HS_SERVER_HELLO_DONE )
@ -1265,6 +1312,43 @@ static int ssl_write_client_key_exchange( ssl_context *ssl )
} }
else else
#endif /* POLARSSL_ECDH_C */ #endif /* POLARSSL_ECDH_C */
#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK )
{
unsigned char *p = ssl->handshake->premaster;
/*
* PSK key exchange
*
* opaque psk_identity<0..2^16-1>;
*/
if( ssl->hostname == NULL )
return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
if( sizeof(ssl->handshake->premaster) < 4 + 2 * ssl->psk_len )
return( POLARSSL_ERR_SSL_BAD_INPUT_DATA );
n = ssl->psk_identity_len;
ssl->out_msg[4] = (unsigned char)( n >> 8 );
ssl->out_msg[5] = (unsigned char)( n );
i = 6;
memcpy( ssl->out_msg + i, ssl->psk_identity, ssl->psk_identity_len );
*(p++) = (unsigned char)( ssl->psk_len >> 8 );
*(p++) = (unsigned char)( ssl->psk_len );
p += ssl->psk_len;
*(p++) = (unsigned char)( ssl->psk_len >> 8 );
*(p++) = (unsigned char)( ssl->psk_len );
memcpy( p, ssl->psk, ssl->psk_len );
p += ssl->psk_len;
ssl->handshake->pmslen = 4 + 2 * ssl->psk_len;
}
else
#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */
{ {
/* /*
* RSA key exchange -- send rsa_public(pkcs1 v1.5(premaster)) * RSA key exchange -- send rsa_public(pkcs1 v1.5(premaster))
@ -1331,10 +1415,12 @@ static int ssl_write_certificate_verify( ssl_context *ssl )
unsigned char hash[48]; unsigned char hash[48];
md_type_t md_alg = POLARSSL_MD_NONE; md_type_t md_alg = POLARSSL_MD_NONE;
unsigned int hashlen = 0; unsigned int hashlen = 0;
const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
if( ssl->client_auth == 0 || ssl->own_cert == NULL ) if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK ||
ssl->client_auth == 0 || ssl->own_cert == NULL )
{ {
SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) );
ssl->state++; ssl->state++;

View File

@ -1848,9 +1848,17 @@ int ssl_write_certificate( ssl_context *ssl )
int ret; int ret;
size_t i, n; size_t i, n;
const x509_cert *crt; const x509_cert *crt;
const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); SSL_DEBUG_MSG( 2, ( "=> write certificate" ) );
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK )
{
SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) );
ssl->state++;
return( 0 );
}
if( ssl->endpoint == SSL_IS_CLIENT ) if( ssl->endpoint == SSL_IS_CLIENT )
{ {
if( ssl->client_auth == 0 ) if( ssl->client_auth == 0 )
@ -1944,9 +1952,17 @@ int ssl_parse_certificate( ssl_context *ssl )
{ {
int ret; int ret;
size_t i, n; size_t i, n;
const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) );
if( ciphersuite_info->key_exchange == POLARSSL_KEY_EXCHANGE_PSK )
{
SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) );
ssl->state++;
return( 0 );
}
if( ssl->endpoint == SSL_IS_SERVER && if( ssl->endpoint == SSL_IS_SERVER &&
ssl->authmode == SSL_VERIFY_NONE ) ssl->authmode == SSL_VERIFY_NONE )
{ {
@ -2753,6 +2769,7 @@ int ssl_session_reset( ssl_context *ssl )
ssl->in_hslen = 0; ssl->in_hslen = 0;
ssl->nb_zero = 0; ssl->nb_zero = 0;
ssl->record_read = 0;
ssl->out_msg = ssl->out_ctr + 13; ssl->out_msg = ssl->out_ctr + 13;
ssl->out_msgtype = 0; ssl->out_msgtype = 0;
@ -2908,6 +2925,16 @@ void ssl_set_own_cert_alt( ssl_context *ssl, x509_cert *own_cert,
ssl->rsa_key_len = rsa_key_len; ssl->rsa_key_len = rsa_key_len;
} }
#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
void ssl_set_psk( ssl_context *ssl, const unsigned char *psk, size_t psk_len,
const unsigned char *psk_identity, size_t psk_identity_len )
{
ssl->psk = psk;
ssl->psk_len = psk_len;
ssl->psk_identity = psk_identity;
ssl->psk_identity_len = psk_identity_len;
}
#endif /* POLARSSL_KEY_EXCHANGE_PSK_ENABLED */
#if defined(POLARSSL_DHM_C) #if defined(POLARSSL_DHM_C)
int ssl_set_dh_param( ssl_context *ssl, const char *dhm_P, const char *dhm_G ) int ssl_set_dh_param( ssl_context *ssl, const char *dhm_P, const char *dhm_G )

View File

@ -49,6 +49,8 @@
#define DFL_CA_PATH "" #define DFL_CA_PATH ""
#define DFL_CRT_FILE "" #define DFL_CRT_FILE ""
#define DFL_KEY_FILE "" #define DFL_KEY_FILE ""
#define DFL_PSK ""
#define DFL_PSK_IDENTITY "Client_identity"
#define DFL_FORCE_CIPHER 0 #define DFL_FORCE_CIPHER 0
#define DFL_RENEGOTIATION SSL_RENEGOTIATION_ENABLED #define DFL_RENEGOTIATION SSL_RENEGOTIATION_ENABLED
#define DFL_ALLOW_LEGACY SSL_LEGACY_NO_RENEGOTIATION #define DFL_ALLOW_LEGACY SSL_LEGACY_NO_RENEGOTIATION
@ -71,6 +73,8 @@ struct options
char *ca_path; /* the path with the CA certificate(s) reside */ char *ca_path; /* the path with the CA certificate(s) reside */
char *crt_file; /* the file with the client certificate */ char *crt_file; /* the file with the client certificate */
char *key_file; /* the file with the client key */ char *key_file; /* the file with the client key */
char *psk; /* the pre-shared key */
char *psk_identity; /* the pre-shared key identity */
int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */ int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
int renegotiation; /* enable / disable renegotiation */ int renegotiation; /* enable / disable renegotiation */
int allow_legacy; /* allow legacy renegotiation */ int allow_legacy; /* allow legacy renegotiation */
@ -158,6 +162,8 @@ int my_verify( void *data, x509_cert *crt, int depth, int *flags )
" options: ssl3, tls1, tls1_1, tls1_2\n" \ " options: ssl3, tls1, tls1_1, tls1_2\n" \
" auth_mode=%%s default: \"optional\"\n" \ " auth_mode=%%s default: \"optional\"\n" \
" options: none, optional, required\n" \ " options: none, optional, required\n" \
" psk=%%s default: \"\" (in hex, without 0x)\n" \
" psk_identity=%%s default: \"Client_identity\"\n" \
"\n" \ "\n" \
" force_ciphersuite=<name> default: all enabled\n"\ " force_ciphersuite=<name> default: all enabled\n"\
" acceptable ciphersuite names:\n" " acceptable ciphersuite names:\n"
@ -180,8 +186,10 @@ int main( int argc, char *argv[] )
#else #else
int main( int argc, char *argv[] ) int main( int argc, char *argv[] )
{ {
int ret = 0, len, server_fd; int ret = 0, len, server_fd, i;
unsigned char buf[1024]; unsigned char buf[1024];
unsigned char psk[256];
size_t psk_len = 0;
char *pers = "ssl_client2"; char *pers = "ssl_client2";
entropy_context entropy; entropy_context entropy;
@ -190,7 +198,6 @@ int main( int argc, char *argv[] )
x509_cert cacert; x509_cert cacert;
x509_cert clicert; x509_cert clicert;
rsa_context rsa; rsa_context rsa;
int i;
char *p, *q; char *p, *q;
const int *list; const int *list;
@ -229,6 +236,8 @@ int main( int argc, char *argv[] )
opt.ca_path = DFL_CA_PATH; opt.ca_path = DFL_CA_PATH;
opt.crt_file = DFL_CRT_FILE; opt.crt_file = DFL_CRT_FILE;
opt.key_file = DFL_KEY_FILE; opt.key_file = DFL_KEY_FILE;
opt.psk = DFL_PSK;
opt.psk_identity = DFL_PSK_IDENTITY;
opt.force_ciphersuite[0]= DFL_FORCE_CIPHER; opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
opt.renegotiation = DFL_RENEGOTIATION; opt.renegotiation = DFL_RENEGOTIATION;
opt.allow_legacy = DFL_ALLOW_LEGACY; opt.allow_legacy = DFL_ALLOW_LEGACY;
@ -267,6 +276,10 @@ int main( int argc, char *argv[] )
opt.crt_file = q; opt.crt_file = q;
else if( strcmp( p, "key_file" ) == 0 ) else if( strcmp( p, "key_file" ) == 0 )
opt.key_file = q; opt.key_file = q;
else if( strcmp( p, "psk" ) == 0 )
opt.psk = q;
else if( strcmp( p, "psk_identity" ) == 0 )
opt.psk_identity = q;
else if( strcmp( p, "force_ciphersuite" ) == 0 ) else if( strcmp( p, "force_ciphersuite" ) == 0 )
{ {
opt.force_ciphersuite[0] = -1; opt.force_ciphersuite[0] = -1;
@ -357,6 +370,54 @@ int main( int argc, char *argv[] )
goto usage; goto usage;
} }
/*
* Unhexify the pre-shared key if any is given
*/
if( strlen( opt.psk ) )
{
unsigned char c;
size_t j;
if( strlen( opt.psk ) % 2 != 0 )
{
printf("pre-shared key not valid hex\n");
goto exit;
}
psk_len = strlen( opt.psk ) / 2;
for( j = 0; j < strlen( opt.psk ); j += 2 )
{
c = opt.psk[j];
if( c >= '0' && c <= '9' )
c -= '0';
else if( c >= 'a' && c <= 'f' )
c -= 'a' - 10;
else if( c >= 'A' && c <= 'F' )
c -= 'A' - 10;
else
{
printf("pre-shared key not valid hex\n");
goto exit;
}
psk[ j / 2 ] = c << 4;
c = opt.psk[j + 1];
if( c >= '0' && c <= '9' )
c -= '0';
else if( c >= 'a' && c <= 'f' )
c -= 'a' - 10;
else if( c >= 'A' && c <= 'F' )
c -= 'A' - 10;
else
{
printf("pre-shared key not valid hex\n");
goto exit;
}
psk[ j / 2 ] |= c;
}
}
/* /*
* 0. Initialize the RNG and the session data * 0. Initialize the RNG and the session data
*/ */
@ -502,7 +563,8 @@ int main( int argc, char *argv[] )
ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name ); ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name );
ssl_set_own_cert( &ssl, &clicert, &rsa ); ssl_set_own_cert( &ssl, &clicert, &rsa );
ssl_set_psk( &ssl, psk, psk_len, (unsigned char *) opt.psk_identity,
strlen( opt.psk_identity ) );
ssl_set_hostname( &ssl, opt.server_name ); ssl_set_hostname( &ssl, opt.server_name );
if( opt.min_version != -1 ) if( opt.min_version != -1 )
@ -554,10 +616,13 @@ int main( int argc, char *argv[] )
else else
printf( " ok\n" ); printf( " ok\n" );
if( ssl_get_peer_cert( &ssl ) != NULL )
{
printf( " . Peer certificate information ...\n" ); printf( " . Peer certificate information ...\n" );
x509parse_cert_info( (char *) buf, sizeof( buf ) - 1, " ", x509parse_cert_info( (char *) buf, sizeof( buf ) - 1, " ",
ssl_get_peer_cert( &ssl ) ); ssl_get_peer_cert( &ssl ) );
printf( "%s\n", buf ); printf( "%s\n", buf );
}
/* /*
* 6. Write the GET request * 6. Write the GET request