Add client support for ECDSA client auth
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 605d466..dbc804a 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -1949,7 +1949,7 @@
size_t n = 0, offset = 0;
unsigned char hash[48];
md_type_t md_alg = POLARSSL_MD_NONE;
- unsigned int hashlen = 0;
+ unsigned int hashlen;
SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
@@ -1968,7 +1968,7 @@
return( 0 );
}
- if( ssl->rsa_key == NULL )
+ if( ssl->pk_key == NULL || ssl->pk_key->pk_info == NULL )
{
SSL_DEBUG_MSG( 1, ( "got no private key" ) );
return( POLARSSL_ERR_SSL_PRIVATE_KEY_REQUIRED );
@@ -1998,6 +1998,7 @@
}
else
{
+ const md_info_t *md_info;
/*
* digitally-signed struct {
* opaque handshake_messages[handshake_messages_length];
@@ -2018,37 +2019,74 @@
{
md_alg = POLARSSL_MD_SHA384;
ssl->out_msg[4] = SSL_HASH_SHA384;
- ssl->out_msg[5] = SSL_SIG_RSA;
}
else
{
md_alg = POLARSSL_MD_SHA256;
ssl->out_msg[4] = SSL_HASH_SHA256;
- ssl->out_msg[5] = SSL_SIG_RSA;
}
+ /* SIG added later */
+
+ if( ( md_info = md_info_from_type( md_alg ) ) == NULL )
+ {
+ SSL_DEBUG_MSG( 1, ( "should never happen" ) );
+ return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
+ }
+
+ hashlen = md_info->size;
offset = 2;
}
- if ( ssl->rsa_key )
+#if defined(POLARSSL_RSA_C)
+ if( ssl->rsa_key != NULL )
+ {
+ if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
+ ssl->out_msg[5] = SSL_SIG_RSA;
+
+ if( ( ret = ssl->rsa_sign( ssl->rsa_key, ssl->f_rng, ssl->p_rng,
+ RSA_PRIVATE, md_alg,
+ hashlen, hash, ssl->out_msg + 6 + offset ) ) != 0 )
+ {
+ SSL_DEBUG_RET( 1, "pkcs1_sign", ret );
+ return( ret );
+ }
+
n = ssl->rsa_key_len ( ssl->rsa_key );
+ }
+ else
+#endif /* POLARSSL_RSA_C */
+#if defined(POLARSSL_ECDSA_C)
+ if( pk_can_do( ssl->pk_key, POLARSSL_PK_ECDSA ) )
+ {
+ ecdsa_context ecdsa;
+
+ if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
+ ssl->out_msg[5] = SSL_SIG_ECDSA;
+
+ ecdsa_init( &ecdsa );
+
+ ret = ecdsa_from_keypair( &ecdsa, ssl->pk_key->pk_ctx ) ||
+ ecdsa_write_signature( &ecdsa, hash, hashlen,
+ ssl->out_msg + 6 + offset, &n,
+ ssl->f_rng, ssl->p_rng );
+
+ ecdsa_free( &ecdsa );
+
+ if( ret != 0 )
+ {
+ SSL_DEBUG_RET( 1, "ecdsa_sign", ret );
+ return( ret );
+ }
+ }
+ else
+#endif /* POLARSSL_ECDSA_C */
+ /* should never happen */
+ return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 );
ssl->out_msg[5 + offset] = (unsigned char)( n );
- if( ssl->rsa_key )
- {
- ret = ssl->rsa_sign( ssl->rsa_key, ssl->f_rng, ssl->p_rng,
- RSA_PRIVATE, md_alg,
- hashlen, hash, ssl->out_msg + 6 + offset );
- }
-
- if (ret != 0)
- {
- SSL_DEBUG_RET( 1, "pkcs1_sign", ret );
- return( ret );
- }
-
ssl->out_msglen = 6 + n + offset;
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
ssl->out_msg[0] = SSL_HS_CERTIFICATE_VERIFY;