aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2019-04-22 11:34:36 +0000
committerNIIBE Yutaka <[email protected]>2019-04-22 11:34:36 +0000
commitb0f0791e4ade845b2a0e2a94dbda4f3bf1ceb039 (patch)
tree5c306b9f8527a66b6311ae93604ffc5969f239f4
parentgpgconf: correct capitalization of "Tor" (diff)
downloadgnupg-b0f0791e4ade845b2a0e2a94dbda4f3bf1ceb039.tar.gz
gnupg-b0f0791e4ade845b2a0e2a94dbda4f3bf1ceb039.zip
scd: Factor out a function to check keyidstr.
* scd/app-openpgp.c (check_keyidstr): New. (do_sign, do_auth, do_decipher, do_check_pin): Use check_keyidstr. Signed-off-by: NIIBE Yutaka <[email protected]>
-rw-r--r--scd/app-openpgp.c185
1 files changed, 59 insertions, 126 deletions
diff --git a/scd/app-openpgp.c b/scd/app-openpgp.c
index 1a537127c..25ec834c8 100644
--- a/scd/app-openpgp.c
+++ b/scd/app-openpgp.c
@@ -4294,6 +4294,50 @@ check_against_given_fingerprint (app_t app, const char *fpr, int key)
}
+static int
+check_keyidstr (app_t app, const char *keyidstr, int keyno)
+{
+ int rc;
+ const char *s;
+ int n;
+ const char *fpr = NULL;
+ unsigned char tmp_sn[20]; /* Actually 16 bytes but also for the fpr. */
+
+ if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12))
+ return gpg_error (GPG_ERR_INV_ID);
+ else
+ {
+ for (s=keyidstr, n=0; hexdigitp (s); s++, n++)
+ ;
+ if (n != 32)
+ return gpg_error (GPG_ERR_INV_ID);
+ else if (!*s)
+ ; /* no fingerprint given: we allow this for now. */
+ else if (*s == '/')
+ fpr = s + 1;
+ else
+ return gpg_error (GPG_ERR_INV_ID);
+
+ for (s=keyidstr, n=0; n < 16; s += 2, n++)
+ tmp_sn[n] = xtoi_2 (s);
+
+ if (app->serialnolen != 16)
+ return gpg_error (GPG_ERR_INV_CARD);
+ if (memcmp (app->serialno, tmp_sn, 16))
+ return gpg_error (GPG_ERR_WRONG_CARD);
+ }
+
+ /* If a fingerprint has been specified check it against the one on
+ the card. This is allows for a meaningful error message in case
+ the key on the card has been replaced but the shadow information
+ known to gpg was not updated. If there is no fingerprint, gpg
+ will detect a bogus signature anyway due to the
+ verify-after-signing feature. */
+ rc = (fpr&&keyno)? check_against_given_fingerprint (app, fpr, keyno) : 0;
+
+ return rc;
+}
+
/* Compute a digital signature on INDATA which is expected to be the
raw message digest. For this application the KEYIDSTR consists of
@@ -4339,10 +4383,6 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
int rc;
unsigned char data[19+64];
size_t datalen;
- unsigned char tmp_sn[20]; /* Actually 16 bytes but also for the fpr. */
- const char *s;
- int n;
- const char *fpr = NULL;
unsigned long sigcount;
int use_auth = 0;
int exmode, le_value;
@@ -4387,40 +4427,13 @@ do_sign (app_t app, const char *keyidstr, int hashalgo,
;
else if (!strcmp (keyidstr, "OPENPGP.3"))
use_auth = 1;
- else if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12))
- return gpg_error (GPG_ERR_INV_ID);
else
{
- for (s=keyidstr, n=0; hexdigitp (s); s++, n++)
- ;
- if (n != 32)
- return gpg_error (GPG_ERR_INV_ID);
- else if (!*s)
- ; /* no fingerprint given: we allow this for now. */
- else if (*s == '/')
- fpr = s + 1;
- else
- return gpg_error (GPG_ERR_INV_ID);
-
- for (s=keyidstr, n=0; n < 16; s += 2, n++)
- tmp_sn[n] = xtoi_2 (s);
-
- if (app->serialnolen != 16)
- return gpg_error (GPG_ERR_INV_CARD);
- if (memcmp (app->serialno, tmp_sn, 16))
- return gpg_error (GPG_ERR_WRONG_CARD);
+ rc = check_keyidstr (app, keyidstr, 1);
+ if (rc)
+ return rc;
}
- /* If a fingerprint has been specified check it against the one on
- the card. This is allows for a meaningful error message in case
- the key on the card has been replaced but the shadow information
- known to gpg was not updated. If there is no fingerprint, gpg
- will detect a bogus signature anyway due to the
- verify-after-signing feature. */
- rc = fpr? check_against_given_fingerprint (app, fpr, 1) : 0;
- if (rc)
- return rc;
-
/* Concatenate prefix and digest. */
#define X(a,b,d) \
if (hashalgo == GCRY_MD_ ## a && (d) ) \
@@ -4537,10 +4550,6 @@ do_auth (app_t app, const char *keyidstr,
unsigned char **outdata, size_t *outdatalen )
{
int rc;
- unsigned char tmp_sn[20]; /* Actually 16 but we use it also for the fpr. */
- const char *s;
- int n;
- const char *fpr = NULL;
if (!keyidstr || !*keyidstr)
return gpg_error (GPG_ERR_INV_VALUE);
@@ -4568,40 +4577,13 @@ do_auth (app_t app, const char *keyidstr,
/* Check whether an OpenPGP card of any version has been requested. */
if (!strcmp (keyidstr, "OPENPGP.3"))
;
- else if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12))
- return gpg_error (GPG_ERR_INV_ID);
else
{
- for (s=keyidstr, n=0; hexdigitp (s); s++, n++)
- ;
- if (n != 32)
- return gpg_error (GPG_ERR_INV_ID);
- else if (!*s)
- ; /* no fingerprint given: we allow this for now. */
- else if (*s == '/')
- fpr = s + 1;
- else
- return gpg_error (GPG_ERR_INV_ID);
-
- for (s=keyidstr, n=0; n < 16; s += 2, n++)
- tmp_sn[n] = xtoi_2 (s);
-
- if (app->serialnolen != 16)
- return gpg_error (GPG_ERR_INV_CARD);
- if (memcmp (app->serialno, tmp_sn, 16))
- return gpg_error (GPG_ERR_WRONG_CARD);
+ rc = check_keyidstr (app, keyidstr, 3);
+ if (rc)
+ return rc;
}
- /* If a fingerprint has been specified check it against the one on
- the card. This is allows for a meaningful error message in case
- the key on the card has been replaced but the shadow information
- known to gpg was not updated. If there is no fingerprint, gpg
- will detect a bogus signature anyway due to the
- verify-after-signing feature. */
- rc = fpr? check_against_given_fingerprint (app, fpr, 3) : 0;
- if (rc)
- return rc;
-
rc = verify_chv2 (app, pincb, pincb_arg);
if (!rc)
{
@@ -4637,11 +4619,8 @@ do_decipher (app_t app, const char *keyidstr,
unsigned char **outdata, size_t *outdatalen,
unsigned int *r_info)
{
- int rc;
- unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */
- const char *s;
int n;
- const char *fpr = NULL;
+ int rc;
int exmode, le_value;
unsigned char *fixbuf = NULL;
int padind = 0;
@@ -4653,39 +4632,13 @@ do_decipher (app_t app, const char *keyidstr,
/* Check whether an OpenPGP card of any version has been requested. */
if (!strcmp (keyidstr, "OPENPGP.2"))
;
- else if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12))
- return gpg_error (GPG_ERR_INV_ID);
else
{
- for (s=keyidstr, n=0; hexdigitp (s); s++, n++)
- ;
- if (n != 32)
- return gpg_error (GPG_ERR_INV_ID);
- else if (!*s)
- ; /* no fingerprint given: we allow this for now. */
- else if (*s == '/')
- fpr = s + 1;
- else
- return gpg_error (GPG_ERR_INV_ID);
-
- for (s=keyidstr, n=0; n < 16; s += 2, n++)
- tmp_sn[n] = xtoi_2 (s);
-
- if (app->serialnolen != 16)
- return gpg_error (GPG_ERR_INV_CARD);
- if (memcmp (app->serialno, tmp_sn, 16))
- return gpg_error (GPG_ERR_WRONG_CARD);
+ rc = check_keyidstr (app, keyidstr, 2);
+ if (rc)
+ return rc;
}
- /* If a fingerprint has been specified check it against the one on
- the card. This is allows for a meaningful error message in case
- the key on the card has been replaced but the shadow information
- known to gpg was not updated. If there is no fingerprint, the
- decryption won't produce the right plaintext anyway. */
- rc = fpr? check_against_given_fingerprint (app, fpr, 2) : 0;
- if (rc)
- return rc;
-
rc = verify_chv2 (app, pincb, pincb_arg);
if (rc)
return rc;
@@ -4901,38 +4854,18 @@ do_check_pin (app_t app, const char *keyidstr,
gpg_error_t (*pincb)(void*, const char *, char **),
void *pincb_arg)
{
- unsigned char tmp_sn[20];
- const char *s;
- int n;
int admin_pin = 0;
+ int rc;
if (!keyidstr || !*keyidstr)
return gpg_error (GPG_ERR_INV_VALUE);
- /* Check whether an OpenPGP card of any version has been requested. */
- if (strlen (keyidstr) < 32 || strncmp (keyidstr, "D27600012401", 12))
- return gpg_error (GPG_ERR_INV_ID);
+ rc = check_keyidstr (app, keyidstr, 0);
+ if (rc)
+ return rc;
- for (s=keyidstr, n=0; hexdigitp (s); s++, n++)
- ;
- if (n != 32)
- return gpg_error (GPG_ERR_INV_ID);
- else if (!*s)
- ; /* No fingerprint given: we allow this for now. */
- else if (*s == '/')
- ; /* We ignore a fingerprint. */
- else if (!strcmp (s, "[CHV3]") )
+ if (strlen (keyidstr) >= 32+6 && !strcmp (keyidstr+32, "[CHV3]"))
admin_pin = 1;
- else
- return gpg_error (GPG_ERR_INV_ID);
-
- for (s=keyidstr, n=0; n < 16; s += 2, n++)
- tmp_sn[n] = xtoi_2 (s);
-
- if (app->serialnolen != 16)
- return gpg_error (GPG_ERR_INV_CARD);
- if (memcmp (app->serialno, tmp_sn, 16))
- return gpg_error (GPG_ERR_WRONG_CARD);
/* Yes, there is a race conditions: The user might pull the card
right here and we won't notice that. However this is not a