PK: add nice interface functions
Also fix a const-corectness issue.
This commit is contained in:
parent
765db07dfb
commit
b3d9187cea
9 changed files with 111 additions and 28 deletions
|
@ -84,7 +84,7 @@
|
|||
* ECP 4 4 (Started from top)
|
||||
* MD 5 4
|
||||
* CIPHER 6 5
|
||||
* SSL 6 5 (Started from top)
|
||||
* SSL 6 6 (Started from top)
|
||||
* SSL 7 31
|
||||
*
|
||||
* Module dependent error code (5 bits 0x.08.-0x.F8.)
|
||||
|
|
|
@ -93,7 +93,7 @@ typedef struct
|
|||
const char *name;
|
||||
|
||||
/** Get key size in bits */
|
||||
size_t (*get_size)( void * );
|
||||
size_t (*get_size)( const void * );
|
||||
|
||||
/** Tell if the context implements this type (eg ECKEY can do ECDSA) */
|
||||
int (*can_do)( pk_type_t type );
|
||||
|
@ -146,6 +146,42 @@ void pk_free( pk_context *ctx );
|
|||
*/
|
||||
int pk_set_type( pk_context *ctx, pk_type_t type );
|
||||
|
||||
/**
|
||||
* \brief Get the size in bits of the underlying key
|
||||
*
|
||||
* \param ctx Context to use
|
||||
*
|
||||
* \return Key size in bits, or 0 on error
|
||||
*/
|
||||
size_t pk_get_size( const pk_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Tell if a context can do the operation given by type
|
||||
*
|
||||
* \param ctx Context to test
|
||||
* \param type Target type
|
||||
*
|
||||
* \return 0 if context can't do the operations,
|
||||
* 1 otherwise.
|
||||
*/
|
||||
int pk_can_do( pk_context *ctx, pk_type_t type );
|
||||
|
||||
/**
|
||||
* \brief Verify signature
|
||||
*
|
||||
* \param ctx PK context to use
|
||||
* \param hash Hash of the message to sign
|
||||
* \param md_info Information about the hash function used
|
||||
* \param sig Signature to verify
|
||||
* \param sig_len Signature length
|
||||
*
|
||||
* \return 0 on success (signature is valid),
|
||||
* or a specific error code.
|
||||
*/
|
||||
int pk_verify( pk_context *ctx,
|
||||
const unsigned char *hash, const md_info_t *md_info,
|
||||
const unsigned char *sig, size_t sig_len );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
#define POLARSSL_ERR_SSL_BAD_HS_PROTOCOL_VERSION -0x6E80 /**< Handshake protocol not within min/max boundaries */
|
||||
#define POLARSSL_ERR_SSL_BAD_HS_NEW_SESSION_TICKET -0x6E00 /**< Processing of the NewSessionTicket handshake message failed. */
|
||||
#define POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED -0x6D80 /**< Session ticket has expired. */
|
||||
|
||||
#define POLARSSL_ERR_SSL_PK_TYPE_MISMATCH -0x6D00 /**< Public key type mismatch (eg, asked for RSA key exchange and presented EC key) */
|
||||
|
||||
/*
|
||||
* Various constants
|
||||
|
|
|
@ -373,6 +373,8 @@ void polarssl_strerror( int ret, char *buf, size_t buflen )
|
|||
snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED) )
|
||||
snprintf( buf, buflen, "SSL - Session ticket has expired" );
|
||||
if( use_ret == -(POLARSSL_ERR_SSL_PK_TYPE_MISMATCH) )
|
||||
snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" );
|
||||
#endif /* POLARSSL_SSL_TLS_C */
|
||||
|
||||
#if defined(POLARSSL_X509_PARSE_C)
|
||||
|
|
36
library/pk.c
36
library/pk.c
|
@ -124,3 +124,39 @@ int pk_set_type( pk_context *ctx, pk_type_t type )
|
|||
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell if a PK can do the operations of the given type
|
||||
*/
|
||||
int pk_can_do( pk_context *ctx, pk_type_t type )
|
||||
{
|
||||
/* null of NONE context can't do anything */
|
||||
if( ctx == NULL || ctx->info == NULL )
|
||||
return( 0 );
|
||||
|
||||
return( ctx->info->can_do( type ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify a signature
|
||||
*/
|
||||
int pk_verify( pk_context *ctx,
|
||||
const unsigned char *hash, const md_info_t *md_info,
|
||||
const unsigned char *sig, size_t sig_len )
|
||||
{
|
||||
if( ctx == NULL || ctx->info == NULL )
|
||||
return( POLARSSL_ERR_PK_TYPE_MISMATCH ); // TODO
|
||||
|
||||
return( ctx->info->verify_func( ctx->data, hash, md_info, sig, sig_len ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Get key size in bits
|
||||
*/
|
||||
size_t pk_get_size( const pk_context *ctx )
|
||||
{
|
||||
if( ctx == NULL || ctx->info == NULL )
|
||||
return( 0 );
|
||||
|
||||
return( ctx->info->get_size( ctx->data ) );
|
||||
}
|
||||
|
|
|
@ -53,9 +53,9 @@ static int rsa_can_do( pk_type_t type )
|
|||
return( type == POLARSSL_PK_RSA );
|
||||
}
|
||||
|
||||
static size_t rsa_get_size( void * ctx )
|
||||
static size_t rsa_get_size( const void * ctx )
|
||||
{
|
||||
return( mpi_size( &((rsa_context *) ctx)->N ) * 8 );
|
||||
return( 8 * ((rsa_context *) ctx)->len );
|
||||
}
|
||||
|
||||
static int rsa_verify_wrap( void *ctx,
|
||||
|
@ -101,7 +101,7 @@ int ecdsa_can_do( pk_type_t type )
|
|||
return( type == POLARSSL_PK_ECDSA );
|
||||
}
|
||||
|
||||
static size_t ecdsa_get_size( void *ctx )
|
||||
static size_t ecdsa_get_size( const void *ctx )
|
||||
{
|
||||
return( ((ecdsa_context *) ctx)->grp.pbits );
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ static int eckey_can_do( pk_type_t type )
|
|||
type == POLARSSL_PK_ECDSA );
|
||||
}
|
||||
|
||||
static size_t eckey_get_size( void *ctx )
|
||||
static size_t eckey_get_size( const void *ctx )
|
||||
{
|
||||
return( ((ecp_keypair *) ctx)->grp.pbits );
|
||||
}
|
||||
|
|
|
@ -1346,12 +1346,15 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
|
|||
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
|
||||
}
|
||||
|
||||
/* EC NOT IMPLEMENTED YET */
|
||||
if( ssl->session_negotiate->peer_cert->pk.type != POLARSSL_PK_RSA )
|
||||
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,
|
||||
POLARSSL_PK_RSA ) )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
|
||||
return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
|
||||
}
|
||||
|
||||
if( (unsigned int)( end - p ) !=
|
||||
pk_rsa( ssl->session_negotiate->peer_cert->pk )->len )
|
||||
if( 8 * (unsigned int)( end - p ) !=
|
||||
pk_get_size( &ssl->session_negotiate->peer_cert->pk ) )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
|
||||
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
|
||||
|
@ -1795,12 +1798,15 @@ static int ssl_write_client_key_exchange( ssl_context *ssl )
|
|||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
/* EC NOT IMPLEMENTED YET */
|
||||
if( ssl->session_negotiate->peer_cert->pk.type != POLARSSL_PK_RSA )
|
||||
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,
|
||||
POLARSSL_PK_RSA ) )
|
||||
{
|
||||
SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
|
||||
return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
|
||||
}
|
||||
|
||||
i = 4;
|
||||
n = pk_rsa( ssl->session_negotiate->peer_cert->pk )->len;
|
||||
n = pk_get_size( &ssl->session_negotiate->peer_cert->pk ) / 8;
|
||||
|
||||
if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
|
||||
{
|
||||
|
|
|
@ -2517,10 +2517,13 @@ static int ssl_parse_certificate_verify( ssl_context *ssl )
|
|||
}
|
||||
|
||||
/* EC NOT IMPLEMENTED YET */
|
||||
if( ssl->session_negotiate->peer_cert->pk.type != POLARSSL_PK_RSA )
|
||||
if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,
|
||||
POLARSSL_PK_RSA ) )
|
||||
{
|
||||
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE );
|
||||
}
|
||||
|
||||
n1 = pk_rsa( ssl->session_negotiate->peer_cert->pk )->len;
|
||||
n1 = pk_get_size( &ssl->session_negotiate->peer_cert->pk ) / 8;
|
||||
n2 = ( ssl->in_msg[4 + n] << 8 ) | ssl->in_msg[5 + n];
|
||||
|
||||
if( n + n1 + 6 != ssl->in_hslen || n1 != n2 )
|
||||
|
|
|
@ -3147,7 +3147,7 @@ int x509parse_cert_info( char *buf, size_t size, const char *prefix,
|
|||
}
|
||||
|
||||
ret = snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
|
||||
(int) crt->pk.info->get_size( crt->pk.data ) );
|
||||
(int) pk_get_size( &crt->pk ) );
|
||||
SAFE_SNPRINTF();
|
||||
|
||||
return( (int) ( size - n ) );
|
||||
|
@ -3399,9 +3399,9 @@ static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
|
|||
|
||||
md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
|
||||
|
||||
if( ca->pk.info->can_do( crl_list->sig_pk ) == 0 ||
|
||||
ca->pk.info->verify_func( ca->pk.data, hash, md_info,
|
||||
crl_list->sig.p, crl_list->sig.len ) != 0 )
|
||||
if( pk_can_do( &ca->pk, crl_list->sig_pk ) == 0 ||
|
||||
pk_verify( &ca->pk, hash, md_info,
|
||||
crl_list->sig.p, crl_list->sig.len ) != 0 )
|
||||
{
|
||||
flags |= BADCRL_NOT_TRUSTED;
|
||||
break;
|
||||
|
@ -3516,9 +3516,9 @@ static int x509parse_verify_top(
|
|||
|
||||
md( md_info, child->tbs.p, child->tbs.len, hash );
|
||||
|
||||
if( trust_ca->pk.info->can_do( child->sig_pk ) == 0 ||
|
||||
trust_ca->pk.info->verify_func( trust_ca->pk.data, hash, md_info,
|
||||
child->sig.p, child->sig.len ) != 0 )
|
||||
if( pk_can_do( &trust_ca->pk, child->sig_pk ) == 0 ||
|
||||
pk_verify( &trust_ca->pk, hash, md_info,
|
||||
child->sig.p, child->sig.len ) != 0 )
|
||||
{
|
||||
trust_ca = trust_ca->next;
|
||||
continue;
|
||||
|
@ -3593,9 +3593,9 @@ static int x509parse_verify_child(
|
|||
{
|
||||
md( md_info, child->tbs.p, child->tbs.len, hash );
|
||||
|
||||
if( parent->pk.info->can_do( child->sig_pk ) == 0 ||
|
||||
parent->pk.info->verify_func( parent->pk.data, hash, md_info,
|
||||
child->sig.p, child->sig.len ) != 0 )
|
||||
if( pk_can_do( &parent->pk, child->sig_pk ) == 0 ||
|
||||
pk_verify( &parent->pk, hash, md_info,
|
||||
child->sig.p, child->sig.len ) != 0 )
|
||||
{
|
||||
*flags |= BADCERT_NOT_TRUSTED;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue