aboutsummaryrefslogtreecommitdiffstats
path: root/scd/app-piv.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-piv.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-piv.c')
-rw-r--r--scd/app-piv.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/scd/app-piv.c b/scd/app-piv.c
index c8ef7b43a..dc92bd2e2 100644
--- a/scd/app-piv.c
+++ b/scd/app-piv.c
@@ -1,5 +1,5 @@
/* app-piv.c - The OpenPGP card application.
- * Copyright (C) 2019, 2020 g10 Code GmbH
+ * Copyright (C) 2019, 2020, 2024 g10 Code GmbH
*
* This file is part of GnuPG.
*
@@ -3642,6 +3642,7 @@ app_select_piv (app_t app)
size_t aptlen;
const unsigned char *s;
size_t n;
+ void *relptr1 = NULL;
/* Note that we select using the AID without the 2 octet version
* number. This allows for better reporting of future specs. We
@@ -3667,7 +3668,21 @@ app_select_piv (app_t app)
s = find_tlv (apt, aptlen, 0x4F, &n);
/* Some cards (new Yubikey) return only the PIX, while others
- * (old Yubikey, PivApplet) return the RID+PIX. */
+ * (old Yubikey, PivApplet) return the RID+PIX.
+ * Sample APTs:
+ * Yubikey 5.4.3: 6111 4f06 000010000100 7907 4f05 a000000308
+ * SCE7.0-G-F-P : 610f 4f06 001000010000 7905 a000000308
+ */
+ if (app->card->cardtype == CARDTYPE_SCE7
+ && s && apt && aptlen == 17
+ && !memcmp (apt, ("\x61\x0f\x4f\x06\x00\x10\x00\x01"
+ "\x00\x00\x79\x05\xa0\x00\x00\x03\x08"), aptlen))
+ {
+ if (opt.verbose)
+ log_info ("piv: assuming G&D SCE7.0-G-F-P\n");
+ app->appversion = 0x0100; /* Let's assume this. */
+ goto apt_checked;
+ }
if (!s || !((n == 6 && !memcmp (s, piv_aid+5, 4))
|| (n == 11 && !memcmp (s, piv_aid, 9))))
{
@@ -3702,6 +3717,7 @@ app_select_piv (app_t app)
goto leave;
}
+ apt_checked:
app->app_local = xtrycalloc (1, sizeof *app->app_local);
if (!app->app_local)
{
@@ -3712,6 +3728,41 @@ app_select_piv (app_t app)
if (app->card->cardtype == CARDTYPE_YUBIKEY)
app->app_local->flags.yubikey = 1;
+ /* If we don't have a s/n construct it from the CHUID. */
+ if (!APP_CARD(app)->serialno)
+ {
+ unsigned char *chuid;
+ size_t chuidlen;
+
+ relptr1 = get_one_do (app, 0x5FC102, &chuid, &chuidlen, NULL);
+ if (!relptr1)
+ log_error ("piv: CHUID not found\n");
+ else
+ {
+ s = find_tlv (chuid, chuidlen, 0x34, &n);
+ if (!s || n != 16)
+ {
+ log_error ("piv: Card UUID %s in CHUID\n",
+ s? "invalid":"missing");
+ if (opt.debug && s)
+ log_printhex (s, n, "got");
+ }
+ else
+ {
+ APP_CARD(app)->serialno = xtrymalloc (n);
+ if (!APP_CARD(app)->serialno)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ memcpy (APP_CARD(app)->serialno, s, n);
+ APP_CARD(app)->serialnolen = n;
+ err = app_munge_serialno (APP_CARD(app));
+ if (err)
+ goto leave;
+ }
+ }
+ }
/* FIXME: Parse the optional and conditional DOs in the APT. */
@@ -3739,6 +3790,7 @@ app_select_piv (app_t app)
leave:
+ xfree (relptr1);
xfree (apt);
if (err)
do_deinit (app);