Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LibreSSL 3.7.x doesn't implement 'openssl x509 -force_pubkey' #842

Closed
orbea opened this issue Apr 13, 2023 · 3 comments
Closed

LibreSSL 3.7.x doesn't implement 'openssl x509 -force_pubkey' #842

orbea opened this issue Apr 13, 2023 · 3 comments

Comments

@orbea
Copy link

orbea commented Apr 13, 2023

When tpm2-tss has been configured with --enable-self-generated-certificate many tests will fail because the create_ca.sh script uses openssl x509 -force_pubkey which is not implemented in LibreSSL.

https://github.com/tpm2-software/tpm2-tss/blob/3d3c9a81db1354fe75dd27f5a87551c101034b0d/script/ekca/create_ca.sh#L163
https://github.com/tpm2-software/tpm2-tss/blob/3d3c9a81db1354fe75dd27f5a87551c101034b0d/script/ekca/create_ca.sh#L198

The script will succeed if the -force_pubkey argument is removed, but then the same tests will still fail. Perhaps its actually important in this case?

Trying to start simulator swtpm
Starting simulator on port 1950
successfully started daemon: swtpm with PID: 6029
/tmp/tpm2-tss
simulator PID: 6029
LISTEN 0      1          127.0.0.1:1950       0.0.0.0:*    users:(("swtpm",pid=6029,fd=3)) 
LISTEN 0      1          127.0.0.1:1951       0.0.0.0:*    users:(("swtpm",pid=6029,fd=2)) 
Simulator with PID 6029 bound to port 1950 and  1951 successfully.
TPM20TEST_TCTI_NAME=swtpm
TPM20TEST_DEVICE_FILE=
TPM20TEST_SOCKET_ADDRESS=127.0.0.1
TPM20TEST_SOCKET_PORT=1950
TPM20TEST_TCTI=swtpm:host=127.0.0.1,port=1950
WARNING:test:test/helper/tpm_writeekcert.c:93:main() Cert input size is 1208 
WARNING:test:test/helper/tpm_writeekcert.c:96:main() Define NV cert with nv index: 1c00002 
WARNING:test:test/helper/tpm_writeekcert.c:93:main() Cert input size is 1208 
WARNING:test:test/helper/tpm_writeekcert.c:96:main() Define NV cert with nv index: 1c0000a 
Execute the test script
info:test:test/integration/main-fapi.c:413:init_fapi() Using config:
{
     "profile_name": "P_ECC",
     "profile_dir": "./test/data/fapi/",
     "user_dir": "/tmp/fapi_tmpdir.MIaDIf/user/dir",
     "system_dir": "/tmp/fapi_tmpdir.MIaDIf/system_dir",
     "system_pcrs" : [],
     "log_dir" : "/tmp/fapi_tmpdir.MIaDIf",
     "tcti": "swtpm:host=127.0.0.1,port=1950",
} 
WARNING:fapi:src/tss2-fapi/ifapi_io.c:339:ifapi_io_check_create_dir() Directory /tmp/fapi_tmpdir.MIaDIf/user/dir does not exist, creating 
WARNING:fapi:src/tss2-fapi/ifapi_io.c:339:ifapi_io_check_create_dir() Directory /tmp/fapi_tmpdir.MIaDIf/system_dir/policy does not exist, creating 
ERROR:fapi:src/tss2-fapi/api/Fapi_Provision.c:885:Fapi_Provision_Finish() ErrorCode (0x00060025) No EK certificate found. 
ERROR:esys:src/tss2-esys/esys_iutil.c:395:iesys_handle_to_tpm_handle() Error: Esys invalid ESAPI handle (ff). 
ERROR:esys:src/tss2-esys/esys_iutil.c:1178:esys_GetResourceObject() Unknown ESYS handle. ErrorCode (0x0007000b) 
ERROR:esys:src/tss2-esys/api/Esys_FlushContext.c:138:Esys_FlushContext_Async() flushHandle unknown. ErrorCode (0x0007000b) 
ERROR:esys:src/tss2-esys/api/Esys_FlushContext.c:66:Esys_FlushContext() Error in async function ErrorCode (0x0007000b) 
ERROR:fapi:src/tss2-fapi/fapi_util.c:1199:ifapi_session_clean() Cleanup session failed. 
ERROR:fapi:src/tss2-fapi/api/Fapi_Provision.c:174:Fapi_Provision() ErrorCode (0x00060025) Provision 
ERROR:test:test/integration/fapi-get-random.int.c:47:test_fapi_get_random() Error Fapi_Provision ErrorCode (0x00060025) 
ERROR:fapi:src/tss2-fapi/api/Fapi_Delete.c:405:Fapi_Delete_Async() ErrorCode (0x00060034) FAPI not provisioned. 
ERROR:fapi:src/tss2-fapi/api/Fapi_Delete.c:313:Fapi_Delete() ErrorCode (0x00060034) Entity_Delete 
info:test:test/integration/main-fapi.c:504:main() Test returned 1 
Script returned 1
FAIL test/integration/dlopen-fapi-get-random.fint (exit status: 1)

