aboutsummaryrefslogtreecommitdiffstats
path: root/scd/app.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2024-01-04 15:29:33 +0000
committerWerner Koch <[email protected]>2024-01-04 15:29:33 +0000
commit3f8cb9b33949494202fefaa8901ab252467cc1f1 (patch)
tree3af38e6e2a1694cb215aa19e4a006d982679e57a /scd/app.c
parentgpg: Choose key from inserted card over a non-inserted card (diff)
downloadgnupg-3f8cb9b33949494202fefaa8901ab252467cc1f1.tar.gz
gnupg-3f8cb9b33949494202fefaa8901ab252467cc1f1.zip
scd: Add support for SCE 7.0
* scd/app-common.h (CARDTYPE_SCE7): New. * scd/app.c (strcardtype): Support it. (atr_to_cardtype): New. (app_new_register): Try to get the cardtype from atr_to_cardtype. * scd/app-piv.c (app_select_piv): Tweak for SCE7. Add general method to construct a S/N from the Card UUID. -- The test cards I have are rsa2048 with X.509 certificates. I don't have the entire chain but loading the certificates work. For testing I created an OpenPGP key from the keys and tested signing and decryption. GnuPG-bug-id: 6919
Diffstat (limited to 'scd/app.c')
-rw-r--r--scd/app.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/scd/app.c b/scd/app.c
index 3686c0f6c..2c92201cf 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -112,6 +112,7 @@ strcardtype (cardtype_t t)
case CARDTYPE_GNUK: return "gnuk";
case CARDTYPE_YUBIKEY: return "yubikey";
case CARDTYPE_ZEITCONTROL: return "zeitcontrol";
+ case CARDTYPE_SCE7: return "smartcafe";
}
return "?";
}
@@ -549,6 +550,51 @@ card_reset (card_t card)
return err;
}
+
+/* Return the card type from (ATR,ATRLEN) or CARDTYPE_GENERIC in case
+ * of error or if the ATR was not found. If ATR is NULL, SLOT is used
+ * to retrieve the ATR from the reader. */
+static cardtype_t
+atr_to_cardtype (int slot, const unsigned char *atr, size_t atrlen)
+{
+#define X(a) ((unsigned char const *)(a))
+ static struct
+ {
+ size_t atrlen;
+ unsigned char const *atr;
+ cardtype_t type;
+ } atrlist[] = {
+ { 19, X("\x3b\xf9\x96\x00\x00\x80\x31\xfe"
+ "\x45\x53\x43\x45\x37\x20\x0f\x00\x20\x46\x4e"),
+ CARDTYPE_SCE7 },
+ { 0 }
+ };
+#undef X
+ unsigned char *atrbuf = NULL;
+ cardtype_t cardtype = 0;
+ int i;
+
+ if (atr)
+ {
+ atrbuf = apdu_get_atr (slot, &atrlen);
+ if (!atrbuf)
+ return 0;
+ atr = atrbuf;
+ }
+
+ for (i=0; atrlist[i].atrlen; i++)
+ if (atrlist[i].atrlen == atrlen
+ && !memcmp (atrlist[i].atr, atr, atrlen))
+ {
+ cardtype = atrlist[i].type;
+ break;
+ }
+ xfree (atrbuf);
+ return cardtype;
+}
+
+
+
static gpg_error_t
app_new_register (int slot, ctrl_t ctrl, const char *name,
int periodical_check_needed)
@@ -666,13 +712,16 @@ app_new_register (int slot, ctrl_t ctrl, const char *name,
}
xfree (buf);
}
+ else
+ card->cardtype = atr_to_cardtype (slot, NULL, 0);
}
- else
+ else /* Got 3F00 */
{
unsigned char *atr;
size_t atrlen;
/* This is heuristics to identify different implementations. */
+ /* FIXME: The first two checks are pretty OpenPGP card specific. */
atr = apdu_get_atr (slot, &atrlen);
if (atr)
{
@@ -680,6 +729,8 @@ app_new_register (int slot, ctrl_t ctrl, const char *name,
card->cardtype = CARDTYPE_GNUK;
else if (atrlen == 21 && atr[7] == 0x75)
card->cardtype = CARDTYPE_ZEITCONTROL;
+ else
+ card->cardtype = atr_to_cardtype (slot, atr, atrlen);
xfree (atr);
}
}