mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
libekmfweb: Make use of the new libseckey
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
e70cde2c5d
commit
26c34a49b1
@@ -21,17 +21,31 @@ else
|
||||
INSTALL_TARGETS += skip-libekmfweb-openssl
|
||||
endif
|
||||
|
||||
libs = $(rootdir)/libutil/libutil.a
|
||||
libs = $(rootdir)/libseckey/libseckey.a
|
||||
|
||||
TMPFILE := $(shell mktemp)
|
||||
|
||||
detect-openssl-version.dep:
|
||||
echo "#include <openssl/opensslv.h>" > detect-openssl-version.dep
|
||||
echo "#include <openssl/evp.h>" >> detect-openssl-version.dep
|
||||
echo "#if OPENSSL_VERSION_NUMBER < 0x10101000L" >> detect-openssl-version.dep
|
||||
echo " #error openssl version 1.1.1 is required" >> detect-openssl-version.dep
|
||||
echo "#endif" >> detect-openssl-version.dep
|
||||
echo "static void __attribute__((unused)) test(void) {" >> detect-openssl-version.dep
|
||||
echo " EVP_PKEY_meth_remove(NULL);" >> detect-openssl-version.dep
|
||||
echo "}" >> detect-openssl-version.dep
|
||||
echo "#include <openssl/opensslv.h>" > $(TMPFILE)
|
||||
echo "#include <openssl/evp.h>" >> $(TMPFILE)
|
||||
echo "#ifndef OPENSSL_VERSION_PREREQ" >> $(TMPFILE)
|
||||
echo " #if defined(OPENSSL_VERSION_MAJOR) && defined(OPENSSL_VERSION_MINOR)" >> $(TMPFILE)
|
||||
echo " #define OPENSSL_VERSION_PREREQ(maj, min) \\" >> $(TMPFILE)
|
||||
echo " ((OPENSSL_VERSION_MAJOR << 16) + \\" >> $(TMPFILE)
|
||||
echo " OPENSSL_VERSION_MINOR >= ((maj) << 16) + (min))" >> $(TMPFILE)
|
||||
echo " #else" >> $(TMPFILE)
|
||||
echo " #define OPENSSL_VERSION_PREREQ(maj, min) \\" >> $(TMPFILE)
|
||||
echo " (OPENSSL_VERSION_NUMBER >= (((maj) << 28) | \\" >> $(TMPFILE)
|
||||
echo " ((min) << 20)))" >> $(TMPFILE)
|
||||
echo " #endif" >> $(TMPFILE)
|
||||
echo "#endif" >> $(TMPFILE)
|
||||
echo "#if !OPENSSL_VERSION_PREREQ(1, 1)" >> $(TMPFILE)
|
||||
echo " #error openssl version 1.1 is required" >> $(TMPFILE)
|
||||
echo "#endif" >> $(TMPFILE)
|
||||
echo "static void __attribute__((unused)) test(void) {" >> $(TMPFILE)
|
||||
echo " EVP_PKEY_meth_remove(NULL);" >> $(TMPFILE)
|
||||
echo "}" >> $(TMPFILE)
|
||||
mv $(TMPFILE) $@
|
||||
|
||||
check-dep-libekmfweb: detect-openssl-version.dep
|
||||
$(call check_dep, \
|
||||
@@ -39,7 +53,7 @@ check-dep-libekmfweb: detect-openssl-version.dep
|
||||
"detect-openssl-version.dep", \
|
||||
"openssl-devel version >= 1.1.1", \
|
||||
"HAVE_OPENSSL=0", \
|
||||
-I. -lcrypto)
|
||||
-I. -lcrypto -DOPENSSL_SUPPRESS_DEPRECATED)
|
||||
$(call check_dep, \
|
||||
"libekmfweb", \
|
||||
"json-c/json.h", \
|
||||
@@ -73,7 +87,7 @@ libekmfweb.so.$(VERSION): ALL_CFLAGS += -fPIC `curl-config --cflags`
|
||||
libekmfweb.so.$(VERSION): LDLIBS = -ljson-c -lcrypto -lssl `curl-config --libs` -ldl
|
||||
libekmfweb.so.$(VERSION): ALL_LDFLAGS += -shared -Wl,--version-script=libekmfweb.map \
|
||||
-Wl,-z,defs,-Bsymbolic -Wl,-soname,libekmfweb.so.$(VERM)
|
||||
libekmfweb.so.$(VERSION): ekmfweb.o utilities.o cca.o
|
||||
libekmfweb.so.$(VERSION): ekmfweb.o utilities.o cca.o $(libs)
|
||||
$(LINK) $(ALL_LDFLAGS) $^ $(LDLIBS) -o $@
|
||||
ln -srf libekmfweb.so.$(VERSION) libekmfweb.so.$(VERM)
|
||||
ln -srf libekmfweb.so.$(VERSION) libekmfweb.so
|
||||
|
||||
1325
libekmfweb/cca.c
1325
libekmfweb/cca.c
File diff suppressed because it is too large
Load Diff
@@ -19,21 +19,6 @@
|
||||
|
||||
#include "ekmfweb/ekmfweb.h"
|
||||
|
||||
/* CCA PKA Key Generate function */
|
||||
typedef void (*CSNDPKG_t)(long *return_code,
|
||||
long *reason_code,
|
||||
long *exit_data_length,
|
||||
unsigned char *exit_data,
|
||||
long *rule_array_count,
|
||||
unsigned char *rule_array,
|
||||
long *regeneration_data_length,
|
||||
unsigned char *regeneration_data,
|
||||
long *skeleton_key_token_length,
|
||||
unsigned char *skeleton_key_token,
|
||||
unsigned char *transport_key_identifier,
|
||||
long *generated_key_identifier_length,
|
||||
unsigned char *generated_key_identifier);
|
||||
|
||||
/* CCA PKA Key Token Build function */
|
||||
typedef void (*CSNDPKB_t)(long *return_code,
|
||||
long *reason_code,
|
||||
@@ -57,31 +42,6 @@ typedef void (*CSNDPKB_t)(long *return_code,
|
||||
unsigned char *reserved_5,
|
||||
long *token_length, unsigned char *token);
|
||||
|
||||
/* CCA PKA Key Token Change function */
|
||||
typedef void (*CSNDKTC_t)(long *return_code,
|
||||
long *reason_code,
|
||||
long *exit_data_length,
|
||||
unsigned char *exit_data,
|
||||
long *rule_array_count,
|
||||
unsigned char *rule_array,
|
||||
long *key_identifier_length,
|
||||
unsigned char *key_identifier);
|
||||
|
||||
/* CCA Digital Signature Generate function */
|
||||
typedef void (*CSNDDSG_t)(long *return_code,
|
||||
long *reason_code,
|
||||
long *exit_data_length,
|
||||
unsigned char *exit_data,
|
||||
long *rule_array_count,
|
||||
unsigned char *rule_array,
|
||||
long *PKA_private_key_identifier_length,
|
||||
unsigned char *PKA_private_key_identifier,
|
||||
long *hash_length,
|
||||
unsigned char *hash,
|
||||
long *signature_field_length,
|
||||
long *signature_bit_length,
|
||||
unsigned char *signature_field);
|
||||
|
||||
/* CCA Key Token Build2 function */
|
||||
typedef void (*CSNBKTB2_t)(long *return_code,
|
||||
long *reason_code,
|
||||
@@ -153,9 +113,6 @@ typedef void (*CSNDSYI2_t)(long *return_code,
|
||||
|
||||
struct cca_lib {
|
||||
CSNDPKB_t dll_CSNDPKB;
|
||||
CSNDPKG_t dll_CSNDPKG;
|
||||
CSNDKTC_t dll_CSNDKTC;
|
||||
CSNDDSG_t dll_CSNDDSG;
|
||||
CSNBKTB2_t dll_CSNBKTB2;
|
||||
CSNDEDH_t dll_CSNDEDH;
|
||||
CSNDSYI2_t dll_CSNDSYI2;
|
||||
@@ -164,34 +121,6 @@ struct cca_lib {
|
||||
#define CCA_MAX_PKA_KEY_TOKEN_SIZE 3500
|
||||
#define CCA_MAX_SYM_KEY_TOKEN_SIZE 725
|
||||
|
||||
int cca_generate_ecc_key_pair(const struct ekmf_cca_lib *cca_lib,
|
||||
int curve_nid, unsigned char *key_token,
|
||||
size_t *key_token_length, bool verbose);
|
||||
|
||||
int cca_generate_rsa_key_pair(const struct ekmf_cca_lib *cca_lib,
|
||||
size_t modulus_bits, unsigned int pub_exp,
|
||||
unsigned char *key_token,
|
||||
size_t *key_token_length, bool verbose);
|
||||
|
||||
int cca_get_key_type(const unsigned char *key_token, size_t key_token_length,
|
||||
int *pkey_type);
|
||||
|
||||
int cca_reencipher_key(const struct ekmf_cca_lib *cca_lib,
|
||||
const unsigned char *key_token, size_t key_token_length,
|
||||
bool to_new, bool verbose);
|
||||
|
||||
int cca_get_ecc_pub_key_as_pkey(const unsigned char *key_token,
|
||||
size_t key_token_length,
|
||||
EVP_PKEY **pkey, bool verbose);
|
||||
|
||||
int cca_get_ecc_pub_key_as_json_web_key(const unsigned char *key_token,
|
||||
size_t key_token_length,
|
||||
json_object **jwk, bool verbose);
|
||||
|
||||
int cca_get_rsa_pub_key_as_pkey(const unsigned char *key_token,
|
||||
size_t key_token_length,
|
||||
int pkey_type, EVP_PKEY **pkey, bool verbose);
|
||||
|
||||
int cca_import_key_from_json_web_key(const struct ekmf_cca_lib *cca_lib,
|
||||
json_object *jwk, unsigned char *key_token,
|
||||
size_t *key_token_length, bool verbose);
|
||||
@@ -225,23 +154,4 @@ int cca_import_external_key(const struct ekmf_cca_lib *cca_lib,
|
||||
size_t *imported_key_token_length,
|
||||
bool verbose);
|
||||
|
||||
int cca_rsa_sign(const struct ekmf_cca_lib *cca_lib,
|
||||
const unsigned char *key_token, size_t key_token_length,
|
||||
unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen,
|
||||
int padding_type, int digest_nid, bool verbose);
|
||||
|
||||
int cca_rsa_pss_sign(const struct ekmf_cca_lib *cca_lib,
|
||||
const unsigned char *key_token, size_t key_token_length,
|
||||
unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen,
|
||||
int digest_nid, int mgf_digest_nid, int saltlen,
|
||||
bool verbose);
|
||||
|
||||
int cca_ecdsa_sign(const struct ekmf_cca_lib *cca_lib,
|
||||
const unsigned char *key_token, size_t key_token_length,
|
||||
unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen, int digest_nid,
|
||||
bool verbose);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
|
||||
#include "lib/zt_common.h"
|
||||
|
||||
#include "libseckey/sk_openssl.h"
|
||||
|
||||
#include "ekmfweb/ekmfweb.h"
|
||||
#include "utilities.h"
|
||||
#include "cca.h"
|
||||
|
||||
#define SERIAL_NUMBER_BIT_SIZE 159
|
||||
|
||||
#define DEFAULT_SESSION_EC_KEY_CURVE NID_secp521r1
|
||||
|
||||
#define MAX_KEY_BLOB_SIZE CCA_MAX_PKA_KEY_TOKEN_SIZE
|
||||
@@ -144,19 +144,61 @@ static const char *accepted_content_types[] = { "application/json",
|
||||
"text/x-json",
|
||||
NULL};
|
||||
|
||||
struct private_data {
|
||||
const struct ekmf_ext_lib *ext_lib;
|
||||
bool verbose;
|
||||
struct ext_lib_info {
|
||||
struct sk_ext_lib ext_lib;
|
||||
union {
|
||||
struct sk_ext_cca_lib cca; /* Used if type = EXT_LIB_CCA */
|
||||
struct sk_ext_ep11_lib ep11; /* Used if type = EXT_LIB_EP11 */
|
||||
};
|
||||
};
|
||||
|
||||
static int _ekmf_setup_sign_context(const unsigned char *key_blob,
|
||||
size_t key_blob_size, EVP_PKEY *pkey,
|
||||
int digest_nid,
|
||||
struct ekmf_rsa_pss_params *rsa_pss_params,
|
||||
EVP_MD_CTX **md_ctx,
|
||||
EVP_PKEY_CTX **pkey_ctx,
|
||||
struct private_data *private,
|
||||
bool verbose);
|
||||
static void _ekmf_copy_ext_lib(const struct ekmf_ext_lib *ekmf_ext_lib,
|
||||
struct ext_lib_info *ext_lib_info)
|
||||
{
|
||||
switch (ekmf_ext_lib->type) {
|
||||
case EKMF_EXT_LIB_CCA:
|
||||
ext_lib_info->ext_lib.type = SK_EXT_LIB_CCA;
|
||||
ext_lib_info->ext_lib.cca = &ext_lib_info->cca;
|
||||
ext_lib_info->cca.cca_lib = ekmf_ext_lib->cca->cca_lib;
|
||||
break;
|
||||
default:
|
||||
ext_lib_info->ext_lib.type = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void _ekmf_copy_key_gen_info(const struct ekmf_key_gen_info *ekmf_info,
|
||||
struct sk_key_gen_info *sk_info)
|
||||
{
|
||||
switch (ekmf_info->type) {
|
||||
case EKMF_KEY_TYPE_ECC:
|
||||
sk_info->type = SK_KEY_TYPE_EC;
|
||||
sk_info->ec.curve_nid = ekmf_info->params.ecc.curve_nid;
|
||||
break;
|
||||
case EKMF_KEY_TYPE_RSA:
|
||||
sk_info->type = SK_KEY_TYPE_RSA;
|
||||
sk_info->rsa.modulus_bits = ekmf_info->params.rsa.modulus_bits;
|
||||
sk_info->rsa.pub_exp = ekmf_info->params.rsa.pub_exp;
|
||||
sk_info->rsa.x9_31 = 0;
|
||||
break;
|
||||
default:
|
||||
sk_info->type = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void _ekmf_copy_pss_params(
|
||||
const struct ekmf_rsa_pss_params *ekmf_pss_params,
|
||||
struct sk_rsa_pss_params *rsa_pss_params)
|
||||
{
|
||||
if (ekmf_pss_params != NULL) {
|
||||
rsa_pss_params->mgf_digest_nid =
|
||||
ekmf_pss_params->mgf_digest_nid;
|
||||
rsa_pss_params->salt_len = ekmf_pss_params->salt_len;
|
||||
} else {
|
||||
rsa_pss_params->mgf_digest_nid = NID_undef;
|
||||
rsa_pss_params->salt_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the public key from a certificate in PEM format and store it into a
|
||||
@@ -1442,6 +1484,13 @@ int ekmf_get_public_key(const struct ekmf_config *config, CURL **curl_handle,
|
||||
if (config == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
rc = SK_OPENSSL_init(verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to initialize secure key support: "
|
||||
"%s", strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ekmf_check_login_token(config, &token_valid, &login_token,
|
||||
verbose);
|
||||
if (rc != 0 || !token_valid) {
|
||||
@@ -1509,6 +1558,7 @@ out:
|
||||
free(login_token);
|
||||
if (pkey != NULL)
|
||||
EVP_PKEY_free(pkey);
|
||||
SK_OPENSSL_term();
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -1938,53 +1988,26 @@ static int _ekmf_build_signature(unsigned char *key_blob,
|
||||
const struct ekmf_ext_lib *ext_lib,
|
||||
bool verbose)
|
||||
{
|
||||
struct ekmf_rsa_pss_params rsa_pss_params;
|
||||
struct sk_rsa_pss_params rsa_pss_params;
|
||||
struct ext_lib_info ext_lib_info;
|
||||
EVP_PKEY_CTX *pkey_ctx = NULL;
|
||||
struct private_data private;
|
||||
EVP_MD_CTX *md_ctx = NULL;
|
||||
bool pkey_meth = false;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
const char *payload;
|
||||
const char *jws_alg;
|
||||
int rc, curve_nid;
|
||||
char *jws = NULL;
|
||||
int pkey_type;
|
||||
BIO *b;
|
||||
|
||||
switch (ext_lib->type) {
|
||||
case EKMF_EXT_LIB_CCA:
|
||||
rc = cca_get_key_type(key_blob, key_blob_length, &pkey_type);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to get the identity key "
|
||||
"type");
|
||||
goto out;
|
||||
}
|
||||
_ekmf_copy_ext_lib(ext_lib, &ext_lib_info);
|
||||
|
||||
switch (pkey_type) {
|
||||
case EVP_PKEY_EC:
|
||||
rc = cca_get_ecc_pub_key_as_pkey(key_blob,
|
||||
key_blob_length,
|
||||
&pkey, verbose);
|
||||
break;
|
||||
case EVP_PKEY_RSA:
|
||||
case EVP_PKEY_RSA_PSS:
|
||||
rc = cca_get_rsa_pub_key_as_pkey(key_blob,
|
||||
key_blob_length,
|
||||
use_rsa_pss ?
|
||||
EVP_PKEY_RSA_PSS :
|
||||
EVP_PKEY_RSA,
|
||||
&pkey, verbose);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to get the identity PKEY");
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_verbose(verbose, "Invalid ext lib type: %d", ext_lib->type);
|
||||
return -EINVAL;
|
||||
rc = SK_OPENSSL_get_secure_key_as_pkey(key_blob, key_blob_length,
|
||||
use_rsa_pss, &pkey,
|
||||
&ext_lib_info.ext_lib,
|
||||
verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to get the identity PKEY");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2002,8 +2025,7 @@ static int _ekmf_build_signature(unsigned char *key_blob,
|
||||
*/
|
||||
switch (EVP_PKEY_id(pkey)) {
|
||||
case EVP_PKEY_EC:
|
||||
curve_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(
|
||||
EVP_PKEY_get0_EC_KEY(pkey)));
|
||||
curve_nid = SK_OPENSSL_get_curve_from_ec_pkey(pkey);
|
||||
switch (curve_nid) {
|
||||
case NID_secp521r1:
|
||||
digest_nid = NID_sha512;
|
||||
@@ -2069,15 +2091,13 @@ static int _ekmf_build_signature(unsigned char *key_blob,
|
||||
goto out;
|
||||
}
|
||||
|
||||
private.ext_lib = ext_lib;
|
||||
private.verbose = verbose;
|
||||
|
||||
rc = _ekmf_setup_sign_context(key_blob, key_blob_length, pkey,
|
||||
digest_nid, &rsa_pss_params, &md_ctx,
|
||||
&pkey_ctx, &private, verbose);
|
||||
if (rc != 0)
|
||||
rc = SK_OPENSSL_setup_sign_context(pkey, false, digest_nid,
|
||||
&rsa_pss_params, &md_ctx, &pkey_ctx,
|
||||
verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to setup secure key sign context");
|
||||
goto out;
|
||||
pkey_meth = true;
|
||||
}
|
||||
|
||||
payload = json_object_to_json_string_ext(payload_obj,
|
||||
JSON_C_TO_STRING_PLAIN |
|
||||
@@ -2111,8 +2131,6 @@ static int _ekmf_build_signature(unsigned char *key_blob,
|
||||
out:
|
||||
if (md_ctx != NULL)
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
if (pkey_meth)
|
||||
cleanup_secure_key_pkey_method(EVP_PKEY_id(pkey));
|
||||
if (pkey != NULL)
|
||||
EVP_PKEY_free(pkey);
|
||||
if (jws != NULL)
|
||||
@@ -2280,6 +2298,51 @@ out:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback function for SK_OPENSSL_get_public_from_secure_key. Construct
|
||||
* a JSON Web key from a public EC key.
|
||||
*/
|
||||
static int _ekmf_pub_key_as_json_web_key(const struct sk_pub_key_info *pub_key,
|
||||
void *private)
|
||||
{
|
||||
json_object **jwk_ret = private;
|
||||
json_object *jwk_obj = NULL;
|
||||
int rc = 0;
|
||||
|
||||
if (pub_key->type != SK_KEY_TYPE_EC)
|
||||
return -EINVAL;
|
||||
|
||||
/* construct the JWK */
|
||||
jwk_obj = json_object_new_object();
|
||||
if (jwk_obj == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* Note: The order of the fields is important, EKMFWeb expects it in
|
||||
* exactly this order!
|
||||
*/
|
||||
rc = json_object_object_add_ex(jwk_obj, "kty",
|
||||
json_object_new_string("EC"), 0);
|
||||
rc |= json_object_object_add_ex(jwk_obj, "crv", json_object_new_string(
|
||||
EC_curve_nid2nist(pub_key->ec.curve_nid)), 0);
|
||||
rc |= json_object_object_add_ex(jwk_obj, "x",
|
||||
json_object_new_base64url(pub_key->ec.x,
|
||||
pub_key->ec.prime_len),
|
||||
0);
|
||||
rc |= json_object_object_add_ex(jwk_obj, "y",
|
||||
json_object_new_base64url(pub_key->ec.y,
|
||||
pub_key->ec.prime_len),
|
||||
0);
|
||||
if (rc != 0) {
|
||||
json_object_put(jwk_obj);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
*jwk_ret = jwk_obj;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests a key to be retrieved from EKMFweb and imported under the current
|
||||
* HSM's master key.
|
||||
@@ -2342,8 +2405,10 @@ int ekmf_retrieve_key(const struct ekmf_config *config, CURL **curl_handle,
|
||||
json_object *resp_sess_jwk_obj = NULL;
|
||||
json_object *req_sess_jwk_obj = NULL;
|
||||
json_object *resp_exp_jwk_obj = NULL;
|
||||
struct ext_lib_info ext_lib_info;
|
||||
json_object *response_obj = NULL;
|
||||
json_object *request_obj = NULL;
|
||||
struct sk_key_gen_info gen_info;
|
||||
EVP_PKEY *server_pubkey = NULL;
|
||||
char *escaped_uuid = NULL;
|
||||
char *login_token = NULL;
|
||||
@@ -2357,6 +2422,15 @@ int ekmf_retrieve_key(const struct ekmf_config *config, CURL **curl_handle,
|
||||
key_blob_length == NULL || ext_lib == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
_ekmf_copy_ext_lib(ext_lib, &ext_lib_info);
|
||||
|
||||
rc = SK_OPENSSL_init(verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to initialize secure key support: "
|
||||
"%s", strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = ekmf_check_login_token(config, &token_valid, &login_token,
|
||||
verbose);
|
||||
if (rc != 0 || !token_valid) {
|
||||
@@ -2390,34 +2464,30 @@ int ekmf_retrieve_key(const struct ekmf_config *config, CURL **curl_handle,
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (ext_lib->type) {
|
||||
case EKMF_EXT_LIB_CCA:
|
||||
req_sess_ec_key_length = sizeof(req_sess_ec_key);
|
||||
rc = cca_generate_ecc_key_pair(ext_lib->cca,
|
||||
sess_ec_curve_nid != 0 ?
|
||||
sess_ec_curve_nid :
|
||||
DEFAULT_SESSION_EC_KEY_CURVE,
|
||||
req_sess_ec_key,
|
||||
&req_sess_ec_key_length,
|
||||
verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to generate a session EC "
|
||||
"key");
|
||||
goto out;
|
||||
}
|
||||
gen_info.type = SK_KEY_TYPE_EC;
|
||||
gen_info.ec.curve_nid = sess_ec_curve_nid != 0 ? sess_ec_curve_nid :
|
||||
DEFAULT_SESSION_EC_KEY_CURVE;
|
||||
|
||||
rc = cca_get_ecc_pub_key_as_json_web_key(req_sess_ec_key,
|
||||
req_sess_ec_key_length,
|
||||
&req_sess_jwk_obj,
|
||||
verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to generate session JWK");
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_verbose(verbose, "Invalid ext lib type: %d", ext_lib->type);
|
||||
return -EINVAL;
|
||||
req_sess_ec_key_length = sizeof(req_sess_ec_key);
|
||||
rc = SK_OPENSSL_generate_secure_key(req_sess_ec_key,
|
||||
&req_sess_ec_key_length,
|
||||
&gen_info, &ext_lib_info.ext_lib,
|
||||
verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to generate a session EC "
|
||||
"key");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = SK_OPENSSL_get_public_from_secure_key(req_sess_ec_key,
|
||||
req_sess_ec_key_length,
|
||||
_ekmf_pub_key_as_json_web_key,
|
||||
&req_sess_jwk_obj,
|
||||
&ext_lib_info.ext_lib,
|
||||
verbose);
|
||||
if (rc != 0 || req_sess_jwk_obj == NULL) {
|
||||
pr_verbose(verbose, "Failed to generate session JWK");
|
||||
goto out;
|
||||
}
|
||||
|
||||
req_timestamp_obj = get_json_timestamp();
|
||||
@@ -2639,6 +2709,7 @@ out:
|
||||
free(resp_party_info);
|
||||
if (escaped_uuid != NULL)
|
||||
curl_free(escaped_uuid);
|
||||
SK_OPENSSL_term();
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -4803,6 +4874,8 @@ int ekmf_generate_identity_key(const struct ekmf_config *config,
|
||||
{
|
||||
unsigned char key_blob[MAX_KEY_BLOB_SIZE];
|
||||
size_t key_blob_size = sizeof(key_blob);
|
||||
struct ext_lib_info ext_lib_info;
|
||||
struct sk_key_gen_info gen_info;
|
||||
int rc;
|
||||
|
||||
if (config == NULL || info == NULL || ext_lib == NULL)
|
||||
@@ -4810,30 +4883,11 @@ int ekmf_generate_identity_key(const struct ekmf_config *config,
|
||||
if (config->identity_secure_key == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
switch (ext_lib->type) {
|
||||
case EKMF_EXT_LIB_CCA:
|
||||
switch (info->type) {
|
||||
case EKMF_KEY_TYPE_ECC:
|
||||
rc = cca_generate_ecc_key_pair(ext_lib->cca,
|
||||
info->params.ecc.curve_nid,
|
||||
key_blob, &key_blob_size, verbose);
|
||||
break;
|
||||
case EKMF_KEY_TYPE_RSA:
|
||||
rc = cca_generate_rsa_key_pair(ext_lib->cca,
|
||||
info->params.rsa.modulus_bits,
|
||||
info->params.rsa.pub_exp,
|
||||
key_blob, &key_blob_size, verbose);
|
||||
break;
|
||||
default:
|
||||
pr_verbose(verbose, "Invalid key type: %d", info->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_verbose(verbose, "Invalid ext lib type: %d", ext_lib->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
_ekmf_copy_ext_lib(ext_lib, &ext_lib_info);
|
||||
_ekmf_copy_key_gen_info(info, &gen_info);
|
||||
|
||||
rc = SK_OPENSSL_generate_secure_key(key_blob, &key_blob_size, &gen_info,
|
||||
&ext_lib_info.ext_lib, verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to generate a key: rc: %d - %s",
|
||||
rc, strerror(-rc));
|
||||
@@ -4896,6 +4950,7 @@ int ekmf_reencipher_identity_key(const struct ekmf_config *config,
|
||||
{
|
||||
unsigned char key_blob[MAX_KEY_BLOB_SIZE];
|
||||
size_t key_blob_size = sizeof(key_blob);
|
||||
struct ext_lib_info ext_lib_info;
|
||||
const char *out_file;
|
||||
int rc;
|
||||
|
||||
@@ -4904,6 +4959,8 @@ int ekmf_reencipher_identity_key(const struct ekmf_config *config,
|
||||
if (config->identity_secure_key == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
_ekmf_copy_ext_lib(ext_lib, &ext_lib_info);
|
||||
|
||||
rc = read_key_blob(config->identity_secure_key, key_blob,
|
||||
&key_blob_size);
|
||||
if (rc != 0) {
|
||||
@@ -4913,16 +4970,8 @@ int ekmf_reencipher_identity_key(const struct ekmf_config *config,
|
||||
return rc;
|
||||
}
|
||||
|
||||
switch (ext_lib->type) {
|
||||
case EKMF_EXT_LIB_CCA:
|
||||
rc = cca_reencipher_key(ext_lib->cca, key_blob, key_blob_size,
|
||||
to_new, verbose);
|
||||
break;
|
||||
default:
|
||||
pr_verbose(verbose, "Invalid ext lib type: %d", ext_lib->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = SK_OPENSSL_reencipher_secure_key(key_blob, key_blob_size, to_new,
|
||||
&ext_lib_info.ext_lib, verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to re-encipher the secure identity "
|
||||
"key from file '%s': %s",
|
||||
@@ -4942,217 +4991,6 @@ int ekmf_reencipher_identity_key(const struct ekmf_config *config,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for the RSA sign callback to route the call to the selected
|
||||
* secure key library.
|
||||
*/
|
||||
static int _ekmf_rsa_sign(const unsigned char *key_blob, size_t key_blob_length,
|
||||
unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen,
|
||||
int padding_type, int md_nid, void *private)
|
||||
{
|
||||
struct private_data *prv = (struct private_data *)private;
|
||||
|
||||
if (prv == NULL || prv->ext_lib == NULL)
|
||||
return 1;
|
||||
|
||||
switch (prv->ext_lib->type) {
|
||||
case EKMF_EXT_LIB_CCA:
|
||||
return cca_rsa_sign(prv->ext_lib->cca, key_blob,
|
||||
key_blob_length, sig, siglen, tbs, tbslen,
|
||||
padding_type, md_nid, prv->verbose);
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for the RSA-PSS sign callback to route the call to the selected
|
||||
* secure key library.
|
||||
*/
|
||||
static int _ekmf_rsa_pss_sign(const unsigned char *key_blob,
|
||||
size_t key_blob_length, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen, int md_nid, int mgfmd_nid,
|
||||
int saltlen, void *private)
|
||||
{
|
||||
struct private_data *prv = (struct private_data *)private;
|
||||
|
||||
if (prv == NULL || prv->ext_lib == NULL)
|
||||
return 1;
|
||||
|
||||
switch (prv->ext_lib->type) {
|
||||
case EKMF_EXT_LIB_CCA:
|
||||
return cca_rsa_pss_sign(prv->ext_lib->cca, key_blob,
|
||||
key_blob_length, sig, siglen, tbs,
|
||||
tbslen, md_nid, mgfmd_nid, saltlen,
|
||||
prv->verbose);
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for the ECDSA sign callback to route the call to the selected
|
||||
* secure key library.
|
||||
*/
|
||||
static int _ekmf_ecdsa_sign(const unsigned char *key_blob,
|
||||
size_t key_blob_length, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen, int md_nid, void *private)
|
||||
{
|
||||
struct private_data *prv = (struct private_data *)private;
|
||||
|
||||
if (prv == NULL || prv->ext_lib == NULL)
|
||||
return 1;
|
||||
|
||||
switch (prv->ext_lib->type) {
|
||||
case EKMF_EXT_LIB_CCA:
|
||||
return cca_ecdsa_sign(prv->ext_lib->cca, key_blob,
|
||||
key_blob_length, sig, siglen, tbs, tbslen,
|
||||
md_nid, prv->verbose);
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the public key from the key blob as a PKEY object.
|
||||
*/
|
||||
static int _ekmf_get_pub_key_as_pkey(const unsigned char *key_blob,
|
||||
size_t key_blob_size, EVP_PKEY **pkey,
|
||||
bool rsa_pss,
|
||||
const struct ekmf_ext_lib *ext_lib,
|
||||
bool verbose)
|
||||
{
|
||||
int rc, pkey_type;
|
||||
|
||||
switch (ext_lib->type) {
|
||||
case EKMF_EXT_LIB_CCA:
|
||||
rc = cca_get_key_type(key_blob, key_blob_size, &pkey_type);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to get the identity key "
|
||||
"type: %s", strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
switch (pkey_type) {
|
||||
case EVP_PKEY_EC:
|
||||
rc = cca_get_ecc_pub_key_as_pkey(key_blob,
|
||||
key_blob_size, pkey, verbose);
|
||||
break;
|
||||
case EVP_PKEY_RSA:
|
||||
case EVP_PKEY_RSA_PSS:
|
||||
rc = cca_get_rsa_pub_key_as_pkey(key_blob,
|
||||
key_blob_size, rsa_pss ?
|
||||
EVP_PKEY_RSA_PSS : pkey_type,
|
||||
pkey, verbose);
|
||||
break;
|
||||
default:
|
||||
pr_verbose(verbose, "Invalid identity key type: %d",
|
||||
pkey_type);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
break;
|
||||
default:
|
||||
pr_verbose(verbose, "Invalid ext lib type: %d", ext_lib->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup a signing context for the specified key, digest_nid, and RSA-PSS
|
||||
* parameters.
|
||||
*/
|
||||
static int _ekmf_setup_sign_context(const unsigned char *key_blob,
|
||||
size_t key_blob_size, EVP_PKEY *pkey,
|
||||
int digest_nid,
|
||||
struct ekmf_rsa_pss_params *rsa_pss_params,
|
||||
EVP_MD_CTX **md_ctx,
|
||||
EVP_PKEY_CTX **pkey_ctx,
|
||||
struct private_data *private,
|
||||
bool verbose)
|
||||
{
|
||||
struct sk_pkey_sign_func sign_func;
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
const EVP_MD *md = NULL;
|
||||
int rc, default_nid;
|
||||
EVP_MD_CTX *ctx;
|
||||
|
||||
rc = setup_secure_key_pkey_method(EVP_PKEY_id(pkey));
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to setup secure key PKEY method");
|
||||
return rc;
|
||||
}
|
||||
|
||||
ctx = EVP_MD_CTX_new();
|
||||
if (ctx == NULL) {
|
||||
pr_verbose(verbose, "Failed to allocate the digest context");
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (digest_nid != 0) {
|
||||
md = EVP_get_digestbynid(digest_nid);
|
||||
if (md == NULL) {
|
||||
pr_verbose(verbose, "Requested digest not supported");
|
||||
rc = -ENOTSUP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_get_default_digest_nid(pkey, &default_nid) == 2 &&
|
||||
default_nid == 0) {
|
||||
pr_verbose(verbose, "The signing algorithm requires "
|
||||
"there to be no digest");
|
||||
md = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
rc = EVP_DigestSignInit(ctx, &pctx, md, NULL, pkey);
|
||||
if (rc != 1) {
|
||||
pr_verbose(verbose, "Failed to initialize the signing "
|
||||
"operation");
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sign_func.rsa_sign = _ekmf_rsa_sign;
|
||||
sign_func.rsa_pss_sign = _ekmf_rsa_pss_sign;
|
||||
sign_func.ecdsa_sign = _ekmf_ecdsa_sign;
|
||||
|
||||
rc = setup_secure_key_pkey_context(pctx, key_blob, key_blob_size,
|
||||
&sign_func, private);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to setup the secure key PKEY "
|
||||
"context: %s", strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA_PSS && rsa_pss_params != NULL) {
|
||||
rc = setup_rsa_pss_pkey_context(pctx, rsa_pss_params);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to setup RSA-PSS context");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
*md_ctx = ctx;
|
||||
*pkey_ctx = pctx;
|
||||
|
||||
out:
|
||||
if (rc != 0) {
|
||||
cleanup_secure_key_pkey_method(EVP_PKEY_id(pkey));
|
||||
if (ctx != NULL)
|
||||
EVP_MD_CTX_free(ctx);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a certificate signing request using the secure identity key (field
|
||||
* identity_secure_key in config structure) with the specified subject name,
|
||||
@@ -5215,15 +5053,10 @@ int ekmf_generate_csr(const struct ekmf_config *config,
|
||||
const char *csr_pem_filename, bool new_hdr,
|
||||
const struct ekmf_ext_lib *ext_lib, bool verbose)
|
||||
{
|
||||
const STACK_OF(X509_EXTENSION) *cert_exts = NULL;
|
||||
unsigned char key_blob[MAX_KEY_BLOB_SIZE];
|
||||
size_t key_blob_size = sizeof(key_blob);
|
||||
X509_NAME *subject_name = NULL;
|
||||
EVP_PKEY_CTX *pkey_ctx = NULL;
|
||||
struct private_data private;
|
||||
EVP_MD_CTX *md_ctx = NULL;
|
||||
bool pkey_meth = false;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
struct sk_rsa_pss_params pss_params;
|
||||
struct ext_lib_info ext_lib_info;
|
||||
X509_REQ *req = NULL;
|
||||
X509 *cert = NULL;
|
||||
int rc;
|
||||
@@ -5238,6 +5071,15 @@ int ekmf_generate_csr(const struct ekmf_config *config,
|
||||
if (num_extensions != 0 && extensions == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
_ekmf_copy_ext_lib(ext_lib, &ext_lib_info);
|
||||
|
||||
rc = SK_OPENSSL_init(verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to initialize secure key support: "
|
||||
"%s", strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = read_key_blob(config->identity_secure_key, key_blob,
|
||||
&key_blob_size);
|
||||
if (rc != 0) {
|
||||
@@ -5247,30 +5089,6 @@ int ekmf_generate_csr(const struct ekmf_config *config,
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = _ekmf_get_pub_key_as_pkey(key_blob, key_blob_size, &pkey,
|
||||
rsa_pss_params != NULL, ext_lib,
|
||||
verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to get identity key as PKEY from "
|
||||
"file '%s': %s", config->identity_secure_key,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
req = X509_REQ_new();
|
||||
if (req == NULL) {
|
||||
pr_verbose(verbose, "X509_REQ_new failed");
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = X509_REQ_set_version(req, 0L);
|
||||
if (rc != 1) {
|
||||
pr_verbose(verbose, "X509_REQ_set_version failed: rc: %d", rc);
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (renew_cert_filename != NULL) {
|
||||
rc = read_x509_certificate(renew_cert_filename, &cert);
|
||||
if (rc != 0) {
|
||||
@@ -5279,63 +5097,20 @@ int ekmf_generate_csr(const struct ekmf_config *config,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
subject_name = X509_NAME_dup(X509_get_subject_name(cert));
|
||||
cert_exts = X509_get0_extensions(cert);
|
||||
}
|
||||
|
||||
if (subject_rdns != NULL && num_subject_rdns > 0) {
|
||||
rc = build_subject_name(&subject_name, subject_rdns,
|
||||
num_subject_rdns, subject_utf8);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to parse the subject name "
|
||||
"RDSn: %s", strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (subject_name == NULL) {
|
||||
rc = -EINVAL;
|
||||
pr_verbose(verbose, "Subject name can not be empty");
|
||||
goto out;
|
||||
}
|
||||
_ekmf_copy_pss_params(rsa_pss_params, &pss_params);
|
||||
|
||||
rc = X509_REQ_set_subject_name(req, subject_name);
|
||||
if (rc != 1) {
|
||||
rc = -EIO;
|
||||
pr_verbose(verbose, "Failed to set subject name into request");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = build_certificate_extensions(NULL, req, extensions,
|
||||
num_extensions, cert_exts);
|
||||
rc = SK_OPENSSL_generate_csr(key_blob, key_blob_size,
|
||||
subject_rdns, num_subject_rdns,
|
||||
subject_utf8, cert,
|
||||
extensions, num_extensions,
|
||||
digest_nid, &pss_params, &req,
|
||||
&ext_lib_info.ext_lib, verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to parse the extensions: "
|
||||
"%s", strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = X509_REQ_set_pubkey(req, pkey);
|
||||
if (rc != 1) {
|
||||
pr_verbose(verbose, "Failed to set the public key");
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
private.ext_lib = ext_lib;
|
||||
private.verbose = verbose;
|
||||
|
||||
rc = _ekmf_setup_sign_context(key_blob, key_blob_size, pkey, digest_nid,
|
||||
rsa_pss_params, &md_ctx, &pkey_ctx,
|
||||
&private, verbose);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
pkey_meth = true;
|
||||
|
||||
rc = X509_REQ_sign_ctx(req, md_ctx);
|
||||
if (rc <= 0) {
|
||||
pr_verbose(verbose, "Failed to perform the signing operation");
|
||||
rc = -EIO;
|
||||
pr_verbose(verbose, "SK_OPENSSL_generate_csr failed "
|
||||
"'%s': %s", csr_pem_filename, strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -5346,24 +5121,15 @@ int ekmf_generate_csr(const struct ekmf_config *config,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
pr_verbose(verbose, "Certificate Signing Request created:");
|
||||
X509_REQ_print_fp(stderr, req);
|
||||
}
|
||||
pr_verbose(verbose, "Certificate Signing Request created successfully "
|
||||
"into '%s'", csr_pem_filename);
|
||||
|
||||
out:
|
||||
if (md_ctx != NULL)
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
if (pkey_meth)
|
||||
cleanup_secure_key_pkey_method(EVP_PKEY_id(pkey));
|
||||
if (subject_name != NULL)
|
||||
X509_NAME_free(subject_name);
|
||||
if (cert != NULL)
|
||||
X509_free(cert);
|
||||
if (req != NULL)
|
||||
X509_REQ_free(req);
|
||||
if (pkey != NULL)
|
||||
EVP_PKEY_free(pkey);
|
||||
SK_OPENSSL_term();
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -5433,15 +5199,10 @@ int ekmf_generate_ss_cert(const struct ekmf_config *config,
|
||||
const char *cert_pem_filename,
|
||||
const struct ekmf_ext_lib *ext_lib, bool verbose)
|
||||
{
|
||||
const STACK_OF(X509_EXTENSION) *cert_exts = NULL;
|
||||
unsigned char key_blob[MAX_KEY_BLOB_SIZE];
|
||||
size_t key_blob_size = sizeof(key_blob);
|
||||
X509_NAME *subject_name = NULL;
|
||||
EVP_PKEY_CTX *pkey_ctx = NULL;
|
||||
struct private_data private;
|
||||
EVP_MD_CTX *md_ctx = NULL;
|
||||
bool pkey_meth = false;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
struct sk_rsa_pss_params pss_params;
|
||||
struct ext_lib_info ext_lib_info;
|
||||
X509 *rcert = NULL;
|
||||
X509 *cert = NULL;
|
||||
int rc;
|
||||
@@ -5456,6 +5217,15 @@ int ekmf_generate_ss_cert(const struct ekmf_config *config,
|
||||
if (num_extensions != 0 && extensions == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
_ekmf_copy_ext_lib(ext_lib, &ext_lib_info);
|
||||
|
||||
rc = SK_OPENSSL_init(verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to initialize secure key support: "
|
||||
"%s", strerror(-rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = read_key_blob(config->identity_secure_key, key_blob,
|
||||
&key_blob_size);
|
||||
if (rc != 0) {
|
||||
@@ -5465,37 +5235,6 @@ int ekmf_generate_ss_cert(const struct ekmf_config *config,
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = _ekmf_get_pub_key_as_pkey(key_blob, key_blob_size, &pkey,
|
||||
rsa_pss_params != NULL, ext_lib,
|
||||
verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to get identity key as PKEY from "
|
||||
"file '%s': %s", config->identity_secure_key,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
cert = X509_new();
|
||||
if (cert == NULL) {
|
||||
pr_verbose(verbose, "X509_new failed");
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = X509_set_version(cert, 2L);
|
||||
if (rc != 1) {
|
||||
pr_verbose(verbose, "X509_set_version failed: rc: %d", rc);
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = generate_x509_serial_number(cert, SERIAL_NUMBER_BIT_SIZE);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to set the serial number: %s",
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (renew_cert_filename != NULL) {
|
||||
rc = read_x509_certificate(renew_cert_filename, &rcert);
|
||||
if (rc != 0) {
|
||||
@@ -5504,83 +5243,20 @@ int ekmf_generate_ss_cert(const struct ekmf_config *config,
|
||||
strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
subject_name = X509_NAME_dup(X509_get_subject_name(rcert));
|
||||
cert_exts = X509_get0_extensions(rcert);
|
||||
}
|
||||
|
||||
if (subject_rdns != NULL && num_subject_rdns > 0) {
|
||||
rc = build_subject_name(&subject_name, subject_rdns,
|
||||
num_subject_rdns, subject_utf8);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to parse the subject name "
|
||||
"RDSn: %s", strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
_ekmf_copy_pss_params(rsa_pss_params, &pss_params);
|
||||
|
||||
if (subject_name == NULL) {
|
||||
rc = -EINVAL;
|
||||
pr_verbose(verbose, "Subject name can not be empty");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = X509_set_subject_name(cert, subject_name);
|
||||
if (rc != 1) {
|
||||
rc = -EIO;
|
||||
pr_verbose(verbose, "Failed to set subject name into cert");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = X509_set_issuer_name(cert, subject_name);
|
||||
if (rc != 1) {
|
||||
rc = -EIO;
|
||||
pr_verbose(verbose, "Failed to set issuer name into cert");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = build_certificate_extensions(cert, NULL, extensions,
|
||||
num_extensions, cert_exts);
|
||||
rc = SK_OPENSSL_generate_ss_cert(key_blob, key_blob_size,
|
||||
subject_rdns, num_subject_rdns,
|
||||
subject_utf8, rcert,
|
||||
extensions, num_extensions,
|
||||
validity_days, digest_nid,
|
||||
&pss_params, &cert,
|
||||
&ext_lib_info.ext_lib, verbose);
|
||||
if (rc != 0) {
|
||||
pr_verbose(verbose, "Failed to parse the extensions: "
|
||||
"%s", strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (X509_gmtime_adj(X509_getm_notBefore(cert), 0) == NULL) {
|
||||
rc = -EIO;
|
||||
pr_verbose(verbose, "Failed to set notBefore time inti cert");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (X509_time_adj_ex(X509_getm_notAfter(cert),
|
||||
validity_days, 0, NULL) == NULL) {
|
||||
rc = -EIO;
|
||||
pr_verbose(verbose, "Failed to set notAfter time into cert");
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = X509_set_pubkey(cert, pkey);
|
||||
if (rc != 1) {
|
||||
pr_verbose(verbose, "Failed to set the public key");
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
private.ext_lib = ext_lib;
|
||||
private.verbose = verbose;
|
||||
|
||||
rc = _ekmf_setup_sign_context(key_blob, key_blob_size, pkey, digest_nid,
|
||||
rsa_pss_params, &md_ctx, &pkey_ctx,
|
||||
&private, verbose);
|
||||
if (rc != 0)
|
||||
goto out;
|
||||
pkey_meth = true;
|
||||
|
||||
rc = X509_sign_ctx(cert, md_ctx);
|
||||
if (rc <= 0) {
|
||||
pr_verbose(verbose, "Failed to perform the signing operation");
|
||||
rc = -EIO;
|
||||
pr_verbose(verbose, "SK_OPENSSL_generate_ss_cert failed "
|
||||
"'%s': %s", cert_pem_filename, strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -5591,24 +5267,15 @@ int ekmf_generate_ss_cert(const struct ekmf_config *config,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
pr_verbose(verbose, "Self-signed Certificate created:");
|
||||
X509_print_fp(stderr, cert);
|
||||
}
|
||||
pr_verbose(verbose, "Self-signed Certificate created successfully "
|
||||
"into '%s'", cert_pem_filename);
|
||||
|
||||
out:
|
||||
if (md_ctx != NULL)
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
if (pkey_meth)
|
||||
cleanup_secure_key_pkey_method(EVP_PKEY_id(pkey));
|
||||
if (subject_name != NULL)
|
||||
X509_NAME_free(subject_name);
|
||||
if (cert != NULL)
|
||||
X509_free(cert);
|
||||
if (rcert != NULL)
|
||||
X509_free(rcert);
|
||||
if (pkey != NULL)
|
||||
EVP_PKEY_free(pkey);
|
||||
SK_OPENSSL_term();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -81,26 +81,6 @@ void free_key_info(struct ekmf_key_info *key);
|
||||
|
||||
char *get_http_header_value(const struct curl_slist *headers, const char *name);
|
||||
|
||||
size_t ecc_get_curve_prime_bits(int curve_nid);
|
||||
size_t ecc_get_curve_prime_length(int curve_nid);
|
||||
const char *ecc_get_curve_id(int curve_nid);
|
||||
bool ecc_is_prime_curve(int curve_nid);
|
||||
bool ecc_is_brainpool_curve(int curve_nid);
|
||||
int ecc_get_curve_by_id(const char *curve_id);
|
||||
int ecc_get_prime_curve_by_prime_bits(size_t prime_bits);
|
||||
int ecc_get_brainpool_curve_by_prime_bits(size_t prime_bits);
|
||||
|
||||
int ecc_calculate_y_coordinate(int nid, size_t prime_len,
|
||||
const unsigned char *x, int y_bit,
|
||||
unsigned char *y);
|
||||
|
||||
int ecc_pub_key_as_pkey(int nid, size_t prime_len, const unsigned char *x,
|
||||
const unsigned char *y, EVP_PKEY **pkey);
|
||||
|
||||
int rsa_pub_key_as_pkey(const unsigned char *modulus, size_t modulus_length,
|
||||
const unsigned char *pub_exp, size_t pub_exp_length,
|
||||
int pkey_type, EVP_PKEY **pkey);
|
||||
|
||||
int json_web_key_as_pkey(json_object *jwk, int pkey_type, EVP_PKEY **pkey);
|
||||
|
||||
int write_key_blob(const char *filename, unsigned char *key_blob,
|
||||
@@ -119,38 +99,6 @@ int read_public_key(const char *pem_filename, EVP_PKEY **pkey);
|
||||
|
||||
int write_public_key(const char *pem_filename, EVP_PKEY *pkey);
|
||||
|
||||
typedef int (*rsa_sign_t)(const unsigned char *key_blob, size_t key_blob_length,
|
||||
unsigned char *sig, size_t *siglen,
|
||||
const unsigned char *tbs, size_t tbslen,
|
||||
int padding_type, int md_nid,
|
||||
void *private);
|
||||
typedef int (*rsa_pss_sign_t)(const unsigned char *key_blob,
|
||||
size_t key_blob_length, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen, int md_nid, int mfgmd_nid,
|
||||
int saltlen, void *private);
|
||||
typedef int (*ecdsa_sign_t)(const unsigned char *key_blob,
|
||||
size_t key_blob_length, unsigned char *sig,
|
||||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen, int md_nid, void *private);
|
||||
|
||||
struct sk_pkey_sign_func {
|
||||
rsa_sign_t rsa_sign;
|
||||
rsa_pss_sign_t rsa_pss_sign;
|
||||
ecdsa_sign_t ecdsa_sign;
|
||||
};
|
||||
|
||||
int setup_secure_key_pkey_method(int pkey_id);
|
||||
int cleanup_secure_key_pkey_method(int pkey_id);
|
||||
int setup_secure_key_pkey_context(EVP_PKEY_CTX *pkey_ctx,
|
||||
const unsigned char *key_blob,
|
||||
size_t key_blob_len,
|
||||
struct sk_pkey_sign_func *sign_funcs,
|
||||
void *private);
|
||||
|
||||
int setup_rsa_pss_pkey_context(EVP_PKEY_CTX *pkey_ctx,
|
||||
struct ekmf_rsa_pss_params *rsa_pss_params);
|
||||
|
||||
int build_subject_name(X509_NAME **name, const char *rdns[], size_t num_rdns,
|
||||
bool utf8);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user