Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[openssl.org #3282] [PATCH] Fix PKCS8/PKCS12 EncryptedPrivateKeyInfo decryption when password is empty

108 views
Skip to first unread message

Marc Bevand via RT

unread,
Mar 20, 2014, 4:09:31 AM3/20/14
to
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 opens...@openssl.org
Automated List Manager majo...@openssl.org

Stephen Henson via RT

unread,
Mar 20, 2014, 8:55:04 AM3/20/14
to
On Thu Mar 20 09:09:31 2014, mbe...@google.com wrote:
> 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.
>

Unfortunately I've come across implementations that use both forms so it isn't
just a case of fixing a bug.

In more detail. The original PKCS#12 PBE didn't give details of how the
password was formatted. Previously for PKCS#5 there was an unwritten rule that
the ASCII form without a terminating null was used.

Existing public browser PKCS#12 implementations used the unicode representation
of the password and included the double zero byte terminator, text was added to
later versions of the standard clarifying this.

The use of the double null terminator has resulted in some ambuguity. Should a
zero length password be treated as literally zero length or empty? If it is
zero length the double zero is all that is passed to the algorithm (i.e. two
bytes). If it is empty then nothing is used, zero bytes. I've come across both
forms so whatever you do it will break something.

Some of the OpenSSL code partially works around this issue. Normally PKCS#12
PBE algorithms are only present in PKCS#12 files. The function PKCS12_parse
tests both an empty and zero length password against the MAC and uses whichever
works. See the note in p12_kiss.c.

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
0 new messages