From 40ce79f1e6c57ba6e9c5fe5ea54c37d361f719a6 Mon Sep 17 00:00:00 2001
From: Paul Bakker
Date: Sun, 15 Sep 2013 17:43:54 +0200
Subject: [PATCH] Moved DHM parsing from X509 module to DHM module
---
include/polarssl/dhm.h | 31 +++++
include/polarssl/error.h | 2 +-
include/polarssl/x509.h | 25 ----
library/dhm.c | 187 ++++++++++++++++++++++++++-
library/error.c | 6 +
library/x509parse.c | 129 +-----------------
programs/test/selftest.c | 6 +
tests/suites/test_suite_dhm.data | 3 +
tests/suites/test_suite_dhm.function | 7 +
9 files changed, 241 insertions(+), 155 deletions(-)
diff --git a/include/polarssl/dhm.h b/include/polarssl/dhm.h
index 09de70b0e..0152dc9fe 100644
--- a/include/polarssl/dhm.h
+++ b/include/polarssl/dhm.h
@@ -38,6 +38,9 @@
#define POLARSSL_ERR_DHM_READ_PUBLIC_FAILED -0x3200 /**< Reading of the public values failed. */
#define POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED -0x3280 /**< Making of the public value failed. */
#define POLARSSL_ERR_DHM_CALC_SECRET_FAILED -0x3300 /**< Calculation of the DHM secret failed. */
+#define POLARSSL_ERR_DHM_INVALID_FORMAT -0x3380 /**< The ASN.1 data is not formatted correctly. */
+#define POLARSSL_ERR_DHM_MALLOC_FAILED -0x3400 /**< Allocation of memory failed. */
+#define POLARSSL_ERR_DHM_FILE_IO_ERROR -0x3480 /**< Read/write of file failed. */
/**
* RFC 3526 defines a number of standardized Diffie-Hellman groups
@@ -245,6 +248,34 @@ int dhm_calc_secret( dhm_context *ctx,
*/
void dhm_free( dhm_context *ctx );
+#if defined(POLARSSL_ASN1_PARSE_C)
+/** \ingroup x509_module */
+/**
+ * \brief Parse DHM parameters
+ *
+ * \param dhm DHM context to be initialized
+ * \param dhmin input buffer
+ * \param dhminlen size of the buffer
+ *
+ * \return 0 if successful, or a specific DHM or PEM error code
+ */
+int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin,
+ size_t dhminlen );
+
+#if defined(POLARSSL_FS_IO)
+/** \ingroup x509_module */
+/**
+ * \brief Load and parse DHM parameters
+ *
+ * \param dhm DHM context to be initialized
+ * \param path filename to read the DHM Parameters from
+ *
+ * \return 0 if successful, or a specific DHM or PEM error code
+ */
+int dhm_parse_dhmfile( dhm_context *dhm, const char *path );
+#endif /* POLARSSL_FS_IO */
+#endif /* POLARSSL_ASN1_PARSE_C */
+
/**
* \brief Checkup routine
*
diff --git a/include/polarssl/error.h b/include/polarssl/error.h
index 8279df5b4..205a105a9 100644
--- a/include/polarssl/error.h
+++ b/include/polarssl/error.h
@@ -78,7 +78,7 @@
* PKCS#12 1 4 (Started from top)
* X509 2 18
* PK 2 13 (Started from top)
- * DHM 3 6
+ * DHM 3 9
* PKCS5 3 4 (Started from top)
* RSA 4 9
* ECP 4 4 (Started from top)
diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h
index 3b5395a71..2fa00f6c6 100644
--- a/include/polarssl/x509.h
+++ b/include/polarssl/x509.h
@@ -472,31 +472,6 @@ int x509parse_public_keyfile_rsa( rsa_context *rsa, const char *path );
#endif /* POLARSSL_FS_IO */
#endif /* POLARSSL_RSA_C */
-/** \ingroup x509_module */
-/**
- * \brief Parse DHM parameters
- *
- * \param dhm DHM context to be initialized
- * \param dhmin input buffer
- * \param dhminlen size of the buffer
- *
- * \return 0 if successful, or a specific X509 or PEM error code
- */
-int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen );
-
-#if defined(POLARSSL_FS_IO)
-/** \ingroup x509_module */
-/**
- * \brief Load and parse DHM parameters
- *
- * \param dhm DHM context to be initialized
- * \param path filename to read the DHM Parameters from
- *
- * \return 0 if successful, or a specific X509 or PEM error code
- */
-int x509parse_dhmfile( dhm_context *dhm, const char *path );
-#endif /* POLARSSL_FS_IO */
-
/** \} name Functions to read in DHM parameters, a certificate, CRL or private RSA key */
/**
diff --git a/library/dhm.c b/library/dhm.c
index f43b047c3..98c8e9f86 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -34,6 +34,22 @@
#include "polarssl/dhm.h"
+#if defined(POLARSSL_PEM_C)
+#include "polarssl/pem.h"
+#endif
+
+#if defined(POLARSSL_ASN1_PARSE_C)
+#include "polarssl/asn1.h"
+#endif
+
+#if defined(POLARSSL_MEMORY_C)
+#include "polarssl/memory.h"
+#else
+#include
+#define polarssl_malloc malloc
+#define polarssl_free free
+#endif
+
/*
* helper to validate the mpi size and import it
*/
@@ -372,14 +388,183 @@ void dhm_free( dhm_context *ctx )
memset( ctx, 0, sizeof( dhm_context ) );
}
+#if defined(POLARSSL_ASN1_PARSE_C)
+/*
+ * Parse DHM parameters
+ */
+int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
+{
+ int ret;
+ size_t len;
+ unsigned char *p, *end;
+#if defined(POLARSSL_PEM_C)
+ pem_context pem;
+
+ pem_init( &pem );
+ memset( dhm, 0, sizeof( dhm_context ) );
+
+ ret = pem_read_buffer( &pem,
+ "-----BEGIN DH PARAMETERS-----",
+ "-----END DH PARAMETERS-----",
+ dhmin, NULL, 0, &dhminlen );
+
+ if( ret == 0 )
+ {
+ /*
+ * Was PEM encoded
+ */
+ dhminlen = pem.buflen;
+ }
+ else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+ goto exit;
+
+ p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
+#else
+ p = (unsigned char *) dhmin;
+#endif
+ end = p + dhminlen;
+
+ /*
+ * DHParams ::= SEQUENCE {
+ * prime INTEGER, -- P
+ * generator INTEGER, -- g
+ * }
+ */
+ if( ( ret = asn1_get_tag( &p, end, &len,
+ ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
+ {
+ ret = POLARSSL_ERR_DHM_INVALID_FORMAT + ret;
+ goto exit;
+ }
+
+ end = p + len;
+
+ if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
+ ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
+ {
+ ret = POLARSSL_ERR_DHM_INVALID_FORMAT + ret;
+ goto exit;
+ }
+
+ if( p != end )
+ {
+ ret = POLARSSL_ERR_DHM_INVALID_FORMAT +
+ POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
+ goto exit;
+ }
+
+ ret = 0;
+
+exit:
+#if defined(POLARSSL_PEM_C)
+ pem_free( &pem );
+#endif
+ if( ret != 0 )
+ dhm_free( dhm );
+
+ return( ret );
+}
+
+#if defined(POLARSSL_FS_IO)
+/*
+ * Load all data from a file into a given buffer.
+ */
+static int load_file( const char *path, unsigned char **buf, size_t *n )
+{
+ FILE *f;
+ long size;
+
+ if( ( f = fopen( path, "rb" ) ) == NULL )
+ return( POLARSSL_ERR_DHM_FILE_IO_ERROR );
+
+ fseek( f, 0, SEEK_END );
+ if( ( size = ftell( f ) ) == -1 )
+ {
+ fclose( f );
+ return( POLARSSL_ERR_DHM_FILE_IO_ERROR );
+ }
+ fseek( f, 0, SEEK_SET );
+
+ *n = (size_t) size;
+
+ if( *n + 1 == 0 ||
+ ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
+ {
+ fclose( f );
+ return( POLARSSL_ERR_DHM_MALLOC_FAILED );
+ }
+
+ if( fread( *buf, 1, *n, f ) != *n )
+ {
+ fclose( f );
+ polarssl_free( *buf );
+ return( POLARSSL_ERR_DHM_FILE_IO_ERROR );
+ }
+
+ fclose( f );
+
+ (*buf)[*n] = '\0';
+
+ return( 0 );
+}
+
+/*
+ * Load and parse DHM parameters
+ */
+int dhm_parse_dhmfile( dhm_context *dhm, const char *path )
+{
+ int ret;
+ size_t n;
+ unsigned char *buf;
+
+ if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
+ return( ret );
+
+ ret = dhm_parse_dhm( dhm, buf, n );
+
+ memset( buf, 0, n + 1 );
+ polarssl_free( buf );
+
+ return( ret );
+}
+#endif /* POLARSSL_FS_IO */
+#endif /* POLARSSL_ASN1_PARSE_C */
+
#if defined(POLARSSL_SELF_TEST)
+#include "polarssl/certs.h"
+
/*
* Checkup routine
*/
int dhm_self_test( int verbose )
{
- return( verbose++ );
+#if defined(POLARSSL_CERTS_C)
+ int ret;
+ dhm_context dhm;
+
+ if( verbose != 0 )
+ printf( " DHM parameter load: " );
+
+ if( ( ret = dhm_parse_dhm( &dhm, (const unsigned char *) test_dhm_params,
+ strlen( test_dhm_params ) ) ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( ret );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n\n" );
+
+ dhm_free( &dhm );
+
+ return( 0 );
+#else
+ ((void) verbose);
+ return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
+#endif
}
#endif
diff --git a/library/error.c b/library/error.c
index b0e3ebd20..78c5faa56 100644
--- a/library/error.c
+++ b/library/error.c
@@ -206,6 +206,12 @@ void polarssl_strerror( int ret, char *buf, size_t buflen )
snprintf( buf, buflen, "DHM - Making of the public value failed" );
if( use_ret == -(POLARSSL_ERR_DHM_CALC_SECRET_FAILED) )
snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" );
+ if( use_ret == -(POLARSSL_ERR_DHM_INVALID_FORMAT) )
+ snprintf( buf, buflen, "DHM - The ASN.1 data is not formatted correctly" );
+ if( use_ret == -(POLARSSL_ERR_DHM_MALLOC_FAILED) )
+ snprintf( buf, buflen, "DHM - Allocation of memory failed" );
+ if( use_ret == -(POLARSSL_ERR_DHM_FILE_IO_ERROR) )
+ snprintf( buf, buflen, "DHM - Read/write of file failed" );
#endif /* POLARSSL_DHM_C */
#if defined(POLARSSL_ECP_C)
diff --git a/library/x509parse.c b/library/x509parse.c
index de4ed7f7d..5d32167f3 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -2219,113 +2219,6 @@ int x509parse_public_key_rsa( rsa_context *rsa,
}
#endif /* POLARSSL_RSA_C */
-#if defined(POLARSSL_DHM_C)
-/*
- * Parse DHM parameters
- */
-int x509parse_dhm( dhm_context *dhm, const unsigned char *dhmin, size_t dhminlen )
-{
- int ret;
- size_t len;
- unsigned char *p, *end;
-#if defined(POLARSSL_PEM_C)
- pem_context pem;
-
- pem_init( &pem );
-
- ret = pem_read_buffer( &pem,
- "-----BEGIN DH PARAMETERS-----",
- "-----END DH PARAMETERS-----",
- dhmin, NULL, 0, &dhminlen );
-
- if( ret == 0 )
- {
- /*
- * Was PEM encoded
- */
- dhminlen = pem.buflen;
- }
- else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
- {
- pem_free( &pem );
- return( ret );
- }
-
- p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
-#else
- p = (unsigned char *) dhmin;
-#endif
- end = p + dhminlen;
-
- memset( dhm, 0, sizeof( dhm_context ) );
-
- /*
- * DHParams ::= SEQUENCE {
- * prime INTEGER, -- P
- * generator INTEGER, -- g
- * }
- */
- if( ( ret = asn1_get_tag( &p, end, &len,
- ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
- {
-#if defined(POLARSSL_PEM_C)
- pem_free( &pem );
-#endif
- return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
- }
-
- end = p + len;
-
- if( ( ret = asn1_get_mpi( &p, end, &dhm->P ) ) != 0 ||
- ( ret = asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
- {
-#if defined(POLARSSL_PEM_C)
- pem_free( &pem );
-#endif
- dhm_free( dhm );
- return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT + ret );
- }
-
- if( p != end )
- {
-#if defined(POLARSSL_PEM_C)
- pem_free( &pem );
-#endif
- dhm_free( dhm );
- return( POLARSSL_ERR_X509_CERT_INVALID_FORMAT +
- POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
- }
-
-#if defined(POLARSSL_PEM_C)
- pem_free( &pem );
-#endif
-
- return( 0 );
-}
-
-#if defined(POLARSSL_FS_IO)
-/*
- * Load and parse DHM parameters
- */
-int x509parse_dhmfile( dhm_context *dhm, const char *path )
-{
- int ret;
- size_t n;
- unsigned char *buf;
-
- if ( ( ret = load_file( path, &buf, &n ) ) != 0 )
- return( ret );
-
- ret = x509parse_dhm( dhm, buf, n );
-
- memset( buf, 0, n + 1 );
- polarssl_free( buf );
-
- return( ret );
-}
-#endif /* POLARSSL_FS_IO */
-#endif /* POLARSSL_DHM_C */
-
#if defined _MSC_VER && !defined snprintf
#include
@@ -3418,9 +3311,6 @@ int x509_self_test( int verbose )
x509_cert cacert;
x509_cert clicert;
pk_context pkey;
-#if defined(POLARSSL_DHM_C)
- dhm_context dhm;
-#endif
if( verbose != 0 )
printf( " X.509 certificate load: " );
@@ -3483,29 +3373,12 @@ int x509_self_test( int verbose )
return( ret );
}
-#if defined(POLARSSL_DHM_C)
if( verbose != 0 )
- printf( "passed\n X.509 DHM parameter load: " );
-
- if( ( ret = x509parse_dhm( &dhm, (const unsigned char *) test_dhm_params,
- strlen( test_dhm_params ) ) ) != 0 )
- {
- if( verbose != 0 )
- printf( "failed\n" );
-
- return( ret );
- }
-
- if( verbose != 0 )
- printf( "passed\n\n" );
-#endif
+ printf( "passed\n\n");
x509_free( &cacert );
x509_free( &clicert );
pk_free( &pkey );
-#if defined(POLARSSL_DHM_C)
- dhm_free( &dhm );
-#endif
return( 0 );
#else
diff --git a/programs/test/selftest.c b/programs/test/selftest.c
index 02606fab0..5b8706ba2 100644
--- a/programs/test/selftest.c
+++ b/programs/test/selftest.c
@@ -33,6 +33,7 @@
#include "polarssl/config.h"
#include "polarssl/ctr_drbg.h"
+#include "polarssl/dhm.h"
#include "polarssl/gcm.h"
#include "polarssl/md2.h"
#include "polarssl/md4.h"
@@ -172,6 +173,11 @@ int main( int argc, char *argv[] )
return( ret );
#endif
+#if defined(POLARSSL_DHM_C)
+ if( ( ret = dhm_self_test( v ) ) != 0 )
+ return( ret );
+#endif
+
#else
printf( " POLARSSL_SELF_TEST not defined.\n" );
#endif
diff --git a/tests/suites/test_suite_dhm.data b/tests/suites/test_suite_dhm.data
index 168c77c1b..aecbfc5c9 100644
--- a/tests/suites/test_suite_dhm.data
+++ b/tests/suites/test_suite_dhm.data
@@ -6,3 +6,6 @@ dhm_do_dhm:10:"93450983094850938450983409623":10:"9345098304850938450983409622"
Diffie-Hellman full exchange #3
dhm_do_dhm:10:"93450983094850938450983409623982317398171298719873918739182739712938719287391879381271":10:"9345098309485093845098340962223981329819812792137312973297123912791271"
+
+Diffie-Hellman selftest
+dhm_selftest:
diff --git a/tests/suites/test_suite_dhm.function b/tests/suites/test_suite_dhm.function
index e8d9cea84..dcf236312 100644
--- a/tests/suites/test_suite_dhm.function
+++ b/tests/suites/test_suite_dhm.function
@@ -93,3 +93,10 @@ void dhm_do_dhm( int radix_P, char *input_P,
dhm_free( &ctx_cli );
}
/* END_CASE */
+
+/* BEGIN_CASE */
+void dhm_selftest()
+{
+ TEST_ASSERT( dhm_self_test( 0 ) == 0 );
+}
+/* END_CASE */