The OpenSSL documentation shows:

-force_pubkey key

When a certificate is created set its public key to key instead of the key in the certificate or certificate request. This option is useful for creating certificates where the algorithm can't normally sign requests, for example DH.

The format or key can be specified using the -keyform option.

https://www.openssl.org/docs/man1.1.1/man1/x509.html

I made WIP upstream PR here. tpm2-software/tpm2-tss#2380

@botovq
Copy link
Contributor

botovq commented Apr 15, 2023

It hasn't come up before. It's easy enough to add, the below was only lightly tested and applies to LibreSSL 3.7.2.
If you could give it a try that would be great. If it works, I'm pretty sure I can land it for LibreSSL 3.8.

diff --git a/src/usr.bin/openssl/x509.c b/src/usr.bin/openssl/x509.c
index 66cad3ab2..e51cfd296 100644
--- apps/openssl/x509.c
+++ apps/openssl/x509.c
@@ -113,6 +113,7 @@ static struct {
 	char *extfile;
 	char *extsect;
 	int fingerprint;
+	char *force_pubkey;
 	char *infile;
 	int informat;
 	int issuer;
@@ -467,6 +468,12 @@ static const struct option x509_options[] = {
 		.opt.order = &cfg.fingerprint,
 		.order = &cfg.num,
 	},
+	{
+		.name = "force_pubkey",
+		.desc = "Force the key to put inside the certificate",
+		.type = OPTION_ARG,
+		.opt.arg = &cfg.force_pubkey,
+	},
 	{
 		.name = "hash",
 		.desc = "Synonym for -subject_hash",
@@ -725,7 +732,7 @@ x509_main(int argc, char **argv)
 	int ret = 1;
 	X509_REQ *req = NULL;
 	X509 *x = NULL, *xca = NULL;
-	EVP_PKEY *Upkey = NULL, *CApkey = NULL;
+	EVP_PKEY *Fpkey = NULL, *Upkey = NULL, *CApkey = NULL;
 	int i;
 	BIO *out = NULL;
 	BIO *STDout = NULL;
@@ -814,6 +821,11 @@ x509_main(int argc, char **argv)
 			goto end;
 		}
 	}
+	if (cfg.force_pubkey != NULL) {
+		if ((Fpkey = load_pubkey(bio_err, cfg.force_pubkey,
+		    cfg.keyformat, 0, NULL, "Forced key")) == NULL)
+			goto end;
+	}
 	if (cfg.reqfile) {
 		EVP_PKEY *pkey;
 		BIO *in;
@@ -890,12 +902,12 @@ x509_main(int argc, char **argv)
 		    NULL) == NULL)
 			goto end;
 
-		if ((pkey = X509_REQ_get0_pubkey(req)) == NULL)
+		if ((pkey = Fpkey) == NULL)
+			pkey = X509_REQ_get0_pubkey(req);
+		if (pkey == NULL)
 			goto end;
