commit 5e374ad2430df824f0b26264943499d1286d1509 Author: CentOS Sources Date: Tue Jan 21 18:03:09 2020 -0500 import openssl-pkcs11-0.4.10-2.el8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..61eac34 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/libp11-0.4.10.tar.gz diff --git a/.openssl-pkcs11.metadata b/.openssl-pkcs11.metadata new file mode 100644 index 0000000..b2563de --- /dev/null +++ b/.openssl-pkcs11.metadata @@ -0,0 +1 @@ +9407888f8f8fd144d0003390c20729cbfb75997f SOURCES/libp11-0.4.10.tar.gz diff --git a/SOURCES/openssl-pkcs11-0.4.10-search-objects-in-all-matching-tokens.patch b/SOURCES/openssl-pkcs11-0.4.10-search-objects-in-all-matching-tokens.patch new file mode 100644 index 0000000..3cc5316 --- /dev/null +++ b/SOURCES/openssl-pkcs11-0.4.10-search-objects-in-all-matching-tokens.patch @@ -0,0 +1,929 @@ +From 3e219e92aecad385ba003c2276d58db3e80387cc Mon Sep 17 00:00:00 2001 +From: Anderson Toshiyuki Sasaki +Date: Thu, 5 Sep 2019 18:29:53 +0200 +Subject: [PATCH 1/4] tests/rsa-common: Add function to create various tokens + +This allows the creation of multiple devices in the test scripts. + +Signed-off-by: Anderson Toshiyuki Sasaki +(cherry picked from commit 712e869189610f900ebf8c50090e228167b6bf8f) +--- + tests/rsa-common.sh | 54 +++++++++++++++++++++++++++++++++++---------- + 1 file changed, 42 insertions(+), 12 deletions(-) + +diff --git a/tests/rsa-common.sh b/tests/rsa-common.sh +index 7db5ba0..e6e12cb 100755 +--- a/tests/rsa-common.sh ++++ b/tests/rsa-common.sh +@@ -86,13 +86,13 @@ init_db () { + + # Create a new device + init_card () { +- PIN="$1" +- PUK="$2" +- DEV_LABEL="$3" ++ pin="$1" ++ puk="$2" ++ dev_label="$3" + +- echo -n "* Initializing smart card... " +- ${SOFTHSM_TOOL} --init-token ${SLOT} --label "${DEV_LABEL}" \ +- --so-pin "${PUK}" --pin "${PIN}" >/dev/null ++ echo -n "* Initializing smart card ${dev_label}..." ++ ${SOFTHSM_TOOL} --init-token ${SLOT} --label "${dev_label}" \ ++ --so-pin "${puk}" --pin "${pin}" >/dev/null + if test $? = 0; then + echo ok + else +@@ -103,22 +103,26 @@ init_card () { + + # Import objects to the token + import_objects () { +- ID=$1 +- OBJ_LABEL=$2 ++ id=$1 ++ obj_label=$2 ++ token_label=$3 + +- pkcs11-tool -p ${PIN} --module ${MODULE} -d ${ID} -a ${OBJ_LABEL} -l -w \ ++ pkcs11-tool -p ${PIN} --module ${MODULE} -d ${id} \ ++ --token-label ${token_label} -a ${obj_label} -l -w \ + ${srcdir}/rsa-prvkey.der -y privkey >/dev/null + if test $? != 0;then + exit 1; + fi + +- pkcs11-tool -p ${PIN} --module ${MODULE} -d ${ID} -a ${OBJ_LABEL} -l -w \ ++ pkcs11-tool -p ${PIN} --module ${MODULE} -d ${id} \ ++ --token-label ${token_label} -a ${obj_label} -l -w \ + ${srcdir}/rsa-pubkey.der -y pubkey >/dev/null + if test $? != 0;then + exit 1; + fi + +- pkcs11-tool -p ${PIN} --module ${MODULE} -d ${ID} -a ${OBJ_LABEL} -l -w \ ++ pkcs11-tool -p ${PIN} --module ${MODULE} -d ${id} \ ++ --token-label ${token_label} -a ${obj_label} -l -w \ + ${srcdir}/rsa-cert.der -y cert >/dev/null + if test $? != 0;then + exit 1; +@@ -148,8 +152,34 @@ common_init () { + + echo Importing + # Import the used objects (private key, public key, and certificate) +- import_objects 01020304 "server-key" ++ import_objects 01020304 "server-key" "libp11-test" + + # List the imported objects + list_objects + } ++ ++create_devices () { ++ num_devices=$1 ++ pin="$2" ++ puk="$3" ++ common_label="$4" ++ object_label="$5" ++ ++ i=0 ++ while [ $i -le ${num_devices} ]; do ++ init_card ${pin} ${puk} "${common_label}-$i" ++ ++ echo "Importing objects to token ${common_label}-$i" ++ # Import objects with different labels ++ import_objects 01020304 "${object_label}-$i" "${common_label}-$i" ++ ++ pkcs11-tool -p ${pin} --module ${MODULE} -l -O --token-label \ ++ "${common_label}-$i" ++ if test $? != 0;then ++ echo Failed! ++ exit 1; ++ fi ++ ++ i=$(($i + 1)) ++ done ++} +-- +2.21.0 + + +From 7530dc3ae1350a9968733a9318825f187bd09f77 Mon Sep 17 00:00:00 2001 +From: Anderson Toshiyuki Sasaki +Date: Tue, 3 Sep 2019 19:04:27 +0200 +Subject: [PATCH 2/4] eng_back: Search objects in all matching tokens + +Previously, the search for objects would stop in the first matching +token when a more generic PKCS#11 URI was provided (e.g. +"pkcs11:type=public"). This change makes the search continue past the +first matching token if the object was not found. + +In ctx_load_{key, cert}(), the search will try to login only if a single +token matched the search. This is to avoid trying the provided PIN +against all matching tokens which could lock the devices. + +This also makes the search for objects to ignore uninitialized tokens +and to avoid trying to login when the token does not require login. + +Signed-off-by: Anderson Toshiyuki Sasaki +(cherry picked from commit 85a91f4502d48371df0d392d19cecfbced2388c0) +--- + src/eng_back.c | 393 +++++++++++++++-------- + tests/Makefile.am | 4 +- + tests/pkcs11-uri-without-token.softhsm | 62 ++++ + tests/search-all-matching-tokens.softhsm | 106 ++++++ + 4 files changed, 426 insertions(+), 139 deletions(-) + create mode 100755 tests/pkcs11-uri-without-token.softhsm + create mode 100755 tests/search-all-matching-tokens.softhsm + +diff --git a/src/eng_back.c b/src/eng_back.c +index 39a685a..afa6271 100644 +--- a/src/eng_back.c ++++ b/src/eng_back.c +@@ -375,7 +375,7 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id, + const int login) + { + PKCS11_SLOT *slot; +- PKCS11_SLOT *found_slot = NULL; ++ PKCS11_SLOT *found_slot = NULL, **matched_slots = NULL; + PKCS11_TOKEN *tok, *match_tok = NULL; + PKCS11_CERT *certs, *selected_cert = NULL; + X509 *x509; +@@ -387,6 +387,7 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id, + size_t tmp_pin_len = MAX_PIN_LENGTH; + int slot_nr = -1; + char flags[64]; ++ size_t matched_count = 0; + + if (ctx_init_libp11(ctx)) /* Delayed libp11 initialization */ + return NULL; +@@ -401,11 +402,9 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id, + "The certificate ID is not a valid PKCS#11 URI\n" + "The PKCS#11 URI format is defined by RFC7512\n"); + ENGerr(ENG_F_CTX_LOAD_CERT, ENG_R_INVALID_ID); +- return NULL; ++ goto error; + } + if (tmp_pin_len > 0 && tmp_pin[0] != 0) { +- if (!login) +- return NULL; /* Process on second attempt */ + ctx_destroy_pin(ctx); + ctx->pin = OPENSSL_malloc(MAX_PIN_LENGTH+1); + if (ctx->pin != NULL) { +@@ -424,7 +423,7 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id, + "The legacy ENGINE_pkcs11 ID format is also " + "still accepted for now\n"); + ENGerr(ENG_F_CTX_LOAD_CERT, ENG_R_INVALID_ID); +- return NULL; ++ goto error; + } + } + ctx_log(ctx, 1, "Looking in slot %d for certificate: ", +@@ -440,6 +439,13 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id, + ctx_log(ctx, 1, "\n"); + } + ++ matched_slots = (PKCS11_SLOT **)calloc(ctx->slot_count, ++ sizeof(PKCS11_SLOT *)); ++ if (matched_slots == NULL) { ++ ctx_log(ctx, 0, "Could not allocate memory for matched slots\n"); ++ goto error; ++ } ++ + for (n = 0; n < ctx->slot_count; n++) { + slot = ctx->slot_list + n; + flags[0] = '\0'; +@@ -463,6 +469,7 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id, + slot_nr == (int)PKCS11_get_slotid_from_slot(slot)) { + found_slot = slot; + } ++ + if (match_tok && slot->token && + (match_tok->label == NULL || + !strcmp(match_tok->label, slot->token->label)) && +@@ -483,75 +490,115 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id, + slot->token->label : "no label"); + } + ctx_log(ctx, 1, "\n"); +- } + +- if (match_tok) { +- OPENSSL_free(match_tok->model); +- OPENSSL_free(match_tok->manufacturer); +- OPENSSL_free(match_tok->serialnr); +- OPENSSL_free(match_tok->label); +- OPENSSL_free(match_tok); +- } +- if (found_slot) { +- slot = found_slot; +- } else if (match_tok) { +- ctx_log(ctx, 0, "Specified object not found\n"); +- return NULL; +- } else if (slot_nr == -1) { +- if (!(slot = PKCS11_find_token(ctx->pkcs11_ctx, +- ctx->slot_list, ctx->slot_count))) { +- ctx_log(ctx, 0, "No tokens found\n"); +- return NULL; +- } +- } else { +- ctx_log(ctx, 0, "Invalid slot number: %d\n", slot_nr); +- return NULL; +- } +- tok = slot->token; ++ if (found_slot && found_slot->token && !found_slot->token->initialized) ++ ctx_log(ctx, 0, "Found uninitialized token\n"); + +- if (tok == NULL) { +- ctx_log(ctx, 0, "Empty token found\n"); +- return NULL; ++ /* Ignore slots without tokens or with uninitialized token */ ++ if (found_slot && found_slot->token && found_slot->token->initialized) { ++ matched_slots[matched_count] = found_slot; ++ matched_count++; ++ } ++ found_slot = NULL; + } + +- ctx_log(ctx, 1, "Found slot: %s\n", slot->description); +- ctx_log(ctx, 1, "Found token: %s\n", slot->token->label); ++ if (matched_count == 0) { ++ if (match_tok) { ++ ctx_log(ctx, 0, "Specified object not found\n"); ++ goto error; ++ } + +- /* In several tokens certificates are marked as private */ +- if (login && !ctx_login(ctx, slot, tok, +- ctx->ui_method, ctx->callback_data)) { +- ctx_log(ctx, 0, "Login to token failed, returning NULL...\n"); +- return NULL; ++ /* If the legacy slot ID format was used */ ++ if (slot_nr != -1) { ++ ctx_log(ctx, 0, "Invalid slot number: %d\n", slot_nr); ++ goto error; ++ } else { ++ found_slot = PKCS11_find_token(ctx->pkcs11_ctx, ++ ctx->slot_list, ctx->slot_count); ++ /* Ignore if the the token is not initialized */ ++ if (found_slot && found_slot->token && ++ found_slot->token->initialized) { ++ matched_slots[matched_count] = found_slot; ++ matched_count++; ++ } else { ++ ctx_log(ctx, 0, "No tokens found\n"); ++ goto error; ++ } ++ } + } + +- if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) { +- ctx_log(ctx, 0, "Unable to enumerate certificates\n"); +- return NULL; +- } ++ for (n = 0; n < matched_count; n++) { ++ slot = matched_slots[n]; ++ tok = slot->token; ++ if (tok == NULL) { ++ ctx_log(ctx, 0, "Empty token found\n"); ++ break; ++ } + +- ctx_log(ctx, 1, "Found %u cert%s:\n", cert_count, +- (cert_count <= 1) ? "" : "s"); +- if ((s_slot_cert_id && *s_slot_cert_id) && +- (cert_id_len != 0 || cert_label != NULL)) { +- for (n = 0; n < cert_count; n++) { +- PKCS11_CERT *k = certs + n; ++ ctx_log(ctx, 1, "Found slot: %s\n", slot->description); ++ ctx_log(ctx, 1, "Found token: %s\n", slot->token->label); ++ ++ /* In several tokens certificates are marked as private */ ++ if (login) { ++ /* Only try to login if login is required */ ++ if (tok->loginRequired) { ++ /* Only try to login if a single slot matched to avoiding trying ++ * the PIN against all matching slots */ ++ if (matched_count == 1) { ++ if (!ctx_login(ctx, slot, tok, ++ ctx->ui_method, ctx->callback_data)) { ++ ctx_log(ctx, 0, "Login to token failed, returning NULL...\n"); ++ goto error; ++ } ++ } else { ++ ctx_log(ctx, 0, "Multiple matching slots (%lu); will not try to" ++ " login\n", matched_count); ++ for (m = 0; m < matched_count; m++){ ++ slot = matched_slots[m]; ++ ctx_log(ctx, 0, "[%u] %s: %s\n", m + 1, ++ slot->description? slot->description: ++ "(no description)", ++ (slot->token && slot->token->label)? ++ slot->token->label: "no label"); ++ } ++ goto error; ++ } ++ } ++ } + +- if (cert_label != NULL && strcmp(k->label, cert_label) == 0) +- selected_cert = k; +- if (cert_id_len != 0 && k->id_len == cert_id_len && +- memcmp(k->id, cert_id, cert_id_len) == 0) +- selected_cert = k; ++ if (PKCS11_enumerate_certs(tok, &certs, &cert_count)) { ++ ctx_log(ctx, 0, "Unable to enumerate certificates\n"); ++ continue; + } +- } else { +- for (n = 0; n < cert_count; n++) { +- PKCS11_CERT *k = certs + n; +- if (k->id && *(k->id)) { +- selected_cert = k; /* Use the first certificate with nonempty id */ +- break; ++ ++ ctx_log(ctx, 1, "Found %u cert%s:\n", cert_count, ++ (cert_count <= 1) ? "" : "s"); ++ if ((s_slot_cert_id && *s_slot_cert_id) && ++ (cert_id_len != 0 || cert_label != NULL)) { ++ for (m = 0; m < cert_count; m++) { ++ PKCS11_CERT *k = certs + m; ++ ++ if (cert_label != NULL && strcmp(k->label, cert_label) == 0) ++ selected_cert = k; ++ if (cert_id_len != 0 && k->id_len == cert_id_len && ++ memcmp(k->id, cert_id, cert_id_len) == 0) ++ selected_cert = k; ++ } ++ } else { ++ for (m = 0; m < cert_count; m++) { ++ PKCS11_CERT *k = certs + m; ++ if (k->id && *(k->id)) { ++ selected_cert = k; /* Use the first certificate with nonempty id */ ++ break; ++ } + } ++ if (!selected_cert) ++ selected_cert = certs; /* Use the first certificate */ ++ } ++ ++ if (selected_cert) { ++ break; + } +- if (!selected_cert) +- selected_cert = certs; /* Use the first certificate */ + } + + if (selected_cert != NULL) { +@@ -561,8 +608,20 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id, + ctx_log(ctx, 0, "Certificate not found.\n"); + x509 = NULL; + } ++error: ++ /* Free the searched token data */ ++ if (match_tok) { ++ OPENSSL_free(match_tok->model); ++ OPENSSL_free(match_tok->manufacturer); ++ OPENSSL_free(match_tok->serialnr); ++ OPENSSL_free(match_tok->label); ++ OPENSSL_free(match_tok); ++ } ++ + if (cert_label != NULL) + OPENSSL_free(cert_label); ++ if (matched_slots != NULL) ++ free(matched_slots); + return x509; + } + +@@ -605,7 +664,7 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id, + const int isPrivate, const int login) + { + PKCS11_SLOT *slot; +- PKCS11_SLOT *found_slot = NULL; ++ PKCS11_SLOT *found_slot = NULL, **matched_slots = NULL; + PKCS11_TOKEN *tok, *match_tok = NULL; + PKCS11_KEY *keys, *selected_key = NULL; + EVP_PKEY *pk = NULL; +@@ -617,6 +676,7 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id, + char tmp_pin[MAX_PIN_LENGTH+1]; + size_t tmp_pin_len = MAX_PIN_LENGTH; + char flags[64]; ++ size_t matched_count = 0; + + if (ctx_init_libp11(ctx)) /* Delayed libp11 initialization */ + goto error; +@@ -637,7 +697,9 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id, + goto error; + } + if (tmp_pin_len > 0 && tmp_pin[0] != 0) { +- if (!login) ++ /* If the searched key is public, try without login once even ++ * when the PIN is provided */ ++ if (!login && isPrivate) + goto error; /* Process on second attempt */ + ctx_destroy_pin(ctx); + ctx->pin = OPENSSL_malloc(MAX_PIN_LENGTH+1); +@@ -673,6 +735,13 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id, + ctx_log(ctx, 1, "\n"); + } + ++ matched_slots = (PKCS11_SLOT **)calloc(ctx->slot_count, ++ sizeof(PKCS11_SLOT *)); ++ if (matched_slots == NULL) { ++ ctx_log(ctx, 0, "Could not allocate memory for matched slots\n"); ++ goto error; ++ } ++ + for (n = 0; n < ctx->slot_count; n++) { + slot = ctx->slot_list + n; + flags[0] = '\0'; +@@ -696,6 +765,7 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id, + slot_nr == (int)PKCS11_get_slotid_from_slot(slot)) { + found_slot = slot; + } ++ + if (match_tok && slot->token && + (match_tok->label == NULL || + !strcmp(match_tok->label, slot->token->label)) && +@@ -716,92 +786,128 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id, + slot->token->label : "no label"); + } + ctx_log(ctx, 1, "\n"); +- } + +- if (match_tok) { +- OPENSSL_free(match_tok->model); +- OPENSSL_free(match_tok->manufacturer); +- OPENSSL_free(match_tok->serialnr); +- OPENSSL_free(match_tok->label); +- OPENSSL_free(match_tok); ++ if (found_slot && found_slot->token && !found_slot->token->initialized) ++ ctx_log(ctx, 0, "Found uninitialized token\n"); ++ ++ /* Ignore slots without tokens or with uninitialized token */ ++ if (found_slot && found_slot->token && found_slot->token->initialized) { ++ matched_slots[matched_count] = found_slot; ++ matched_count++; ++ } ++ found_slot = NULL; + } +- if (found_slot) { +- slot = found_slot; +- } else if (match_tok) { +- ctx_log(ctx, 0, "Specified object not found\n"); +- goto error; +- } else if (slot_nr == -1) { +- if (!(slot = PKCS11_find_token(ctx->pkcs11_ctx, +- ctx->slot_list, ctx->slot_count))) { +- ctx_log(ctx, 0, "No tokens found\n"); ++ ++ if (matched_count == 0) { ++ if (match_tok) { ++ ctx_log(ctx, 0, "Specified object not found\n"); + goto error; + } +- } else { +- ctx_log(ctx, 0, "Invalid slot number: %d\n", slot_nr); +- goto error; +- } +- tok = slot->token; + +- if (tok == NULL) { +- ctx_log(ctx, 0, "Found empty token\n"); +- goto error; ++ /* If the legacy slot ID format was used */ ++ if (slot_nr != -1) { ++ ctx_log(ctx, 0, "Invalid slot number: %d\n", slot_nr); ++ goto error; ++ } else { ++ found_slot = PKCS11_find_token(ctx->pkcs11_ctx, ++ ctx->slot_list, ctx->slot_count); ++ /* Ignore if the the token is not initialized */ ++ if (found_slot && found_slot->token && ++ found_slot->token->initialized) { ++ matched_slots[matched_count] = found_slot; ++ matched_count++; ++ } else { ++ ctx_log(ctx, 0, "No tokens found\n"); ++ goto error; ++ } ++ } + } +- /* The following check is non-critical to ensure interoperability +- * with some other (which ones?) PKCS#11 libraries */ +- if (!tok->initialized) +- ctx_log(ctx, 0, "Found uninitialized token\n"); + +- ctx_log(ctx, 1, "Found slot: %s\n", slot->description); +- ctx_log(ctx, 1, "Found token: %s\n", slot->token->label); ++ for (n = 0; n < matched_count; n++) { ++ slot = matched_slots[n]; ++ tok = slot->token; ++ if (tok == NULL) { ++ ctx_log(ctx, 0, "Found empty token\n"); ++ break; ++ } + +- /* Both private and public keys can have the CKA_PRIVATE attribute +- * set and thus require login (even to retrieve attributes!) */ +- if (login && !ctx_login(ctx, slot, tok, ui_method, callback_data)) { +- ctx_log(ctx, 0, "Login to token failed, returning NULL...\n"); +- goto error; +- } ++ ctx_log(ctx, 1, "Found slot: %s\n", slot->description); ++ ctx_log(ctx, 1, "Found token: %s\n", slot->token->label); ++ ++ /* Both private and public keys can have the CKA_PRIVATE attribute ++ * set and thus require login (even to retrieve attributes!) */ ++ if (login) { ++ /* Try to login only if login is required */ ++ if (tok->loginRequired) { ++ /* Try to login only if a single slot matched to avoiding trying ++ * the PIN against all matching slots */ ++ if (matched_count == 1) { ++ if (!ctx_login(ctx, slot, tok, ui_method, callback_data)) { ++ ctx_log(ctx, 0, "Login to token failed, returning NULL...\n"); ++ goto error; ++ } ++ } else { ++ ctx_log(ctx, 0, "Multiple matching slots (%lu); will not try to" ++ " login\n", matched_count); ++ for (m = 0; m < matched_count; m++){ ++ slot = matched_slots[m]; ++ ctx_log(ctx, 1, "[%u] %s: %s\n", m + 1, ++ slot->description? slot->description: ++ "(no description)", ++ (slot->token && slot->token->label)? ++ slot->token->label: "no label"); ++ } ++ goto error; ++ } ++ } ++ } + +- if (isPrivate) { +- /* Make sure there is at least one private key on the token */ +- if (PKCS11_enumerate_keys(tok, &keys, &key_count)) { +- ctx_log(ctx, 0, "Unable to enumerate private keys\n"); +- goto error; ++ if (isPrivate) { ++ /* Make sure there is at least one private key on the token */ ++ if (PKCS11_enumerate_keys(tok, &keys, &key_count)) { ++ ctx_log(ctx, 0, "Unable to enumerate private keys\n"); ++ continue; ++ } ++ } else { ++ /* Make sure there is at least one public key on the token */ ++ if (PKCS11_enumerate_public_keys(tok, &keys, &key_count)) { ++ ctx_log(ctx, 0, "Unable to enumerate public keys\n"); ++ continue; ++ } + } +- } else { +- /* Make sure there is at least one public key on the token */ +- if (PKCS11_enumerate_public_keys(tok, &keys, &key_count)) { +- ctx_log(ctx, 0, "Unable to enumerate public keys\n"); +- goto error; ++ if (key_count == 0) { ++ if (login) /* Only print the error on the second attempt */ ++ ctx_log(ctx, 0, "No %s keys found.\n", ++ (char *)(isPrivate ? "private" : "public")); ++ continue; + } +- } +- if (key_count == 0) { +- if (login) /* Only print the error on the second attempt */ +- ctx_log(ctx, 0, "No %s keys found.\n", +- (char *)(isPrivate ? "private" : "public")); +- goto error; +- } +- ctx_log(ctx, 1, "Found %u %s key%s:\n", key_count, +- (char *)(isPrivate ? "private" : "public"), +- (key_count == 1) ? "" : "s"); +- +- if (s_slot_key_id && *s_slot_key_id && +- (key_id_len != 0 || key_label != NULL)) { +- for (n = 0; n < key_count; n++) { +- PKCS11_KEY *k = keys + n; +- +- ctx_log(ctx, 1, " %2u %c%c id=", n + 1, +- k->isPrivate ? 'P' : ' ', +- k->needLogin ? 'L' : ' '); +- dump_hex(ctx, 1, k->id, k->id_len); +- ctx_log(ctx, 1, " label=%s\n", k->label); +- if (key_label != NULL && strcmp(k->label, key_label) == 0) +- selected_key = k; +- if (key_id_len != 0 && k->id_len == key_id_len +- && memcmp(k->id, key_id, key_id_len) == 0) +- selected_key = k; ++ ctx_log(ctx, 1, "Found %u %s key%s:\n", key_count, ++ (char *)(isPrivate ? "private" : "public"), ++ (key_count == 1) ? "" : "s"); ++ ++ if (s_slot_key_id && *s_slot_key_id && ++ (key_id_len != 0 || key_label != NULL)) { ++ for (m = 0; m < key_count; m++) { ++ PKCS11_KEY *k = keys + m; ++ ++ ctx_log(ctx, 1, " %2u %c%c id=", m + 1, ++ k->isPrivate ? 'P' : ' ', ++ k->needLogin ? 'L' : ' '); ++ dump_hex(ctx, 1, k->id, k->id_len); ++ ctx_log(ctx, 1, " label=%s\n", k->label); ++ if (key_label != NULL && strcmp(k->label, key_label) == 0) ++ selected_key = k; ++ if (key_id_len != 0 && k->id_len == key_id_len ++ && memcmp(k->id, key_id, key_id_len) == 0) ++ selected_key = k; ++ } ++ } else { ++ selected_key = keys; /* Use the first key */ ++ } ++ ++ if (selected_key) { ++ break; + } +- } else { +- selected_key = keys; /* Use the first key */ + } + + if (selected_key != NULL) { +@@ -813,9 +919,20 @@ static EVP_PKEY *ctx_load_key(ENGINE_CTX *ctx, const char *s_slot_key_id, + ctx_log(ctx, 0, "Key not found.\n"); + pk = NULL; + } ++ + error: ++ /* Free the searched token data */ ++ if (match_tok) { ++ OPENSSL_free(match_tok->model); ++ OPENSSL_free(match_tok->manufacturer); ++ OPENSSL_free(match_tok->serialnr); ++ OPENSSL_free(match_tok->label); ++ OPENSSL_free(match_tok); ++ } + if (key_label != NULL) + OPENSSL_free(key_label); ++ if (matched_slots != NULL) ++ free(matched_slots); + return pk; + } + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 2a84403..18886df 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -28,7 +28,9 @@ dist_check_SCRIPTS = \ + rsa-pss-sign.softhsm \ + rsa-oaep.softhsm \ + case-insensitive.softhsm \ +- ec-check-privkey.softhsm ++ ec-check-privkey.softhsm \ ++ pkcs11-uri-without-token.softhsm \ ++ search-all-matching-tokens.softhsm + dist_check_DATA = \ + rsa-cert.der rsa-prvkey.der rsa-pubkey.der \ + ec-cert.der ec-prvkey.der ec-pubkey.der +diff --git a/tests/pkcs11-uri-without-token.softhsm b/tests/pkcs11-uri-without-token.softhsm +new file mode 100755 +index 0000000..f82e1f4 +--- /dev/null ++++ b/tests/pkcs11-uri-without-token.softhsm +@@ -0,0 +1,62 @@ ++#!/bin/sh ++ ++# Copyright (C) 2015 Nikos Mavrogiannopoulos ++# ++# GnuTLS is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation; either version 3 of the License, or (at ++# your option) any later version. ++# ++# GnuTLS is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with GnuTLS; if not, write to the Free Software Foundation, ++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++# This test checks if it is possible to use the keys without specifying the ++# token if there is only one initialized token available. ++ ++outdir="output.$$" ++ ++# Load common test functions ++. ${srcdir}/rsa-common.sh ++ ++# Do the common test initialization ++common_init ++ ++sed -e "s|@MODULE_PATH@|${MODULE}|g" -e \ ++ "s|@ENGINE_PATH@|../src/.libs/pkcs11.so|g" \ ++ <"${srcdir}/engines.cnf.in" >"${outdir}/engines.cnf" ++ ++export OPENSSL_ENGINES="../src/.libs/" ++export OPENSSL_CONF="${outdir}/engines.cnf" ++ ++# These URIs don't contain the token specification ++PRIVATE_KEY="pkcs11:object=server-key;type=private;pin-value=1234" ++PUBLIC_KEY="pkcs11:object=server-key;type=public;pin-value=1234" ++ ++# Create input file ++echo "secret" >"${outdir}/in.txt" ++ ++# Generate signature without specifying the token in the PKCS#11 URI ++openssl pkeyutl -engine pkcs11 -keyform engine -inkey "${PRIVATE_KEY}" \ ++ -sign -out "${outdir}/signature.bin" -in "${outdir}/in.txt" ++if test $? != 0;then ++ echo "Failed to generate signature using PKCS#11 URI ${PRIVATE_KEY}" ++ exit 1; ++fi ++ ++# Verify the signature without specifying the token in the PKCS#11 URI ++openssl pkeyutl -engine pkcs11 -keyform engine -pubin -inkey "${PUBLIC_KEY}" \ ++ -verify -sigfile "${outdir}/signature.bin" -in "${outdir}/in.txt" ++if test $? != 0;then ++ echo "Failed to verify signature using PKCS#11 URI ${PUBLIC_KEY}" ++ exit 1; ++fi ++ ++rm -rf "$outdir" ++ ++exit 0 +diff --git a/tests/search-all-matching-tokens.softhsm b/tests/search-all-matching-tokens.softhsm +new file mode 100755 +index 0000000..d0810c4 +--- /dev/null ++++ b/tests/search-all-matching-tokens.softhsm +@@ -0,0 +1,106 @@ ++#!/bin/sh ++ ++# Copyright (C) 2015 Nikos Mavrogiannopoulos ++# ++# GnuTLS is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation; either version 3 of the License, or (at ++# your option) any later version. ++# ++# GnuTLS is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with GnuTLS; if not, write to the Free Software Foundation, ++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++# This test checks if the search for objects in tokens will continue past the ++# first token found. ++# ++# Generic PKCS#11 URIs are used to make the search to match more than one ++# token. The search should be able to find the objects in each device, which are ++# labeled differently per token. ++# ++# This test also contains a negative test to verify that the engine will not try ++# to login to a token if more than one token matched the search. This is why it ++# is required to have only one match to be able to use a private key. ++ ++outdir="output.$$" ++ ++# Load common test functions ++. ${srcdir}/rsa-common.sh ++ ++PIN=1234 ++PUK=1234 ++ ++NUM_DEVICES=5 ++ ++# Initialize the SoftHSM DB ++init_db ++ ++# Create some devices ++create_devices $NUM_DEVICES $PIN $PUK "libp11-test" "label" ++ ++sed -e "s|@MODULE_PATH@|${MODULE}|g" -e "s|@ENGINE_PATH@|../src/.libs/pkcs11.so|g" <"${srcdir}/engines.cnf.in" >"${outdir}/engines.cnf" ++ ++export OPENSSL_ENGINES="../src/.libs/" ++export OPENSSL_CONF="${outdir}/engines.cnf" ++ ++PRIVATE_KEY="pkcs11:token=libp11-test-3;object=label-3;type=private;pin-value=1234" ++PRIVATE_KEY_WITHOUT_TOKEN="pkcs11:object=label-3;type=private;pin-value=1234" ++PUBLIC_KEY_ANY="pkcs11:type=public" ++CERTIFICATE="pkcs11:object=label-3;type=cert;pin-value=1234" ++ ++# Create input file ++echo "secret" > "${outdir}/in.txt" ++ ++# Verify that it doesn't try to login if more than one token matched the search ++openssl pkeyutl -engine pkcs11 -keyform engine \ ++ -inkey "${PRIVATE_KEY_WITHOUT_TOKEN}" \ ++ -sign -out "${outdir}/signature.bin" -in "${outdir}/in.txt" ++if test $? = 0;then ++ echo "Did not fail when the PKCS#11 URI matched multiple tokens" ++fi ++ ++# Generate signature specifying the token in the PKCS#11 URI ++openssl pkeyutl -engine pkcs11 -keyform engine -inkey "${PRIVATE_KEY}" \ ++ -sign -out "${outdir}/signature.bin" -in "${outdir}/in.txt" ++if test $? != 0;then ++ echo "Failed to sign file using PKCS#11 URI ${PRIVATE_KEY}" ++ exit 1; ++fi ++ ++# Verify the signature using the public key from each token ++i=0 ++while [ $i -le ${NUM_DEVICES} ]; do ++ pubkey="pkcs11:object=label-$i;type=public;pin-value=1234" ++ openssl pkeyutl -engine pkcs11 -keyform engine -pubin -inkey "${pubkey}" \ ++ -verify -sigfile "${outdir}/signature.bin" -in "${outdir}/in.txt" ++ if test $? != 0;then ++ echo "Failed to verify the signature using the PKCS#11 URI ${pubkey}" ++ exit 1; ++ fi ++ i=$(($i + 1)) ++done ++ ++# Verify the signature using a certificate without specifying the token ++openssl pkeyutl -engine pkcs11 -keyform engine -pubin -inkey "${CERTIFICATE}" \ ++ -verify -sigfile "${outdir}/signature.bin" -in "${outdir}/in.txt" ++if test $? != 0;then ++ echo "Failed to verify the signature using the PKCS#11 URI ${CERTIFICATE}" ++ exit 1; ++fi ++ ++# Verify the signature using the first public key found ++openssl pkeyutl -engine pkcs11 -keyform engine -pubin -inkey "${PUBLIC_KEY_ANY}" \ ++ -verify -sigfile "${outdir}/signature.bin" -in "${outdir}/in.txt" ++if test $? != 0;then ++ echo "Failed to verify the signature using the PKCS#11 URI ${PUBLIC_KEY_ANY}." ++ exit 1; ++fi ++ ++rm -rf "$outdir" ++ ++exit 0 +-- +2.21.0 + + +From f7e9c100386e8ed9c0670e36c6023d4c928d132f Mon Sep 17 00:00:00 2001 +From: Anderson Toshiyuki Sasaki +Date: Thu, 21 Nov 2019 16:40:45 +0100 +Subject: [PATCH 3/4] eng_back: Initialize variable + +The unitialized variable could be returned to the caller in case of +error, being the value undefined. + +Signed-off-by: Anderson Toshiyuki Sasaki +(cherry picked from commit f9fd7e65f15d20d4f4f767bb84dfccce02f834e5) +--- + src/eng_back.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/eng_back.c b/src/eng_back.c +index afa6271..0dd697d 100644 +--- a/src/eng_back.c ++++ b/src/eng_back.c +@@ -378,7 +378,7 @@ static X509 *ctx_load_cert(ENGINE_CTX *ctx, const char *s_slot_cert_id, + PKCS11_SLOT *found_slot = NULL, **matched_slots = NULL; + PKCS11_TOKEN *tok, *match_tok = NULL; + PKCS11_CERT *certs, *selected_cert = NULL; +- X509 *x509; ++ X509 *x509 = NULL; + unsigned int cert_count, n, m; + unsigned char cert_id[MAX_VALUE_LEN / 2]; + size_t cert_id_len = sizeof(cert_id); +-- +2.21.0 + + +From 823a97403c80d475c5a0ba88e1f63923dd540db8 Mon Sep 17 00:00:00 2001 +From: Anderson Toshiyuki Sasaki +Date: Mon, 25 Nov 2019 16:00:33 +0100 +Subject: [PATCH 4/4] tests: Add missing exit when test case fail + +The missing exit would make the test to pass even when the test case +failed. + +Signed-off-by: Anderson Toshiyuki Sasaki +(cherry picked from commit a41cbb29083545ceee8da35fa0067e402ed7d676) +--- + tests/search-all-matching-tokens.softhsm | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tests/search-all-matching-tokens.softhsm b/tests/search-all-matching-tokens.softhsm +index d0810c4..0db697e 100755 +--- a/tests/search-all-matching-tokens.softhsm ++++ b/tests/search-all-matching-tokens.softhsm +@@ -62,6 +62,7 @@ openssl pkeyutl -engine pkcs11 -keyform engine \ + -sign -out "${outdir}/signature.bin" -in "${outdir}/in.txt" + if test $? = 0;then + echo "Did not fail when the PKCS#11 URI matched multiple tokens" ++ exit 1; + fi + + # Generate signature specifying the token in the PKCS#11 URI +-- +2.21.0 + diff --git a/SOURCES/openssl-pkcs11-0.4.10-set-rsa-fips-method-flag.patch b/SOURCES/openssl-pkcs11-0.4.10-set-rsa-fips-method-flag.patch new file mode 100644 index 0000000..8abbb38 --- /dev/null +++ b/SOURCES/openssl-pkcs11-0.4.10-set-rsa-fips-method-flag.patch @@ -0,0 +1,11 @@ +--- a/src/p11_rsa.c 2019-04-03 21:58:18.000000000 +0200 ++++ b/src/p11_rsa.c 2019-11-28 15:46:18.898258545 +0100 +@@ -478,7 +478,7 @@ + if (ops == NULL) + return NULL; + RSA_meth_set1_name(ops, "libp11 RSA method"); +- RSA_meth_set_flags(ops, 0); ++ RSA_meth_set_flags(ops, RSA_FLAG_FIPS_METHOD); + RSA_meth_set_priv_enc(ops, pkcs11_rsa_priv_enc_method); + RSA_meth_set_priv_dec(ops, pkcs11_rsa_priv_dec_method); + RSA_meth_set_finish(ops, pkcs11_rsa_free_method); diff --git a/SOURCES/openssl-pkcs11-0.4.10-small-bug-fixes.patch b/SOURCES/openssl-pkcs11-0.4.10-small-bug-fixes.patch new file mode 100644 index 0000000..3370eb5 --- /dev/null +++ b/SOURCES/openssl-pkcs11-0.4.10-small-bug-fixes.patch @@ -0,0 +1,112 @@ +From 987ad38fbb16e5c4fb2f7e8ba7be50f54d108417 Mon Sep 17 00:00:00 2001 +From: Henrik Riomar +Date: Wed, 10 Apr 2019 13:54:17 +0200 +Subject: [PATCH 1/3] add needed include for getpid() + +Fixes: + p11_atfork.c: In function '_P11_get_forkid': + p11_atfork.c:78:9: warning: implicit declaration of function 'getpid'; did you mean 'getenv'? [-Wimplicit-function-declaration] + return getpid(); +(cherry picked from commit 97700cb51ac1e84f5ac8bc402e6f9e0fc271d76b) +--- + src/p11_atfork.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/p11_atfork.c b/src/p11_atfork.c +index 8fc8689..43c38f7 100644 +--- a/src/p11_atfork.c ++++ b/src/p11_atfork.c +@@ -23,6 +23,7 @@ + #include "libp11-int.h" + + #ifndef _WIN32 ++#include + + #ifndef __STDC_VERSION__ + /* older than C90 */ +-- +2.21.0 + + +From 8103e98e452624e254beef0fd788f66d13fc8ae6 Mon Sep 17 00:00:00 2001 +From: ucq +Date: Tue, 14 May 2019 12:17:45 +0900 +Subject: [PATCH 2/3] fix use-after-free on PKCS11_pkey_meths. + +(cherry picked from commit e64496a198d4d2eb0310a22dc21be8b81367d319) +--- + src/p11_pkey.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/src/p11_pkey.c b/src/p11_pkey.c +index 7eaf761..2995881 100644 +--- a/src/p11_pkey.c ++++ b/src/p11_pkey.c +@@ -666,8 +666,8 @@ int PKCS11_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth, + EVP_PKEY_EC, + 0 + }; +- static EVP_PKEY_METHOD *pkey_method_rsa = NULL; +- static EVP_PKEY_METHOD *pkey_method_ec = NULL; ++ EVP_PKEY_METHOD *pkey_method_rsa = NULL; ++ EVP_PKEY_METHOD *pkey_method_ec = NULL; + + (void)e; /* squash the unused parameter warning */ + /* all PKCS#11 engines currently share the same pkey_meths */ +@@ -680,16 +680,14 @@ int PKCS11_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth, + /* get the EVP_PKEY_METHOD */ + switch (nid) { + case EVP_PKEY_RSA: +- if (pkey_method_rsa == NULL) +- pkey_method_rsa = pkcs11_pkey_method_rsa(); ++ pkey_method_rsa = pkcs11_pkey_method_rsa(); + if (pkey_method_rsa == NULL) + return 0; + *pmeth = pkey_method_rsa; + return 1; /* success */ + #ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: +- if (pkey_method_ec == NULL) +- pkey_method_ec = pkcs11_pkey_method_ec(); ++ pkey_method_ec = pkcs11_pkey_method_ec(); + if (pkey_method_ec == NULL) + return 0; + *pmeth = pkey_method_ec; +-- +2.21.0 + + +From d24c5dfa149a15c002d202964c513624d7ae1380 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Micha=C5=82=20Trojnara?= +Date: Wed, 14 Aug 2019 15:23:41 +0200 +Subject: [PATCH 3/3] Remove an unused variable + +(cherry picked from commit 5d48d2ff75918409684a6aefe5b1f3e5d8ec7f0d) +--- + src/p11_pkey.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/p11_pkey.c b/src/p11_pkey.c +index 2995881..de0277e 100644 +--- a/src/p11_pkey.c ++++ b/src/p11_pkey.c +@@ -545,7 +545,7 @@ static int pkcs11_try_pkey_ec_sign(EVP_PKEY_CTX *evp_pkey_ctx, + + ossl_sig = ECDSA_SIG_new(); + if (ossl_sig == NULL) +- return-1; ++ return -1; + + pkey = EVP_PKEY_CTX_get0_pkey(evp_pkey_ctx); + if (pkey == NULL) +@@ -578,7 +578,6 @@ static int pkcs11_try_pkey_ec_sign(EVP_PKEY_CTX *evp_pkey_ctx, + return -1; + + if (!cpriv->sign_initialized) { +- int padding; + CK_MECHANISM mechanism; + memset(&mechanism, 0, sizeof mechanism); + +-- +2.21.0 + diff --git a/SPECS/openssl-pkcs11.spec b/SPECS/openssl-pkcs11.spec new file mode 100644 index 0000000..d16f40d --- /dev/null +++ b/SPECS/openssl-pkcs11.spec @@ -0,0 +1,160 @@ +Version: 0.4.10 +Release: 2%{?dist} + +# Define the directory where the OpenSSL engines are installed +%global enginesdir %{_libdir}/engines-1.1 + +Name: openssl-pkcs11 +Summary: A PKCS#11 engine for use with OpenSSL +# The source code is LGPLv2+ except eng_back.c and eng_parse.c which are BSD +License: LGPLv2+ and BSD +URL: https://github.com/OpenSC/libp11 +Source0: https://github.com/OpenSC/libp11/releases/download/libp11-%{version}/libp11-%{version}.tar.gz + +Patch0: openssl-pkcs11-0.4.10-small-bug-fixes.patch +Patch1: openssl-pkcs11-0.4.10-search-objects-in-all-matching-tokens.patch +Patch2: openssl-pkcs11-0.4.10-set-rsa-fips-method-flag.patch + +BuildRequires: autoconf automake libtool +BuildRequires: openssl-devel +BuildRequires: openssl >= 1.0.2 +BuildRequires: pkgconfig +BuildRequires: pkgconfig(p11-kit-1) +# Needed for testsuite +BuildRequires: softhsm opensc procps-ng + +%if 0%{?fedora} +BuildRequires: doxygen +%endif + +Requires: p11-kit-trust +Requires: openssl >= 1.0.2 + +# Package renamed from libp11 to openssl-pkcs11 in release 0.4.7-4 +Provides: libp11%{?_isa} = %{version}-%{release} +Obsoletes: libp11 < 0.4.7-4 +# The engine_pkcs11 subpackage is also provided +Provides: engine_pkcs11%{?_isa} = %{version}-%{release} +Obsoletes: engine_pkcs11 < 0.4.7-4 + +%if 0%{?fedora} +# The libp11-devel subpackage was removed in libp11-0.4.7-1, but not obsoleted +# This Obsoletes prevents the conflict in updates by removing old libp11-devel +Obsoletes: libp11-devel < 0.4.7-4 +%endif + +%description -n openssl-pkcs11 +openssl-pkcs11 enables hardware security module (HSM), and smart card support in +OpenSSL applications. More precisely, it is an OpenSSL engine which makes +registered PKCS#11 modules available for OpenSSL applications. The engine is +optional and can be loaded by configuration file, command line or through the +OpenSSL ENGINE API. + +# The libp11-devel subpackage was reintroduced in libp11-0.4.7-7 for Fedora +%if 0%{?fedora} +%package -n libp11-devel +Summary: Files for developing with libp11 +Requires: %{name} = %{version}-%{release} + +%description -n libp11-devel +The libp11-devel package contains libraries and header files for +developing applications that use libp11. + +%endif + +%prep +%autosetup -p 1 -n libp11-%{version} + +%build +autoreconf -fvi +export CFLAGS="%{optflags}" +%if 0%{?fedora} +%configure --disable-static --enable-api-doc --with-enginesdir=%{enginesdir} +%else +%configure --disable-static --with-enginesdir=%{enginesdir} +%endif +make V=1 %{?_smp_mflags} + +%install +mkdir -p %{buildroot}%{enginesdir} +make install DESTDIR=%{buildroot} + +# Remove libtool .la files +rm -f %{buildroot}%{_libdir}/*.la +rm -f %{buildroot}%{enginesdir}/*.la + +%if ! 0%{?fedora} +## Remove development files +rm -f %{buildroot}%{_libdir}/libp11.so +rm -f %{buildroot}%{_libdir}/pkgconfig/libp11.pc +rm -f %{buildroot}%{_includedir}/*.h +%endif + +# Remove documentation automatically installed by make install +rm -rf %{buildroot}%{_docdir}/libp11/ + +%check +make check %{?_smp_mflags} || if [ $? -ne 0 ]; then cat tests/*.log; exit 1; fi; + +%ldconfig_scriptlets + +%files +%license COPYING +%doc NEWS +%{_libdir}/libp11.so.* +%{enginesdir}/*.so + +%if 0%{?fedora} +%files -n libp11-devel +%doc examples/ doc/api.out/html/ +%{_libdir}/libp11.so +%{_libdir}/pkgconfig/libp11.pc +%{_includedir}/*.h +%endif + +%changelog +* Thu Nov 28 2019 Anderson Sasaki - 0.4.10-2 +- Set RSA_FLAG_FIPS_METHOD for RSA methods (#1777892) + +* Thu Nov 21 2019 Anderson Sasaki - 0.4.10-1 +- Update to 0.4.10 (#1745082) +- Add BuildRequires for OpenSSL >= 1.0.2, required for testing +- Print tests logs if failed during build +- Small bug fixes such as removal of unused variable +- Search objects in all matching tokens (#1705505) + +* Tue Sep 18 2018 Anderson Sasaki - 0.4.8-2 +- Require OpenSSL >= 1.0.2 +- Fixed missing declaration of ERR_get_CKR_code() +- Add support to use EC keys and tests (#1625338) +- Exposed check_fork() API +- Fixed memory leak of RSA objects in pkcs11_store_key() +- Updated OpenSSL license in eng_front.c +- Fixed build for old C dialects +- Allow engine to use private key without PIN +- Require DEBUG to be defined to print debug messages +- Changed package description + +* Mon Aug 06 2018 Anderson Sasaki - 0.4.8-1 +- Update to 0.4.8-1 +- RSA key generation on the token +- RSA-OAEP and RSA-PKCS encryption support +- RSA-PSS signature support +- Support for OpenSSL 1.1.1 beta +- Removed support for OpenSSL 0.9.8 +- Various bug fixes and enhancements + +* Fri Jul 13 2018 Fedora Release Engineering - 0.4.7-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Wed Jun 06 2018 Anderson Sasaki - 0.4.7-7 +- Reintroduce libp11-devel subpackage to Fedora (#1583719) + +* Tue Mar 13 2018 Anderson Sasaki - 0.4.7-6 +- Obsolete libp11-devel to fix update + +* Tue Mar 06 2018 Anderson Sasaki - 0.4.7-5 +- Fixed broken Obsoletes + +* Thu Mar 01 2018 Anderson Sasaki - 0.4.7-4 +- Package renamed from libp11 to openssl-pkcs11