mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02:00
Implement READKEY command.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
This commit is contained in:
parent
86d1d3ecd2
commit
c3dee068f9
@ -204,110 +204,23 @@ cmd_slotlist (assuan_context_t ctx, char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const char hlp_readkey[] =
|
static const char hlp_readkey[] =
|
||||||
"READKEY [--format=advanced|ssh] [--info[-only]] <keygrip>\n"
|
"READKEY [--info[-only]] <keygrip>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Return the public key for the given cert or key ID as a standard\n"
|
"Return the public key for the given KEYGRIP, as a standard\n"
|
||||||
"S-expression. With --format option, it may be returned in advanced\n"
|
"S-expression.";
|
||||||
"S-expression format, or SSH format. With --info a KEYPAIRINFO\n"
|
|
||||||
"status line is also emitted; with --info-only the regular output is\n"
|
|
||||||
"suppressed.";
|
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
cmd_readkey (assuan_context_t ctx, char *line)
|
cmd_readkey (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
int advanced = 0;
|
|
||||||
int ssh = 0;
|
|
||||||
int opt_info = 0;
|
|
||||||
int opt_nokey = 0;
|
|
||||||
unsigned char *pk = NULL;
|
|
||||||
size_t pklen;
|
|
||||||
const char *keygrip;
|
const char *keygrip;
|
||||||
|
|
||||||
if (has_option (line, "--format=advanced"))
|
|
||||||
advanced = 1;
|
|
||||||
if (has_option (line, "--format=ssh"))
|
|
||||||
ssh = 1;
|
|
||||||
if (has_option (line, "--info"))
|
|
||||||
opt_info = 1;
|
|
||||||
if (has_option (line, "--info-only"))
|
|
||||||
opt_info = opt_nokey = 1;
|
|
||||||
|
|
||||||
keygrip = skip_options (line);
|
keygrip = skip_options (line);
|
||||||
if (strlen (keygrip) != 40)
|
if (strlen (keygrip) != 40)
|
||||||
err = gpg_error (GPG_ERR_INV_ID);
|
err = gpg_error (GPG_ERR_INV_ID);
|
||||||
|
|
||||||
err = token_readkey (ctrl, ctx, keygrip, opt_info, &pk, &pklen);
|
err = token_readkey (ctrl, ctx, keygrip);
|
||||||
if (err)
|
|
||||||
goto leave;
|
|
||||||
|
|
||||||
if (opt_nokey)
|
|
||||||
;
|
|
||||||
else if (ssh)
|
|
||||||
{
|
|
||||||
estream_t stream = NULL;
|
|
||||||
gcry_sexp_t s_key;
|
|
||||||
void *buf = NULL;
|
|
||||||
size_t buflen;
|
|
||||||
|
|
||||||
stream = es_fopenmem (0, "r+b");
|
|
||||||
if (!stream)
|
|
||||||
{
|
|
||||||
err = gpg_error_from_syserror ();
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = gcry_sexp_new (&s_key, pk, pklen, 0);
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
es_fclose (stream);
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ssh_public_key_in_base64 (s_key, stream, "(none)");
|
|
||||||
if (err)
|
|
||||||
{
|
|
||||||
gcry_sexp_release (s_key);
|
|
||||||
es_fclose (stream);
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = es_fclose_snatch (stream, &buf, &buflen);
|
|
||||||
gcry_sexp_release (s_key);
|
|
||||||
if (!err)
|
|
||||||
err = assuan_send_data (ctx, buf, buflen);
|
|
||||||
}
|
|
||||||
else if (advanced)
|
|
||||||
{
|
|
||||||
gcry_sexp_t s_key;
|
|
||||||
unsigned char *pkadv;
|
|
||||||
size_t pkadvlen;
|
|
||||||
|
|
||||||
err = gcry_sexp_new (&s_key, pk, pklen, 0);
|
|
||||||
if (err)
|
|
||||||
goto leave;
|
|
||||||
|
|
||||||
pkadvlen = gcry_sexp_sprint (s_key, GCRYSEXP_FMT_ADVANCED, NULL, 0);
|
|
||||||
pkadv = xtrymalloc (pkadvlen);
|
|
||||||
if (!pkadv)
|
|
||||||
{
|
|
||||||
err = gpg_error_from_syserror ();
|
|
||||||
gcry_sexp_release (s_key);
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
log_assert (pkadvlen);
|
|
||||||
|
|
||||||
gcry_sexp_sprint (s_key, GCRYSEXP_FMT_ADVANCED, pkadv, pkadvlen);
|
|
||||||
gcry_sexp_release (s_key);
|
|
||||||
/* (One less to adjust for the trailing '\0') */
|
|
||||||
err = assuan_send_data (ctx, pkadv, pkadvlen-1);
|
|
||||||
xfree (pkadv);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
err = assuan_send_data (ctx, pk, pklen);
|
|
||||||
|
|
||||||
leave:
|
|
||||||
xfree (pk);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
109
tkd/pkcs11.c
109
tkd/pkcs11.c
@ -54,10 +54,10 @@ enum key_type {
|
|||||||
KEY_EDDSA,
|
KEY_EDDSA,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define KEY_FLAGS_VALID (1 << 0)
|
#define KEY_FLAG_VALID (1 << 0)
|
||||||
#define KEY_FLAGS_NO_PUBKEY (1 << 1)
|
#define KEY_FLAG_NO_PUBKEY (1 << 1)
|
||||||
#define KEY_FLAGS_USAGE_SIGN (1 << 2)
|
#define KEY_FLAG_USAGE_SIGN (1 << 2)
|
||||||
#define KEY_FLAGS_USAGE_DECRYPT (1 << 3)
|
#define KEY_FLAG_USAGE_DECRYPT (1 << 3)
|
||||||
|
|
||||||
struct key {
|
struct key {
|
||||||
struct token *token; /* Back pointer. */
|
struct token *token; /* Back pointer. */
|
||||||
@ -346,12 +346,12 @@ examine_public_key (struct token *token, struct key *k, unsigned long keytype,
|
|||||||
err = ck->f->C_GetAttributeValue (token->session, obj, templ, 2);
|
err = ck->f->C_GetAttributeValue (token->session, obj, templ, 2);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
k->flags |= KEY_FLAGS_NO_PUBKEY;
|
k->flags |= KEY_FLAG_NO_PUBKEY;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
k->flags |= KEY_FLAGS_VALID;
|
k->flags |= KEY_FLAG_VALID;
|
||||||
k->flags &= ~KEY_FLAGS_NO_PUBKEY;
|
k->flags &= ~KEY_FLAG_NO_PUBKEY;
|
||||||
if ((modulus[0] & 0x80))
|
if ((modulus[0] & 0x80))
|
||||||
{
|
{
|
||||||
memmove (modulus+1, modulus, templ[0].ulValueLen);
|
memmove (modulus+1, modulus, templ[0].ulValueLen);
|
||||||
@ -390,12 +390,12 @@ examine_public_key (struct token *token, struct key *k, unsigned long keytype,
|
|||||||
err = ck->f->C_GetAttributeValue (token->session, obj, templ, 2);
|
err = ck->f->C_GetAttributeValue (token->session, obj, templ, 2);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
k->flags |= KEY_FLAGS_NO_PUBKEY;
|
k->flags |= KEY_FLAG_NO_PUBKEY;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
k->flags |= KEY_FLAGS_VALID;
|
k->flags |= KEY_FLAG_VALID;
|
||||||
k->flags &= ~KEY_FLAGS_NO_PUBKEY;
|
k->flags &= ~KEY_FLAG_NO_PUBKEY;
|
||||||
/* Found an ECC key. */
|
/* Found an ECC key. */
|
||||||
log_debug ("ECC: %ld %ld\n",
|
log_debug ("ECC: %ld %ld\n",
|
||||||
templ[0].ulValueLen,
|
templ[0].ulValueLen,
|
||||||
@ -444,7 +444,7 @@ examine_public_key (struct token *token, struct key *k, unsigned long keytype,
|
|||||||
if (!err)
|
if (!err)
|
||||||
{
|
{
|
||||||
/* XXX: Scute has the attribute, but not set. */
|
/* XXX: Scute has the attribute, but not set. */
|
||||||
k->flags |= KEY_FLAGS_USAGE_SIGN;
|
k->flags |= KEY_FLAG_USAGE_SIGN;
|
||||||
}
|
}
|
||||||
|
|
||||||
templ[0].type = CKA_DECRYPT;
|
templ[0].type = CKA_DECRYPT;
|
||||||
@ -454,7 +454,7 @@ examine_public_key (struct token *token, struct key *k, unsigned long keytype,
|
|||||||
err = ck->f->C_GetAttributeValue (token->session, obj, templ, 1);
|
err = ck->f->C_GetAttributeValue (token->session, obj, templ, 1);
|
||||||
if (!err && supported)
|
if (!err && supported)
|
||||||
{
|
{
|
||||||
k->flags |= KEY_FLAGS_USAGE_DECRYPT;
|
k->flags |= KEY_FLAG_USAGE_DECRYPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -599,7 +599,7 @@ check_public_keys (struct token *token)
|
|||||||
{
|
{
|
||||||
k = &token->key_list[i];
|
k = &token->key_list[i];
|
||||||
|
|
||||||
if ((k->flags & KEY_FLAGS_NO_PUBKEY)
|
if ((k->flags & KEY_FLAG_NO_PUBKEY)
|
||||||
&& k->label_len == templ[0].ulValueLen
|
&& k->label_len == templ[0].ulValueLen
|
||||||
&& memcmp (label, k->label, k->label_len) == 0
|
&& memcmp (label, k->label, k->label_len) == 0
|
||||||
&& ((keytype == CKK_RSA && k->key_type == KEY_RSA)
|
&& ((keytype == CKK_RSA && k->key_type == KEY_RSA)
|
||||||
@ -719,8 +719,8 @@ learn_keys (struct token *token)
|
|||||||
{
|
{
|
||||||
struct key *k = &token->key_list[i];
|
struct key *k = &token->key_list[i];
|
||||||
|
|
||||||
if ((k->flags & KEY_FLAGS_NO_PUBKEY))
|
if ((k->flags & KEY_FLAG_NO_PUBKEY))
|
||||||
k->flags &= ~KEY_FLAGS_NO_PUBKEY;
|
k->flags &= ~KEY_FLAG_NO_PUBKEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@ -751,7 +751,7 @@ find_key (struct cryptoki *ck, const char *keygrip, struct key **r_key)
|
|||||||
{
|
{
|
||||||
struct key *k = &token->key_list[j];
|
struct key *k = &token->key_list[j];
|
||||||
|
|
||||||
if ((k->flags & KEY_FLAGS_VALID) == 0)
|
if ((k->flags & KEY_FLAG_VALID) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (memcmp (k->keygrip, keygrip, 40) == 0)
|
if (memcmp (k->keygrip, keygrip, 40) == 0)
|
||||||
@ -783,11 +783,11 @@ iter_find_key_setup (struct iter_key *iter, struct cryptoki *ck, int cap)
|
|||||||
iter->j = 0;
|
iter->j = 0;
|
||||||
iter->mask = 0;
|
iter->mask = 0;
|
||||||
if (cap == GCRY_PK_USAGE_SIGN)
|
if (cap == GCRY_PK_USAGE_SIGN)
|
||||||
iter->mask |= KEY_FLAGS_USAGE_SIGN;
|
iter->mask |= KEY_FLAG_USAGE_SIGN;
|
||||||
else if (cap == GCRY_PK_USAGE_ENCR)
|
else if (cap == GCRY_PK_USAGE_ENCR)
|
||||||
iter->mask = KEY_FLAGS_USAGE_DECRYPT;
|
iter->mask = KEY_FLAG_USAGE_DECRYPT;
|
||||||
else
|
else
|
||||||
iter->mask = KEY_FLAGS_USAGE_SIGN | KEY_FLAGS_USAGE_DECRYPT;
|
iter->mask = KEY_FLAG_USAGE_SIGN | KEY_FLAG_USAGE_DECRYPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -830,7 +830,7 @@ iter_find_key (struct iter_key *iter, struct key **r_key)
|
|||||||
if (token && iter->j < token->num_keys)
|
if (token && iter->j < token->num_keys)
|
||||||
{
|
{
|
||||||
k = &token->key_list[iter->j++];
|
k = &token->key_list[iter->j++];
|
||||||
if ((k->flags & KEY_FLAGS_VALID) && (k->flags & iter->mask))
|
if ((k->flags & KEY_FLAG_VALID) && (k->flags & iter->mask))
|
||||||
{
|
{
|
||||||
/* Found */
|
/* Found */
|
||||||
*r_key = k;
|
*r_key = k;
|
||||||
@ -1120,14 +1120,43 @@ token_sign (ctrl_t ctrl, assuan_context_t ctx,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
get_usage_string (struct key *k)
|
||||||
|
{
|
||||||
|
const char *usage = NULL;
|
||||||
|
|
||||||
|
if ((k->flags & KEY_FLAG_USAGE_SIGN))
|
||||||
|
{
|
||||||
|
if ((k->flags & KEY_FLAG_USAGE_DECRYPT))
|
||||||
|
usage = "se";
|
||||||
|
else
|
||||||
|
usage = "s";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((k->flags & KEY_FLAG_USAGE_DECRYPT))
|
||||||
|
usage = "e";
|
||||||
|
else
|
||||||
|
usage = "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
return usage;
|
||||||
|
}
|
||||||
|
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
token_readkey (ctrl_t ctrl, assuan_context_t ctx,
|
token_readkey (ctrl_t ctrl, assuan_context_t ctx, const char *keygrip)
|
||||||
const char *keygrip, int opt_info,
|
|
||||||
unsigned char **r_pk,
|
|
||||||
size_t *r_pklen)
|
|
||||||
{
|
{
|
||||||
gpg_error_t err = 0;
|
gpg_error_t err = 0;
|
||||||
|
struct key *k;
|
||||||
|
struct cryptoki *ck = ck_instance;
|
||||||
|
unsigned long r;
|
||||||
|
|
||||||
(void)ctrl;
|
(void)ctrl;
|
||||||
|
|
||||||
|
r = find_key (ck, keygrip, &k);
|
||||||
|
if (r)
|
||||||
|
return gpg_error (GPG_ERR_NO_SECKEY);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1147,21 +1176,7 @@ token_keyinfo (ctrl_t ctrl, const char *keygrip, int opt_data, int cap)
|
|||||||
if (r)
|
if (r)
|
||||||
return gpg_error (GPG_ERR_NO_SECKEY);
|
return gpg_error (GPG_ERR_NO_SECKEY);
|
||||||
|
|
||||||
if ((k->flags & KEY_FLAGS_USAGE_SIGN))
|
usage = get_usage_string (k);
|
||||||
{
|
|
||||||
if ((k->flags & KEY_FLAGS_USAGE_DECRYPT))
|
|
||||||
usage = "se";
|
|
||||||
else
|
|
||||||
usage = "s";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((k->flags & KEY_FLAGS_USAGE_DECRYPT))
|
|
||||||
usage = "e";
|
|
||||||
else
|
|
||||||
usage = "-";
|
|
||||||
}
|
|
||||||
|
|
||||||
send_keyinfo (ctrl, opt_data, keygrip,
|
send_keyinfo (ctrl, opt_data, keygrip,
|
||||||
k->label_len ? (const char *)k->label : "-",
|
k->label_len ? (const char *)k->label : "-",
|
||||||
k->id_len ? (const char *)k->id : "-",
|
k->id_len ? (const char *)k->id : "-",
|
||||||
@ -1174,21 +1189,7 @@ token_keyinfo (ctrl_t ctrl, const char *keygrip, int opt_data, int cap)
|
|||||||
iter_find_key_setup (&iter, ck, cap);
|
iter_find_key_setup (&iter, ck, cap);
|
||||||
while (iter_find_key (&iter, &k))
|
while (iter_find_key (&iter, &k))
|
||||||
{
|
{
|
||||||
if ((k->flags & KEY_FLAGS_USAGE_SIGN))
|
usage = get_usage_string (k);
|
||||||
{
|
|
||||||
if ((k->flags & KEY_FLAGS_USAGE_DECRYPT))
|
|
||||||
usage = "se";
|
|
||||||
else
|
|
||||||
usage = "s";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((k->flags & KEY_FLAGS_USAGE_DECRYPT))
|
|
||||||
usage = "e";
|
|
||||||
else
|
|
||||||
usage = "-";
|
|
||||||
}
|
|
||||||
|
|
||||||
send_keyinfo (ctrl, opt_data, k->keygrip,
|
send_keyinfo (ctrl, opt_data, k->keygrip,
|
||||||
k->label_len ? (const char *)k->label : "-",
|
k->label_len ? (const char *)k->label : "-",
|
||||||
k->id_len ? (const char *)k->id : "-",
|
k->id_len ? (const char *)k->id : "-",
|
||||||
|
@ -115,9 +115,7 @@ gpg_error_t token_sign (ctrl_t ctrl, assuan_context_t ctx,
|
|||||||
unsigned char **r_outdata,
|
unsigned char **r_outdata,
|
||||||
size_t *r_outdatalen);
|
size_t *r_outdatalen);
|
||||||
gpg_error_t token_readkey (ctrl_t ctrl, assuan_context_t ctx,
|
gpg_error_t token_readkey (ctrl_t ctrl, assuan_context_t ctx,
|
||||||
const char *keygrip, int opt_info,
|
const char *keygrip);
|
||||||
unsigned char **r_pk,
|
|
||||||
size_t *r_pklen);
|
|
||||||
gpg_error_t token_keyinfo (ctrl_t ctrl,
|
gpg_error_t token_keyinfo (ctrl_t ctrl,
|
||||||
const char *keygrip, int opt_data, int cap);
|
const char *keygrip, int opt_data, int cap);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user