Fix PKCS#12 key generation bug.
authorDr. Stephen Henson <steve@openssl.org>
Sun, 18 Mar 2001 02:10:25 +0000 (02:10 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 18 Mar 2001 02:10:25 +0000 (02:10 +0000)
CHANGES
crypto/pkcs12/p12_key.c
doc/apps/pkcs12.pod

diff --git a/CHANGES b/CHANGES
index d3086a7fba03421c60cf6de660627a2a8e1302f1..b55c928cabe069735ff362e3a4c9d1cee4f1157a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,12 @@
 
  Changes between 0.9.6 and 0.9.6a  [xx XXX 2001]
 
+  *) Fix bug in PKCS#12 key generation routines. This was triggered
+     if a 3DES key was generated with a 0 initial byte. Include
+     PKCS12_BROKEN_KEYGEN compilation option to retain the old
+     (but broken) behaviour.
+     [Steve Henson]
+
   *) Fix memory leaks in err.c: free err_data string if necessary;
      don't write to the wrong index in ERR_set_error_data.
      [Bodo Moeller]
index a9b4b8c9721e68a866abdc38168d399ebfff9554..a4fd5b98ec9ab85bc7941609b89e0893614d2dec 100644 (file)
@@ -102,7 +102,7 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
             const EVP_MD *md_type)
 {
        unsigned char *B, *D, *I, *p, *Ai;
-       int Slen, Plen, Ilen;
+       int Slen, Plen, Ilen, Ijlen;
        int i, j, u, v;
        BIGNUM *Ij, *Bpl1;      /* These hold Ij and B + 1 */
        EVP_MD_CTX ctx;
@@ -180,10 +180,17 @@ int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
                        BN_bin2bn (I + j, v, Ij);
                        BN_add (Ij, Ij, Bpl1);
                        BN_bn2bin (Ij, B);
+                       Ijlen = BN_num_bytes (Ij);
                        /* If more than 2^(v*8) - 1 cut off MSB */
-                       if (BN_num_bytes (Ij) > v) {
+                       if (Ijlen > v) {
                                BN_bn2bin (Ij, B);
                                memcpy (I + j, B + 1, v);
+#ifndef PKCS12_BROKEN_KEYGEN
+                       /* If less than v bytes pad with zeroes */
+                       } else if (Ijlen < v) {
+                               memset(I + j, 0, v - Ijlen);
+                               BN_bn2bin(Ij, I + j + v - Ijlen); 
+#endif
                        } else BN_bn2bin (Ij, I + j);
                }
        }
index c4009998b8a94a1c6fc5b0404ccfce2654f3a5ec..7e0307dda0bfc44a1e0eea302e1cb5c6c66d5e89 100644 (file)
@@ -304,6 +304,26 @@ Include some extra certificates:
 
 Some would argue that the PKCS#12 standard is one big bug :-)
 
+Versions of OpenSSL before 0.9.6a had a bug in the PKCS#12 key generation
+routines. Under rare circumstances this could produce a PKCS#12 file encrypted
+with an invalid key. As a result some PKCS#12 files which triggered this bug
+from other implementations (MSIE or Netscape) could not be decrypted
+by OpenSSL and similarly OpenSSL could produce PKCS#12 files which could
+not be decrypted by other implementations. The chances of producing such
+a file are relatively small: less than 1 in 256.
+
+A side effect of fixing this bug is that any old invalidly encrypted PKCS#12
+files cannot no longer be parsed by the fixed version. Under such circumstances
+the B<pkcs12> utility will report that the MAC is OK but fail with a decryption
+error when extracting private keys.
+
+This problem can be resolved by extracting the private keys and certificates
+from the PKCS#12 file using an older version of OpenSSL and recreating the PKCS#12
+file from the keys and certificates using a newer version of OpenSSL. For example:
+
+ old-openssl -in bad.p12 -out keycerts.pem
+ openssl -in keycerts.pem -export -name "My PKCS#12 file" -out fixed.p12
+
 =head1 SEE ALSO
 
 L<pkcs8(1)|pkcs8(1)>