From d73b3c13bed9d9ff32a29ad6cdd1d8275c265ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20P=C3=A9gouri=C3=A9-Gonnard?= Date: Mon, 12 Aug 2013 17:06:05 +0200 Subject: [PATCH] PK: use wrappers and function pointers for verify --- include/polarssl/pk.h | 28 ++++++++-- include/polarssl/pk_wrap.h | 47 ++++++++++++++++ library/CMakeLists.txt | 1 + library/Makefile | 2 +- library/pk.c | 14 +++++ library/pk_wrap.c | 106 +++++++++++++++++++++++++++++++++++++ library/x509parse.c | 30 +++++------ 7 files changed, 205 insertions(+), 23 deletions(-) create mode 100644 include/polarssl/pk_wrap.h create mode 100644 library/pk_wrap.c diff --git a/include/polarssl/pk.h b/include/polarssl/pk.h index 2f7008514f..f06ec68a4c 100644 --- a/include/polarssl/pk.h +++ b/include/polarssl/pk.h @@ -24,6 +24,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + #ifndef POLARSSL_PK_H #define POLARSSL_PK_H @@ -33,6 +34,10 @@ #include "rsa.h" #endif +#if defined(POLARSSL_ECP_C) +#include "ecp.h" +#endif + #if defined(POLARSSL_ECDSA_C) #include "ecdsa.h" #endif @@ -76,14 +81,29 @@ typedef enum { POLARSSL_PK_ECDSA, } pk_type_t; +/** + * \brief Public key info + */ +typedef struct +{ + /** Public key type */ + pk_type_t type; + + /** Verify signature */ + int (*verify_func)( void *ctx, + const unsigned char *hash, const md_info_t *md_info, + const unsigned char *sig, size_t sig_len ); +} pk_info_t; + /** * \brief Public key container */ typedef struct { - pk_type_t type; /**< Public key type */ - void * data; /**< Public key data */ - int dont_free; /**< True if data must not be freed */ + const pk_info_t * info; /**< Public key informations */ + pk_type_t type; /**< Public key type (temporary) */ + void * data; /**< Public key data */ + int dont_free; /**< True if data must not be freed */ } pk_context; /** @@ -157,4 +177,4 @@ int pk_wrap_rsa( pk_context *ctx, const rsa_context *rsa); } #endif -#endif /* pk.h */ +#endif /* POLARSSL_PK_H */ diff --git a/include/polarssl/pk_wrap.h b/include/polarssl/pk_wrap.h new file mode 100644 index 0000000000..7d2c3dd8ce --- /dev/null +++ b/include/polarssl/pk_wrap.h @@ -0,0 +1,47 @@ +/** + * \file pk.h + * + * \brief Public Key abstraction layer: wrapper functions + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef POLARSSL_PK_WRAP_H +#define POLARSSL_PK_WRAP_H + +#include "config.h" + +#include "pk.h" + +#if defined(POLARSSL_RSA_C) +extern const pk_info_t rsa_info; +#endif + +#if defined(POLARSSL_ECP_C) +extern const pk_info_t eckey_info; +#endif + +#if defined(POLARSSL_ECDSA_C) +extern const pk_info_t ecdsa_info; +#endif + +#endif /* POLARSSL_PK_WRAP_H */ diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index 3fa76a972c..9eea7dc058 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -40,6 +40,7 @@ set(src pkcs11.c pkcs12.c pk.c + pk_wrap.c rsa.c sha1.c sha256.c diff --git a/library/Makefile b/library/Makefile index 48c3bdcbb6..044e2b7a4e 100644 --- a/library/Makefile +++ b/library/Makefile @@ -49,7 +49,7 @@ OBJS= aes.o arc4.o asn1parse.o \ oid.o \ padlock.o pbkdf2.o pem.o \ pkcs5.o pkcs11.o pkcs12.o \ - pk.o \ + pk.o pk_wrap.o \ rsa.o sha1.o sha256.o \ sha512.o ssl_cache.o ssl_cli.o \ ssl_srv.o ssl_ciphersuites.o \ diff --git a/library/pk.c b/library/pk.c index c5583c3638..1210490542 100644 --- a/library/pk.c +++ b/library/pk.c @@ -26,6 +26,7 @@ #include "polarssl/config.h" #include "polarssl/pk.h" +#include "polarssl/pk_wrap.h" #if defined(POLARSSL_RSA_C) #include "polarssl/rsa.h" @@ -54,6 +55,7 @@ void pk_init( pk_context *ctx ) if( ctx == NULL ) return; + ctx->info = NULL; ctx->type = POLARSSL_PK_NONE; ctx->data = NULL; ctx->dont_free = 0; @@ -89,6 +91,7 @@ void pk_free( pk_context *ctx ) if( ! ctx->dont_free ) polarssl_free( ctx->data ); + ctx->info = NULL; ctx->type = POLARSSL_PK_NONE; ctx->data = NULL; } @@ -99,6 +102,7 @@ void pk_free( pk_context *ctx ) int pk_set_type( pk_context *ctx, pk_type_t type ) { size_t size; + const pk_info_t *info; if( ctx->type == type ) return( 0 ); @@ -108,17 +112,26 @@ int pk_set_type( pk_context *ctx, pk_type_t type ) #if defined(POLARSSL_RSA_C) if( type == POLARSSL_PK_RSA ) + { size = sizeof( rsa_context ); + info = &rsa_info; + } else #endif #if defined(POLARSSL_ECP_C) if( type == POLARSSL_PK_ECKEY || type == POLARSSL_PK_ECKEY_DH ) + { size = sizeof( ecp_keypair ); + info = &eckey_info; + } else #endif #if defined(POLARSSL_ECDSA_C) if( type == POLARSSL_PK_ECDSA ) + { size = sizeof( ecdsa_context ); + info = &ecdsa_info; + } else #endif return( POLARSSL_ERR_PK_TYPE_MISMATCH ); @@ -128,6 +141,7 @@ int pk_set_type( pk_context *ctx, pk_type_t type ) memset( ctx->data, 0, size ); ctx->type = type; + ctx->info = info; return( 0 ); } diff --git a/library/pk_wrap.c b/library/pk_wrap.c new file mode 100644 index 0000000000..fe47b388ed --- /dev/null +++ b/library/pk_wrap.c @@ -0,0 +1,106 @@ +/* + * Public Key abstraction layer: wrapper functions + * + * Copyright (C) 2006-2013, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "polarssl/config.h" + +#include "polarssl/pk_wrap.h" + +#if defined(POLARSSL_RSA_C) +#include "polarssl/rsa.h" +#endif + +#if defined(POLARSSL_ECP_C) +#include "polarssl/ecp.h" +#endif + +#if defined(POLARSSL_ECDSA_C) +#include "polarssl/ecdsa.h" +#endif + +#if defined(POLARSSL_RSA_C) +static int rsa_verify_wrap( void *ctx, + const unsigned char *hash, const md_info_t *md_info, + const unsigned char *sig, size_t sig_len ) +{ + ((void) sig_len); + + return( rsa_pkcs1_verify( (rsa_context *) ctx, + RSA_PUBLIC, md_info->type, 0, hash, sig ) ); +} + +const pk_info_t rsa_info = { + POLARSSL_PK_RSA, + rsa_verify_wrap, +}; +#endif /* POLARSSL_RSA_C */ + +#if defined(POLARSSL_ECDSA_C) +int ecdsa_verify_wrap( void *ctx, + const unsigned char *hash, const md_info_t *md_info, + const unsigned char *sig, size_t sig_len ) +{ + return( ecdsa_read_signature( (ecdsa_context *) ctx, + hash, md_info->size, sig, sig_len ) ); +} + +const pk_info_t ecdsa_info = { + POLARSSL_PK_ECDSA, + ecdsa_verify_wrap, +}; +#endif /* POLARSSL_ECDSA_C */ + +#if defined(POLARSSL_ECP_C) +static int eckey_verify_wrap( void *ctx, + const unsigned char *hash, const md_info_t *md_info, + const unsigned char *sig, size_t sig_len ) +{ +#if !defined(POLARSSL_ECDSA_C) + ((void) ctx); + ((void) hash); + ((void) md_info); + ((void) sig); + ((void) sig_len); + + return( POLARSSL_ERR_PK_TYPE_MISMATCH ); +#else + int ret; + ecdsa_context ecdsa; + + ecdsa_init( &ecdsa ); + + ret = ecdsa_from_keypair( &ecdsa, ctx ) || + ecdsa_verify_wrap( &ecdsa, hash, md_info, sig, sig_len ); + + ecdsa_free( &ecdsa ); + + return( ret ); +#endif /* POLARSSL_ECDSA_C */ +} + +const pk_info_t eckey_info = { + POLARSSL_PK_ECKEY, + eckey_verify_wrap, +}; +#endif /* POLARSSL_ECP_C */ diff --git a/library/x509parse.c b/library/x509parse.c index b68640368f..15823bd97e 100644 --- a/library/x509parse.c +++ b/library/x509parse.c @@ -3348,8 +3348,8 @@ static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca, if( crl_list->sig_pk == POLARSSL_PK_RSA ) { if( ca->pk.type != POLARSSL_PK_RSA || - rsa_pkcs1_verify( pk_rsa( ca->pk ), RSA_PUBLIC, - crl_list->sig_md, 0, hash, crl_list->sig.p ) != 0 ) + ca->pk.info->verify_func( ca->pk.data, + hash, md_info, crl_list->sig.p, crl_list->sig.len ) != 0 ) { flags |= BADCRL_NOT_TRUSTED; break; @@ -3361,10 +3361,8 @@ static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca, if( crl_list->sig_pk == POLARSSL_PK_ECDSA ) { if( ! pk_can_ecdsa( ca->pk ) || - pk_ec_to_ecdsa( &ca->pk ) != 0 || - ecdsa_read_signature( (ecdsa_context *) ca->pk.data, - hash, md_info->size, - crl_list->sig.p, crl_list->sig.len ) != 0 ) + ca->pk.info->verify_func( ca->pk.data, + hash, md_info, crl_list->sig.p, crl_list->sig.len ) != 0 ) { flags |= BADCRL_NOT_TRUSTED; break; @@ -3487,8 +3485,8 @@ static int x509parse_verify_top( if( child->sig_pk == POLARSSL_PK_RSA ) { if( trust_ca->pk.type != POLARSSL_PK_RSA || - rsa_pkcs1_verify( pk_rsa( trust_ca->pk ), RSA_PUBLIC, - child->sig_md, 0, hash, child->sig.p ) != 0 ) + trust_ca->pk.info->verify_func( trust_ca->pk.data, + hash, md_info, child->sig.p, child->sig.len ) != 0 ) { trust_ca = trust_ca->next; continue; @@ -3500,10 +3498,8 @@ static int x509parse_verify_top( if( child->sig_pk == POLARSSL_PK_ECDSA ) { if( ! pk_can_ecdsa( trust_ca->pk ) || - pk_ec_to_ecdsa( &trust_ca->pk ) != 0 || - ecdsa_read_signature( (ecdsa_context *) trust_ca->pk.data, - hash, md_info->size, - child->sig.p, child->sig.len ) != 0 ) + trust_ca->pk.info->verify_func( trust_ca->pk.data, + hash, md_info, child->sig.p, child->sig.len ) != 0 ) { trust_ca = trust_ca->next; continue; @@ -3586,8 +3582,8 @@ static int x509parse_verify_child( if( child->sig_pk == POLARSSL_PK_RSA ) { if( parent->pk.type != POLARSSL_PK_RSA || - rsa_pkcs1_verify( pk_rsa( parent->pk ), RSA_PUBLIC, - child->sig_md, 0, hash, child->sig.p ) != 0 ) + parent->pk.info->verify_func( parent->pk.data, + hash, md_info, child->sig.p, child->sig.len ) != 0 ) { *flags |= BADCERT_NOT_TRUSTED; } @@ -3598,10 +3594,8 @@ static int x509parse_verify_child( if( child->sig_pk == POLARSSL_PK_ECDSA ) { if( ! pk_can_ecdsa( parent->pk ) || - pk_ec_to_ecdsa( &parent->pk ) != 0 || - ecdsa_read_signature( (ecdsa_context *) parent->pk.data, - hash, md_info->size, - child->sig.p, child->sig.len ) != 0 ) + parent->pk.info->verify_func( parent->pk.data, + hash, md_info, child->sig.p, child->sig.len ) != 0 ) { *flags |= BADCERT_NOT_TRUSTED; }