diff --git a/CMakeLists.txt b/CMakeLists.txt
index ec0088b..8e13231 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.14)
-project(everest-evse_security VERSION 0.6
+project(everest-evse_security VERSION 0.8
DESCRIPTION "Implementation of EVSE related security operations"
LANGUAGES CXX C
)
@@ -14,18 +14,30 @@ option(${PROJECT_NAME}_BUILD_TESTING "Build unit tests, used if included as depe
option(BUILD_TESTING "Build unit tests, used if standalone project" OFF)
option(EVSE_SECURITY_INSTALL "Install the library (shared data might be installed anyway)" ${EVC_MAIN_PROJECT})
option(USING_TPM2 "Include code for using OpenSSL 3 and the tpm2 provider" OFF)
+option(USING_CUSTOM_PROVIDER "Include code for using OpenSSL 3 and the custom provider" OFF)
if((${CMAKE_PROJECT_NAME} STREQUAL ${PROJECT_NAME} OR ${PROJECT_NAME}_BUILD_TESTING) AND BUILD_TESTING)
set(LIBEVSE_SECURITY_BUILD_TESTING ON)
endif()
+if(USING_TPM2 AND USING_CUSTOM_PROVIDER)
+ message(FATAL_ERROR, "TPM2 provider and custom provider are incompatible")
+endif()
+
if(USING_TPM2)
- # OpenSSL property string when using the default provider
- set(PROPQUERY_DEFAULT "provider!=tpm2")
- # OpenSSL property string when using the tpm2 provider
- set(PROPQUERY_TPM2 "?provider=tpm2,tpm2.digest!=yes,tpm2.cipher!=yes")
+ set(CUSTOM_PROVIDER_NAME "tpm2")
endif()
+if(USING_CUSTOM_PROVIDER)
+ set(CUSTOM_PROVIDER_NAME "custom_provider")
+endif()
+
+if(USING_TPM2 OR USING_CUSTOM_PROVIDER)
+# OpenSSL property string when using the default provider
+ set(PROPQUERY_PROVIDER_DEFAULT "provider!=${CUSTOM_PROVIDER_NAME}")
+ # OpenSSL property string when using the tpm2/custom provider
+ set(PROPQUERY_PROVIDER_CUSTOM "?provider=${CUSTOM_PROVIDER_NAME},${CUSTOM_PROVIDER_NAME}.digest!=yes,${CUSTOM_PROVIDER_NAME}.cipher!=yes")
+endif()
# dependencies
if (NOT DISABLE_EDM)
diff --git a/README.md b/README.md
index 25f3abe..f65ba0a 100644
--- a/README.md
+++ b/README.md
@@ -4,8 +4,6 @@
This is a C++ library for security related operations for charging stations. It respects the requirements specified in OCPP and ISO15118 and can be used in combination with OCPP and ISO15118 implementations.
-In the near future this library will also contain support for secure storage on TPM2.0.
-
All documentation and the issue tracking can be found in our main repository here: https://github.com/EVerest/everest
## Prerequisites
@@ -43,7 +41,7 @@ We allow any certificate structure with the following recommendations:
- Root CA certificate directories/bundles should not overlap leaf certificates
- It is not recommended to store any SUBCAs in the root certificate bundle (if using files)
-**Important:** when requesting leaf certificates with [get_key_pair](https://github.com/EVerest/libevse-security/blob/5cd5f8284229ffd28ae1dfed2137ef194c39e732/lib/evse_security/evse_security.cpp#L820) care should be taken if you require the full certificate chain.
+**Important:** when requesting leaf certificates with [get_leaf_certificate_info](https://github.com/EVerest/libevse-security/blob/b140c17b0a5eaf09b60035605ed8aeb84627eb78/include/evse_security/evse_security.hpp#L195) care should be taken if you require the full certificate chain.
If a full chain is **Leaf->SubCA2->SubCA1->Root**, it is recommended to have the root certificate in a single file, **V2G_ROOT_CA.pem** for example. The **Leaf->SubCA2->SubCA1** should be placed in a file e.g. **SECC_CERT_CHAIN.pem**.
@@ -56,9 +54,9 @@ By default they are not added.
- `cmake -DCSR_DNS_NAME=charger.pionix.de ...` to include a DNS name
- `cmake -DCSR_IP_ADDRESS=192.168.2.1 ...` to include an IPv4 address
-When receiving back a signed CSR, the library will take care to create two files, one containing the **Leaf->SubCA2->SubCA1** chain and another containing the single **Leaf**. When they both exist, the return of [get_key_pair](https://github.com/EVerest/libevse-security/blob/5cd5f8284229ffd28ae1dfed2137ef194c39e732/include/evse_security/evse_types.hpp#L126) will contain a path to both the single file and the chain file.
+When receiving back a signed CSR, the library will take care to create two files, one containing the **Leaf->SubCA2->SubCA1** chain and another containing the single **Leaf**. When they both exist, the return of [get_leaf_certificate_info](https://github.com/EVerest/libevse-security/blob/b140c17b0a5eaf09b60035605ed8aeb84627eb78/include/evse_security/evse_security.hpp#L195) will contain a path to both the single file and the chain file.
-## TPM
+## TPM Provider
There is a configuration option to configure OpenSSL for use with a TPM.
`cmake` ... `-DUSING_TPM2=ON`
@@ -67,8 +65,8 @@ configure whether to use the `default` provider or the `tpm2` provider.
Configuration is managed via propquery strings (see CMakeLists.txt)
-- `PROPQUERY_DEFAULT` is the string to use when selecting the default provider
-- `PROPQUERY_TPM2` is the string to use when selecting the tpm2 provider
+- `PROPQUERY_PROVIDER_DEFAULT` is the string to use when selecting the default provider
+- `PROPQUERY_PROVIDER_CUSTOM` is the string to use when selecting the tpm2 provider
propquery|action
---------|------
@@ -83,6 +81,17 @@ For more information see:
- [OpenSSL property](https://www.openssl.org/docs/man3.0/man7/property.html)
- [OpenSSL provider](https://www.openssl.org/docs/man3.0/man7/provider.html)
+Note: In case of errors related to CSR signing, update tpm2-openssl to v 1.2.0.
+
+## Custom Provider
+There is a configuration option to configure OpenSSL for use with a custom provider.
+`cmake` ... `-DUSING_CUSTOM_PROVIDER=ON`
+
+The workflow follows the same steps as using the TPM provider. The library will
+have a flag to configure whether it uses the `default` provider or the `custom` one.
+
+Note: The custom provider name has to be defined [here](https://github.com/EVerest/libevse-security/blob/4afe644cb62d0bf06fff1e2ca5d2dbc489342e0c/CMakeLists.txt#L32). Change the name from "custom_provider" to the required provider.
+
## Garbage Collect
By default a garbage collect function will run and delete all expired leaf certificates and their respective keys, only if the certificate storage is full. A minimum count of leaf certificates will be kept even if they are expired.
diff --git a/include/evse_security/crypto/evse_crypto.hpp b/include/evse_security/crypto/evse_crypto.hpp
index e25703c..704a5e5 100644
--- a/include/evse_security/crypto/evse_crypto.hpp
+++ b/include/evse_security/crypto/evse_crypto.hpp
@@ -6,7 +6,7 @@
// Include other required suppliers here
#ifdef LIBEVSE_CRYPTO_SUPPLIER_OPENSSL
-#include
+#include
namespace evse_security {
typedef OpenSSLSupplier CryptoSupplier; // Define others with the same 'CryptoSupplier' name
}
diff --git a/include/evse_security/crypto/interface/crypto_supplier.hpp b/include/evse_security/crypto/interface/crypto_supplier.hpp
index d73ddde..ed9a88b 100644
--- a/include/evse_security/crypto/interface/crypto_supplier.hpp
+++ b/include/evse_security/crypto/interface/crypto_supplier.hpp
@@ -22,6 +22,8 @@ class AbstractCryptoSupplier {
/// @brief If any TPM operations are supported
static bool supports_tpm();
static bool supports_tpm_key_creation();
+ /// @brief If creation from a custom provider is supported
+ static bool supports_custom_key_creation();
public: // Key utilities
static bool generate_key(const KeyGenerationInfo& generation_info, KeyHandle_ptr& out_key);
diff --git a/include/evse_security/crypto/interface/crypto_types.hpp b/include/evse_security/crypto/interface/crypto_types.hpp
index a29e4b4..1c4bf1f 100644
--- a/include/evse_security/crypto/interface/crypto_types.hpp
+++ b/include/evse_security/crypto/interface/crypto_types.hpp
@@ -39,9 +39,10 @@ enum class CertificateSignRequestResult {
struct KeyGenerationInfo {
CryptoKeyType key_type;
- /// @brief If the key should be generated on the TPM, should check before if
+ /// @brief If the key should be generated using the custom provider. The custom
+ /// provider can be the TPM if it was so configured. Should check before if
/// the provider supports the operation, or the operation will fail by default
- bool generate_on_tpm;
+ bool generate_on_custom;
/// @brief If we should export the public key to a file
std::optional public_key_file;
diff --git a/include/evse_security/crypto/openssl/openssl_supplier.hpp b/include/evse_security/crypto/openssl/openssl_crypto_supplier.hpp
similarity index 98%
rename from include/evse_security/crypto/openssl/openssl_supplier.hpp
rename to include/evse_security/crypto/openssl/openssl_crypto_supplier.hpp
index b0fe169..8400332 100644
--- a/include/evse_security/crypto/openssl/openssl_supplier.hpp
+++ b/include/evse_security/crypto/openssl/openssl_crypto_supplier.hpp
@@ -12,6 +12,7 @@ class OpenSSLSupplier : public AbstractCryptoSupplier {
static bool supports_tpm();
static bool supports_tpm_key_creation();
+ static bool supports_custom_key_creation();
public:
static bool generate_key(const KeyGenerationInfo& key_info, KeyHandle_ptr& out_key);
diff --git a/include/evse_security/crypto/openssl/openssl_tpm.hpp b/include/evse_security/crypto/openssl/openssl_provider.hpp
similarity index 72%
rename from include/evse_security/crypto/openssl/openssl_tpm.hpp
rename to include/evse_security/crypto/openssl/openssl_provider.hpp
index 80853e7..eac04ba 100644
--- a/include/evse_security/crypto/openssl/openssl_tpm.hpp
+++ b/include/evse_security/crypto/openssl/openssl_provider.hpp
@@ -17,23 +17,26 @@ struct ossl_provider_st; // OpenSSL OSSL_PROVIDER
namespace evse_security {
-/// @brief determine if the PEM string is a TSS2 private key
+/// @brief determine if the PEM string is a custom private key. Will
+/// only work for private keys, public keys will always return true
/// @param private_key_pem string containing the PEM encoded key
-/// @return true when "-----BEGIN TSS2 PRIVATE KEY-----" found
+/// @return true when file does not start "-----BEGIN PRIVATE KEY-----"
/// @note works irrespective of OpenSSL version
-bool is_tpm_key_string(const std::string& private_key_pem);
+bool is_custom_private_key_string(const std::string& private_key_pem);
-/// @brief determine if the PEM file contains a TSS2 private key
+/// @brief determine if the PEM file contains a custom private key. Will
+/// only work for private keys, public keys will always return true
/// @param private_key_file_pem filename of the PEM file
-/// @return true when file starts "-----BEGIN TSS2 PRIVATE KEY-----"
+/// @return true when file does not start "-----BEGIN PRIVATE KEY-----"
/// @note works irrespective of OpenSSL version
-bool is_tpm_key_file(const fs::path& private_key_file_pem);
+bool is_custom_private_key_file(const fs::path& private_key_file_pem);
/// @brief Manage the loading and configuring of OpenSSL providers
///
/// There are two providers considered:
/// - 'default'
/// - 'tpm2' for working with TSS2 keys (protected by a TPM)
+/// The 'tpm2' can be replaced with a custom provider (see CMakeLists.txt)
///
/// There are two contexts:
/// - 'global' for general use
@@ -55,25 +58,25 @@ class OpenSSLProvider {
/// @brief supported propquery strings
enum class mode_t {
default_provider,
- tpm2_provider,
+ custom_provider,
};
private:
typedef std::uint8_t flags_underlying_t;
enum class flags_t : flags_underlying_t {
initialised,
- tpm2_available,
- global_tpm2,
- tls_tpm2,
+ custom_provider_available,
+ global_custom_provider,
+ tls_custom_provider,
};
static std::mutex s_mux;
static flags_underlying_t s_flags;
static struct ossl_provider_st* s_global_prov_default_p;
- static struct ossl_provider_st* s_global_prov_tpm_p;
+ static struct ossl_provider_st* s_global_prov_custom_p;
static struct ossl_provider_st* s_tls_prov_default_p;
- static struct ossl_provider_st* s_tls_prov_tpm_p;
+ static struct ossl_provider_st* s_tls_prov_custom_p;
static struct ossl_lib_ctx_st* s_tls_libctx_p;
static inline void reset(flags_t f) {
@@ -97,22 +100,22 @@ class OpenSSLProvider {
/// @param val - whether to set or reset the flag
/// @return true when the flag was changed
static inline bool update(flags_t f, bool val) {
- bool bResult = val != is_set(f);
+ bool result = (val != is_set(f));
if (val) {
set(f);
} else {
reset(f);
}
- return bResult;
+ return result;
}
- bool load(struct ossl_provider_st*& default_p, struct ossl_provider_st*& tpm2_p, struct ossl_lib_ctx_st* libctx_p,
+ bool load(struct ossl_provider_st*& default_p, struct ossl_provider_st*& custom_p, struct ossl_lib_ctx_st* libctx_p,
mode_t mode);
inline bool load_global(mode_t mode) {
- return load(s_global_prov_default_p, s_global_prov_tpm_p, nullptr, mode);
+ return load(s_global_prov_default_p, s_global_prov_custom_p, nullptr, mode);
}
inline bool load_tls(mode_t mode) {
- return load(s_tls_prov_default_p, s_tls_prov_tpm_p, s_tls_libctx_p, mode);
+ return load(s_tls_prov_default_p, s_tls_prov_custom_p, s_tls_libctx_p, mode);
}
bool set_propstr(struct ossl_lib_ctx_st* libctx, mode_t mode);
@@ -133,10 +136,10 @@ class OpenSSLProvider {
const char* propquery(mode_t mode) const;
inline mode_t propquery_global() const {
- return (is_set(flags_t::global_tpm2)) ? mode_t::tpm2_provider : mode_t::default_provider;
+ return (is_set(flags_t::global_custom_provider)) ? mode_t::custom_provider : mode_t::default_provider;
}
inline mode_t propquery_tls() const {
- return (is_set(flags_t::tls_tpm2)) ? mode_t::tpm2_provider : mode_t::default_provider;
+ return (is_set(flags_t::tls_custom_provider)) ? mode_t::custom_provider : mode_t::default_provider;
}
inline const char* propquery_global_str() const {
@@ -151,9 +154,8 @@ class OpenSSLProvider {
return s_tls_libctx_p;
}
- static inline bool supports_tpm() {
- return is_set(flags_t::tpm2_available);
- }
+ static bool supports_provider_tpm();
+ static bool supports_provider_custom();
static void cleanup();
};
diff --git a/include/evse_security/evse_security.hpp b/include/evse_security/evse_security.hpp
index db8b9e2..e1a7507 100644
--- a/include/evse_security/evse_security.hpp
+++ b/include/evse_security/evse_security.hpp
@@ -164,12 +164,14 @@ class EvseSecurity {
/// @param country
/// @param organization
/// @param common
- /// @param use_tpm If the TPM should be used for the CSR request
+ /// @param use_custom_provider If the custom provider (which can be the TPM if using -DUSING_TPM2=ON) should be
+ /// used for the CSR request
/// @return the status and an optional PEM formatted certificate signing request string
GetCertificateSignRequestResult generate_certificate_signing_request(LeafCertificateType certificate_type,
const std::string& country,
const std::string& organization,
- const std::string& common, bool use_tpm);
+ const std::string& common,
+ bool use_custom_provider);
/// @brief Generates a certificate signing request for the given \p certificate_type , \p country , \p organization
/// and \p common without using the TPM
diff --git a/include/evse_security/evse_types.hpp b/include/evse_security/evse_types.hpp
index 804004d..a038e48 100644
--- a/include/evse_security/evse_types.hpp
+++ b/include/evse_security/evse_types.hpp
@@ -13,7 +13,7 @@ namespace evse_security {
const fs::path PEM_EXTENSION = ".pem";
const fs::path DER_EXTENSION = ".der";
const fs::path KEY_EXTENSION = ".key";
-const fs::path TPM_KEY_EXTENSION = ".tkey";
+const fs::path CUSTOM_KEY_EXTENSION = ".tkey";
const fs::path CERT_HASH_EXTENSION = ".hash";
enum class EncodingFormat {
diff --git a/lib/evse_security/CMakeLists.txt b/lib/evse_security/CMakeLists.txt
index 3c0ad29..45defdd 100644
--- a/lib/evse_security/CMakeLists.txt
+++ b/lib/evse_security/CMakeLists.txt
@@ -15,8 +15,8 @@ target_sources(evse_security
crypto/interface/crypto_supplier.cpp
crypto/interface/crypto_types.cpp
- crypto/openssl/openssl_supplier.cpp
- crypto/openssl/openssl_tpm.cpp
+ crypto/openssl/openssl_crypto_supplier.cpp
+ crypto/openssl/openssl_provider.cpp
)
target_include_directories(evse_security
@@ -83,11 +83,12 @@ if(LIBEVSE_CRYPTO_SUPPLIER_OPENSSL)
add_compile_definitions(LIBEVSE_CRYPTO_SUPPLIER_OPENSSL)
endif()
-if(USING_TPM2)
+if(USING_TPM2 OR USING_CUSTOM_PROVIDER)
target_compile_definitions(evse_security PRIVATE
- USING_TPM2
- PROPQUERY_DEFAULT="${PROPQUERY_DEFAULT}"
- PROPQUERY_TPM2="${PROPQUERY_TPM2}"
+ USING_CUSTOM_PROVIDER
+ CUSTOM_PROVIDER_NAME="${CUSTOM_PROVIDER_NAME}"
+ PROPQUERY_PROVIDER_DEFAULT="${PROPQUERY_PROVIDER_DEFAULT}"
+ PROPQUERY_PROVIDER_CUSTOM="${PROPQUERY_PROVIDER_CUSTOM}"
)
endif()
diff --git a/lib/evse_security/crypto/openssl/openssl_supplier.cpp b/lib/evse_security/crypto/openssl/openssl_crypto_supplier.cpp
similarity index 97%
rename from lib/evse_security/crypto/openssl/openssl_supplier.cpp
rename to lib/evse_security/crypto/openssl/openssl_crypto_supplier.cpp
index b011609..4952c2b 100644
--- a/lib/evse_security/crypto/openssl/openssl_supplier.cpp
+++ b/lib/evse_security/crypto/openssl/openssl_crypto_supplier.cpp
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest
-#include
+#include
#include
#include
@@ -22,7 +22,7 @@
#include
#include
-#include
+#include
namespace evse_security {
@@ -68,7 +68,7 @@ const char* OpenSSLSupplier::get_supplier_name() {
bool OpenSSLSupplier::supports_tpm_key_creation() {
OpenSSLProvider provider;
- return provider.supports_tpm();
+ return provider.supports_provider_tpm();
}
static bool export_key_internal(const KeyGenerationInfo& key_info, const EVP_PKEY_ptr& evp_key) {
@@ -218,8 +218,8 @@ bool OpenSSLSupplier::generate_key(const KeyGenerationInfo& key_info, KeyHandle_
OpenSSLProvider provider;
bool bResult = true;
- if (key_info.generate_on_tpm) {
- provider.set_global_mode(OpenSSLProvider::mode_t::tpm2_provider);
+ if (key_info.generate_on_custom) {
+ provider.set_global_mode(OpenSSLProvider::mode_t::custom_provider);
} else {
provider.set_global_mode(OpenSSLProvider::mode_t::default_provider);
@@ -564,13 +564,13 @@ KeyValidationResult OpenSSLSupplier::x509_check_private_key(X509Handle* handle,
OpenSSLProvider provider;
- const bool tpm_key = is_tpm_key_string(private_key);
- if (tpm_key) {
- provider.set_global_mode(OpenSSLProvider::mode_t::tpm2_provider);
+ const bool custom_key = is_custom_private_key_string(private_key);
+ if (custom_key) {
+ provider.set_global_mode(OpenSSLProvider::mode_t::custom_provider);
} else {
provider.set_global_mode(OpenSSLProvider::mode_t::default_provider);
}
- EVLOG_debug << "TPM Key: " << tpm_key;
+ EVLOG_debug << "Is Custom Key: " << custom_key;
BIO_ptr bio(BIO_new_mem_buf(private_key.c_str(), -1));
// Passing password string since if NULL is provided, the password CB will be called
@@ -648,8 +648,8 @@ CertificateSignRequestResult OpenSSLSupplier::x509_generate_csr(const Certificat
EVP_PKEY_CTX_ptr ctx;
OpenSSLProvider provider;
- if (csr_info.key_info.generate_on_tpm) {
- provider.set_global_mode(OpenSSLProvider::mode_t::tpm2_provider);
+ if (csr_info.key_info.generate_on_custom) {
+ provider.set_global_mode(OpenSSLProvider::mode_t::custom_provider);
} else {
provider.set_global_mode(OpenSSLProvider::mode_t::default_provider);
}
diff --git a/lib/evse_security/crypto/openssl/openssl_tpm.cpp b/lib/evse_security/crypto/openssl/openssl_provider.cpp
similarity index 66%
rename from lib/evse_security/crypto/openssl/openssl_tpm.cpp
rename to lib/evse_security/crypto/openssl/openssl_provider.cpp
index c4edb0d..5d83fcb 100644
--- a/lib/evse_security/crypto/openssl/openssl_tpm.cpp
+++ b/lib/evse_security/crypto/openssl/openssl_provider.cpp
@@ -1,18 +1,18 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Pionix GmbH and Contributors to EVerest
-#include
+#include
+#include
#include
-#if USING_TPM2
+#if USING_CUSTOM_PROVIDER
// OpenSSL3 without TPM will use the default provider anyway
#include
#include
#include
#include
-#define USING_OPENSSL_3_TPM
#else
// dummy structures for non-OpenSSL 3
struct ossl_provider_st {};
@@ -23,45 +23,57 @@ typedef struct ossl_lib_ctx_st OSSL_LIB_CTX;
namespace evse_security {
-bool is_tpm_key_string(const std::string& private_key_pem) {
- return private_key_pem.find("-----BEGIN TSS2 PRIVATE KEY-----") != std::string::npos;
+static auto KEY_HEADER_DEFAULT = "-----BEGIN PRIVATE KEY-----";
+static auto KEY_HEADER_TPM2 = "-----BEGIN TSS2 PRIVATE KEY-----";
+
+bool is_custom_private_key_string(const std::string& private_key_pem) {
+ // If we can't find the standard header it means it's a custom key
+ return private_key_pem.find(KEY_HEADER_DEFAULT) == std::string::npos;
}
-bool is_tpm_key_file(const fs::path& private_key_file_pem) {
+bool is_custom_private_key_file(const fs::path& private_key_file_pem) {
if (fs::is_regular_file(private_key_file_pem)) {
std::ifstream key_file(private_key_file_pem);
std::string line;
std::getline(key_file, line);
key_file.close();
- return line.find("-----BEGIN TSS2 PRIVATE KEY-----") != std::string::npos;
+ // Search for the standard header
+ return is_custom_private_key_string(line);
}
return false;
}
-#ifdef USING_OPENSSL_3_TPM
+#ifdef USING_CUSTOM_PROVIDER
+
+constexpr bool is_custom_provider_tpm() {
+ // custom provider string (see CMakeLists.txt)
+ constexpr const std::string_view custom_provider(CUSTOM_PROVIDER_NAME);
+ return (custom_provider == "tpm2");
+}
+
// ----------------------------------------------------------------------------
// class OpenSSLProvider OpenSSL 3
static const char* mode_t_str[2] = {
"default provider", // mode_t::default_provider
- "tpm2 provider" // mode_t::tpm2_provider
+ "custom provider" // mode_t::custom_provider
};
static_assert(static_cast(OpenSSLProvider::mode_t::default_provider) == 0);
-static_assert(static_cast(OpenSSLProvider::mode_t::tpm2_provider) == 1);
+static_assert(static_cast(OpenSSLProvider::mode_t::custom_provider) == 1);
std::ostream& operator<<(std::ostream& out, OpenSSLProvider::mode_t mode) {
const unsigned int idx = static_cast(mode);
- if (idx <= static_cast(OpenSSLProvider::mode_t::tpm2_provider)) {
+ if (idx <= static_cast(OpenSSLProvider::mode_t::custom_provider)) {
out << mode_t_str[idx];
}
return out;
}
static bool s_load_and_test_provider(OSSL_PROVIDER*& provider, OSSL_LIB_CTX* libctx, const char* provider_name) {
- bool bResult = true;
+ bool result = true;
#ifdef DEBUG
const char* modestr = (libctx == nullptr) ? "global" : "TLS";
EVLOG_info << "Loading " << modestr << " provider: " << provider_name;
@@ -69,7 +81,7 @@ static bool s_load_and_test_provider(OSSL_PROVIDER*& provider, OSSL_LIB_CTX* lib
if ((provider = OSSL_PROVIDER_load(libctx, provider_name)) == nullptr) {
EVLOG_error << "Unable to load OSSL_PROVIDER: " << provider_name;
ERR_print_errors_fp(stderr);
- bResult = false;
+ result = false;
} else {
#ifdef DEBUG
EVLOG_info << "Testing " << modestr << " provider: " << provider_name;
@@ -79,24 +91,24 @@ static bool s_load_and_test_provider(OSSL_PROVIDER*& provider, OSSL_LIB_CTX* lib
ERR_print_errors_fp(stderr);
OSSL_PROVIDER_unload(provider);
provider = nullptr;
- bResult = false;
+ result = false;
}
}
- return bResult;
+ return result;
}
std::mutex OpenSSLProvider::s_mux;
OpenSSLProvider::flags_underlying_t OpenSSLProvider::s_flags = 0;
OSSL_PROVIDER* OpenSSLProvider::s_global_prov_default_p = nullptr;
-OSSL_PROVIDER* OpenSSLProvider::s_global_prov_tpm_p = nullptr;
+OSSL_PROVIDER* OpenSSLProvider::s_global_prov_custom_p = nullptr;
OSSL_PROVIDER* OpenSSLProvider::s_tls_prov_default_p = nullptr;
-OSSL_PROVIDER* OpenSSLProvider::s_tls_prov_tpm_p = nullptr;
+OSSL_PROVIDER* OpenSSLProvider::s_tls_prov_custom_p = nullptr;
OSSL_LIB_CTX* OpenSSLProvider::s_tls_libctx_p = nullptr;
// propquery strings (see CMakeLists.txt)
-static const char* s_default_provider = PROPQUERY_DEFAULT;
-static const char* s_tpm2_provider = PROPQUERY_TPM2;
+static const char* s_default_provider = PROPQUERY_PROVIDER_DEFAULT;
+static const char* s_custom_provider = PROPQUERY_PROVIDER_CUSTOM;
OpenSSLProvider::OpenSSLProvider() {
s_mux.lock();
@@ -115,12 +127,12 @@ OpenSSLProvider::OpenSSLProvider() {
// load providers for global context
(void)load_global(mode_t::default_provider);
- (void)load_global(mode_t::tpm2_provider);
+ (void)load_global(mode_t::custom_provider);
(void)set_propstr(nullptr, mode_t::default_provider);
// load providers for tls context
(void)load_tls(mode_t::default_provider);
- (void)load_tls(mode_t::tpm2_provider);
+ (void)load_tls(mode_t::custom_provider);
(void)set_propstr(s_tls_libctx_p, mode_t::default_provider);
}
}
@@ -129,23 +141,24 @@ OpenSSLProvider::~OpenSSLProvider() {
s_mux.unlock();
}
-bool OpenSSLProvider::load(OSSL_PROVIDER*& default_p, OSSL_PROVIDER*& tpm2_p, OSSL_LIB_CTX* libctx_p, mode_t mode) {
- bool bResult = true;
+bool OpenSSLProvider::load(OSSL_PROVIDER*& default_p, OSSL_PROVIDER*& custom_p, OSSL_LIB_CTX* libctx_p, mode_t mode) {
+ bool result = true;
switch (mode) {
- case mode_t::tpm2_provider:
- if (tpm2_p == nullptr) {
- bResult = s_load_and_test_provider(tpm2_p, libctx_p, "tpm2");
- update(flags_t::tpm2_available, bResult);
+ case mode_t::custom_provider:
+ if (custom_p == nullptr) {
+ // custom provider string (see CMakeLists.txt)
+ result = s_load_and_test_provider(custom_p, libctx_p, CUSTOM_PROVIDER_NAME);
+ update(flags_t::custom_provider_available, result);
}
break;
case mode_t::default_provider:
default:
if (default_p == nullptr) {
- bResult = s_load_and_test_provider(default_p, libctx_p, "default");
+ result = s_load_and_test_provider(default_p, libctx_p, "default");
}
break;
}
- return bResult;
+ return result;
}
bool OpenSSLProvider::set_propstr(OSSL_LIB_CTX* libctx, mode_t mode) {
@@ -162,15 +175,15 @@ bool OpenSSLProvider::set_propstr(OSSL_LIB_CTX* libctx, mode_t mode) {
}
bool OpenSSLProvider::set_mode(OSSL_LIB_CTX* libctx, mode_t mode) {
- bool bResult;
- const flags_t f = (libctx == nullptr) ? flags_t::global_tpm2 : flags_t::tls_tpm2;
+ bool result;
+ const flags_t f = (libctx == nullptr) ? flags_t::global_custom_provider : flags_t::tls_custom_provider;
- const bool apply = update(f, mode == mode_t::tpm2_provider);
+ const bool apply = update(f, mode == mode_t::custom_provider);
if (apply) {
- bResult = set_propstr(libctx, mode);
+ result = set_propstr(libctx, mode);
}
- return bResult;
+ return result;
}
const char* OpenSSLProvider::propquery(mode_t mode) const {
@@ -180,8 +193,8 @@ const char* OpenSSLProvider::propquery(mode_t mode) const {
case mode_t::default_provider:
propquery_str = s_default_provider;
break;
- case mode_t::tpm2_provider:
- propquery_str = s_tpm2_provider;
+ case mode_t::custom_provider:
+ propquery_str = s_custom_provider;
break;
default:
break;
@@ -194,22 +207,22 @@ void OpenSSLProvider::cleanup() {
// at the point this is called logging may not be available
// relying on OpenSSL errors
std::lock_guard guard(s_mux);
- if (OSSL_PROVIDER_unload(s_tls_prov_tpm_p) == 0) {
+ if (OSSL_PROVIDER_unload(s_tls_prov_custom_p) == 0) {
ERR_print_errors_fp(stderr);
}
if (OSSL_PROVIDER_unload(s_tls_prov_default_p) == 0) {
ERR_print_errors_fp(stderr);
}
- if (OSSL_PROVIDER_unload(s_global_prov_tpm_p) == 0) {
+ if (OSSL_PROVIDER_unload(s_global_prov_custom_p) == 0) {
ERR_print_errors_fp(stderr);
}
if (OSSL_PROVIDER_unload(s_global_prov_default_p) == 0) {
ERR_print_errors_fp(stderr);
}
- s_tls_prov_tpm_p = nullptr;
+ s_tls_prov_custom_p = nullptr;
s_tls_prov_default_p = nullptr;
- s_global_prov_tpm_p = nullptr;
+ s_global_prov_custom_p = nullptr;
s_global_prov_default_p = nullptr;
OSSL_LIB_CTX_free(s_tls_libctx_p);
@@ -218,6 +231,14 @@ void OpenSSLProvider::cleanup() {
s_flags = 0;
}
+bool OpenSSLProvider::supports_provider_tpm() {
+ return is_set(flags_t::custom_provider_available) && is_custom_provider_tpm();
+}
+
+bool OpenSSLProvider::supports_provider_custom() {
+ return is_set(flags_t::custom_provider_available);
+}
+
#else // USING_OPENSSL_3_TPM
// ----------------------------------------------------------------------------
// class OpenSSLProvider dummy where OpenSSL 3 is not available
@@ -225,9 +246,9 @@ void OpenSSLProvider::cleanup() {
OpenSSLProvider::flags_underlying_t OpenSSLProvider::s_flags = 0;
OSSL_PROVIDER* OpenSSLProvider::s_global_prov_default_p = nullptr;
-OSSL_PROVIDER* OpenSSLProvider::s_global_prov_tpm_p = nullptr;
+OSSL_PROVIDER* OpenSSLProvider::s_global_prov_custom_p = nullptr;
OSSL_PROVIDER* OpenSSLProvider::s_tls_prov_default_p = nullptr;
-OSSL_PROVIDER* OpenSSLProvider::s_tls_prov_tpm_p = nullptr;
+OSSL_PROVIDER* OpenSSLProvider::s_tls_prov_custom_p = nullptr;
OSSL_LIB_CTX* OpenSSLProvider::s_tls_libctx_p = nullptr;
OpenSSLProvider::OpenSSLProvider() {
@@ -255,6 +276,14 @@ const char* OpenSSLProvider::propquery(mode_t mode) const {
void OpenSSLProvider::cleanup() {
}
+bool OpenSSLProvider::supports_provider_tpm() {
+ return false;
+}
+
+bool OpenSSLProvider::supports_provider_custom() {
+ return false;
+}
+
#endif // USING_OPENSSL_3_TPM
} // namespace evse_security
diff --git a/lib/evse_security/evse_security.cpp b/lib/evse_security/evse_security.cpp
index 8bf6261..e23264a 100644
--- a/lib/evse_security/evse_security.cpp
+++ b/lib/evse_security/evse_security.cpp
@@ -82,7 +82,7 @@ static bool is_keyfile(const fs::path& file_path) {
if (fs::is_regular_file(file_path)) {
if (file_path.has_extension()) {
auto extension = file_path.extension();
- if (extension == KEY_EXTENSION || extension == TPM_KEY_EXTENSION) {
+ if (extension == KEY_EXTENSION || extension == CUSTOM_KEY_EXTENSION) {
return true;
}
}
@@ -97,7 +97,7 @@ static fs::path get_private_key_path_of_certificate(const X509Wrapper& certifica
// Before iterating the whole dir check by the filename first 'key_path'.key/.tkey
if (certificate.get_file().has_value()) {
// Check normal keyfile & tpm filename
- for (const auto& extension : {KEY_EXTENSION, TPM_KEY_EXTENSION}) {
+ for (const auto& extension : {KEY_EXTENSION, CUSTOM_KEY_EXTENSION}) {
fs::path potential_keyfile = certificate.get_file().value();
potential_keyfile.replace_extension(extension);
@@ -1020,13 +1020,13 @@ GetCertificateSignRequestResult EvseSecurity::generate_certificate_signing_reque
const std::string& country,
const std::string& organization,
const std::string& common,
- bool use_tpm) {
+ bool use_custom_provider) {
std::lock_guard guard(EvseSecurity::security_mutex);
// Make a difference between normal and tpm keys for identification
- const auto file_name =
- conversions::leaf_certificate_type_to_filename(certificate_type) +
- filesystem_utils::get_random_file_name(use_tpm ? TPM_KEY_EXTENSION.string() : KEY_EXTENSION.string());
+ const auto file_name = conversions::leaf_certificate_type_to_filename(certificate_type) +
+ filesystem_utils::get_random_file_name(use_custom_provider ? CUSTOM_KEY_EXTENSION.string()
+ : KEY_EXTENSION.string());
fs::path key_path;
if (certificate_type == LeafCertificateType::CSMS) {
@@ -1060,10 +1060,10 @@ GetCertificateSignRequestResult EvseSecurity::generate_certificate_signing_reque
#endif
info.key_info.key_type = CryptoKeyType::EC_prime256v1;
- info.key_info.generate_on_tpm = use_tpm;
+ info.key_info.generate_on_custom = use_custom_provider;
info.key_info.private_key_file = key_path;
- if ((use_tpm == false) && private_key_password.has_value()) {
+ if ((use_custom_provider == false) && private_key_password.has_value()) {
info.key_info.private_key_pass = private_key_password;
}
diff --git a/tests/openssl_supplier_test.cpp b/tests/openssl_supplier_test.cpp
index d1106c3..ed73e7a 100644
--- a/tests/openssl_supplier_test.cpp
+++ b/tests/openssl_supplier_test.cpp
@@ -2,7 +2,7 @@
#include
#include
-#include
+#include
#include
// #define OUTPUT_CSR
diff --git a/tests/openssl_supplier_test_tpm.cpp b/tests/openssl_supplier_test_tpm.cpp
index 0315317..e0d1f2d 100644
--- a/tests/openssl_supplier_test_tpm.cpp
+++ b/tests/openssl_supplier_test_tpm.cpp
@@ -4,8 +4,8 @@
#include
#include
-#include
-#include
+#include
+#include
using namespace evse_security;
@@ -23,18 +23,18 @@ class OpenSSLSupplierTpmTest : public testing::Test {
}
};
-TEST_F(OpenSSLSupplierTpmTest, supports_tpm) {
+TEST_F(OpenSSLSupplierTpmTest, supports_provider_tpm) {
OpenSSLProvider::cleanup();
- ASSERT_FALSE(OpenSSLProvider::supports_tpm());
+ ASSERT_FALSE(OpenSSLProvider::supports_provider_tpm());
// calculates
OpenSSLProvider provider;
// returns cached
- ASSERT_TRUE(OpenSSLProvider::supports_tpm());
+ ASSERT_TRUE(OpenSSLProvider::supports_provider_tpm());
}
-TEST_F(OpenSSLSupplierTpmTest, supports_tpm_key_creation) {
+TEST_F(OpenSSLSupplierTpmTest, supports_provider_tpm_key_creation) {
OpenSSLProvider::cleanup();
- ASSERT_FALSE(OpenSSLProvider::supports_tpm());
+ ASSERT_FALSE(OpenSSLProvider::supports_provider_tpm());
// should calculate
ASSERT_TRUE(OpenSSLSupplier::supports_tpm_key_creation());
}
@@ -51,7 +51,7 @@ TEST_F(OpenSSLSupplierTpmTest, generate_key_RSA_TPM20) {
TEST_F(OpenSSLSupplierTpmTest, generate_key_RSA_3072) {
// Enable this test manually only if your platform supports 3072 TPM keys
GTEST_SKIP() << "Skipping TPM2.0 GEN_RSA_3072 test since it is a non-spec value"
- "which probably will not be supported on many platforms!";
+ " which probably will not be supported on many platforms!";
KeyGenerationInfo info = {
CryptoKeyType::RSA_3072, true, std::nullopt, std::nullopt, std::nullopt,
diff --git a/tests/tests.cpp b/tests/tests.cpp
index efb6d53..c31c016 100644
--- a/tests/tests.cpp
+++ b/tests/tests.cpp
@@ -21,7 +21,7 @@
#ifdef USING_TPM2
// updates so that existing tests run with the OpenSSLProvider
-#include
+#include
#include
namespace evse_security {
@@ -277,7 +277,7 @@ TEST_F(EvseSecurityTests, verify_normal_keygen) {
KeyHandle_ptr key;
info.key_type = CryptoKeyType::RSA_3072;
- info.generate_on_tpm = false;
+ info.generate_on_custom = false;
info.public_key_file = fs::path("key/nrm_pubkey.key");
info.private_key_file = fs::path("key/nrm_privkey.key");
@@ -291,7 +291,7 @@ TEST_F(EvseSecurityTests, verify_keygen_csr) {
KeyHandle_ptr key;
info.key_type = CryptoKeyType::EC_prime256v1;
- info.generate_on_tpm = false;
+ info.generate_on_custom = false;
info.public_key_file = fs::path("key/pubkey.key");
info.private_key_file = fs::path("key/privkey.key");