PK: add nice interface functions

Also fix a const-corectness issue.
This commit is contained in:
Manuel Pégourié-Gonnard 2013-08-14 15:56:19 +02:00
parent 765db07dfb
commit b3d9187cea
9 changed files with 111 additions and 28 deletions

View File

@ -84,7 +84,7 @@
* ECP 4 4 (Started from top) * ECP 4 4 (Started from top)
* MD 5 4 * MD 5 4
* CIPHER 6 5 * CIPHER 6 5
* SSL 6 5 (Started from top) * SSL 6 6 (Started from top)
* SSL 7 31 * SSL 7 31
* *
* Module dependent error code (5 bits 0x.08.-0x.F8.) * Module dependent error code (5 bits 0x.08.-0x.F8.)

View File

@ -93,7 +93,7 @@ typedef struct
const char *name; const char *name;
/** Get key size in bits */ /** 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) */ /** Tell if the context implements this type (eg ECKEY can do ECDSA) */
int (*can_do)( pk_type_t type ); 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 ); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -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_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_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_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 * Various constants

View File

@ -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" ); snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" );
if( use_ret == -(POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED) ) if( use_ret == -(POLARSSL_ERR_SSL_SESSION_TICKET_EXPIRED) )
snprintf( buf, buflen, "SSL - Session ticket has 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 */ #endif /* POLARSSL_SSL_TLS_C */
#if defined(POLARSSL_X509_PARSE_C) #if defined(POLARSSL_X509_PARSE_C)

View File

@ -124,3 +124,39 @@ int pk_set_type( pk_context *ctx, pk_type_t type )
return( 0 ); 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 ) );
}

View File

@ -53,9 +53,9 @@ static int rsa_can_do( pk_type_t type )
return( type == POLARSSL_PK_RSA ); 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, static int rsa_verify_wrap( void *ctx,
@ -101,7 +101,7 @@ int ecdsa_can_do( pk_type_t type )
return( type == POLARSSL_PK_ECDSA ); 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 ); return( ((ecdsa_context *) ctx)->grp.pbits );
} }
@ -152,7 +152,7 @@ static int eckey_can_do( pk_type_t type )
type == POLARSSL_PK_ECDSA ); 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 ); return( ((ecp_keypair *) ctx)->grp.pbits );
} }

View File

@ -1346,12 +1346,15 @@ static int ssl_parse_server_key_exchange( ssl_context *ssl )
return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); return( POLARSSL_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE );
} }
/* EC NOT IMPLEMENTED YET */ if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,
if( ssl->session_negotiate->peer_cert->pk.type != POLARSSL_PK_RSA ) POLARSSL_PK_RSA ) )
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); {
SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) );
return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
}
if( (unsigned int)( end - p ) != if( 8 * (unsigned int)( end - p ) !=
pk_rsa( ssl->session_negotiate->peer_cert->pk )->len ) pk_get_size( &ssl->session_negotiate->peer_cert->pk ) )
{ {
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 );
@ -1795,12 +1798,15 @@ static int ssl_write_client_key_exchange( ssl_context *ssl )
if( ret != 0 ) if( ret != 0 )
return( ret ); return( ret );
/* EC NOT IMPLEMENTED YET */ if( ! pk_can_do( &ssl->session_negotiate->peer_cert->pk,
if( ssl->session_negotiate->peer_cert->pk.type != POLARSSL_PK_RSA ) POLARSSL_PK_RSA ) )
return( POLARSSL_ERR_SSL_FEATURE_UNAVAILABLE ); {
SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) );
return( POLARSSL_ERR_SSL_PK_TYPE_MISMATCH );
}
i = 4; 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 ) if( ssl->minor_ver != SSL_MINOR_VERSION_0 )
{ {

View File

@ -2517,10 +2517,13 @@ static int ssl_parse_certificate_verify( ssl_context *ssl )
} }
/* EC NOT IMPLEMENTED YET */ /* 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 ); 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]; n2 = ( ssl->in_msg[4 + n] << 8 ) | ssl->in_msg[5 + n];
if( n + n1 + 6 != ssl->in_hslen || n1 != n2 ) if( n + n1 + 6 != ssl->in_hslen || n1 != n2 )

View File

@ -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, 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(); SAFE_SNPRINTF();
return( (int) ( size - n ) ); 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 ); md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
if( ca->pk.info->can_do( crl_list->sig_pk ) == 0 || if( pk_can_do( &ca->pk, crl_list->sig_pk ) == 0 ||
ca->pk.info->verify_func( ca->pk.data, hash, md_info, pk_verify( &ca->pk, hash, md_info,
crl_list->sig.p, crl_list->sig.len ) != 0 ) crl_list->sig.p, crl_list->sig.len ) != 0 )
{ {
flags |= BADCRL_NOT_TRUSTED; flags |= BADCRL_NOT_TRUSTED;
break; break;
@ -3516,9 +3516,9 @@ static int x509parse_verify_top(
md( md_info, child->tbs.p, child->tbs.len, hash ); md( md_info, child->tbs.p, child->tbs.len, hash );
if( trust_ca->pk.info->can_do( child->sig_pk ) == 0 || if( pk_can_do( &trust_ca->pk, child->sig_pk ) == 0 ||
trust_ca->pk.info->verify_func( trust_ca->pk.data, hash, md_info, pk_verify( &trust_ca->pk, hash, md_info,
child->sig.p, child->sig.len ) != 0 ) child->sig.p, child->sig.len ) != 0 )
{ {
trust_ca = trust_ca->next; trust_ca = trust_ca->next;
continue; continue;
@ -3593,9 +3593,9 @@ static int x509parse_verify_child(
{ {
md( md_info, child->tbs.p, child->tbs.len, hash ); md( md_info, child->tbs.p, child->tbs.len, hash );
if( parent->pk.info->can_do( child->sig_pk ) == 0 || if( pk_can_do( &parent->pk, child->sig_pk ) == 0 ||
parent->pk.info->verify_func( parent->pk.data, hash, md_info, pk_verify( &parent->pk, hash, md_info,
child->sig.p, child->sig.len ) != 0 ) child->sig.p, child->sig.len ) != 0 )
{ {
*flags |= BADCERT_NOT_TRUSTED; *flags |= BADCERT_NOT_TRUSTED;
} }