mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-10 13:04:23 +01:00
* app-openpgp.c (do_setattr): Add setting of the URL.
(app_select_openpgp): Dump card data only in very verbose mode. (do_decipher): New.
This commit is contained in:
parent
d1165b2132
commit
8b9f0bda3d
@ -1,3 +1,15 @@
|
||||
2003-07-03 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* app-openpgp.c (do_setattr): Add setting of the URL.
|
||||
(app_select_openpgp): Dump card data only in very verbose mode.
|
||||
(do_decipher): New.
|
||||
|
||||
2003-07-02 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* app-openpgp.c (get_sig_counter): New.
|
||||
(do_sign): Print the signature counter and enable the PIN callback.
|
||||
(do_genkey): Implement the PIN callback.
|
||||
|
||||
2003-07-01 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* app-openpgp.c (store_fpr): Fixed fingerprint calculation.
|
||||
|
@ -43,12 +43,12 @@ struct app_ctx_s {
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen );
|
||||
unsigned char **outdata, size_t *outdatalen );
|
||||
int (*decipher) (APP app, const char *keyidstr,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen);
|
||||
unsigned char **outdata, size_t *outdatalen);
|
||||
int (*genkey) (APP app, CTRL ctrl,
|
||||
const char *keynostr, unsigned int flags,
|
||||
int (*pincb)(void*, const char *, char **),
|
||||
@ -70,12 +70,12 @@ int app_sign (APP app, const char *keyidstr, int hashalgo,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen );
|
||||
unsigned char **outdata, size_t *outdatalen );
|
||||
int app_decipher (APP app, const char *keyidstr,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen );
|
||||
unsigned char **outdata, size_t *outdatalen );
|
||||
int app_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
|
||||
int (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg);
|
||||
|
@ -176,15 +176,19 @@ get_one_do (int slot, int tag, unsigned char **result, size_t *nbytes)
|
||||
&buffer, &buflen);
|
||||
if (!rc)
|
||||
{
|
||||
value = find_tlv (buffer, buflen, tag, &valuelen, 0);
|
||||
if (!value)
|
||||
; /* not found */
|
||||
else if (valuelen > buflen - (value - buffer))
|
||||
const unsigned char *s;
|
||||
|
||||
s = find_tlv (buffer, buflen, tag, &valuelen, 0);
|
||||
if (!s)
|
||||
value = NULL; /* not found */
|
||||
else if (valuelen > buflen - (s - buffer))
|
||||
{
|
||||
log_error ("warning: constructed DO too short\n");
|
||||
value = NULL;
|
||||
xfree (buffer); buffer = NULL;
|
||||
}
|
||||
else
|
||||
value = buffer + (s - buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -436,7 +440,7 @@ do_learn_status (APP app, CTRL ctrl)
|
||||
send_status_info (ctrl, "DISP-NAME", value, valuelen, NULL, 0);
|
||||
xfree (relptr);
|
||||
}
|
||||
relptr = get_one_do (app->slot, 0x5FF0, &value, &valuelen);
|
||||
relptr = get_one_do (app->slot, 0x5F50, &value, &valuelen);
|
||||
if (relptr)
|
||||
{
|
||||
send_status_info (ctrl, "PUBKEY-URL", value, valuelen, NULL, 0);
|
||||
@ -479,8 +483,8 @@ do_setattr (APP app, const char *name,
|
||||
{
|
||||
char *pinvalue;
|
||||
|
||||
/* rc = pincb (pincb_arg, "Please enter the card's admin PIN (CHV3)", */
|
||||
/* &pinvalue); */
|
||||
rc = pincb (pincb_arg, "Admin PIN (CHV3)",
|
||||
&pinvalue);
|
||||
pinvalue = xstrdup ("12345678");
|
||||
rc = 0;
|
||||
if (rc)
|
||||
@ -515,6 +519,15 @@ do_setattr (APP app, const char *name,
|
||||
rc = gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
}
|
||||
else if (!strcmp (name, "PUBKEY-URL"))
|
||||
{
|
||||
rc = iso7816_put_data (app->slot, 0x5F50, value, valuelen);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("failed to set `Pubkey-URL'\n");
|
||||
rc = gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
rc = gpg_error (GPG_ERR_INV_NAME);
|
||||
|
||||
@ -539,6 +552,7 @@ do_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
|
||||
time_t created_at;
|
||||
int keyno = atoi (keynostr);
|
||||
int force = (flags & 1);
|
||||
time_t start_at;
|
||||
|
||||
if (keyno < 1 || keyno > 3)
|
||||
return gpg_error (GPG_ERR_INV_ID);
|
||||
@ -571,7 +585,17 @@ do_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
|
||||
else
|
||||
log_info ("generating new key\n");
|
||||
|
||||
rc = iso7816_verify (app->slot, 0x83, "12345678", 8);
|
||||
{
|
||||
char *pinvalue;
|
||||
rc = pincb (pincb_arg, "Admin PIN", &pinvalue);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("error getting PIN: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
rc = iso7816_verify (app->slot, 0x83, pinvalue, strlen (pinvalue));
|
||||
xfree (pinvalue);
|
||||
}
|
||||
if (rc)
|
||||
{
|
||||
log_error ("verify CHV3 failed: rc=%04X\n", rc);
|
||||
@ -580,6 +604,8 @@ do_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
|
||||
|
||||
xfree (buffer); buffer = NULL;
|
||||
#if 1
|
||||
log_info ("please wait while key is being generated ...\n");
|
||||
start_at = time (NULL);
|
||||
rc = iso7816_generate_keypair
|
||||
#else
|
||||
#warning key generation temporary replaced by reading an existing key.
|
||||
@ -596,6 +622,8 @@ do_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
|
||||
log_error ("generating key failed\n");
|
||||
goto leave;
|
||||
}
|
||||
log_info ("key generation completed (%d seconds)\n",
|
||||
(int)(time (NULL) - start_at));
|
||||
keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen, 0);
|
||||
if (!keydata)
|
||||
{
|
||||
@ -609,7 +637,7 @@ do_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
|
||||
log_error ("response does not contain the RSA modulus\n");
|
||||
goto leave;
|
||||
}
|
||||
log_printhex ("RSA n:", m, mlen);
|
||||
/* log_printhex ("RSA n:", m, mlen); */
|
||||
send_key_data (ctrl, "n", m, mlen);
|
||||
|
||||
e = find_tlv (keydata, keydatalen, 0x0082, &elen, 0);
|
||||
@ -618,7 +646,7 @@ do_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
|
||||
log_error ("response does not contain the RSA public exponent\n");
|
||||
goto leave;
|
||||
}
|
||||
log_printhex ("RSA e:", e, elen);
|
||||
/* log_printhex ("RSA e:", e, elen); */
|
||||
send_key_data (ctrl, "e", e, elen);
|
||||
|
||||
created_at = gnupg_get_time ();
|
||||
@ -639,6 +667,28 @@ do_genkey (APP app, CTRL ctrl, const char *keynostr, unsigned int flags,
|
||||
}
|
||||
|
||||
|
||||
static unsigned long
|
||||
get_sig_counter (APP app)
|
||||
{
|
||||
void *relptr;
|
||||
unsigned char *value;
|
||||
size_t valuelen;
|
||||
unsigned long ul;
|
||||
|
||||
relptr = get_one_do (app->slot, 0x0093, &value, &valuelen);
|
||||
if (!relptr)
|
||||
return 0;
|
||||
if (valuelen == 3 )
|
||||
ul = (value[0] << 16) | (value[1] << 8) | value[2];
|
||||
else
|
||||
{
|
||||
log_error ("invalid structure of OpenPGP card (DO 0x93)\n");
|
||||
ul = 0;
|
||||
}
|
||||
xfree (relptr);
|
||||
return ul;
|
||||
}
|
||||
|
||||
static int
|
||||
compare_fingerprint (APP app, int keyno, unsigned char *sha1fpr)
|
||||
{
|
||||
@ -688,7 +738,7 @@ do_sign (APP app, const char *keyidstr, int hashalgo,
|
||||
int (*pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen )
|
||||
unsigned char **outdata, size_t *outdatalen )
|
||||
{
|
||||
static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */
|
||||
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
|
||||
@ -702,6 +752,7 @@ do_sign (APP app, const char *keyidstr, int hashalgo,
|
||||
const char *s;
|
||||
int n;
|
||||
const char *fpr = NULL;
|
||||
unsigned long sigcount;
|
||||
|
||||
if (!keyidstr || !*keyidstr)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
@ -731,7 +782,7 @@ do_sign (APP app, const char *keyidstr, int hashalgo,
|
||||
if (memcmp (app->serialno, tmp_sn, 16))
|
||||
return gpg_error (GPG_ERR_WRONG_CARD);
|
||||
|
||||
/* If a fingerprint has been speicified check it against the one on
|
||||
/* 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
|
||||
@ -763,14 +814,24 @@ do_sign (APP app, const char *keyidstr, int hashalgo,
|
||||
return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
|
||||
memcpy (data+15, indata, indatalen);
|
||||
|
||||
sigcount = get_sig_counter (app);
|
||||
log_info ("signatures created so far: %lu\n", sigcount);
|
||||
|
||||
if (!app->did_chv1)
|
||||
/* FIXME: Check whether we are really required to enter the PIN for
|
||||
each signature. There is a DO for this. */
|
||||
if (!app->did_chv1 || 1)
|
||||
{
|
||||
char *pinvalue;
|
||||
|
||||
/* rc = pincb (pincb_arg, "signature PIN", &pinvalue); */
|
||||
pinvalue = xstrdup ("123456");
|
||||
rc = 0;
|
||||
{
|
||||
char *prompt;
|
||||
if (asprintf (&prompt, "Signature PIN [sigs done: %lu]", sigcount) < 0)
|
||||
return gpg_error_from_errno (errno);
|
||||
rc = pincb (pincb_arg, prompt, &pinvalue);
|
||||
free (prompt);
|
||||
}
|
||||
/* pinvalue = xstrdup ("123456"); */
|
||||
/* rc = 0; */
|
||||
if (rc)
|
||||
{
|
||||
log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
|
||||
@ -789,11 +850,103 @@ do_sign (APP app, const char *keyidstr, int hashalgo,
|
||||
}
|
||||
|
||||
rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_decipher (APP app, const char *keyidstr,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
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 || !indatalen)
|
||||
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);
|
||||
|
||||
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, the
|
||||
decryption will won't produce the right plaintext anyway. */
|
||||
if (fpr)
|
||||
{
|
||||
for (s=fpr, n=0; hexdigitp (s); s++, n++)
|
||||
;
|
||||
if (n != 40)
|
||||
return gpg_error (GPG_ERR_INV_ID);
|
||||
else if (!*s)
|
||||
; /* okay */
|
||||
else
|
||||
return gpg_error (GPG_ERR_INV_ID);
|
||||
|
||||
for (s=fpr, n=0; n < 20; s += 2, n++)
|
||||
tmp_sn[n] = xtoi_2 (s);
|
||||
rc = compare_fingerprint (app, 2, tmp_sn);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!app->did_chv2)
|
||||
{
|
||||
char *pinvalue;
|
||||
|
||||
rc = pincb (pincb_arg, "Decryption PIN", &pinvalue);
|
||||
/* pinvalue = xstrdup ("123456"); */
|
||||
/* rc = 0; */
|
||||
if (rc)
|
||||
{
|
||||
log_info ("PIN callback returned error: %s\n", gpg_strerror (rc));
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue));
|
||||
xfree (pinvalue);
|
||||
if (rc)
|
||||
{
|
||||
log_error ("verify CHV2 failed\n");
|
||||
rc = gpg_error (GPG_ERR_GENERAL);
|
||||
return rc;
|
||||
}
|
||||
app->did_chv2 = 1;
|
||||
}
|
||||
|
||||
rc = iso7816_decipher (app->slot, indata, indatalen, outdata, outdatalen);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Select the OpenPGP application on the card in SLOT. This function
|
||||
must be used before any other OpenPGP application functions. */
|
||||
int
|
||||
@ -827,12 +980,14 @@ app_select_openpgp (APP app, unsigned char **sn, size_t *snlen)
|
||||
else
|
||||
xfree (buffer);
|
||||
|
||||
dump_all_do (slot);
|
||||
if (opt.verbose > 1)
|
||||
dump_all_do (slot);
|
||||
|
||||
app->fnc.learn_status = do_learn_status;
|
||||
app->fnc.setattr = do_setattr;
|
||||
app->fnc.genkey = do_genkey;
|
||||
app->fnc.sign = do_sign;
|
||||
app->fnc.decipher = do_decipher;
|
||||
}
|
||||
|
||||
leave:
|
||||
|
@ -138,7 +138,7 @@ app_sign (APP app, const char *keyidstr, int hashalgo,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen )
|
||||
unsigned char **outdata, size_t *outdatalen )
|
||||
{
|
||||
int rc;
|
||||
|
||||
@ -166,7 +166,7 @@ app_decipher (APP app, const char *keyidstr,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen )
|
||||
unsigned char **outdata, size_t *outdatalen )
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
@ -48,12 +48,12 @@ struct card_ctx_s {
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen );
|
||||
unsigned char **outdata, size_t *outdatalen );
|
||||
int (*decipher) (CARD card, const char *keyidstr,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen);
|
||||
unsigned char **outdata, size_t *outdatalen);
|
||||
} fnc;
|
||||
|
||||
};
|
||||
|
@ -382,7 +382,7 @@ p15_sign (CARD card, const char *keyidstr, int hashalgo,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen )
|
||||
unsigned char **outdata, size_t *outdatalen )
|
||||
{
|
||||
unsigned int cryptflags;
|
||||
struct sc_pkcs15_object *keyobj;
|
||||
@ -432,7 +432,7 @@ p15_decipher (CARD card, const char *keyidstr,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen )
|
||||
unsigned char **outdata, size_t *outdatalen )
|
||||
{
|
||||
struct sc_pkcs15_object *keyobj;
|
||||
int rc;
|
||||
|
@ -512,7 +512,7 @@ card_sign (CARD card, const char *keyidstr, int hashalgo,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen )
|
||||
unsigned char **outdata, size_t *outdatalen )
|
||||
{
|
||||
int rc;
|
||||
|
||||
@ -540,7 +540,7 @@ card_decipher (CARD card, const char *keyidstr,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen )
|
||||
unsigned char **outdata, size_t *outdatalen )
|
||||
{
|
||||
int rc;
|
||||
|
||||
|
@ -565,7 +565,7 @@ cmd_pksign (ASSUAN_CONTEXT ctx, char *line)
|
||||
{
|
||||
CTRL ctrl = assuan_get_pointer (ctx);
|
||||
int rc;
|
||||
void *outdata;
|
||||
unsigned char *outdata;
|
||||
size_t outdatalen;
|
||||
char *keyidstr;
|
||||
|
||||
@ -615,7 +615,7 @@ cmd_pkdecrypt (ASSUAN_CONTEXT ctx, char *line)
|
||||
{
|
||||
CTRL ctrl = assuan_get_pointer (ctx);
|
||||
int rc;
|
||||
void *outdata;
|
||||
unsigned char *outdata;
|
||||
size_t outdatalen;
|
||||
char *keyidstr;
|
||||
|
||||
|
@ -140,7 +140,7 @@ iso7816_compute_ds (int slot, const unsigned char *data, size_t datalen,
|
||||
if (sw != SW_SUCCESS)
|
||||
{
|
||||
/* Make sure that pending buffers are released. */
|
||||
xfree (result);
|
||||
xfree (*result);
|
||||
*result = NULL;
|
||||
*resultlen = 0;
|
||||
return -1; /* FIXME: Map error codes. */
|
||||
@ -178,7 +178,7 @@ iso7816_decipher (int slot, const unsigned char *data, size_t datalen,
|
||||
if (sw != SW_SUCCESS)
|
||||
{
|
||||
/* Make sure that pending buffers are released. */
|
||||
xfree (result);
|
||||
xfree (*result);
|
||||
*result = NULL;
|
||||
*resultlen = 0;
|
||||
return -1; /* FIXME: Map error codes. */
|
||||
@ -205,7 +205,7 @@ iso7816_internal_authenticate (int slot,
|
||||
if (sw != SW_SUCCESS)
|
||||
{
|
||||
/* Make sure that pending buffers are released. */
|
||||
xfree (result);
|
||||
xfree (*result);
|
||||
*result = NULL;
|
||||
*resultlen = 0;
|
||||
return -1; /* FIXME: Map error codes. */
|
||||
|
@ -140,6 +140,9 @@ main (int argc, char **argv )
|
||||
if (log_get_errorcount(0))
|
||||
exit(2);
|
||||
|
||||
if (opt.verbose < 2)
|
||||
opt.verbose = 2; /* hack to let select_openpgp print some info. */
|
||||
|
||||
if (argc)
|
||||
usage (1);
|
||||
|
||||
|
@ -116,12 +116,12 @@ int card_sign (CARD card,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen );
|
||||
unsigned char **outdata, size_t *outdatalen );
|
||||
int card_decipher (CARD card, const char *keyidstr,
|
||||
int (pincb)(void*, const char *, char **),
|
||||
void *pincb_arg,
|
||||
const void *indata, size_t indatalen,
|
||||
void **outdata, size_t *outdatalen);
|
||||
unsigned char **outdata, size_t *outdatalen);
|
||||
|
||||
|
||||
#endif /*SCDAEMON_H*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user