From 9f4d3044acca0a398e53cd9e10c4679156ed275f Mon Sep 17 00:00:00 2001 From: John Logan Date: Thu, 31 Aug 2023 12:54:17 +0100 Subject: [PATCH] Adding initial pkcs#11 support for TLS private key storage --- src/session_client_tls.c | 56 ++++++++++++++++++++++++++++++-- src/session_server_tls.c | 70 ++++++++++++++++++++++++++++++++++------ 2 files changed, 113 insertions(+), 13 deletions(-) diff --git a/src/session_client_tls.c b/src/session_client_tls.c index f95fd460..0959ef17 100644 --- a/src/session_client_tls.c +++ b/src/session_client_tls.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -508,6 +509,10 @@ nc_client_tls_update_opts(struct nc_client_tls_opts *opts, const char *peername) char *key; X509_LOOKUP *lookup; X509_VERIFY_PARAM *vpm = NULL; + const int CMD_MANDATORY = 0; + EVP_PKEY *pkey = NULL; + ENGINE * pkcs11 = NULL; + const char* opensc_pkcs11_so = getenv("MODULE"); if (!opts->tls_ctx || opts->tls_ctx_change) { SSL_CTX_free(opts->tls_ctx); @@ -540,13 +545,57 @@ nc_client_tls_update_opts(struct nc_client_tls_opts *opts, const char *peername) } else { key = opts->key_path; } - if (SSL_CTX_use_PrivateKey_file(opts->tls_ctx, key, SSL_FILETYPE_PEM) != 1) { - ERR(NULL, "Loading the client private key from \'%s\' failed (%s).", key, - ERR_reason_error_string(ERR_get_error())); + + ENGINE_load_dynamic(); + pkcs11 = ENGINE_by_id( "pkcs11" ); + if ( pkcs11 == NULL ) + { + ERR(NULL, "Error retrieving 'pkcs11' engine"); + rc = -1; + goto cleanup; + } + + if ( 0 != access( opensc_pkcs11_so, R_OK ) ) + { + ERR(NULL, "Error finding '/usr/local/lib/libpkcs11-proxy.so'"); rc = -1; goto cleanup; } + if ( 1 != ENGINE_ctrl_cmd_string( pkcs11, "MODULE_PATH", opensc_pkcs11_so, CMD_MANDATORY ) ) + { + ERR(NULL, "Error setting module_path <= '/usr/local/lib/libpkcs11-proxy.so'"); + rc = -1; + goto cleanup; + } + + if ( 1 != ENGINE_init( pkcs11 ) ) + { + ERR(NULL, "Error pkcs11: unable to initialize engine"); + rc = -1; + goto cleanup; + } + + if ( 1 != ENGINE_ctrl_cmd_string( pkcs11, "PIN", "1234", CMD_MANDATORY ) ) + { + ERR(NULL, "Error setting pin"); + rc = -1; + goto cleanup; + } + + pkey = ENGINE_load_private_key( pkcs11, key, NULL, NULL ); + if (!key) + { + ERR(NULL, "Error reading private key"); + rc = -1; + goto cleanup; + } + if ((SSL_CTX_use_PrivateKey(opts->tls_ctx, pkey) != 1)) + { + ERR(NULL, "Loading the client private key failed (%s).", ERR_reason_error_string(ERR_get_error())); + rc = -1; + goto cleanup; + } if (!SSL_CTX_load_verify_locations(opts->tls_ctx, opts->ca_file, opts->ca_dir)) { ERR(NULL, "Failed to load the locations of trusted CA certificates (%s).", ERR_reason_error_string(ERR_get_error())); @@ -617,6 +666,7 @@ nc_client_tls_update_opts(struct nc_client_tls_opts *opts, const char *peername) cleanup: X509_VERIFY_PARAM_free(vpm); + EVP_PKEY_free(pkey); return rc; } diff --git a/src/session_server_tls.c b/src/session_server_tls.c index 9b9b3f10..0f4fdd04 100644 --- a/src/session_server_tls.c +++ b/src/session_server_tls.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -1748,7 +1749,12 @@ nc_tls_ctx_set_server_cert_key(SSL_CTX *tls_ctx, const char *cert_name) int ret = 0; NC_SSH_KEY_TYPE privkey_type; X509 *cert = NULL; - EVP_PKEY *pkey = NULL; + EVP_PKEY *key = NULL; + ENGINE * pkcs11 = NULL; + const int CMD_MANDATORY = 0; + const char* opensc_pkcs11_so = getenv("MODULE"); + const char* uri = getenv("TOKEN_KEY_URI"); + const char* pin = getenv("DEFAULT_USER_PIN"); if (!cert_name) { ERR(NULL, "Server certificate not set."); @@ -1781,26 +1787,70 @@ nc_tls_ctx_set_server_cert_key(SSL_CTX *tls_ctx, const char *cert_name) } /* load the private key */ - if (privkey_path) { - if (SSL_CTX_use_PrivateKey_file(tls_ctx, privkey_path, SSL_FILETYPE_PEM) != 1) { - ERR(NULL, "Loading the server private key failed (%s).", ERR_reason_error_string(ERR_get_error())); + if (privkey_path) { + if (SSL_CTX_use_PrivateKey_file(tls_ctx, privkey_path, SSL_FILETYPE_PEM) != 1) { + ERR(NULL, "1 Loading the server private key failed (%s).", ERR_reason_error_string(ERR_get_error())); + ret = -1; + goto cleanup; + } + } else { + + ENGINE_load_dynamic(); + pkcs11 = ENGINE_by_id( "pkcs11" ); + if ( pkcs11 == NULL ) + { + ERR(NULL, "Error retrieving 'pkcs11' engine"); ret = -1; goto cleanup; } - } else { - pkey = base64der_to_privatekey(privkey_data, nc_keytype2str(privkey_type)); - if (!pkey || (SSL_CTX_use_PrivateKey(tls_ctx, pkey) != 1)) { - ERR(NULL, "Loading the server private key failed (%s).", ERR_reason_error_string(ERR_get_error())); + + if ( 0 != access( opensc_pkcs11_so, R_OK ) ) + { + ERR(NULL, "Error finding pkcs module"); + ret = -1; + goto cleanup; + } + + if ( 1 != ENGINE_ctrl_cmd_string( pkcs11, "MODULE_PATH", opensc_pkcs11_so, CMD_MANDATORY ) ) + { + ERR(NULL, "Error setting module_path"); + ret = -1; + goto cleanup; + } + + if ( 1 != ENGINE_init( pkcs11 ) ) + { + ERR(NULL, "Error pkcs11: unable to initialize engine"); ret = -1; goto cleanup; } - } + if ( 1 != ENGINE_ctrl_cmd_string( pkcs11, "PIN", pin, CMD_MANDATORY ) ) + { + ERR(NULL, "Error setting pin"); + ret = -1; + goto cleanup; + } + + key = ENGINE_load_private_key( pkcs11, uri, NULL, NULL ); + if (!key) + { + ERR(NULL, "Error reading private key using uri"); + ret = -1; + goto cleanup; + } + + if ((SSL_CTX_use_PrivateKey(tls_ctx, key) != 1)) { + ERR(NULL, "Loading the server private key failed (%s).", ERR_reason_error_string(ERR_get_error())); + ret = -1; + goto cleanup; + } + } ret = nc_tls_ctx_set_server_cert_chain(tls_ctx, cert_name); cleanup: X509_free(cert); - EVP_PKEY_free(pkey); + EVP_PKEY_free(key); free(cert_path); free(cert_data); free(privkey_path);