Bug 1664807 - httpd fails to use ECDSA keys and certificates on PKCS#11 device
Summary: httpd fails to use ECDSA keys and certificates on PKCS#11 device
Status: POST
Alias: None
Product: Red Hat Enterprise Linux 8
Classification: Red Hat
Component: openssl-pkcs11
Version: 8.0
Hardware: All
OS: Linux
Target Milestone: rc
: 8.2
Assignee: Anderson Sasaki
QA Contact: BaseOS QE Security Team
Marc Muehlfeld
Depends On: 1682502
Blocks: 1701002
TreeView+ depends on / blocked
Reported: 2019-01-09 17:22 UTC by Stanislav Zidek
Modified: 2019-09-06 13:51 UTC (History)
11 users (show)

Fixed In Version:
Doc Type: Known Issue
Doc Text:
.`httpd` fails to start if it uses an ECDSA private key without corresponding public key stored in a PKCS#11 device Unlike RSA keys, ECDSA private keys do not necessarily contain public key information. In this case, you cannot obtain the public key from an ECDSA private key. For this reason, a PKCS#11 device stores public key information in a separate object whether it is a public key object or a certificate object. OpenSSL expects the `EVP_PKEY` structure provided by an engine for a private key to contain the public key information. When filling the `EVP_PKEY` structure to be provided to OpenSSL, the engine in the `openssl-pkcs11` package tries to fetch the public key information only from matching public key objects and ignores the present certificate objects. When OpenSSL requests an ECDSA private key from the engine, the provided `EVP_PKEY` structure does not contain the public key information if the public key is not present in the PKCS#11 device, even when a matching certificate that contains the public key is available. As a consequence, since the Apache `httpd` web server calls the `X509_check_private_key()` function, which requires the public key, in its start-up process, `httpd` fails to start in this scenario. To work around the problem, store both the private and public key in the PKCS#11 device when using ECDSA keys. As a result, `httpd` starts correctly when ECDSA keys are stored in the PKCS#11 device.
Clone Of: 1664802
Last Closed:
Type: Bug

Attachments (Terms of Use)
Minimal reproducer for the issue (2.16 KB, text/x-csrc)
2019-02-06 17:45 UTC, Anderson Sasaki
no flags Details

Description Stanislav Zidek 2019-01-09 17:22:53 UTC
Description of problem:
httpd does not work with ECDSA keys stored on PKCS#11 token. I am not sure however if the problems is in httpd or perhaps "lower" (in openssl-pkcs11?).

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. cd into directory with /CoreOS/p11-kit/Integration/httpd-pkcs11-uri
2. change KEYTYPES array to test rsa-pss - "KEYTYPES=(ecdsa)"
3. 1minutetip --buildroot rhel8

Actual results:

Found slot:  SoftHSM slot ID 0x207efe18
Found token: softhsm
Found 1 private key:
   1 P  id=a67ded529c7faeea455b90589c1003e4b95df7e9 label=httpd
AH00016: Configuration Failed

[...] [ssl:debug] [...] ssl_engine_pphrase.c(872): Init: Initialized engine pkcs11 for private key pkcs11:model=SoftHSM%20v2;manufacturer=SoftHSM%20project;serial=45e2053c207efe18;token=softhsm;id=%a6%7d%ed%52%9c%7f%ae%ea%45%5b%90%58%9c%10%03%e4%b9%5d%f7%e9;object=httpd;type=private?pin-value=123456
[...] [ssl:emerg] [...] AH10130: Failed to configure private key pkcs11:model=SoftHSM%20v2;manufacturer=SoftHSM%20project;serial=45e2053c207efe18;token=softhsm;id=%a6%7d%ed%52%9c%7f%ae%ea%45%5b%90%58%9c%10%03%e4%b9%5d%f7%e9;object=httpd;type=private?pin-value=123456 from engine
[...] [ssl:emerg] [...] SSL Library Error: error:0B080075:x509 certificate routines:X509_check_private_key:unknown key type

Expected results:
no problems

Comment 2 Stanislav Zidek 2019-01-09 17:28:26 UTC
(In reply to Stanislav Zidek from comment #0)
> Description of problem:
> Steps to Reproduce:
> 1. cd into directory with /CoreOS/p11-kit/Integration/httpd-pkcs11-uri
> 2. change KEYTYPES array to test rsa-pss - "KEYTYPES=(ecdsa)"

I meant ecdsa, not rsa-pss, of course. There is separate rsa-pss bug - bz1664802

Comment 3 Anderson Sasaki 2019-02-06 17:45:07 UTC
Created attachment 1527629 [details]
Minimal reproducer for the issue

Comment 4 Anderson Sasaki 2019-02-06 17:47:05 UTC
The root of this issue is because the openssl-pkcs11 engine does not extract the public key from the certificate, but tries to find a matching public key object inside the device when initializing the EVP_PKEY structure for the private key. So, if the public key is not present in the device, the EVP_PKEY structure returned by ENGINE_load_private_key() will not hold a reference to the public key.

When httpd calls X509_check_private_key() to verify if the private key matches with the certificate, it ends up calling EC_KEY_get0_public_key() to get the public key from the EVP_PKEY structure, which will return NULL, since the reference is not there. This causes a failure in the matching check and consequently the failure in httpd start up.

The solution for ECDSA, is to store both private and public keys in the device.

I've attached a minimal reproducer for this issue in comment 3.

Comment 9 Anderson Sasaki 2019-02-27 13:25:48 UTC
This issue was set to medium priority because it has a simple workaround and it has moderate impact on a small amount of users.

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