aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2020-11-26 08:46:20 +0100
committerWerner Koch <wk@gnupg.org>2020-11-26 09:54:23 +0100
commit764c69a841abc1a4dff2fa86b4cd0b63ec737860 (patch)
treefe39ca58f8eb43656319a48a728c0d626042a955
parent605ab99912ac632363d1b4378a710229e40ca99e (diff)
downloadgnupg-764c69a841abc1a4dff2fa86b4cd0b63ec737860.tar.gz
scd: Add special serialno compare for OpenPGP cards.
* scd/app.c (is_same_serialno): New. (check_application_conflict): Use this. (select_application): Ditto. (app_switch_current_card): Ditto. * scd/app-openpgp.c (check_keyidstr): Ignore the card version and also compare case insensitive. -- This is required because we change what we emit as serialno of OpenPGP cards but existing keys still use the old form of the serial number (i.e. with a firmware version). See-commit: 3a8250c02031080c6c8eebd5dea03f5f87f9ddd7 Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r--doc/HACKING1
-rw-r--r--scd/app-openpgp.c13
-rw-r--r--scd/app.c41
3 files changed, 45 insertions, 10 deletions
diff --git a/doc/HACKING b/doc/HACKING
index 0f7a33a25..eb46d50c9 100644
--- a/doc/HACKING
+++ b/doc/HACKING
@@ -220,6 +220,7 @@ Note that such a comment will be removed if the git commit option
- Regression-due-to :: Commit id of the regression fixed by this commit.
- Fixes-commit :: Commit id this commit fixes.
- Updates-commit :: Commit id this commit updates.
+ - See-commit :: Commit id of a related commit.
- Reported-by :: Value is a name or mail address of a bug reporte.
- Suggested-by :: Value is a name or mail address of someone how
suggested this change.
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 440c4d027..36301ee8d 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -1102,8 +1102,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
if (table[idx].special == -1)
{
- /* The serial number is very special. We can't use the the AID
- DO (0x4f) becuase this is the serialno per specs with the
+ /* The serial number is very special. We can't use the AID
+ DO (0x4f) because this is the serialno per specs with the
correct appversion. We might however use a serialno with the
version set to 0.0 and that is what we need to return. */
char *serial = app_get_serialno (app);
@@ -5031,7 +5031,10 @@ check_keyidstr (app_t app, const char *keyidstr, int keyno, int *r_use_auth)
return gpg_error (GPG_ERR_INV_ID);
}
- if (n != 32 || strncmp (keyidstr, "D27600012401", 12))
+ /* For a description of the serialno compare function see
+ * is_same_serialno. We don't use that function because here we
+ * are working on a hex string. */
+ if (n != 32 || ascii_strncasecmp (keyidstr, "D27600012401", 12))
return gpg_error (GPG_ERR_INV_ID);
else if (!*s)
; /* no fingerprint given: we allow this for now. */
@@ -5039,7 +5042,9 @@ check_keyidstr (app_t app, const char *keyidstr, int keyno, int *r_use_auth)
fpr = s + 1;
serial = app_get_serialno (app);
- if (strncmp (serial, keyidstr, 32))
+ if (!serial || strlen (serial) != 32
+ || ascii_memcasecmp (serial, "D27600012401", 12)
+ || ascii_memcasecmp (serial+16, keyidstr+16, 16))
{
xfree (serial);
return gpg_error (GPG_ERR_WRONG_CARD);
diff --git a/scd/app.c b/scd/app.c
index f17e2d62b..7ba714b3e 100644
--- a/scd/app.c
+++ b/scd/app.c
@@ -155,6 +155,35 @@ apptype_from_keyref (const char *keyref)
}
+/* Return true if both serilanumbers are the same. This function
+ * takes care of some peculiarities. */
+static int
+is_same_serialno (const unsigned char *sna, size_t snalen,
+ const unsigned char *snb, size_t snblen)
+{
+ if ((!sna && !snb) || (!snalen && !snblen))
+ return 1;
+ if (!sna || !snb)
+ return 0; /* One of them is NULL. (Both NULL tested above). */
+
+ if (snalen != snblen)
+ return 0; /* (No special cases for this below). */
+
+ /* The special case for OpenPGP cards where we ignore the version
+ * bytes (vvvv). Example: D276000124010304000500009D8A0000
+ * ^^^^^^^^^^^^vvvvmmmmssssssssrrrr */
+ if (snalen == 16 && !memcmp (sna, "\xD2\x76\x00\x01\x24\x01", 6))
+ {
+ if (memcmp (snb, "\xD2\x76\x00\x01\x24\x01", 6))
+ return 0; /* No */
+ return !memcmp (sna + 8, snb + 8, 8);
+ }
+
+ return !memcmp (sna, snb, snalen);
+}
+
+
+
/* Initialization function to change the default app_priority_list.
* LIST is a list of comma or space separated strings with application
* names. Unknown names will only result in warning message.
@@ -357,8 +386,8 @@ check_application_conflict (card_t card, const char *name,
if (serialno_bin && card->serialno)
{
- if (serialno_bin_len != card->serialnolen
- || memcmp (serialno_bin, card->serialno, card->serialnolen))
+ if (!is_same_serialno (card->serialno, card->serialnolen,
+ serialno_bin, serialno_bin_len))
return 0; /* The card does not match the requested S/N. */
}
@@ -734,8 +763,8 @@ select_application (ctrl_t ctrl, const char *name, card_t *r_card,
lock_card (card, ctrl);
if (serialno_bin == NULL)
break;
- if (card->serialnolen == serialno_bin_len
- && !memcmp (card->serialno, serialno_bin, card->serialnolen))
+ if (is_same_serialno (card->serialno, card->serialnolen,
+ serialno_bin, serialno_bin_len))
break;
unlock_card (card);
card_prev = card;
@@ -805,8 +834,8 @@ app_switch_current_card (ctrl_t ctrl,
{
for (card = card_top; card; card = card->next)
{
- if (card->serialnolen == serialnolen
- && !memcmp (card->serialno, serialno, card->serialnolen))
+ if (is_same_serialno (card->serialno, card->serialnolen,
+ serialno, serialnolen))
break;
}
if (!card)