diff --git a/src/decoder.c b/src/decoder.c index f5f47ce8..8c3c3636 100644 --- a/src/decoder.c +++ b/src/decoder.c @@ -81,29 +81,15 @@ static int filter_for_desired_data_type(const OSSL_PARAM params[], void *arg) return RET_OSSL_CARRY_ON_DECODING; } -static int p11prov_der_decoder_p11prov_obj_decode( - const char *desired_data_type, void *inctx, OSSL_CORE_BIO *cin, - int selection, OSSL_CALLBACK *object_cb, void *object_cbarg, - OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +static int load_obj(struct desired_data_type_cbdata *cbdata, + const P11PROV_DECODER_CTX *ctx, const unsigned char *der, + long der_len, OSSL_CALLBACK *object_cb, void *object_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) { - P11PROV_DECODER_CTX *const ctx = inctx; - P11PROV_PK11_URI *obj = NULL; - BIO *bin; int ret = RET_OSSL_CARRY_ON_DECODING; + P11PROV_PK11_URI *obj = NULL; char *uri = NULL; - bin = BIO_new_from_core_bio(p11prov_ctx_get_libctx(ctx->provctx), cin); - if (!bin) { - P11PROV_debug("P11 DECODER BIO_new_from_core_bio failed"); - goto done; - } - - const unsigned char *der; - long der_len = BIO_get_mem_data(bin, &der); - if (der_len <= 0) { - P11PROV_debug("P11 DECODER BIO_get_mem_data failed"); - goto done; - } obj = d2i_P11PROV_PK11_URI(NULL, &der, der_len); if (!obj) { P11PROV_debug("P11 KEY DECODER d2i_P11PROV_PK11_URI failed"); @@ -121,18 +107,51 @@ static int p11prov_der_decoder_p11prov_obj_decode( p11prov_set_error_mark(ctx->provctx); - struct desired_data_type_cbdata cbdata = { desired_data_type, object_cb, - object_cbarg }; ret = p11prov_store_direct_fetch(ctx->provctx, uri, - filter_for_desired_data_type, &cbdata, + filter_for_desired_data_type, cbdata, pw_cb, pw_cbarg); p11prov_pop_error_to_mark(ctx->provctx); p11prov_clear_last_error_mark(ctx->provctx); - done: OPENSSL_free(uri); P11PROV_PK11_URI_free(obj); + return ret; +} + +static int p11prov_der_decoder_p11prov_obj_decode( + const char *desired_data_type, void *inctx, OSSL_CORE_BIO *cin, + int selection, OSSL_CALLBACK *object_cb, void *object_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + const P11PROV_DECODER_CTX *ctx = inctx; + BIO *bin; + unsigned char *der = NULL; + long der_len; + int ret = RET_OSSL_CARRY_ON_DECODING; + + bin = BIO_new_from_core_bio(p11prov_ctx_get_libctx(ctx->provctx), cin); + if (!bin) { + P11PROV_debug("P11 DECODER BIO_new_from_core_bio failed"); + goto done; + } + + der_len = BIO_get_mem_data(bin, &der); + if (der_len <= 0) { + P11PROV_debug("P11 DECODER BIO_get_mem_data failed"); + goto done; + } + + struct desired_data_type_cbdata cbdata = { + .desired_data_type = desired_data_type, + .cb = object_cb, + .cbarg = object_cbarg, + }; + + ret = load_obj(&cbdata, ctx, der, der_len, object_cb, object_cbarg, pw_cb, + pw_cbarg); + +done: BIO_free(bin); P11PROV_debug("der decoder (carry on:%d)", ret); return ret; @@ -194,6 +213,17 @@ static int p11prov_pem_decoder_p11prov_der_decode( if (PEM_read_bio(bin, &pem_label, &pem_header, &der_data, &der_len) > 0 && strcmp(pem_label, P11PROV_PEM_LABEL) == 0) { + + /* special case certificates */ + struct desired_data_type_cbdata cbdata = { + .desired_data_type = P11PROV_NAME_CERTIFICATE, + .cb = object_cb, + .cbarg = object_cbarg, + }; + load_obj(&cbdata, ctx, der_data, der_len, object_cb, object_cbarg, + pw_cb, pw_cbarg); + /* */ + params[0] = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA, der_data, der_len); params[1] = OSSL_PARAM_construct_utf8_string( diff --git a/src/provider.h b/src/provider.h index 8294c119..5fdf4a0e 100644 --- a/src/provider.h +++ b/src/provider.h @@ -59,6 +59,7 @@ #define P11PROV_DESCS_RAND "PKCS11 Random Generator" #define P11PROV_NAMES_RSAKEY "RSA" #define P11PROV_DESCS_RSAKEY "PKCS11 RSA Key" +#define P11PROV_NAME_CERTIFICATE "CERTIFICATE" #define P11PROV_PARAM_URI "pkcs11_uri" #define P11PROV_PARAM_KEY_USAGE "pkcs11_key_usage" diff --git a/src/store.c b/src/store.c index 330f2fd0..27d2e5f3 100644 --- a/src/store.c +++ b/src/store.c @@ -384,7 +384,7 @@ static int p11prov_store_load(void *pctx, OSSL_CALLBACK *object_cb, break; case CKO_CERTIFICATE: object_type = OSSL_OBJECT_CERT; - data_type = (char *)"CERTIFICATE"; + data_type = (char *)P11PROV_NAME_CERTIFICATE; cert = p11prov_obj_get_attr(obj, CKA_VALUE); if (cert == NULL) { return RET_OSSL_ERR; diff --git a/tests/tpem_encoder b/tests/tpem_encoder index 09eea2da..988e113a 100755 --- a/tests/tpem_encoder +++ b/tests/tpem_encoder @@ -146,4 +146,17 @@ if [[ ! ${DATA} =~ "Total found: 1" ]]; then exit 1 fi + +title PARA "Test certificate is usable" +make-uri-pem "${ECCRTURI}" "${TMPPDIR}/eccrturi-cert.pem" +ossl ' +storeutl + -out "${TMPPDIR}/storeutl-eccrturi-cert.txt" + "${TMPPDIR}/eccrturi-cert.pem"' +DATA=$(cat "${TMPPDIR}/storeutl-eccrturi-cert.txt") +if [[ ! ${DATA} =~ "Total found: 1" ]]; then + echo "Should return certificate" + exit 1 +fi + exit 0