opensc/SOURCES/opensc-0.23.0-openpgp.patch
2023-09-21 19:44:18 +00:00

226 lines
8.5 KiB
Diff

From 3b580b6fff9ac463ecc6e996cfaf573f62749368 Mon Sep 17 00:00:00 2001
From: Frank Morgner <frankmorgner@gmail.com>
Date: Fri, 14 Apr 2023 12:02:54 +0200
Subject: [PATCH 1/2] openpgp: identify OpenPGP compliance with bcd_version
rather than card type
---
src/libopensc/card-openpgp.c | 22 +++++++++++++---------
1 file changed, 13 insertions(+), 9 deletions(-)
diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
index fad32f0ce7..2ea5dc9d36 100644
--- a/src/libopensc/card-openpgp.c
+++ b/src/libopensc/card-openpgp.c
@@ -1780,13 +1780,18 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len)
* p1: number of an instance (DO 7F21: 0x00 for AUT, 0x01 for DEC and 0x02 for SIG)
*/
static int
-pgp_select_data(sc_card_t *card, u8 p1){
+pgp_select_data(sc_card_t *card, u8 p1)
+{
sc_apdu_t apdu;
u8 apdu_data[6];
int r;
+ struct pgp_priv_data *priv = DRVDATA(card);
LOG_FUNC_CALLED(card->ctx);
+ if (priv->bcd_version < OPENPGP_CARD_3_0)
+ LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
+
sc_log(card->ctx, "select data with: %u", p1);
// create apdu data (taken from spec: SELECT DATA 7.2.5.)
@@ -2179,8 +2184,7 @@ pgp_set_security_env(sc_card_t *card,
/* The SC_SEC_ENV_ALG_PRESENT is set always so let it pass for GNUK */
if ((env->flags & SC_SEC_ENV_ALG_PRESENT)
&& (env->algorithm != SC_ALGORITHM_RSA)
- && (priv->bcd_version < OPENPGP_CARD_3_0)
- && (card->type != SC_CARD_TYPE_OPENPGP_GNUK))
+ && (priv->bcd_version < OPENPGP_CARD_3_0))
LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
"only RSA algorithm supported");
@@ -2944,13 +2948,13 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke
{
sc_algorithm_info_t *algo;
u8 id = key_info->key_id;
+ struct pgp_priv_data *priv = DRVDATA(card);
LOG_FUNC_CALLED(card->ctx);
/* protect incompatible cards against non-RSA */
if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA
- && card->type < SC_CARD_TYPE_OPENPGP_V3
- && card->type != SC_CARD_TYPE_OPENPGP_GNUK)
+ && priv->bcd_version < OPENPGP_CARD_3_0)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
if (id > card->algorithm_count) {
@@ -2992,13 +2996,13 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info)
size_t apdu_le;
size_t resplen = 0;
int r = SC_SUCCESS;
+ struct pgp_priv_data *priv = DRVDATA(card);
LOG_FUNC_CALLED(card->ctx);
/* protect incompatible cards against non-RSA */
if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA
- && card->type < SC_CARD_TYPE_OPENPGP_V3
- && card->type != SC_CARD_TYPE_OPENPGP_GNUK)
+ && priv->bcd_version < OPENPGP_CARD_3_0)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
if (key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA
&& card->type != SC_CARD_TYPE_OPENPGP_GNUK)
@@ -3358,13 +3362,13 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info)
u8 *data = NULL;
size_t len = 0;
int r;
+ struct pgp_priv_data *priv = DRVDATA(card);
LOG_FUNC_CALLED(card->ctx);
/* protect incompatible cards against non-RSA */
if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA
- && card->type < SC_CARD_TYPE_OPENPGP_V3
- && card->type != SC_CARD_TYPE_OPENPGP_GNUK)
+ && priv->bcd_version < OPENPGP_CARD_3_0)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
/* Validate */
From 9eccc1494d8303ffe42beb772732df218875e3ac Mon Sep 17 00:00:00 2001
From: Frank Morgner <frankmorgner@gmail.com>
Date: Fri, 14 Apr 2023 12:09:55 +0200
Subject: [PATCH 2/2] openpgp: ignore errors on SELECT DATA for OpenPGP 2 and
below
fixes https://github.com/OpenSC/OpenSC/issues/2752
---
src/libopensc/pkcs15-openpgp.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c
index e2f3442238..9d3fd746a0 100644
--- a/src/libopensc/pkcs15-openpgp.c
+++ b/src/libopensc/pkcs15-openpgp.c
@@ -556,14 +556,9 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
memset(&cert_info, 0, sizeof(cert_info));
memset(&cert_obj, 0, sizeof(cert_obj));
- /* only try to SELECT DATA for OpenPGP >= v3 */
- if (card->type >= SC_CARD_TYPE_OPENPGP_V3) {
- r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, &i);
- if (r < 0) {
- free(buffer);
- LOG_TEST_RET(card->ctx, r, "Failed OpenPGP - select data");
- }
- }
+ /* try to SELECT DATA. Will only work for OpenPGP >= v3, errors are non-critical */
+ sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, &i);
+
sc_format_path(certs[i].path, &cert_info.path);
/* Certificate ID. We use the same ID as the authentication key */
commit e8fba322a2f4d06ec5c74fe80f9e2b0e9fdefec6
Author: Jakub Jelen <jjelen@redhat.com>
Date: Fri May 19 16:49:00 2023 +0200
openpgp: Fix fingerprint calculation
fixes https://github.com/OpenSC/OpenSC/issues/2775
diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c
index cc454cef..496e38e6 100644
--- a/src/libopensc/card-openpgp.c
+++ b/src/libopensc/card-openpgp.c
@@ -2697,15 +2697,23 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime,
/* RSA */
if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA) {
+ unsigned short bytes_length = 0;
+
*p = 1; /* Algorithm ID, RSA */
p += 1;
+
+ /* Modulus */
+ bytes_length = BYTES4BITS(key_info->u.rsa.modulus_len);
ushort2bebytes(p, (unsigned short)key_info->u.rsa.modulus_len);
p += 2;
- memcpy(p, key_info->u.rsa.modulus, (BYTES4BITS(key_info->u.rsa.modulus_len)));
- p += (key_info->u.rsa.modulus_len >> 3);
- ushort2bebytes(++p, (unsigned short)key_info->u.rsa.exponent_len);
+ memcpy(p, key_info->u.rsa.modulus, bytes_length);
+ p += bytes_length;
+
+ /* Exponent */
+ bytes_length = BYTES4BITS(key_info->u.rsa.exponent_len);
+ ushort2bebytes(p, (unsigned short)key_info->u.rsa.exponent_len);
p += 2;
- memcpy(p, key_info->u.rsa.exponent, (BYTES4BITS(key_info->u.rsa.exponent_len)));
+ memcpy(p, key_info->u.rsa.exponent, bytes_length);
}
/* ECC */
else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH
commit 891f10e49de1a5ee038b1cb2fb59dce40429e6c2
Author: Jakub Jelen <jjelen@redhat.com>
Date: Fri May 19 17:53:35 2023 +0200
openpgp: Fix modulus length calculation in pkc15init layer
diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h
index 5a0a19c5..ba685a30 100644
--- a/src/libopensc/pkcs15.h
+++ b/src/libopensc/pkcs15.h
@@ -373,7 +373,7 @@ struct sc_pkcs15_prkey_info {
unsigned int usage, access_flags;
int native, key_reference;
/* convert to union if other types are supported */
- size_t modulus_length; /* RSA */
+ size_t modulus_length; /* RSA, in bits */
size_t field_length; /* EC in bits */
unsigned int algo_refs[SC_MAX_SUPPORTED_ALGORITHMS];
diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c
index c75bcbda..3e060be5 100644
--- a/src/pkcs15init/pkcs15-openpgp.c
+++ b/src/pkcs15init/pkcs15-openpgp.c
@@ -235,7 +235,7 @@ static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj,
/* Prepare buffer */
key_info.u.rsa.modulus_len = required->modulus_length;
- key_info.u.rsa.modulus = calloc(required->modulus_length >> 3, 1);
+ key_info.u.rsa.modulus = calloc(BYTES4BITS(required->modulus_length), 1);
if (key_info.u.rsa.modulus == NULL)
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY);
@@ -252,18 +252,18 @@ static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj,
pubkey->algorithm = SC_ALGORITHM_RSA;
sc_log(ctx, "Set output modulus info");
- pubkey->u.rsa.modulus.len = key_info.u.rsa.modulus_len;
- pubkey->u.rsa.modulus.data = calloc(key_info.u.rsa.modulus_len, 1);
+ pubkey->u.rsa.modulus.len = BYTES4BITS(key_info.u.rsa.modulus_len);
+ pubkey->u.rsa.modulus.data = calloc(pubkey->u.rsa.modulus.len, 1);
if (pubkey->u.rsa.modulus.data == NULL)
goto err;
- memcpy(pubkey->u.rsa.modulus.data, key_info.u.rsa.modulus, key_info.u.rsa.modulus_len);
+ memcpy(pubkey->u.rsa.modulus.data, key_info.u.rsa.modulus, BYTES4BITS(key_info.u.rsa.modulus_len));
sc_log(ctx, "Set output exponent info");
- pubkey->u.rsa.exponent.len = key_info.u.rsa.exponent_len;
- pubkey->u.rsa.exponent.data = calloc(BYTES4BITS(key_info.u.rsa.exponent_len), 1);
+ pubkey->u.rsa.exponent.len = BYTES4BITS(key_info.u.rsa.exponent_len);
+ pubkey->u.rsa.exponent.data = calloc(pubkey->u.rsa.exponent.len, 1);
if (pubkey->u.rsa.exponent.data == NULL)
goto err;
- memcpy(pubkey->u.rsa.exponent.data, key_info.u.rsa.exponent, BYTES4BITS(key_info.u.rsa.exponent_len));
+ memcpy(pubkey->u.rsa.exponent.data, key_info.u.rsa.exponent, pubkey->u.rsa.exponent.len);
err:
free(key_info.u.rsa.modulus);