OID functionality moved to a separate module.
A new OID module has been created that contains the main OID searching
functionality based on type-dependent arrays. A base type is used to
contain the basic values (oid_descriptor_t) and that type is extended to
contain type specific information (like a pk_alg_t).
As a result the rsa sign and verify function prototypes have changed. They
now expect a md_type_t identifier instead of the removed RSA_SIG_XXX
defines.
All OID definitions have been moved to oid.h
All OID matching code is in the OID module.
The RSA PKCS#1 functions cleaned up as a result and adapted to use the
MD layer.
The SSL layer cleanup up as a result and adapted to use the MD layer.
The X509 parser cleaned up and matches OIDs in certificates with new
module and adapted to use the MD layer.
The X509 writer cleaned up and adapted to use the MD layer.
Apps and tests modified accordingly
diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
index c96a42a..a4b3113 100644
--- a/library/CMakeLists.txt
+++ b/library/CMakeLists.txt
@@ -30,6 +30,7 @@
md4.c
md5.c
net.c
+ oid.c
padlock.c
pbkdf2.c
pem.c
diff --git a/library/Makefile b/library/Makefile
index 1d3a38a..e878583 100644
--- a/library/Makefile
+++ b/library/Makefile
@@ -45,6 +45,7 @@
error.o gcm.o havege.o \
md.o md_wrap.o md2.o \
md4.o md5.o net.o \
+ oid.o \
padlock.o pbkdf2.o pem.o \
pkcs11.o \
rsa.o sha1.o sha2.o \
diff --git a/library/error.c b/library/error.c
index fce6b2c..66f0784 100644
--- a/library/error.c
+++ b/library/error.c
@@ -95,6 +95,10 @@
#include "polarssl/net.h"
#endif
+#if defined(POLARSSL_OID_C)
+#include "polarssl/oid.h"
+#endif
+
#if defined(POLARSSL_PADLOCK_C)
#include "polarssl/padlock.h"
#endif
@@ -530,6 +534,11 @@
snprintf( buf, buflen, "NET - Connection requires a write call" );
#endif /* POLARSSL_NET_C */
+#if defined(POLARSSL_OID_C)
+ if( use_ret == -(POLARSSL_ERR_OID_NOT_FOUND) )
+ snprintf( buf, buflen, "OID - OID is not found" );
+#endif /* POLARSSL_OID_C */
+
#if defined(POLARSSL_PADLOCK_C)
if( use_ret == -(POLARSSL_ERR_PADLOCK_DATA_MISALIGNED) )
snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
diff --git a/library/oid.c b/library/oid.c
new file mode 100644
index 0000000..53c2e5d
--- /dev/null
+++ b/library/oid.c
@@ -0,0 +1,550 @@
+/**
+ * \file oid.c
+ *
+ * \brief Object Identifier (OID) database
+ *
+ * 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"
+
+#if defined(POLARSSL_OID_C)
+
+#include "polarssl/oid.h"
+#include "polarssl/md.h"
+#include "polarssl/rsa.h"
+
+/*
+ * For X520 attribute types
+ */
+typedef struct {
+ oid_descriptor_t descriptor;
+ const char *short_name;
+} oid_x520_attr_t;
+
+static const oid_x520_attr_t oid_x520_attr_type[] =
+{
+ {
+ { OID_AT_CN, "id-at-commonName", "Common Name" },
+ "CN",
+ },
+ {
+ { OID_AT_COUNTRY, "id-at-countryName", "Country" },
+ "C",
+ },
+ {
+ { OID_AT_LOCALITY, "id-at-locality", "Locality" },
+ "L",
+ },
+ {
+ { OID_AT_STATE, "id-at-state", "State" },
+ "ST",
+ },
+ {
+ { OID_AT_ORGANIZATION,"id-at-organizationName", "Organization" },
+ "O",
+ },
+ {
+ { OID_AT_ORG_UNIT, "id-at-organizationalUnitName", "Org Unit" },
+ "OU",
+ },
+ {
+ { OID_PKCS9_EMAIL, "emailAddress", "E-mail address" },
+ "emailAddress",
+ },
+ {
+ { NULL, NULL, NULL },
+ NULL,
+ }
+};
+
+/*
+ * For X509 extensions
+ */
+typedef struct {
+ oid_descriptor_t descriptor;
+ int ext_type;
+} oid_x509_ext_t;
+
+static const oid_x509_ext_t oid_x509_ext[] =
+{
+ {
+ { OID_BASIC_CONSTRAINTS, "id-ce-basicConstraints", "Basic Constraints" },
+ EXT_BASIC_CONSTRAINTS,
+ },
+ {
+ { OID_KEY_USAGE, "id-ce-keyUsage", "Key Usage" },
+ EXT_KEY_USAGE,
+ },
+ {
+ { OID_EXTENDED_KEY_USAGE, "id-ce-keyUsage", "Extended Key Usage" },
+ EXT_EXTENDED_KEY_USAGE,
+ },
+ {
+ { OID_SUBJECT_ALT_NAME, "id-ce-subjectAltName", "Subject Alt Name" },
+ EXT_SUBJECT_ALT_NAME,
+ },
+ {
+ { OID_NS_CERT_TYPE, "id-netscape-certtype", "Netscape Certificate Type" },
+ EXT_NS_CERT_TYPE,
+ },
+ {
+ { NULL, NULL, NULL },
+ 0,
+ },
+};
+
+static const oid_descriptor_t oid_ext_key_usage[] =
+{
+ { OID_SERVER_AUTH, "id-kp-serverAuth", "TLS Web Server Authentication" },
+ { OID_CLIENT_AUTH, "id-kp-clientAuth", "TLS Web Client Authentication" },
+ { OID_CODE_SIGNING, "id-kp-codeSigning", "Code Signing" },
+ { OID_EMAIL_PROTECTION, "id-kp-emailProtection", "E-mail Protection" },
+ { OID_TIME_STAMPING, "id-kp-timeStamping", "Time Stamping" },
+ { OID_OCSP_SIGNING, "id-kp-OCSPSigning", "OCSP Signing" },
+ { NULL, NULL, NULL },
+};
+
+/*
+ * For SignatureAlgorithmIdentifier
+ */
+typedef struct {
+ oid_descriptor_t descriptor;
+ md_type_t md_alg;
+ pk_type_t pk_alg;
+} oid_sig_alg_t;
+
+static const oid_sig_alg_t oid_sig_alg[] =
+{
+ {
+ { OID_PKCS1_MD2, "md2WithRSAEncryption", "RSA with MD2" },
+ POLARSSL_MD_MD2, POLARSSL_PK_RSA,
+ },
+ {
+ { OID_PKCS1_MD4, "md4WithRSAEncryption", "RSA with MD4" },
+ POLARSSL_MD_MD4, POLARSSL_PK_RSA,
+ },
+ {
+ { OID_PKCS1_MD5, "md5WithRSAEncryption", "RSA with MD5" },
+ POLARSSL_MD_MD5, POLARSSL_PK_RSA,
+ },
+ {
+ { OID_PKCS1_SHA1, "sha-1WithRSAEncryption", "RSA with SHA1" },
+ POLARSSL_MD_SHA1, POLARSSL_PK_RSA,
+ },
+ {
+ { OID_PKCS1_SHA224, "sha224WithRSAEncryption", "RSA with SHA-224" },
+ POLARSSL_MD_SHA224, POLARSSL_PK_RSA,
+ },
+ {
+ { OID_PKCS1_SHA256, "sha256WithRSAEncryption", "RSA with SHA-256" },
+ POLARSSL_MD_SHA256, POLARSSL_PK_RSA,
+ },
+ {
+ { OID_PKCS1_SHA384, "sha384WithRSAEncryption", "RSA with SHA-384" },
+ POLARSSL_MD_SHA384, POLARSSL_PK_RSA,
+ },
+ {
+ { OID_PKCS1_SHA512, "sha512WithRSAEncryption", "RSA with SHA-512" },
+ POLARSSL_MD_SHA512, POLARSSL_PK_RSA,
+ },
+ {
+ { OID_RSA_SHA_OBS, "sha-1WithRSAEncryption", "RSA with SHA1" },
+ POLARSSL_MD_SHA1, POLARSSL_PK_RSA,
+ },
+ {
+ { NULL, NULL, NULL },
+ 0, 0,
+ },
+};
+
+/*
+ * For PublicKeyInfo
+ */
+typedef struct {
+ oid_descriptor_t descriptor;
+ pk_type_t pk_alg;
+} oid_pk_alg_t;
+
+static const oid_pk_alg_t oid_pk_alg[] =
+{
+ {
+ { OID_PKCS1_RSA, "rsaEncryption", "RSA" },
+ POLARSSL_PK_RSA,
+ },
+ {
+ { NULL, NULL, NULL },
+ 0,
+ },
+};
+
+/*
+ * For digestAlgorithm
+ */
+typedef struct {
+ oid_descriptor_t descriptor;
+ md_type_t md_alg;
+} oid_md_alg_t;
+
+static const oid_md_alg_t oid_md_alg[] =
+{
+ {
+ { OID_DIGEST_ALG_MD2, "id-md2", "MD2" },
+ POLARSSL_MD_MD2,
+ },
+ {
+ { OID_DIGEST_ALG_MD4, "id-md4", "MD4" },
+ POLARSSL_MD_MD4,
+ },
+ {
+ { OID_DIGEST_ALG_MD5, "id-md5", "MD5" },
+ POLARSSL_MD_MD5,
+ },
+ {
+ { OID_DIGEST_ALG_SHA1, "id-sha1", "SHA-1" },
+ POLARSSL_MD_SHA1,
+ },
+ {
+ { OID_DIGEST_ALG_SHA1, "id-sha1", "SHA-1" },
+ POLARSSL_MD_SHA1,
+ },
+ {
+ { OID_DIGEST_ALG_SHA224, "id-sha224", "SHA-224" },
+ POLARSSL_MD_SHA224,
+ },
+ {
+ { OID_DIGEST_ALG_SHA256, "id-sha256", "SHA-256" },
+ POLARSSL_MD_SHA256,
+ },
+ {
+ { OID_DIGEST_ALG_SHA384, "id-sha384", "SHA-384" },
+ POLARSSL_MD_SHA384,
+ },
+ {
+ { OID_DIGEST_ALG_SHA512, "id-sha512", "SHA-512" },
+ POLARSSL_MD_SHA512,
+ },
+ {
+ { NULL, NULL, NULL },
+ 0,
+ },
+};
+
+#if defined _MSC_VER && !defined snprintf
+#include <stdarg.h>
+
+#if !defined vsnprintf
+#define vsnprintf _vsnprintf
+#endif // vsnprintf
+
+/*
+ * Windows _snprintf and _vsnprintf are not compatible to linux versions.
+ * Result value is not size of buffer needed, but -1 if no fit is possible.
+ *
+ * This fuction tries to 'fix' this by at least suggesting enlarging the
+ * size by 20.
+ */
+static int compat_snprintf(char *str, size_t size, const char *format, ...)
+{
+ va_list ap;
+ int res = -1;
+
+ va_start( ap, format );
+
+ res = vsnprintf( str, size, format, ap );
+
+ va_end( ap );
+
+ // No quick fix possible
+ if ( res < 0 )
+ return( (int) size + 20 );
+
+ return res;
+}
+
+#define snprintf compat_snprintf
+#endif
+
+#define POLARSSL_ERR_DEBUG_BUF_TOO_SMALL -2
+
+#define SAFE_SNPRINTF() \
+{ \
+ if( ret == -1 ) \
+ return( -1 ); \
+ \
+ if ( (unsigned int) ret > n ) { \
+ p[n - 1] = '\0'; \
+ return POLARSSL_ERR_DEBUG_BUF_TOO_SMALL;\
+ } \
+ \
+ n -= (unsigned int) ret; \
+ p += (unsigned int) ret; \
+}
+
+/* Return the x.y.z.... style numeric string for the given OID */
+int oid_get_numeric_string( char *buf, size_t size,
+ const asn1_buf *oid )
+{
+ int ret;
+ size_t i, n;
+ unsigned int value;
+ char *p;
+
+ p = buf;
+ n = size;
+
+ /* First byte contains first two dots */
+ if( oid->len > 0 )
+ {
+ ret = snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 );
+ SAFE_SNPRINTF();
+ }
+
+ /* Prevent overflow in value. */
+ if( oid->len > sizeof(value) )
+ return( POLARSSL_ERR_DEBUG_BUF_TOO_SMALL );
+
+ value = 0;
+ for( i = 1; i < oid->len; i++ )
+ {
+ value <<= 7;
+ value += oid->p[i] & 0x7F;
+
+ if( !( oid->p[i] & 0x80 ) )
+ {
+ /* Last byte */
+ ret = snprintf( p, n, ".%d", value );
+ SAFE_SNPRINTF();
+ value = 0;
+ }
+ }
+
+ return( (int) ( size - n ) );
+}
+
+static const oid_descriptor_t *oid_descriptor_from_buf(
+ const void *struct_set,
+ size_t struct_size,
+ const unsigned char *oid,
+ size_t len )
+{
+ const unsigned char *p = (unsigned char *) struct_set;
+ const oid_descriptor_t *cur;
+
+ if( struct_set == NULL || oid == NULL )
+ return( NULL );
+
+ cur = (const oid_descriptor_t *) p;
+ while( cur->asn1 != NULL )
+ {
+ if( strlen( cur->asn1 ) == len &&
+ memcmp( cur->asn1, oid, len ) == 0 )
+ {
+ return( cur );
+ }
+
+ p += struct_size;
+ cur = (const oid_descriptor_t *) p;
+ }
+
+ return( NULL );
+}
+
+static const oid_descriptor_t *oid_descriptor_from_asn1(
+ const void *struct_set,
+ size_t struct_size,
+ const asn1_buf *oid )
+{
+ return oid_descriptor_from_buf( struct_set, struct_size,
+ oid->p, oid->len );
+}
+
+int oid_get_extended_key_usage( const asn1_buf *oid, const char **desc )
+{
+ const oid_descriptor_t *data = oid_descriptor_from_asn1(
+ oid_ext_key_usage,
+ sizeof(oid_descriptor_t),
+ oid );
+
+ if( data == NULL )
+ return( POLARSSL_ERR_OID_NOT_FOUND );
+
+ *desc = data->description;
+
+ return( 0 );
+}
+
+static const oid_x509_ext_t *oid_x509_ext_from_asn1( const asn1_buf *oid )
+{
+ return (const oid_x509_ext_t *) oid_descriptor_from_asn1(
+ oid_x509_ext,
+ sizeof(oid_x509_ext_t),
+ oid );
+}
+
+static const oid_x520_attr_t *oid_x520_attr_from_asn1( const asn1_buf *oid )
+{
+ return (const oid_x520_attr_t *) oid_descriptor_from_asn1(
+ oid_x520_attr_type,
+ sizeof(oid_x520_attr_t),
+ oid );
+}
+
+static const oid_pk_alg_t *oid_pk_alg_from_asn1( const asn1_buf *oid )
+{
+ return (const oid_pk_alg_t *) oid_descriptor_from_asn1(
+ oid_pk_alg,
+ sizeof(oid_pk_alg_t),
+ oid );
+}
+
+static const oid_sig_alg_t *oid_sig_alg_from_asn1( const asn1_buf *oid )
+{
+ return (const oid_sig_alg_t *) oid_descriptor_from_asn1(
+ oid_sig_alg,
+ sizeof(oid_sig_alg_t),
+ oid );
+}
+
+static const oid_md_alg_t *oid_md_alg_from_asn1( const asn1_buf *oid )
+{
+ return (const oid_md_alg_t *) oid_descriptor_from_asn1(
+ oid_md_alg,
+ sizeof(oid_md_alg_t),
+ oid );
+}
+
+int oid_get_x509_ext_type( const asn1_buf *oid, int *ext_type )
+{
+ const oid_x509_ext_t *data = oid_x509_ext_from_asn1( oid );
+
+ if( data == NULL )
+ return( POLARSSL_ERR_OID_NOT_FOUND );
+
+ *ext_type = data->ext_type;
+
+ return( 0 );
+}
+
+int oid_get_attr_short_name( const asn1_buf *oid, const char **short_name )
+{
+ const oid_x520_attr_t *data = oid_x520_attr_from_asn1( oid );
+
+ if( data == NULL )
+ return( POLARSSL_ERR_OID_NOT_FOUND );
+
+ *short_name = data->short_name;
+
+ return( 0 );
+}
+
+int oid_get_pk_alg( const asn1_buf *oid, pk_type_t *pk_alg )
+{
+ const oid_pk_alg_t *data = oid_pk_alg_from_asn1( oid );
+
+ if( data == NULL )
+ return( POLARSSL_ERR_OID_NOT_FOUND );
+
+ *pk_alg = data->pk_alg;
+
+ return( 0 );
+}
+
+int oid_get_sig_alg_desc( const asn1_buf *oid, const char **desc )
+{
+ const oid_sig_alg_t *data = oid_sig_alg_from_asn1( oid );
+
+ if( data == NULL )
+ return( POLARSSL_ERR_OID_NOT_FOUND );
+
+ *desc = data->descriptor.description;
+
+ return( 0 );
+}
+
+int oid_get_sig_alg( const asn1_buf *oid,
+ md_type_t *md_alg, pk_type_t *pk_alg )
+{
+ const oid_sig_alg_t *data = oid_sig_alg_from_asn1( oid );
+
+ if( data == NULL )
+ return( POLARSSL_ERR_OID_NOT_FOUND );
+
+ *md_alg = data->md_alg;
+ *pk_alg = data->pk_alg;
+
+ return( 0 );
+}
+
+int oid_get_oid_by_sig_alg( pk_type_t pk_alg, md_type_t md_alg,
+ const char **oid_str )
+{
+ const oid_sig_alg_t *cur = oid_sig_alg;
+
+ while( cur->descriptor.asn1 != NULL )
+ {
+ if( cur->pk_alg == pk_alg &&
+ cur->md_alg == md_alg )
+ {
+ *oid_str = cur->descriptor.asn1;
+ return( 0 );
+ }
+
+ cur++;
+ }
+
+ return( POLARSSL_ERR_OID_NOT_FOUND );
+}
+
+int oid_get_md_alg( const asn1_buf *oid,
+ md_type_t *md_alg )
+{
+ const oid_md_alg_t *data = oid_md_alg_from_asn1( oid );
+
+ if( data == NULL )
+ return( POLARSSL_ERR_OID_NOT_FOUND );
+
+ *md_alg = data->md_alg;
+
+ return( 0 );
+}
+
+int oid_get_oid_by_md( md_type_t md_alg,
+ const char **oid_str )
+{
+ const oid_md_alg_t *cur = oid_md_alg;
+
+ while( cur->descriptor.asn1 != NULL )
+ {
+ if( cur->md_alg == md_alg )
+ {
+ *oid_str = cur->descriptor.asn1;
+ return( 0 );
+ }
+
+ cur++;
+ }
+
+ return( POLARSSL_ERR_OID_NOT_FOUND );
+}
+
+#endif /* POLARSSL_OID_C */
diff --git a/library/rsa.c b/library/rsa.c
index e53d9a2..146b4a3 100644
--- a/library/rsa.c
+++ b/library/rsa.c
@@ -34,6 +34,7 @@
#if defined(POLARSSL_RSA_C)
#include "polarssl/rsa.h"
+#include "polarssl/oid.h"
#if defined(POLARSSL_PKCS1_V21)
#include "polarssl/md.h"
@@ -385,7 +386,6 @@
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
md_info = md_info_from_type( ctx->hash_id );
-
if( md_info == NULL )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
@@ -741,7 +741,7 @@
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
int mode,
- int hash_id,
+ md_type_t md_alg,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig )
@@ -760,36 +760,15 @@
olen = ctx->len;
- switch( hash_id )
+ if( md_alg != POLARSSL_MD_NONE )
{
- case SIG_RSA_MD2:
- case SIG_RSA_MD4:
- case SIG_RSA_MD5:
- hashlen = 16;
- break;
-
- case SIG_RSA_SHA1:
- hashlen = 20;
- break;
-
- case SIG_RSA_SHA224:
- hashlen = 28;
- break;
-
- case SIG_RSA_SHA256:
- hashlen = 32;
- break;
-
- case SIG_RSA_SHA384:
- hashlen = 48;
- break;
-
- case SIG_RSA_SHA512:
- hashlen = 64;
- break;
-
- default:
+ // Gather length of hash to sign
+ //
+ md_info = md_info_from_type( md_alg );
+ if( md_info == NULL )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ hashlen = md_get_size( md_info );
}
md_info = md_info_from_type( ctx->hash_id );
@@ -860,56 +839,38 @@
*/
int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
int mode,
- int hash_id,
+ md_type_t md_alg,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig )
{
- size_t nb_pad, olen;
+ size_t nb_pad, olen, oid_size = 0;
unsigned char *p = sig;
+ const char *oid;
if( ctx->padding != RSA_PKCS_V15 )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
olen = ctx->len;
+ nb_pad = olen - 3;
- switch( hash_id )
+ if( md_alg != POLARSSL_MD_NONE )
{
- case SIG_RSA_RAW:
- nb_pad = olen - 3 - hashlen;
- break;
-
- case SIG_RSA_MD2:
- case SIG_RSA_MD4:
- case SIG_RSA_MD5:
- nb_pad = olen - 3 - 34;
- break;
-
- case SIG_RSA_SHA1:
- nb_pad = olen - 3 - 35;
- break;
-
- case SIG_RSA_SHA224:
- nb_pad = olen - 3 - 47;
- break;
-
- case SIG_RSA_SHA256:
- nb_pad = olen - 3 - 51;
- break;
-
- case SIG_RSA_SHA384:
- nb_pad = olen - 3 - 67;
- break;
-
- case SIG_RSA_SHA512:
- nb_pad = olen - 3 - 83;
- break;
-
-
- default:
+ const md_info_t *md_info = md_info_from_type( md_alg );
+ if( md_info == NULL )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ if( oid_get_oid_by_md( md_alg, &oid ) != 0 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ oid_size = strlen( oid );
+ nb_pad -= 10 + oid_size;
+
+ hashlen = md_get_size( md_info );
}
+ nb_pad -= hashlen;
+
if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
@@ -919,54 +880,34 @@
p += nb_pad;
*p++ = 0;
- switch( hash_id )
+ if( md_alg == POLARSSL_MD_NONE )
{
- case SIG_RSA_RAW:
- memcpy( p, hash, hashlen );
- break;
-
- case SIG_RSA_MD2:
- memcpy( p, ASN1_HASH_MDX, 18 );
- memcpy( p + 18, hash, 16 );
- p[13] = 2; break;
-
- case SIG_RSA_MD4:
- memcpy( p, ASN1_HASH_MDX, 18 );
- memcpy( p + 18, hash, 16 );
- p[13] = 4; break;
-
- case SIG_RSA_MD5:
- memcpy( p, ASN1_HASH_MDX, 18 );
- memcpy( p + 18, hash, 16 );
- p[13] = 5; break;
-
- case SIG_RSA_SHA1:
- memcpy( p, ASN1_HASH_SHA1, 15 );
- memcpy( p + 15, hash, 20 );
- break;
-
- case SIG_RSA_SHA224:
- memcpy( p, ASN1_HASH_SHA2X, 19 );
- memcpy( p + 19, hash, 28 );
- p[1] += 28; p[14] = 4; p[18] += 28; break;
-
- case SIG_RSA_SHA256:
- memcpy( p, ASN1_HASH_SHA2X, 19 );
- memcpy( p + 19, hash, 32 );
- p[1] += 32; p[14] = 1; p[18] += 32; break;
-
- case SIG_RSA_SHA384:
- memcpy( p, ASN1_HASH_SHA2X, 19 );
- memcpy( p + 19, hash, 48 );
- p[1] += 48; p[14] = 2; p[18] += 48; break;
-
- case SIG_RSA_SHA512:
- memcpy( p, ASN1_HASH_SHA2X, 19 );
- memcpy( p + 19, hash, 64 );
- p[1] += 64; p[14] = 3; p[18] += 64; break;
-
- default:
- return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ memcpy( p, hash, hashlen );
+ }
+ else
+ {
+ /*
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * digest Digest }
+ *
+ * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * Digest ::= OCTET STRING
+ */
+ *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
+ *p++ = 0x08 + oid_size + hashlen;
+ *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
+ *p++ = 0x04 + oid_size;
+ *p++ = ASN1_OID;
+ *p++ = oid_size;
+ memcpy( p, oid, oid_size );
+ p += oid_size;
+ *p++ = ASN1_NULL;
+ *p++ = 0x00;
+ *p++ = ASN1_OCTET_STRING;
+ *p++ = hashlen;
+ memcpy( p, hash, hashlen );
}
return( ( mode == RSA_PUBLIC )
@@ -981,7 +922,7 @@
int (*f_rng)(void *, unsigned char *, size_t),
void *p_rng,
int mode,
- int hash_id,
+ md_type_t md_alg,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig )
@@ -989,12 +930,12 @@
switch( ctx->padding )
{
case RSA_PKCS_V15:
- return rsa_rsassa_pkcs1_v15_sign( ctx, mode, hash_id,
+ return rsa_rsassa_pkcs1_v15_sign( ctx, mode, md_alg,
hashlen, hash, sig );
#if defined(POLARSSL_PKCS1_V21)
case RSA_PKCS_V21:
- return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, hash_id,
+ return rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
hashlen, hash, sig );
#endif
@@ -1009,7 +950,7 @@
*/
int rsa_rsassa_pss_verify( rsa_context *ctx,
int mode,
- int hash_id,
+ md_type_t md_alg,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig )
@@ -1045,36 +986,15 @@
if( buf[siglen - 1] != 0xBC )
return( POLARSSL_ERR_RSA_INVALID_PADDING );
- switch( hash_id )
+ if( md_alg != POLARSSL_MD_NONE )
{
- case SIG_RSA_MD2:
- case SIG_RSA_MD4:
- case SIG_RSA_MD5:
- hashlen = 16;
- break;
-
- case SIG_RSA_SHA1:
- hashlen = 20;
- break;
-
- case SIG_RSA_SHA224:
- hashlen = 28;
- break;
-
- case SIG_RSA_SHA256:
- hashlen = 32;
- break;
-
- case SIG_RSA_SHA384:
- hashlen = 48;
- break;
-
- case SIG_RSA_SHA512:
- hashlen = 64;
- break;
-
- default:
+ // Gather length of hash to sign
+ //
+ md_info = md_info_from_type( md_alg );
+ if( md_info == NULL )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ hashlen = md_get_size( md_info );
}
md_info = md_info_from_type( ctx->hash_id );
@@ -1140,15 +1060,18 @@
*/
int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
int mode,
- int hash_id,
+ md_type_t md_alg,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig )
{
int ret;
- size_t len, siglen;
- unsigned char *p, c;
+ size_t len, siglen, asn1_len;
+ unsigned char *p, *end;
unsigned char buf[POLARSSL_MPI_MAX_SIZE];
+ md_type_t msg_md_alg;
+ const md_info_t *md_info;
+ asn1_buf oid;
if( ctx->padding != RSA_PKCS_V15 )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
@@ -1180,59 +1103,7 @@
len = siglen - ( p - buf );
- if( len == 33 && hash_id == SIG_RSA_SHA1 )
- {
- if( memcmp( p, ASN1_HASH_SHA1_ALT, 13 ) == 0 &&
- memcmp( p + 13, hash, 20 ) == 0 )
- return( 0 );
- else
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
- }
- if( len == 34 )
- {
- c = p[13];
- p[13] = 0;
-
- if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
-
- if( ( c == 2 && hash_id == SIG_RSA_MD2 ) ||
- ( c == 4 && hash_id == SIG_RSA_MD4 ) ||
- ( c == 5 && hash_id == SIG_RSA_MD5 ) )
- {
- if( memcmp( p + 18, hash, 16 ) == 0 )
- return( 0 );
- else
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
- }
- }
-
- if( len == 35 && hash_id == SIG_RSA_SHA1 )
- {
- if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
- memcmp( p + 15, hash, 20 ) == 0 )
- return( 0 );
- else
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
- }
- if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) ||
- ( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) ||
- ( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
- ( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
- {
- c = p[1] - 17;
- p[1] = 17;
- p[14] = 0;
-
- if( p[18] == c &&
- memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 &&
- memcmp( p + 19, hash, c ) == 0 )
- return( 0 );
- else
- return( POLARSSL_ERR_RSA_VERIFY_FAILED );
- }
-
- if( len == hashlen && hash_id == SIG_RSA_RAW )
+ if( len == hashlen && md_alg == POLARSSL_MD_NONE )
{
if( memcmp( p, hash, hashlen ) == 0 )
return( 0 );
@@ -1240,7 +1111,62 @@
return( POLARSSL_ERR_RSA_VERIFY_FAILED );
}
- return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ md_info = md_info_from_type( md_alg );
+ if( md_info == NULL )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ hashlen = md_get_size( md_info );
+
+ end = p + len;
+
+ // Parse the ASN.1 structure inside the PKCS#1 v1.5 structure
+ //
+ if( ( ret = asn1_get_tag( &p, end, &asn1_len,
+ ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ if( asn1_len + 2 != len )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ if( ( ret = asn1_get_tag( &p, end, &asn1_len,
+ ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ if( asn1_len + 6 + hashlen != len )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ if( ( ret = asn1_get_tag( &p, end, &oid.len, ASN1_OID ) ) != 0 )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ oid.p = p;
+ p += oid.len;
+
+ if( oid_get_md_alg( &oid, &msg_md_alg ) != 0 )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ if( md_alg != msg_md_alg )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ /*
+ * assume the algorithm parameters must be NULL
+ */
+ if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_NULL ) ) != 0 )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ if( ( ret = asn1_get_tag( &p, end, &asn1_len, ASN1_OCTET_STRING ) ) != 0 )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ if( asn1_len != hashlen )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ if( memcmp( p, hash, hashlen ) != 0 )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ p += hashlen;
+
+ if( p != end )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ return( 0 );
}
/*
@@ -1248,7 +1174,7 @@
*/
int rsa_pkcs1_verify( rsa_context *ctx,
int mode,
- int hash_id,
+ md_type_t md_alg,
unsigned int hashlen,
const unsigned char *hash,
unsigned char *sig )
@@ -1256,12 +1182,12 @@
switch( ctx->padding )
{
case RSA_PKCS_V15:
- return rsa_rsassa_pkcs1_v15_verify( ctx, mode, hash_id,
+ return rsa_rsassa_pkcs1_v15_verify( ctx, mode, md_alg,
hashlen, hash, sig );
#if defined(POLARSSL_PKCS1_V21)
case RSA_PKCS_V21:
- return rsa_rsassa_pss_verify( ctx, mode, hash_id,
+ return rsa_rsassa_pss_verify( ctx, mode, md_alg,
hashlen, hash, sig );
#endif
@@ -1431,7 +1357,7 @@
sha1( rsa_plaintext, PT_LEN, sha1sum );
- if( rsa_pkcs1_sign( &rsa, NULL, NULL, RSA_PRIVATE, SIG_RSA_SHA1, 20,
+ if( rsa_pkcs1_sign( &rsa, NULL, NULL, RSA_PRIVATE, POLARSSL_MD_SHA1, 0,
sha1sum, rsa_ciphertext ) != 0 )
{
if( verbose != 0 )
@@ -1443,7 +1369,7 @@
if( verbose != 0 )
printf( "passed\n PKCS#1 sig. verify: " );
- if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1, 20,
+ if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, POLARSSL_MD_SHA1, 0,
sha1sum, rsa_ciphertext ) != 0 )
{
if( verbose != 0 )
diff --git a/library/ssl_cli.c b/library/ssl_cli.c
index 502a61a..9ad69dc 100644
--- a/library/ssl_cli.c
+++ b/library/ssl_cli.c
@@ -737,9 +737,7 @@
size_t n;
unsigned char *p, *end;
unsigned char hash[64];
- md5_context md5;
- sha1_context sha1;
- int hash_id = SIG_RSA_RAW;
+ md_type_t md_alg = POLARSSL_MD_NONE;
unsigned int hashlen = 0;
const ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info;
@@ -834,28 +832,28 @@
{
#if defined(POLARSSL_MD5_C)
case SSL_HASH_MD5:
- hash_id = SIG_RSA_MD5;
+ md_alg = POLARSSL_MD_MD5;
break;
#endif
#if defined(POLARSSL_SHA1_C)
case SSL_HASH_SHA1:
- hash_id = SIG_RSA_SHA1;
+ md_alg = POLARSSL_MD_SHA1;
break;
#endif
#if defined(POLARSSL_SHA2_C)
case SSL_HASH_SHA224:
- hash_id = SIG_RSA_SHA224;
+ md_alg = POLARSSL_MD_SHA224;
break;
case SSL_HASH_SHA256:
- hash_id = SIG_RSA_SHA256;
+ md_alg = POLARSSL_MD_SHA256;
break;
#endif
#if defined(POLARSSL_SHA4_C)
case SSL_HASH_SHA384:
- hash_id = SIG_RSA_SHA384;
+ md_alg = POLARSSL_MD_SHA384;
break;
case SSL_HASH_SHA512:
- hash_id = SIG_RSA_SHA512;
+ md_alg = POLARSSL_MD_SHA512;
break;
#endif
default:
@@ -917,6 +915,9 @@
if( ssl->minor_ver != SSL_MINOR_VERSION_3 )
{
+ md5_context md5;
+ sha1_context sha1;
+
/*
* digitally-signed struct {
* opaque md5_hash[16];
@@ -942,15 +943,12 @@
sha1_update( &sha1, ssl->in_msg + 4, n );
sha1_finish( &sha1, hash + 16 );
- hash_id = SIG_RSA_RAW;
+ md_alg = POLARSSL_MD_NONE;
hashlen = 36;
}
else
{
- sha2_context sha2;
-#if defined(POLARSSL_SHA4_C)
- sha4_context sha4;
-#endif
+ md_context_t ctx;
n = ssl->in_hslen - ( end - p ) - 8;
@@ -961,66 +959,23 @@
* ServerDHParams params;
* };
*/
- switch( hash_id )
+ if( ( ret = md_init_ctx( &ctx, md_info_from_type( md_alg ) ) ) != 0 )
{
-#if defined(POLARSSL_MD5_C)
- case SIG_RSA_MD5:
- md5_starts( &md5 );
- md5_update( &md5, ssl->handshake->randbytes, 64 );
- md5_update( &md5, ssl->in_msg + 4, n );
- md5_finish( &md5, hash );
- hashlen = 16;
- break;
-#endif
-#if defined(POLARSSL_SHA1_C)
- case SIG_RSA_SHA1:
- sha1_starts( &sha1 );
- sha1_update( &sha1, ssl->handshake->randbytes, 64 );
- sha1_update( &sha1, ssl->in_msg + 4, n );
- sha1_finish( &sha1, hash );
- hashlen = 20;
- break;
-#endif
-#if defined(POLARSSL_SHA2_C)
- case SIG_RSA_SHA224:
- sha2_starts( &sha2, 1 );
- sha2_update( &sha2, ssl->handshake->randbytes, 64 );
- sha2_update( &sha2, ssl->in_msg + 4, n );
- sha2_finish( &sha2, hash );
- hashlen = 28;
- break;
- case SIG_RSA_SHA256:
- sha2_starts( &sha2, 0 );
- sha2_update( &sha2, ssl->handshake->randbytes, 64 );
- sha2_update( &sha2, ssl->in_msg + 4, n );
- sha2_finish( &sha2, hash );
- hashlen = 32;
- break;
-#endif
-#if defined(POLARSSL_SHA4_C)
- case SIG_RSA_SHA384:
- sha4_starts( &sha4, 1 );
- sha4_update( &sha4, ssl->handshake->randbytes, 64 );
- sha4_update( &sha4, ssl->in_msg + 4, n );
- sha4_finish( &sha4, hash );
- hashlen = 48;
- break;
- case SIG_RSA_SHA512:
- sha4_starts( &sha4, 0 );
- sha4_update( &sha4, ssl->handshake->randbytes, 64 );
- sha4_update( &sha4, ssl->in_msg + 4, n );
- sha4_finish( &sha4, hash );
- hashlen = 64;
- break;
-#endif
+ SSL_DEBUG_RET( 1, "md_init_ctx", ret );
+ return( ret );
}
+
+ md_starts( &ctx );
+ md_update( &ctx, ssl->handshake->randbytes, 64 );
+ md_update( &ctx, ssl->in_msg + 4, n );
+ md_finish( &ctx, hash );
}
SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
if( ( ret = rsa_pkcs1_verify( &ssl->session_negotiate->peer_cert->rsa,
RSA_PUBLIC,
- hash_id, hashlen, hash, p ) ) != 0 )
+ md_alg, hashlen, hash, p ) ) != 0 )
{
SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret );
return( ret );
@@ -1327,8 +1282,8 @@
int ret = 0;
size_t n = 0, offset = 0;
unsigned char hash[48];
- int hash_id = SIG_RSA_RAW;
- unsigned int hashlen = 36;
+ md_type_t md_alg = POLARSSL_MD_NONE;
+ unsigned int hashlen = 0;
SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) );
@@ -1365,7 +1320,7 @@
* SHA(handshake_messages);
*/
hashlen = 36;
- hash_id = SIG_RSA_RAW;
+ md_alg = POLARSSL_MD_NONE;
}
else
{
@@ -1387,15 +1342,13 @@
if( ssl->transform_negotiate->ciphersuite_info->mac ==
POLARSSL_MD_SHA384 )
{
- hash_id = SIG_RSA_SHA384;
- hashlen = 48;
+ md_alg = POLARSSL_MD_SHA384;
ssl->out_msg[4] = SSL_HASH_SHA384;
ssl->out_msg[5] = SSL_SIG_RSA;
}
else
{
- hash_id = SIG_RSA_SHA256;
- hashlen = 32;
+ md_alg = POLARSSL_MD_SHA256;
ssl->out_msg[4] = SSL_HASH_SHA256;
ssl->out_msg[5] = SSL_SIG_RSA;
}
@@ -1412,7 +1365,7 @@
if( ssl->rsa_key )
{
ret = ssl->rsa_sign( ssl->rsa_key, ssl->f_rng, ssl->p_rng,
- RSA_PRIVATE, hash_id,
+ RSA_PRIVATE, md_alg,
hashlen, hash, ssl->out_msg + 6 + offset );
}
diff --git a/library/ssl_srv.c b/library/ssl_srv.c
index c7c7367..b94ac92 100644
--- a/library/ssl_srv.c
+++ b/library/ssl_srv.c
@@ -1128,7 +1128,7 @@
int ret;
size_t n, rsa_key_len = 0;
unsigned char hash[64];
- int hash_id = 0;
+ md_type_t md_alg = POLARSSL_MD_NONE;
unsigned int hashlen = 0;
const ssl_ciphersuite_t *ciphersuite_info;
@@ -1247,10 +1247,12 @@
sha1_finish( &sha1, hash + 16 );
hashlen = 36;
- hash_id = SIG_RSA_RAW;
+ md_alg = POLARSSL_MD_NONE;
}
else
{
+ md_context_t ctx;
+
/*
* digitally-signed struct {
* opaque client_random[32];
@@ -1258,84 +1260,49 @@
* ServerDHParams params;
* };
*/
-#if defined(POLARSSL_SHA4_C)
- if( ssl->handshake->sig_alg == SSL_HASH_SHA512 )
+ switch( ssl->handshake->sig_alg )
{
- sha4_context sha4;
-
- sha4_starts( &sha4, 0 );
- sha4_update( &sha4, ssl->handshake->randbytes, 64 );
- sha4_update( &sha4, ssl->out_msg + 4, n );
- sha4_finish( &sha4, hash );
-
- hashlen = 64;
- hash_id = SIG_RSA_SHA512;
- }
- else if( ssl->handshake->sig_alg == SSL_HASH_SHA384 )
- {
- sha4_context sha4;
-
- sha4_starts( &sha4, 1 );
- sha4_update( &sha4, ssl->handshake->randbytes, 64 );
- sha4_update( &sha4, ssl->out_msg + 4, n );
- sha4_finish( &sha4, hash );
-
- hashlen = 48;
- hash_id = SIG_RSA_SHA384;
- }
- else
+#if defined(POLARSSL_MD5_C)
+ case SSL_HASH_MD5:
+ md_alg = POLARSSL_MD_MD5;
+ break;
+#endif
+#if defined(POLARSSL_SHA1_C)
+ case SSL_HASH_SHA1:
+ md_alg = POLARSSL_MD_SHA1;
+ break;
#endif
#if defined(POLARSSL_SHA2_C)
- if( ssl->handshake->sig_alg == SSL_HASH_SHA256 )
- {
- sha2_context sha2;
-
- sha2_starts( &sha2, 0 );
- sha2_update( &sha2, ssl->handshake->randbytes, 64 );
- sha2_update( &sha2, ssl->out_msg + 4, n );
- sha2_finish( &sha2, hash );
-
- hashlen = 32;
- hash_id = SIG_RSA_SHA256;
- }
- else if( ssl->handshake->sig_alg == SSL_HASH_SHA224 )
- {
- sha2_context sha2;
-
- sha2_starts( &sha2, 1 );
- sha2_update( &sha2, ssl->handshake->randbytes, 64 );
- sha2_update( &sha2, ssl->out_msg + 4, n );
- sha2_finish( &sha2, hash );
-
- hashlen = 24;
- hash_id = SIG_RSA_SHA224;
- }
- else
+ case SSL_HASH_SHA224:
+ md_alg = POLARSSL_MD_SHA224;
+ break;
+ case SSL_HASH_SHA256:
+ md_alg = POLARSSL_MD_SHA256;
+ break;
#endif
- if( ssl->handshake->sig_alg == SSL_HASH_SHA1 )
- {
- sha1_context sha1;
-
- sha1_starts( &sha1 );
- sha1_update( &sha1, ssl->handshake->randbytes, 64 );
- sha1_update( &sha1, ssl->out_msg + 4, n );
- sha1_finish( &sha1, hash );
-
- hashlen = 20;
- hash_id = SIG_RSA_SHA1;
+#if defined(POLARSSL_SHA4_C)
+ case SSL_HASH_SHA384:
+ md_alg = POLARSSL_MD_SHA384;
+ break;
+ case SSL_HASH_SHA512:
+ md_alg = POLARSSL_MD_SHA512;
+ break;
+#endif
+ default:
+ /* Should never happen */
+ return( -1 );
}
- else if( ssl->handshake->sig_alg == SSL_HASH_MD5 )
+
+ if( ( ret = md_init_ctx( &ctx, md_info_from_type( md_alg ) ) ) != 0 )
{
- md5_context md5;
-
- md5_starts( &md5 );
- md5_update( &md5, ssl->handshake->randbytes, 64 );
- md5_update( &md5, ssl->out_msg + 4, n );
- md5_finish( &md5, hash );
-
- hashlen = 16;
- hash_id = SIG_RSA_MD5;
+ SSL_DEBUG_RET( 1, "md_init_ctx", ret );
+ return( ret );
}
+
+ md_starts( &ctx );
+ md_update( &ctx, ssl->handshake->randbytes, 64 );
+ md_update( &ctx, ssl->out_msg + 4, n );
+ md_finish( &ctx, hash );
}
SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen );
@@ -1358,7 +1325,7 @@
{
ret = ssl->rsa_sign( ssl->rsa_key, ssl->f_rng, ssl->p_rng,
RSA_PRIVATE,
- hash_id, hashlen, hash,
+ md_alg, hashlen, hash,
ssl->out_msg + 6 + n );
}
@@ -1594,8 +1561,8 @@
int ret;
size_t n = 0, n1, n2;
unsigned char hash[48];
- int hash_id;
- unsigned int hashlen;
+ md_type_t md_alg = POLARSSL_MD_NONE;
+ unsigned int hashlen = 0;
SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) );
@@ -1642,22 +1609,16 @@
}
if( ssl->handshake->verify_sig_alg == SSL_HASH_SHA384 )
- {
- hashlen = 48;
- hash_id = SIG_RSA_SHA384;
- }
+ md_alg = POLARSSL_MD_SHA384;
else
- {
- hashlen = 32;
- hash_id = SIG_RSA_SHA256;
- }
+ md_alg = POLARSSL_MD_SHA256;
n += 2;
}
else
{
hashlen = 36;
- hash_id = SIG_RSA_RAW;
+ md_alg = POLARSSL_MD_NONE;
}
n1 = ssl->session_negotiate->peer_cert->rsa.len;
@@ -1670,7 +1631,7 @@
}
ret = rsa_pkcs1_verify( &ssl->session_negotiate->peer_cert->rsa, RSA_PUBLIC,
- hash_id, hashlen, hash, ssl->in_msg + 6 + n );
+ md_alg, hashlen, hash, ssl->in_msg + 6 + n );
if( ret != 0 )
{
SSL_DEBUG_RET( 1, "rsa_pkcs1_verify", ret );
diff --git a/library/x509parse.c b/library/x509parse.c
index bac0e93..3e99bdc 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -40,6 +40,7 @@
#include "polarssl/x509.h"
#include "polarssl/asn1.h"
+#include "polarssl/oid.h"
#include "polarssl/pem.h"
#include "polarssl/des.h"
#if defined(POLARSSL_MD2_C)
@@ -438,9 +439,10 @@
x509_buf *pk_alg_oid,
mpi *N, mpi *E )
{
- int ret, can_handle;
+ int ret;
size_t len;
unsigned char *end2;
+ pk_type_t pk_alg = POLARSSL_PK_NONE;
if( ( ret = x509_get_alg( p, end, pk_alg_oid ) ) != 0 )
return( ret );
@@ -448,27 +450,7 @@
/*
* only RSA public keys handled at this time
*/
- can_handle = 0;
-
- if( pk_alg_oid->len == 9 &&
- memcmp( pk_alg_oid->p, OID_PKCS1_RSA, 9 ) == 0 )
- can_handle = 1;
-
- if( pk_alg_oid->len == 9 &&
- memcmp( pk_alg_oid->p, OID_PKCS1, 8 ) == 0 )
- {
- if( pk_alg_oid->p[8] >= 2 && pk_alg_oid->p[8] <= 5 )
- can_handle = 1;
-
- if ( pk_alg_oid->p[8] >= 11 && pk_alg_oid->p[8] <= 14 )
- can_handle = 1;
- }
-
- if( pk_alg_oid->len == 5 &&
- memcmp( pk_alg_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
- can_handle = 1;
-
- if( can_handle == 0 )
+ if( oid_get_pk_alg( pk_alg_oid, &pk_alg ) != 0 )
return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
if( ( ret = asn1_get_tag( p, end, &len, ASN1_BIT_STRING ) ) != 0 )
@@ -936,6 +918,7 @@
*/
x509_buf extn_oid = {0, 0, NULL};
int is_critical = 0; /* DEFAULT FALSE */
+ int ext_type = 0;
if( ( ret = asn1_get_tag( p, end, &len,
ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
@@ -975,52 +958,9 @@
/*
* Detect supported extensions
*/
- if( ( OID_SIZE( OID_BASIC_CONSTRAINTS ) == extn_oid.len ) &&
- memcmp( extn_oid.p, OID_BASIC_CONSTRAINTS, extn_oid.len ) == 0 )
- {
- /* Parse basic constraints */
- if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
- &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
- return ( ret );
- crt->ext_types |= EXT_BASIC_CONSTRAINTS;
- }
- else if( ( OID_SIZE( OID_NS_CERT_TYPE ) == extn_oid.len ) &&
- memcmp( extn_oid.p, OID_NS_CERT_TYPE, extn_oid.len ) == 0 )
- {
- /* Parse netscape certificate type */
- if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
- &crt->ns_cert_type ) ) != 0 )
- return ( ret );
- crt->ext_types |= EXT_NS_CERT_TYPE;
- }
- else if( ( OID_SIZE( OID_KEY_USAGE ) == extn_oid.len ) &&
- memcmp( extn_oid.p, OID_KEY_USAGE, extn_oid.len ) == 0 )
- {
- /* Parse key usage */
- if( ( ret = x509_get_key_usage( p, end_ext_octet,
- &crt->key_usage ) ) != 0 )
- return ( ret );
- crt->ext_types |= EXT_KEY_USAGE;
- }
- else if( ( OID_SIZE( OID_EXTENDED_KEY_USAGE ) == extn_oid.len ) &&
- memcmp( extn_oid.p, OID_EXTENDED_KEY_USAGE, extn_oid.len ) == 0 )
- {
- /* Parse extended key usage */
- if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
- &crt->ext_key_usage ) ) != 0 )
- return ( ret );
- crt->ext_types |= EXT_EXTENDED_KEY_USAGE;
- }
- else if( ( OID_SIZE( OID_SUBJECT_ALT_NAME ) == extn_oid.len ) &&
- memcmp( extn_oid.p, OID_SUBJECT_ALT_NAME, extn_oid.len ) == 0 )
- {
- /* Parse extended key usage */
- if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
- &crt->subject_alt_names ) ) != 0 )
- return ( ret );
- crt->ext_types |= EXT_SUBJECT_ALT_NAME;
- }
- else
+ ret = oid_get_x509_ext_type( &extn_oid, &ext_type );
+
+ if( ret != 0 )
{
/* No parser found, skip extension */
*p = end_ext_octet;
@@ -1033,6 +973,50 @@
POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
}
#endif
+ continue;
+ }
+
+ crt->ext_types |= ext_type;
+
+ switch( ext_type )
+ {
+ case EXT_BASIC_CONSTRAINTS:
+ /* Parse basic constraints */
+ if( ( ret = x509_get_basic_constraints( p, end_ext_octet,
+ &crt->ca_istrue, &crt->max_pathlen ) ) != 0 )
+ return ( ret );
+ break;
+
+ case EXT_KEY_USAGE:
+ /* Parse key usage */
+ if( ( ret = x509_get_key_usage( p, end_ext_octet,
+ &crt->key_usage ) ) != 0 )
+ return ( ret );
+ break;
+
+ case EXT_EXTENDED_KEY_USAGE:
+ /* Parse extended key usage */
+ if( ( ret = x509_get_ext_key_usage( p, end_ext_octet,
+ &crt->ext_key_usage ) ) != 0 )
+ return ( ret );
+ break;
+
+ case EXT_SUBJECT_ALT_NAME:
+ /* Parse subject alt name */
+ if( ( ret = x509_get_subject_alt_name( p, end_ext_octet,
+ &crt->subject_alt_names ) ) != 0 )
+ return ( ret );
+ break;
+
+ case EXT_NS_CERT_TYPE:
+ /* Parse netscape certificate type */
+ if( ( ret = x509_get_ns_cert_type( p, end_ext_octet,
+ &crt->ns_cert_type ) ) != 0 )
+ return ( ret );
+ break;
+
+ default:
+ return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
}
}
@@ -1108,33 +1092,15 @@
return( 0 );
}
-static int x509_get_sig_alg( const x509_buf *sig_oid, int *sig_alg )
+static int x509_get_sig_alg( const x509_buf *sig_oid, md_type_t *md_alg,
+ pk_type_t *pk_alg )
{
- if( sig_oid->len == 9 &&
- memcmp( sig_oid->p, OID_PKCS1, 8 ) == 0 )
- {
- if( sig_oid->p[8] >= 2 && sig_oid->p[8] <= 5 )
- {
- *sig_alg = sig_oid->p[8];
- return( 0 );
- }
+ int ret = oid_get_sig_alg( sig_oid, md_alg, pk_alg );
- if ( sig_oid->p[8] >= 11 && sig_oid->p[8] <= 14 )
- {
- *sig_alg = sig_oid->p[8];
- return( 0 );
- }
+ if( ret != 0 )
+ return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG + ret );
- return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
- }
- if( sig_oid->len == 5 &&
- memcmp( sig_oid->p, OID_RSA_SHA_OBS, 5 ) == 0 )
- {
- *sig_alg = SIG_RSA_SHA1;
- return( 0 );
- }
-
- return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
+ return( 0 );
}
/*
@@ -1224,7 +1190,8 @@
return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
}
- if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_alg ) ) != 0 )
+ if( ( ret = x509_get_sig_alg( &crt->sig_oid1, &crt->sig_md,
+ &crt->sig_pk ) ) != 0 )
{
x509_free( crt );
return( ret );
@@ -1693,7 +1660,8 @@
return( POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION );
}
- if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_alg ) ) != 0 )
+ if( ( ret = x509_get_sig_alg( &crl->sig_oid1, &crl->sig_md,
+ &crl->sig_pk ) ) != 0 )
{
x509_crl_free( crl );
return( POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG );
@@ -2160,32 +2128,12 @@
}
else
{
- int can_handle;
+ pk_type_t pk_alg = POLARSSL_PK_NONE;
/*
* only RSA keys handled at this time
*/
- can_handle = 0;
-
- if( pk_alg_oid.len == 9 &&
- memcmp( pk_alg_oid.p, OID_PKCS1_RSA, 9 ) == 0 )
- can_handle = 1;
-
- if( pk_alg_oid.len == 9 &&
- memcmp( pk_alg_oid.p, OID_PKCS1, 8 ) == 0 )
- {
- if( pk_alg_oid.p[8] >= 2 && pk_alg_oid.p[8] <= 5 )
- can_handle = 1;
-
- if ( pk_alg_oid.p[8] >= 11 && pk_alg_oid.p[8] <= 14 )
- can_handle = 1;
- }
-
- if( pk_alg_oid.len == 5 &&
- memcmp( pk_alg_oid.p, OID_RSA_SHA_OBS, 5 ) == 0 )
- can_handle = 1;
-
- if( can_handle == 0 )
+ if( oid_get_pk_alg( &pk_alg_oid, &pk_alg ) != 0 )
return( POLARSSL_ERR_X509_UNKNOWN_PK_ALG );
/*
@@ -2501,7 +2449,7 @@
* This fuction tries to 'fix' this by at least suggesting enlarging the
* size by 20.
*/
-int compat_snprintf(char *str, size_t size, const char *format, ...)
+static int compat_snprintf(char *str, size_t size, const char *format, ...)
{
va_list ap;
int res = -1;
@@ -2548,6 +2496,7 @@
size_t i, n;
unsigned char c;
const x509_name *name;
+ const char *short_name = NULL;
char s[128], *p;
memset( s, 0, sizeof( s ) );
@@ -2570,56 +2519,13 @@
SAFE_SNPRINTF();
}
- if( name->oid.len == 3 &&
- memcmp( name->oid.p, OID_X520, 2 ) == 0 )
- {
- switch( name->oid.p[2] )
- {
- case X520_COMMON_NAME:
- ret = snprintf( p, n, "CN=" ); break;
+ ret = oid_get_attr_short_name( &name->oid, &short_name );
- case X520_COUNTRY:
- ret = snprintf( p, n, "C=" ); break;
-
- case X520_LOCALITY:
- ret = snprintf( p, n, "L=" ); break;
-
- case X520_STATE:
- ret = snprintf( p, n, "ST=" ); break;
-
- case X520_ORGANIZATION:
- ret = snprintf( p, n, "O=" ); break;
-
- case X520_ORG_UNIT:
- ret = snprintf( p, n, "OU=" ); break;
-
- default:
- ret = snprintf( p, n, "0x%02X=",
- name->oid.p[2] );
- break;
- }
- SAFE_SNPRINTF();
- }
- else if( name->oid.len == 9 &&
- memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
- {
- switch( name->oid.p[8] )
- {
- case PKCS9_EMAIL:
- ret = snprintf( p, n, "emailAddress=" ); break;
-
- default:
- ret = snprintf( p, n, "0x%02X=",
- name->oid.p[8] );
- break;
- }
- SAFE_SNPRINTF();
- }
+ if( ret == 0 )
+ ret = snprintf( p, n, "%s=", short_name );
else
- {
ret = snprintf( p, n, "\?\?=" );
- SAFE_SNPRINTF();
- }
+ SAFE_SNPRINTF();
for( i = 0; i < name->val.len; i++ )
{
@@ -2633,7 +2539,7 @@
}
s[i] = '\0';
ret = snprintf( p, n, "%s", s );
- SAFE_SNPRINTF();
+ SAFE_SNPRINTF();
name = name->next;
}
@@ -2684,6 +2590,7 @@
int ret;
size_t n;
char *p;
+ const char *desc = NULL;
p = buf;
n = size;
@@ -2722,21 +2629,14 @@
crt->valid_to.min, crt->valid_to.sec );
SAFE_SNPRINTF();
- ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
+ ret = snprintf( p, n, "\n%ssigned using : ", prefix );
SAFE_SNPRINTF();
- switch( crt->sig_alg )
- {
- case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
- case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
- case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
- case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
- case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
- case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
- case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
- case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
- default: ret = snprintf( p, n, "???" ); break;
- }
+ ret = oid_get_sig_alg_desc( &crt->sig_oid1, &desc );
+ if( ret != 0 )
+ ret = snprintf( p, n, "???" );
+ else
+ ret = snprintf( p, n, desc );
SAFE_SNPRINTF();
ret = snprintf( p, n, "\n%sRSA key size : %d bits\n", prefix,
@@ -2746,75 +2646,26 @@
return( (int) ( size - n ) );
}
-/* Compare a given OID string with an OID x509_buf * */
-#define OID_CMP(oid_str, oid_buf) \
- ( ( OID_SIZE(oid_str) == (oid_buf)->len ) && \
- memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) == 0)
-
/*
* Return an informational string describing the given OID
*/
const char *x509_oid_get_description( x509_buf *oid )
{
- if ( oid == NULL )
- return ( NULL );
+ const char *desc = NULL;
+ int ret;
- else if( OID_CMP( OID_SERVER_AUTH, oid ) )
- return( STRING_SERVER_AUTH );
-
- else if( OID_CMP( OID_CLIENT_AUTH, oid ) )
- return( STRING_CLIENT_AUTH );
-
- else if( OID_CMP( OID_CODE_SIGNING, oid ) )
- return( STRING_CODE_SIGNING );
-
- else if( OID_CMP( OID_EMAIL_PROTECTION, oid ) )
- return( STRING_EMAIL_PROTECTION );
-
- else if( OID_CMP( OID_TIME_STAMPING, oid ) )
- return( STRING_TIME_STAMPING );
+ ret = oid_get_extended_key_usage( oid, &desc );
- else if( OID_CMP( OID_OCSP_SIGNING, oid ) )
- return( STRING_OCSP_SIGNING );
+ if( ret != 0 )
+ return( NULL );
- return( NULL );
+ return( desc );
}
/* Return the x.y.z.... style numeric string for the given OID */
int x509_oid_get_numeric_string( char *buf, size_t size, x509_buf *oid )
{
- int ret;
- size_t i, n;
- unsigned int value;
- char *p;
-
- p = buf;
- n = size;
-
- /* First byte contains first two dots */
- if( oid->len > 0 )
- {
- ret = snprintf( p, n, "%d.%d", oid->p[0]/40, oid->p[0]%40 );
- SAFE_SNPRINTF();
- }
-
- /* TODO: value can overflow in value. */
- value = 0;
- for( i = 1; i < oid->len; i++ )
- {
- value <<= 7;
- value += oid->p[i] & 0x7F;
-
- if( !( oid->p[i] & 0x80 ) )
- {
- /* Last byte */
- ret = snprintf( p, n, ".%d", value );
- SAFE_SNPRINTF();
- value = 0;
- }
- }
-
- return( (int) ( size - n ) );
+ return oid_get_numeric_string( buf, size, oid );
}
/*
@@ -2826,6 +2677,7 @@
int ret;
size_t n;
char *p;
+ const char *desc;
const x509_crl_entry *entry;
p = buf;
@@ -2879,21 +2731,14 @@
entry = entry->next;
}
- ret = snprintf( p, n, "\n%ssigned using : RSA+", prefix );
+ ret = snprintf( p, n, "\n%ssigned using : ", prefix );
SAFE_SNPRINTF();
- switch( crl->sig_alg )
- {
- case SIG_RSA_MD2 : ret = snprintf( p, n, "MD2" ); break;
- case SIG_RSA_MD4 : ret = snprintf( p, n, "MD4" ); break;
- case SIG_RSA_MD5 : ret = snprintf( p, n, "MD5" ); break;
- case SIG_RSA_SHA1 : ret = snprintf( p, n, "SHA1" ); break;
- case SIG_RSA_SHA224 : ret = snprintf( p, n, "SHA224" ); break;
- case SIG_RSA_SHA256 : ret = snprintf( p, n, "SHA256" ); break;
- case SIG_RSA_SHA384 : ret = snprintf( p, n, "SHA384" ); break;
- case SIG_RSA_SHA512 : ret = snprintf( p, n, "SHA512" ); break;
- default: ret = snprintf( p, n, "???" ); break;
- }
+ ret = oid_get_sig_alg_desc( &crl->sig_oid1, &desc );
+ if( ret != 0 )
+ ret = snprintf( p, n, "???" );
+ else
+ ret = snprintf( p, n, desc );
SAFE_SNPRINTF();
ret = snprintf( p, n, "\n" );
@@ -2995,48 +2840,14 @@
}
/*
- * Wrapper for x509 hashes.
- */
-static void x509_hash( const unsigned char *in, size_t len, int alg,
- unsigned char *out )
-{
- switch( alg )
- {
-#if defined(POLARSSL_MD2_C)
- case SIG_RSA_MD2 : md2( in, len, out ); break;
-#endif
-#if defined(POLARSSL_MD4_C)
- case SIG_RSA_MD4 : md4( in, len, out ); break;
-#endif
-#if defined(POLARSSL_MD5_C)
- case SIG_RSA_MD5 : md5( in, len, out ); break;
-#endif
-#if defined(POLARSSL_SHA1_C)
- case SIG_RSA_SHA1 : sha1( in, len, out ); break;
-#endif
-#if defined(POLARSSL_SHA2_C)
- case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
- case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
-#endif
-#if defined(POLARSSL_SHA4_C)
- case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
- case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
-#endif
- default:
- memset( out, '\xFF', 64 );
- break;
- }
-}
-
-/*
* Check that the given certificate is valid accoring to the CRL.
*/
static int x509parse_verifycrl(x509_cert *crt, x509_cert *ca,
x509_crl *crl_list)
{
int flags = 0;
- int hash_id;
- unsigned char hash[64];
+ unsigned char hash[POLARSSL_MD_MAX_SIZE];
+ const md_info_t *md_info;
if( ca == NULL )
return( flags );
@@ -3061,11 +2872,19 @@
/*
* Check if CRL is correctly signed by the trusted CA
*/
- hash_id = crl_list->sig_alg;
+ md_info = md_info_from_type( crl_list->sig_md );
+ if( md_info == NULL )
+ {
+ /*
+ * Cannot check 'unknown' hash
+ */
+ flags |= BADCRL_NOT_TRUSTED;
+ break;
+ }
- x509_hash( crl_list->tbs.p, crl_list->tbs.len, hash_id, hash );
+ md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash );
- if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, hash_id,
+ if( !rsa_pkcs1_verify( &ca->rsa, RSA_PUBLIC, crl_list->sig_md,
0, hash, crl_list->sig.p ) == 0 )
{
/*
@@ -3130,9 +2949,10 @@
int (*f_vrfy)(void *, x509_cert *, int, int *),
void *p_vrfy )
{
- int hash_id, ret;
+ int ret;
int ca_flags = 0, check_path_cnt = path_cnt + 1;
- unsigned char hash[64];
+ unsigned char hash[POLARSSL_MD_MAX_SIZE];
+ const md_info_t *md_info;
if( x509parse_time_expired( &child->valid_to ) )
*flags |= BADCERT_EXPIRED;
@@ -3171,11 +2991,18 @@
continue;
}
- hash_id = child->sig_alg;
+ md_info = md_info_from_type( child->sig_md );
+ if( md_info == NULL )
+ {
+ /*
+ * Cannot check 'unknown' hash
+ */
+ continue;
+ }
- x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
+ md( md_info, child->tbs.p, child->tbs.len, hash );
- if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, hash_id,
+ if( rsa_pkcs1_verify( &trust_ca->rsa, RSA_PUBLIC, child->sig_md,
0, hash, child->sig.p ) != 0 )
{
trust_ca = trust_ca->next;
@@ -3230,22 +3057,32 @@
int (*f_vrfy)(void *, x509_cert *, int, int *),
void *p_vrfy )
{
- int hash_id, ret;
+ int ret;
int parent_flags = 0;
- unsigned char hash[64];
+ unsigned char hash[POLARSSL_MD_MAX_SIZE];
x509_cert *grandparent;
+ const md_info_t *md_info;
if( x509parse_time_expired( &child->valid_to ) )
*flags |= BADCERT_EXPIRED;
- hash_id = child->sig_alg;
-
- x509_hash( child->tbs.p, child->tbs.len, hash_id, hash );
-
- if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, hash_id, 0, hash,
- child->sig.p ) != 0 )
+ md_info = md_info_from_type( child->sig_md );
+ if( md_info == NULL )
+ {
+ /*
+ * Cannot check 'unknown' hash
+ */
*flags |= BADCERT_NOT_TRUSTED;
-
+ }
+ else
+ {
+ md( md_info, child->tbs.p, child->tbs.len, hash );
+
+ if( rsa_pkcs1_verify( &parent->rsa, RSA_PUBLIC, child->sig_md, 0, hash,
+ child->sig.p ) != 0 )
+ *flags |= BADCERT_NOT_TRUSTED;
+ }
+
/* Check trusted CA's CRL for the given crt */
*flags |= x509parse_verifycrl(child, parent, ca_crl);
@@ -3340,8 +3177,7 @@
{
while( name != NULL )
{
- if( name->oid.len == 3 &&
- memcmp( name->oid.p, OID_CN, 3 ) == 0 )
+ if( OID_CMP( OID_AT_CN, &name->oid ) )
{
if( name->val.len == cn_len &&
memcmp( name->val.p, cn, cn_len ) == 0 )
diff --git a/library/x509write.c b/library/x509write.c
index 026afe6..cf68b02 100644
--- a/library/x509write.c
+++ b/library/x509write.c
@@ -30,24 +30,8 @@
#include "polarssl/asn1write.h"
#include "polarssl/x509write.h"
#include "polarssl/x509.h"
-#if defined(POLARSSL_MD2_C)
-#include "polarssl/md2.h"
-#endif
-#if defined(POLARSSL_MD4_C)
-#include "polarssl/md4.h"
-#endif
-#if defined(POLARSSL_MD5_C)
-#include "polarssl/md5.h"
-#endif
-#if defined(POLARSSL_SHA1_C)
-#include "polarssl/sha1.h"
-#endif
-#if defined(POLARSSL_SHA2_C)
-#include "polarssl/sha2.h"
-#endif
-#if defined(POLARSSL_SHA4_C)
-#include "polarssl/sha4.h"
-#endif
+#include "polarssl/md.h"
+#include "polarssl/oid.h"
int x509_write_pubkey_der( unsigned char *buf, size_t size, rsa_context *rsa )
{
@@ -157,41 +141,7 @@
return( len );
}
-/*
- * Wrapper for x509 hashes.
- */
-static void x509_hash( const unsigned char *in, size_t len, int alg,
- unsigned char *out )
-{
- switch( alg )
- {
-#if defined(POLARSSL_MD2_C)
- case SIG_RSA_MD2 : md2( in, len, out ); break;
-#endif
-#if defined(POLARSSL_MD4_C)
- case SIG_RSA_MD4 : md4( in, len, out ); break;
-#endif
-#if defined(POLARSSL_MD5_C)
- case SIG_RSA_MD5 : md5( in, len, out ); break;
-#endif
-#if defined(POLARSSL_SHA1_C)
- case SIG_RSA_SHA1 : sha1( in, len, out ); break;
-#endif
-#if defined(POLARSSL_SHA2_C)
- case SIG_RSA_SHA224 : sha2( in, len, out, 1 ); break;
- case SIG_RSA_SHA256 : sha2( in, len, out, 0 ); break;
-#endif
-#if defined(POLARSSL_SHA4_C)
- case SIG_RSA_SHA384 : sha4( in, len, out, 1 ); break;
- case SIG_RSA_SHA512 : sha4( in, len, out, 0 ); break;
-#endif
- default:
- memset( out, '\xFF', 64 );
- break;
- }
-}
-
-int x509_write_sig( unsigned char **p, unsigned char *start, char *oid,
+int x509_write_sig( unsigned char **p, unsigned char *start, const char *oid,
unsigned char *sig, size_t size )
{
int ret;
@@ -218,10 +168,10 @@
}
int x509_write_cert_req( unsigned char *buf, size_t size, rsa_context *rsa,
- x509_req_name *req_name, int hash_id )
+ x509_req_name *req_name, md_type_t md_alg )
{
int ret;
- char sig_oid[10];
+ const char *sig_oid;
unsigned char *c, *c2;
unsigned char hash[64];
unsigned char sig[POLARSSL_MPI_MAX_SIZE];
@@ -272,15 +222,13 @@
ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
- x509_hash( c, len, hash_id, hash );
+ md( md_info_from_type( md_alg ), c, len, hash );
- rsa_pkcs1_sign( rsa, NULL, NULL, RSA_PRIVATE, hash_id, 0, hash, sig );
+ rsa_pkcs1_sign( rsa, NULL, NULL, RSA_PRIVATE, md_alg, 0, hash, sig );
// Generate correct OID
//
- memcpy( sig_oid, OID_PKCS1, 8 );
- sig_oid[8] = hash_id;
- sig_oid[9] = '\0';
+ ret = oid_get_oid_by_sig_alg( POLARSSL_PK_RSA, md_alg, &sig_oid );
c2 = buf + size - 1;
ASN1_CHK_ADD( sig_len, x509_write_sig( &c2, buf, sig_oid, sig, rsa->len ) );