From 2ed81733a647880f147f6887fd9a1863ddd3ee1b Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Fri, 3 Apr 2015 13:09:24 -0400 Subject: [PATCH] accept PKCS#3 DH parameters with privateValueLength included library/dhm.c: accept (and ignore) optional privateValueLength for PKCS#3 DH parameters. PKCS#3 defines the ASN.1 encoding of a DH parameter set like this: ---------------- DHParameter ::= SEQUENCE { prime INTEGER, -- p base INTEGER, -- g privateValueLength INTEGER OPTIONAL } The fields of type DHParameter have the following meanings: o prime is the prime p. o base is the base g. o privateValueLength is the optional private-value length l. ---------------- See: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-3.asc This optional parameter was added in PKCS#3 version 1.4, released November 1, 1993. dhm.c currently doesn't cope well with PKCS#3 files that have this optional final parameter included. i see errors like: ------------ dhm_parse_dhmfile returned -0x33E6 Last error was: -0x33E6 - DHM - The ASN.1 data is not formatted correctly : ASN1 - Actual length differs from expected lengt ------------ You can generate PKCS#3 files with this final parameter with recent versions of certtool from GnuTLS: certtool --generate-dh-params > dh.pem --- library/dhm.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/library/dhm.c b/library/dhm.c index 9fb7a218b..0a4f82028 100644 --- a/library/dhm.c +++ b/library/dhm.c @@ -444,8 +444,9 @@ int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin, /* * DHParams ::= SEQUENCE { - * prime INTEGER, -- P - * generator INTEGER, -- g + * prime INTEGER, -- P + * generator INTEGER, -- g + * privateValueLength INTEGER OPTIONAL * } */ if( ( ret = asn1_get_tag( &p, end, &len, @@ -466,9 +467,23 @@ int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin, if( p != end ) { - ret = POLARSSL_ERR_DHM_INVALID_FORMAT + - POLARSSL_ERR_ASN1_LENGTH_MISMATCH; - goto exit; + /* this might be the optional privateValueLength; If so, we + can cleanly discard it; */ + mpi rec; + mpi_init( &rec ); + ret = asn1_get_mpi( &p, end, &rec ); + mpi_free( &rec ); + if ( ret != 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;