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
diff --git a/library/dhm.c b/library/dhm.c
index 9fb7a21..0a4f820 100644
--- a/library/dhm.c
+++ b/library/dhm.c
@@ -444,8 +444,9 @@
 
     /*
      *  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 @@
 
     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;