Tolerate PKCS#8 DSA format with negative private key.
authorDr. Stephen Henson <steve@openssl.org>
Fri, 22 Jan 2010 20:17:12 +0000 (20:17 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 22 Jan 2010 20:17:12 +0000 (20:17 +0000)
CHANGES
apps/pkcs8.c
crypto/dsa/dsa_ameth.c
crypto/x509/x509.h

diff --git a/CHANGES b/CHANGES
index 00ea5eecb2fd28d0a6ac734983bf3cf8c52ef86e..6b11989fe62fa0e9c0a2be476f5832545dd8cb17 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -44,6 +44,9 @@
 
  Changes between 0.9.8m (?) and 1.0.0  [xx XXX xxxx]
 
 
  Changes between 0.9.8m (?) and 1.0.0  [xx XXX xxxx]
 
+  *) Tolerate yet another broken PKCS#8 key format: private key value negative.
+     [Steve Henson]
+
   *) Add new -subject_hash_old and -issuer_hash_old options to x509 utility to
      output hashes compatible with older versions of OpenSSL.
      [Willy Weisz <weisz@vcpc.univie.ac.at>]
   *) Add new -subject_hash_old and -issuer_hash_old options to x509 utility to
      output hashes compatible with older versions of OpenSSL.
      [Willy Weisz <weisz@vcpc.univie.ac.at>]
index c93ce7734de9b325d35bec5aa870b5bbb9fc4f2a..7edeb179dd1afd52bf8d7d35bfaa5432094756a2 100644 (file)
@@ -403,6 +403,10 @@ int MAIN(int argc, char **argv)
                        BIO_printf(bio_err, "DSA public key include in PrivateKey\n");
                        break;
 
                        BIO_printf(bio_err, "DSA public key include in PrivateKey\n");
                        break;
 
+                       case PKCS8_NEG_PRIVKEY:
+                       BIO_printf(bio_err, "DSA private key value is negative\n");
+                       break;
+
                        default:
                        BIO_printf(bio_err, "Unknown broken type\n");
                        break;
                        default:
                        BIO_printf(bio_err, "Unknown broken type\n");
                        break;
index a588740cd80c327ed652bc9e27d3748f456560cc..5482330c84ded5b47aeb24e21dcd7a9019465231 100644 (file)
@@ -237,8 +237,16 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
                }
        else
                {
                }
        else
                {
+               const unsigned char *q = p;
                if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
                        goto decerr;
                if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
                        goto decerr;
+               if (privkey->type == V_ASN1_NEG_INTEGER)
+                       {
+                       p8->broken = PKCS8_NEG_PRIVKEY;
+                       ASN1_INTEGER_free(privkey);
+                       if (!(privkey=d2i_ASN1_UINTEGER(NULL, &q, pklen)))
+                               goto decerr;
+                       }
                if (ptype != V_ASN1_SEQUENCE)
                        goto decerr;
                }
                if (ptype != V_ASN1_SEQUENCE)
                        goto decerr;
                }
index a2383b387a1efe00e1425a7ae10a7cb2298eee64..eb1b7c6b2d34a8cf14b751f9688e73510f0f2245 100644 (file)
@@ -585,6 +585,7 @@ struct pkcs8_priv_key_info_st
 #define PKCS8_NO_OCTET         1
 #define PKCS8_EMBEDDED_PARAM   2
 #define PKCS8_NS_DB            3
 #define PKCS8_NO_OCTET         1
 #define PKCS8_EMBEDDED_PARAM   2
 #define PKCS8_NS_DB            3
+#define PKCS8_NEG_PRIVKEY      4
         ASN1_INTEGER *version;
         X509_ALGOR *pkeyalg;
         ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */
         ASN1_INTEGER *version;
         X509_ALGOR *pkeyalg;
         ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */