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
This commit is contained in:
Daniel Kahn Gillmor 2015-04-03 13:09:24 -04:00 committed by Manuel Pégourié-Gonnard
parent 0645bfa74e
commit 2ed81733a6

View File

@ -446,6 +446,7 @@ int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin,
* DHParams ::= SEQUENCE { * DHParams ::= SEQUENCE {
* prime INTEGER, -- P * prime INTEGER, -- P
* generator INTEGER, -- g * generator INTEGER, -- g
* privateValueLength INTEGER OPTIONAL
* } * }
*/ */
if( ( ret = asn1_get_tag( &p, end, &len, if( ( ret = asn1_get_tag( &p, end, &len,
@ -464,12 +465,26 @@ int dhm_parse_dhm( dhm_context *dhm, const unsigned char *dhmin,
goto exit; goto exit;
} }
if( p != end )
{
/* 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 ) if ( p != end )
{ {
ret = POLARSSL_ERR_DHM_INVALID_FORMAT + ret = POLARSSL_ERR_DHM_INVALID_FORMAT +
POLARSSL_ERR_ASN1_LENGTH_MISMATCH; POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
goto exit; goto exit;
} }
}
ret = 0; ret = 0;