mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-01-26 12:35:20 +00:00
Add server-side support for ECDSA client auth
This commit is contained in:
parent
fb08fd2e23
commit
0b03200e96
@ -192,6 +192,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Supported Signature and Hash algorithms (For TLS 1.2)
|
* Supported Signature and Hash algorithms (For TLS 1.2)
|
||||||
|
* RFC 5246 section 7.4.1.4.1
|
||||||
*/
|
*/
|
||||||
#define SSL_HASH_NONE 0
|
#define SSL_HASH_NONE 0
|
||||||
#define SSL_HASH_MD5 1
|
#define SSL_HASH_MD5 1
|
||||||
@ -202,11 +203,14 @@
|
|||||||
#define SSL_HASH_SHA512 6
|
#define SSL_HASH_SHA512 6
|
||||||
|
|
||||||
#define SSL_SIG_RSA 1
|
#define SSL_SIG_RSA 1
|
||||||
|
#define SSL_SIG_ECDSA 3
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Client Certificate Types
|
* Client Certificate Types
|
||||||
|
* RFC 5246 section 7.4.4 plus RFC 4492 section 5.5
|
||||||
*/
|
*/
|
||||||
#define SSL_CERT_TYPE_RSA_SIGN 1
|
#define SSL_CERT_TYPE_RSA_SIGN 1
|
||||||
|
#define SSL_CERT_TYPE_ECDSA_SIGN 64
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Message, alert and handshake types
|
* Message, alert and handshake types
|
||||||
|
@ -1676,7 +1676,8 @@ static int ssl_write_certificate_request( ssl_context *ssl )
|
|||||||
{
|
{
|
||||||
int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
|
int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
|
||||||
const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
|
const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
|
||||||
size_t n = 0, dn_size, total_dn_size;
|
size_t dn_size, total_dn_size; /* excluding length bytes */
|
||||||
|
size_t ct_len, sa_len; /* including length bytes */
|
||||||
unsigned char *buf, *p;
|
unsigned char *buf, *p;
|
||||||
const x509_cert *crt;
|
const x509_cert *crt;
|
||||||
|
|
||||||
@ -1708,37 +1709,73 @@ static int ssl_write_certificate_request( ssl_context *ssl )
|
|||||||
p = buf + 4;
|
p = buf + 4;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At the moment, only RSA certificates are supported
|
* Supported certificate types
|
||||||
|
*
|
||||||
|
* ClientCertificateType certificate_types<1..2^8-1>;
|
||||||
|
* enum { (255) } ClientCertificateType;
|
||||||
*/
|
*/
|
||||||
*p++ = 1;
|
ct_len = 0;
|
||||||
*p++ = SSL_CERT_TYPE_RSA_SIGN;
|
|
||||||
|
#if defined(POLARSSL_RSA_C)
|
||||||
|
p[1 + ct_len++] = SSL_CERT_TYPE_RSA_SIGN;
|
||||||
|
#endif
|
||||||
|
#if defined(POLARSSL_ECDSA_C)
|
||||||
|
p[1 + ct_len++] = SSL_CERT_TYPE_ECDSA_SIGN;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
p[0] = ct_len++;
|
||||||
|
p += ct_len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add signature_algorithms for verify (TLS 1.2)
|
* Add signature_algorithms for verify (TLS 1.2)
|
||||||
* Only add current running algorithm that is already required for
|
|
||||||
* requested ciphersuite.
|
|
||||||
*
|
*
|
||||||
* Length is always 2
|
* SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>;
|
||||||
|
*
|
||||||
|
* struct {
|
||||||
|
* HashAlgorithm hash;
|
||||||
|
* SignatureAlgorithm signature;
|
||||||
|
* } SignatureAndHashAlgorithm;
|
||||||
|
*
|
||||||
|
* enum { (255) } HashAlgorithm;
|
||||||
|
* enum { (255) } SignatureAlgorithm;
|
||||||
*/
|
*/
|
||||||
|
sa_len = 0;
|
||||||
if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
|
if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Only use current running hash algorithm that is already required
|
||||||
|
* for requested ciphersuite.
|
||||||
|
*/
|
||||||
ssl->handshake->verify_sig_alg = SSL_HASH_SHA256;
|
ssl->handshake->verify_sig_alg = SSL_HASH_SHA256;
|
||||||
|
|
||||||
*p++ = 0;
|
|
||||||
*p++ = 2;
|
|
||||||
|
|
||||||
if( ssl->transform_negotiate->ciphersuite_info->mac ==
|
if( ssl->transform_negotiate->ciphersuite_info->mac ==
|
||||||
POLARSSL_MD_SHA384 )
|
POLARSSL_MD_SHA384 )
|
||||||
{
|
{
|
||||||
ssl->handshake->verify_sig_alg = SSL_HASH_SHA384;
|
ssl->handshake->verify_sig_alg = SSL_HASH_SHA384;
|
||||||
}
|
}
|
||||||
|
|
||||||
*p++ = ssl->handshake->verify_sig_alg;
|
/*
|
||||||
*p++ = SSL_SIG_RSA;
|
* Supported signature algorithms
|
||||||
|
*/
|
||||||
|
#if defined(POLARSSL_RSA_C)
|
||||||
|
p[2 + sa_len++] = ssl->handshake->verify_sig_alg;
|
||||||
|
p[2 + sa_len++] = SSL_SIG_RSA;
|
||||||
|
#endif
|
||||||
|
#if defined(POLARSSL_ECDSA_C)
|
||||||
|
p[2 + sa_len++] = ssl->handshake->verify_sig_alg;
|
||||||
|
p[2 + sa_len++] = SSL_SIG_ECDSA;
|
||||||
|
#endif
|
||||||
|
|
||||||
n += 4;
|
p[0] = (unsigned char)( sa_len >> 8 );
|
||||||
|
p[1] = (unsigned char)( sa_len );
|
||||||
|
sa_len += 2;
|
||||||
|
p += sa_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DistinguishedName certificate_authorities<0..2^16-1>;
|
||||||
|
* opaque DistinguishedName<1..2^16-1>;
|
||||||
|
*/
|
||||||
p += 2;
|
p += 2;
|
||||||
crt = ssl->ca_chain;
|
crt = ssl->ca_chain;
|
||||||
|
|
||||||
@ -1763,8 +1800,8 @@ static int ssl_write_certificate_request( ssl_context *ssl )
|
|||||||
ssl->out_msglen = p - buf;
|
ssl->out_msglen = p - buf;
|
||||||
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
|
ssl->out_msgtype = SSL_MSG_HANDSHAKE;
|
||||||
ssl->out_msg[0] = SSL_HS_CERTIFICATE_REQUEST;
|
ssl->out_msg[0] = SSL_HS_CERTIFICATE_REQUEST;
|
||||||
ssl->out_msg[6 + n] = (unsigned char)( total_dn_size >> 8 );
|
ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 );
|
||||||
ssl->out_msg[7 + n] = (unsigned char)( total_dn_size );
|
ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size );
|
||||||
|
|
||||||
ret = ssl_write_record( ssl );
|
ret = ssl_write_record( ssl );
|
||||||
|
|
||||||
@ -2468,10 +2505,12 @@ static int ssl_parse_certificate_verify( ssl_context *ssl )
|
|||||||
static int ssl_parse_certificate_verify( ssl_context *ssl )
|
static int ssl_parse_certificate_verify( ssl_context *ssl )
|
||||||
{
|
{
|
||||||
int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
|
int ret = POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE;
|
||||||
size_t n = 0, n1, n2;
|
size_t sa_len, sig_len;
|
||||||
unsigned char hash[48];
|
unsigned char hash[48];
|
||||||
md_type_t md_alg = POLARSSL_MD_NONE;
|
size_t hashlen;
|
||||||
unsigned int hashlen = 0;
|
pk_type_t pk_alg;
|
||||||
|
md_type_t md_alg;
|
||||||
|
const md_info_t *md_info;
|
||||||
const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
|
const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
|
||||||
|
|
||||||
SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
|
SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
|
||||||
@ -2513,16 +2552,33 @@ static int ssl_parse_certificate_verify( ssl_context *ssl )
|
|||||||
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ssl->minor_ver == SSL_MINOR_VERSION_3 )
|
/*
|
||||||
|
* 0 . 0 handshake type
|
||||||
|
* 1 . 3 handshake length
|
||||||
|
* 4 . 5 sig alg (TLS 1.2 only)
|
||||||
|
* 4+n . 5+n signature length (n = sa_len)
|
||||||
|
* 6+n . 6+n+m signature (m = sig_len)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
|
||||||
{
|
{
|
||||||
|
sa_len = 0;
|
||||||
|
|
||||||
|
md_alg = POLARSSL_MD_NONE;
|
||||||
|
hashlen = 36;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sa_len = 2;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* As server we know we either have SSL_HASH_SHA384 or
|
* Hash: as server we know we either have SSL_HASH_SHA384 or
|
||||||
* SSL_HASH_SHA256
|
* SSL_HASH_SHA256
|
||||||
*/
|
*/
|
||||||
if( ssl->in_msg[4] != ssl->handshake->verify_sig_alg ||
|
if( ssl->in_msg[4] != ssl->handshake->verify_sig_alg )
|
||||||
ssl->in_msg[5] != SSL_SIG_RSA )
|
|
||||||
{
|
{
|
||||||
SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg for verify message" ) );
|
SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
|
||||||
|
" for verify message" ) );
|
||||||
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2531,36 +2587,65 @@ static int ssl_parse_certificate_verify( ssl_context *ssl )
|
|||||||
else
|
else
|
||||||
md_alg = POLARSSL_MD_SHA256;
|
md_alg = POLARSSL_MD_SHA256;
|
||||||
|
|
||||||
n += 2;
|
/*
|
||||||
}
|
* Get hashlen from MD
|
||||||
else
|
*/
|
||||||
{
|
if( ( md_info = md_info_from_type( md_alg ) ) == NULL )
|
||||||
hashlen = 36;
|
{
|
||||||
md_alg = POLARSSL_MD_NONE;
|
SSL_DEBUG_MSG( 1, ( "requested hash not available " ) );
|
||||||
|
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||||
|
}
|
||||||
|
hashlen = md_info->size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Signature
|
||||||
|
*/
|
||||||
|
switch( ssl->in_msg[5] )
|
||||||
|
{
|
||||||
|
#if defined(POLARSSL_RSA_C)
|
||||||
|
case SSL_SIG_RSA:
|
||||||
|
pk_alg = POLARSSL_PK_RSA;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(POLARSSL_ECDSA_C)
|
||||||
|
case SSL_SIG_ECDSA:
|
||||||
|
pk_alg = POLARSSL_PK_ECDSA;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg"
|
||||||
|
" for verify message" ) );
|
||||||
|
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check the certificate's key type matches the signature alg
|
||||||
|
*/
|
||||||
|
if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) )
|
||||||
|
{
|
||||||
|
SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) );
|
||||||
|
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EC NOT IMPLEMENTED YET */
|
sig_len = ( ssl->in_msg[4 + sa_len] << 8 ) | ssl->in_msg[5 + sa_len];
|
||||||
if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,
|
|
||||||
POLARSSL_PK_RSA ) )
|
|
||||||
{
|
|
||||||
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
|
|
||||||
}
|
|
||||||
|
|
||||||
n1 = pk_get_size( &ssl->session_negotiate->peer_cert->pk ) / 8;
|
if( sa_len + sig_len + 6 != ssl->in_hslen )
|
||||||
n2 = ( ssl->in_msg[4 + n] << 8 ) | ssl->in_msg[5 + n];
|
|
||||||
|
|
||||||
if( n + n1 + 6 != ssl->in_hslen || n1 != n2 )
|
|
||||||
{
|
{
|
||||||
SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
|
SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) );
|
||||||
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY );
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = rsa_pkcs1_verify( pk_rsa( ssl->session_negotiate->peer_cert->pk ),
|
ret = pk_verify( &ssl->session_negotiate->peer_cert->pk,
|
||||||
RSA_PUBLIC, md_alg, hashlen, hash,
|
md_alg, hash, hashlen,
|
||||||
ssl->in_msg + 6 + n );
|
ssl->in_msg + 6 + sa_len, sig_len );
|
||||||
if( ret != 0 )
|
if( ret != 0 )
|
||||||
{
|
{
|
||||||
SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret );
|
SSL_DEBUG_RET( 1, "pk_verify", ret );
|
||||||
return( ret );
|
return( ret );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user