-		if (!X509_set_pubkey(x, pkey)) {
-			EVP_PKEY_free(pkey);
+		if (!X509_set_pubkey(x, pkey))
 			goto end;
-		}
 	} else {
 		x = load_cert(bio_err, cfg.infile, cfg.informat,
 		    NULL, "Certificate");
@@ -1321,6 +1333,7 @@ x509_main(int argc, char **argv)
 	X509_REQ_free(req);
 	X509_free(x);
 	X509_free(xca);
+	EVP_PKEY_free(Fpkey);
 	EVP_PKEY_free(Upkey);
 	EVP_PKEY_free(CApkey);
 	sk_OPENSSL_STRING_free(cfg.sigopts);

@orbea
Copy link
Author

orbea commented Apr 15, 2023

I tested the patch, but the tests still fail to verify the intermediate certificate.

Trying to start simulator swtpm
Starting simulator on port 1634
successfully started daemon: swtpm with PID: 17481
/tmp/tpm2-tss
simulator PID: 17481
LISTEN 0      1          127.0.0.1:1634      0.0.0.0:*    users:(("swtpm",pid=17481,fd=3))
LISTEN 0      1          127.0.0.1:1635      0.0.0.0:*    users:(("swtpm",pid=17481,fd=2))
Simulator with PID 17481 bound to port 1634 and  1635 successfully.
TPM20TEST_TCTI_NAME=swtpm
TPM20TEST_DEVICE_FILE=
TPM20TEST_SOCKET_ADDRESS=127.0.0.1
TPM20TEST_SOCKET_PORT=1634
TPM20TEST_TCTI=swtpm:host=127.0.0.1,port=1634
WARNING:test:test/helper/tpm_writeekcert.c:93:main() Cert input size is 1208 
WARNING:test:test/helper/tpm_writeekcert.c:96:main() Define NV cert with nv index: 1c00002 
WARNING:test:test/helper/tpm_writeekcert.c:93:main() Cert input size is 1005 
WARNING:test:test/helper/tpm_writeekcert.c:96:main() Define NV cert with nv index: 1c0000a 
Execute the test script
info:test:test/integration/main-fapi.c:413:init_fapi() Using config:
{
     "profile_name": "P_ECC",
     "profile_dir": "./test/data/fapi/",
     "user_dir": "/tmp/fapi_tmpdir.PeLMeB/user/dir",
     "system_dir": "/tmp/fapi_tmpdir.PeLMeB/system_dir",
     "system_pcrs" : [],
     "log_dir" : "/tmp/fapi_tmpdir.PeLMeB",
     "tcti": "swtpm:host=127.0.0.1,port=1634",
} 
WARNING:fapi:src/tss2-fapi/ifapi_io.c:339:ifapi_io_check_create_dir() Directory /tmp/fapi_tmpdir.PeLMeB/user/dir does not exist, creating 
WARNING:fapi:src/tss2-fapi/ifapi_io.c:339:ifapi_io_check_create_dir() Directory /tmp/fapi_tmpdir.PeLMeB/system_dir/policy does not exist, creating 
ERROR:fapi:src/tss2-fapi/ifapi_curl.c:267:ifapi_curl_verify_ek_cert() certificate signature failure 
ERROR:fapi:src/tss2-fapi/ifapi_curl.c:268:ifapi_curl_verify_ek_cert() ErrorCode (0x00060001) Failed to verify intermediate certificate 
ERROR:fapi:src/tss2-fapi/api/Fapi_Provision.c:943:Fapi_Provision_Finish() ErrorCode (0x00060001) Verify EK certificate 
ERROR:esys:src/tss2-esys/esys_iutil.c:395:iesys_handle_to_tpm_handle() Error: Esys invalid ESAPI handle (ff). 
ERROR:esys:src/tss2-esys/esys_iutil.c:1178:esys_GetResourceObject() Unknown ESYS handle. ErrorCode (0x0007000b) 
ERROR:esys:src/tss2-esys/api/Esys_FlushContext.c:138:Esys_FlushContext_Async() flushHandle unknown. ErrorCode (0x0007000b) 
ERROR:esys:src/tss2-esys/api/Esys_FlushContext.c:66:Esys_FlushContext() Error in async function ErrorCode (0x0007000b) 
ERROR:fapi:src/tss2-fapi/fapi_util.c:1199:ifapi_session_clean() Cleanup session failed. 
ERROR:fapi:src/tss2-fapi/api/Fapi_Provision.c:174:Fapi_Provision() ErrorCode (0x00060001) Provision 
ERROR:test:test/integration/fapi-get-random.int.c:47:test_fapi_get_random() Error Fapi_Provision ErrorCode (0x00060001) 
ERROR:fapi:src/tss2-fapi/api/Fapi_Delete.c:405:Fapi_Delete_Async() ErrorCode (0x00060034) FAPI not provisioned. 
ERROR:fapi:src/tss2-fapi/api/Fapi_Delete.c:313:Fapi_Delete() ErrorCode (0x00060034) Entity_Delete 
info:test:test/integration/main-fapi.c:504:main() Test returned 1 
Script returned 1
FAIL test/integration/dlopen-fapi-get-random.fint (exit status: 1)

I attached the full create_ca.sh log with set -x if its helpful.
dlopen-fapi-get-random.fint_ca.log

@botovq
Copy link
Contributor

botovq commented Apr 24, 2024

This has been available since openbsd/src@0293fcf

There may still be behavior differences to openssl with what goes to stdout and stderr which might be the reason why the tests you tried still fail. I think that's an independent issue that should be raised and fixed separately.

@botovq botovq closed this as completed Apr 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants