Bug 1369484 - Cannot read encrypted PKCS#8 from OpenSSL
Summary: Cannot read encrypted PKCS#8 from OpenSSL
Alias: None
Product: Fedora
Classification: Fedora
Component: gnutls
Version: 24
Hardware: Unspecified
OS: Unspecified
Target Milestone: ---
Assignee: Nikos Mavrogiannopoulos
QA Contact: Fedora Extras Quality Assurance
Depends On:
Blocks: 1380642
TreeView+ depends on / blocked
Reported: 2016-08-23 14:19 UTC by David Woodhouse
Modified: 2016-09-30 08:50 UTC (History)
2 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
: 1380642 (view as bug list)
Last Closed: 2016-09-27 14:08:11 UTC
Type: Bug

Attachments (Terms of Use)
cert.pem (1.27 KB, text/x-vhdl)
2016-08-23 14:19 UTC, David Woodhouse
no flags Details
PKCS#8 generated with OpenSSL 1.1 (1.83 KB, text/x-vhdl)
2016-08-23 14:20 UTC, David Woodhouse
no flags Details
PKCS#8 generated with OpenSSL 1.0.2 (1.81 KB, text/x-vhdl)
2016-08-23 14:20 UTC, David Woodhouse
no flags Details
PKCS#8 pbeWithMD5AndDES-CBC (2.03 KB, text/x-vhdl)
2016-08-24 15:44 UTC, David Woodhouse
no flags Details

Description David Woodhouse 2016-08-23 14:19:30 UTC
Created attachment 1193336 [details]

GnuTLS (for example openconnect) can read PKCS#8 files generated by Fedora's OpenSSL 1.0.2 — as long as we explictly request PBES2.

It cannot read files generated by OpenSSL 1.1.

$ yes XX | openssl req -new -x509  -out cert.pem -nodes 
$ openssl pkcs8 -topk8 -in privkey.pem -out pk8-ossl102.pem -v2 aes256 -passout pass:asdf
$ ~/git/openssl/apps/openssl pkcs8 -topk8 -in privkey.pem -out pk8-ossl11.pem -v2 aes256 -passout pass:asdf

$ openconnect -c cert.pem -k pk8-ossl102.pem --key-password asdf $URL
Client certificate expires soon at: Thu, 22 Sep 2016 14:12:06 GMT
Using client certificate 'XX'

$ openconnect -c cert.pem -k pk8-ossl11.pem --key-password asdf $URL
Failed to decrypt PKCS#8 certificate file
Enter PEM pass phrase:

Works with openconnect built against OpenSSL (even 1.0.2) though:

$ ~/git/openconnect/ossl/openconnect -c cert.pem -k pk8-ossl11.pem --key-password asdf $URL
Using client certificate '/C=XX/ST=XX/L=XX/O=XX/OU=XX/CN=XX/emailAddress=XX'
Client certificate expires soon at: Sep 22 14:12:06 2016 GMT

Going back to GnuTLS-built openconnect and adding debugging...

$ openconnect -c cert.pem -k pk8-ossl11.pem --key-password asdf --gnutls-debug=99 $URL
ASSERT: pkcs12.c:245
ASSERT: x509_b64.c:305
Could not find '-----BEGIN PRIVATE KEY'
keyDerivationFunc.algorithm: 1.2.840.113549.1.5.12
salt.specified.size: 8
iterationCount: 2048
ASSERT: mpi.c:246
keyLength: 0
encryptionScheme.algorithm: 2.16.840.
IV.size: 16
ASSERT: privkey_pkcs8.c:1358
ASSERT: privkey_pkcs8.c:1047
ASSERT: privkey_pkcs8.c:1506
Failed to decrypt PKCS#8 certificate file
Enter PEM pass phrase:

Comment 1 David Woodhouse 2016-08-23 14:20:00 UTC
Created attachment 1193338 [details]
PKCS#8 generated with OpenSSL 1.1

Comment 2 David Woodhouse 2016-08-23 14:20:31 UTC
Created attachment 1193339 [details]
PKCS#8 generated with OpenSSL 1.0.2

Comment 3 David Woodhouse 2016-08-23 15:20:05 UTC
It started at OpenSSL commit 8fc06e8860:

Specifically, changing the PRF to use SHA256. So this works:

$ apps/openssl pkcs8 -topk8 -in ~/privkey.pem -out ~/pk8-test.pem -v2 aes256 -passout pass:asdf -v2prf hmacWithSHA1

... and GnuTLS fails to parse this one:

$ apps/openssl pkcs8 -topk8 -in ~/privkey.pem -out ~/pk8-test.pem -v2 aes256 -passout pass:asdf -v2prf hmacWithSHA256

Comment 5 David Woodhouse 2016-08-24 13:07:14 UTC
Excellent; thank you. Passes the test cases I'm currently working on adding to openconnect.

Unfortunately I have another test case that's already failing, and it's the key file generated by default with OpenSSL 1.0.2 and 'openssl pkcs8 -topk8', so it probably wants supporting too.

It uses pbeWithMD5AndDES-CBC.

Comment 6 David Woodhouse 2016-08-24 15:44:58 UTC
Created attachment 1193678 [details]

Test cases updated in

The attached user-key-pkcs8-pbes1-md5-des.pem is what OpenSSL 1.0.2 outputs by default with 'openssl pkcs8 -topk8' and no further specification.

$ openssl pkcs8 -topk8 -in privkey.pem -passout pass:password | certtool -k
Encrypted structure detected...
PKCS #8 information:
	Schema: unsupported (1.2.840.113549.1.5.3)
Enter password: 
import error: Error in parsing.

Comment 7 Tomas Mraz 2016-08-25 07:40:33 UTC
As this is an insecure algorithm and upstream changed the default in 1.1.0 I think I could change the default in 1.0.2 in Fedora too. On the other hand for compatibility unpatched 1.0.2 and for legacy reasons the support could be added to gnutls anyway.

Comment 8 David Woodhouse 2016-08-25 11:27:05 UTC
Changing the default for Fedora users who create certs after today would be good. 

You might also want to change the default created by 'openssl req -new', which is at least 3DES but still... is 3DES. I love that they're all *different* defaults :)

But it doesn't help GnuTLS much for existing certs, and certs produced before today, or on other distributions. I do think we need to make GnuTLS cope with them too. We don't need to support *everything*, but we *should* support anything that OpenSSL has ever used as a default output format.

Comment 9 Nikos Mavrogiannopoulos 2016-08-25 13:58:51 UTC
There is a initial patch which only allows decryption with this cipher at:

A review is welcome.

Comment 10 David Woodhouse 2016-08-25 14:45:06 UTC
Have heckled on IRC about the fact that GNUTLS_PKCS_PBES1_DES_MD5 is equal to GNUTLS_PKCS_PBES2_DES and that I'm confused by the naming of the new C file and functions — whose names suggest that they *ought* to be handling the existing PBES1-3DES-SHA1 support, and that they ought to be handling any new PBES1 algorithms if (hypothetically) we found it necessary to add them. Yet they are very specific to DES-MD5.

But other than that, it works. Running 'make check' in OpenConnect git HEAD with all the "don't try this on GnuTLS" key formats re-enabled now passes. That includes both PKCS#12 and PKCS#8 files using pbeWithMD5AndDES-CBC


Comment 11 Nikos Mavrogiannopoulos 2016-09-27 14:08:11 UTC
Addressed in F25.

Note You need to log in before you can comment on or make changes to this bug.