The "openssl pkcs8" CLI tool fails to properly decrypt a file containing an EncryptedPrivateKeyInfo structure encrypted with an empty password (see error below). This happens when a PKCS #12 algorithm is used (such as PBE-SHA1-3DES); I have not investigated PKCS #5 algorithms. I hit this bug when attempting to decrypt Chrome's Channel ID/Origin Bound Certs private keys which are encrypted by (non-broken) NSS.
The PKCS #12 standard explains that if the password is empty, then P should be empty when concatenating I=S||P (see section B.2, step 3, in ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1.pdf). But openssl accidentally makes P an array of NUL bytes. This corrupts the calculation of the key and iv, causing the error. The following patch fixes the bug: --- ./openssl-1.0.1c/crypto/pkcs12/p12_key.c 2011-06-03 13:52:59.000000000 -0700 +++ p12_key.c 2014-03-18 22:17:49.440922335 -0700 @@ -82,7 +82,7 @@ unsigned char *unipass; int uniplen; - if(!pass) { + if(!pass || !passlen) { unipass = NULL; uniplen = 0; } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) { Here is a non-sensitive test key file encrypted with an empty password to reproduce the issue (c.key.pem): -----BEGIN ENCRYPTED PRIVATE KEY----- MIG4MCMGCiqGSIb3DQEMAQMwFQQQR9OULaNdA8urOek0ctO63QIBAQSBkA6coyL6 Q5PBiPezjbBYursIzB3iedW5YNWIeHLoNUJ7TEQjeBd69rAXx3AFdEJJ7ngpkAko m5pE/48sf1LsJpeXfFDLPQxgWe5cflc96j/siVVUa5QNssX7hTMVQ6AYujFtqOBH QedhUrUyDlJSo+1cF0eG0+rvYz2Rj/dLnLxgP94V8NldChOulFIxqMThXw== -----END ENCRYPTED PRIVATE KEY----- Before applying the patch, we get this error: $ openssl pkcs8 -passin pass: -in c.key.pem Error decrypting key 140145364022944:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539: 140145364022944:error:23077074:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 cipherfinal error:p12_decr.c:104: 140145364022944:error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error:p12_decr.c:130: After applying the patch: $ openssl pkcs8 -passin pass: -in c.key.pem -----BEGIN PRIVATE KEY----- ... -----END PRIVATE KEY----- Note that applying the patch will of course make ALL PKCS8 FILES encrypted by openssl with an empty password UNREADABLE by the patched openssl. If you guys deem this to be a serious problem, then I suggest that we leave the p12_key.c API unmodified, and instead patch the bug at a higher level in pkcs8.c. The two ways of computing the key & iv are actually already supported by the PKCS8_decrypt(X509_SIG *p8, const char *pass, int passlen): PKCS8_decrypt(..., "", 0) computes the key/iv in a broken way (P as an array of NUL bytes) PKCS8_decrypt(..., NULL, 0) computes the key/iv in a standard-compliant way (empty P) And we could add a command line option to pkcs8.c (-brokenemptypw) to enable the broken behavior. The PKCS8_decrypt() documentation need to clearly document that the standard-compliant way to encrypt with a empty password is to pass NULL as the password argument. -- Cheers, mbevand ______________________________________________________________________ OpenSSL Project http://www.openssl.org Development Mailing List openssl-dev@openssl.org Automated List Manager majord...@openssl.org