PK: use wrappers and function pointers for verify
diff --git a/include/polarssl/pk.h b/include/polarssl/pk.h
index 2f70085..f06ec68 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
@@ -77,13 +82,28 @@
} 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 @@
}
#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 0000000..7d2c3dd
--- /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 <polarssl_maintainer at polarssl.org>
+ *
+ * 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 3fa76a9..9eea7dc 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -40,6 +40,7 @@
pkcs11.c
pkcs12.c
pk.c
+ pk_wrap.c
rsa.c
sha1.c
sha256.c
diff --git a/library/Makefile b/library/Makefile
index 48c3bdc..044e2b7 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -49,7 +49,7 @@
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 c5583c3..1210490 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 @@
if( ctx == NULL )
return;
+ ctx->info = NULL;
ctx->type = POLARSSL_PK_NONE;
ctx->data = NULL;
ctx->dont_free = 0;
@@ -89,6 +91,7 @@
if( ! ctx->dont_free )
polarssl_free( ctx->data );
+ ctx->info = NULL;
ctx->type = POLARSSL_PK_NONE;
ctx->data = NULL;
}
@@ -99,6 +102,7 @@
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 @@
#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 @@
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 0000000..fe47b38
--- /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 <polarssl_maintainer at polarssl.org>
+ *
+ * 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 b686403..15823bd 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -3348,8 +3348,8 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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;
}