aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2023-03-08 05:30:33 +0000
committerNIIBE Yutaka <[email protected]>2023-03-08 05:30:33 +0000
commitc3dee068f9bd126ccc8f205819c1b25862591bb4 (patch)
tree7ba8622f3ed5536f3211e1ba8febec00c9662f1a
parentAdd login feature. (diff)
downloadgnupg-c3dee068f9bd126ccc8f205819c1b25862591bb4.tar.gz
gnupg-c3dee068f9bd126ccc8f205819c1b25862591bb4.zip
Implement READKEY command.
Signed-off-by: NIIBE Yutaka <[email protected]>
-rw-r--r--tkd/command.c95
-rw-r--r--tkd/pkcs11.c109
-rw-r--r--tkd/tkdaemon.h4
3 files changed, 60 insertions, 148 deletions
diff --git a/tkd/command.c b/tkd/command.c
index f0f528462..772b3d3e4 100644
--- a/tkd/command.c
+++ b/tkd/command.c
@@ -204,110 +204,23 @@ cmd_slotlist (assuan_context_t ctx, char *line)
}
static const char hlp_readkey[] =
- "READKEY [--format=advanced|ssh] [--info[-only]] <keygrip>\n"
+ "READKEY [--info[-only]] <keygrip>\n"
"\n"
- "Return the public key for the given cert or key ID as a standard\n"
- "S-expression. With --format option, it may be returned in advanced\n"
- "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.";
+ "Return the public key for the given KEYGRIP, as a standard\n"
+ "S-expression.";
static gpg_error_t
cmd_readkey (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
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;
- 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);
if (strlen (keygrip) != 40)
err = gpg_error (GPG_ERR_INV_ID);
- err = token_readkey (ctrl, ctx, keygrip, opt_info, &pk, &pklen);
- 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);
+ err = token_readkey (ctrl, ctx, keygrip);
- leave:
- xfree (pk);
return err;
}
diff --git a/tkd/pkcs11.c b/tkd/pkcs11.c
index 79ca8f7d6..21ef32875 100644
--- a/tkd/pkcs11.c
+++ b/tkd/pkcs11.c
@@ -54,10 +54,10 @@ enum key_type {
KEY_EDDSA,
};
-#define KEY_FLAGS_VALID (1 << 0)
-#define KEY_FLAGS_NO_PUBKEY (1 << 1)
-#define KEY_FLAGS_USAGE_SIGN (1 << 2)
-#define KEY_FLAGS_USAGE_DECRYPT (1 << 3)
+#define KEY_FLAG_VALID (1 << 0)
+#define KEY_FLAG_NO_PUBKEY (1 << 1)
+#define KEY_FLAG_USAGE_SIGN (1 << 2)
+#define KEY_FLAG_USAGE_DECRYPT (1 << 3)
struct key {
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);
if (err)
{
- k->flags |= KEY_FLAGS_NO_PUBKEY;
+ k->flags |= KEY_FLAG_NO_PUBKEY;
return 1;
}
- k->flags |= KEY_FLAGS_VALID;
- k->flags &= ~KEY_FLAGS_NO_PUBKEY;
+ k->flags |= KEY_FLAG_VALID;
+ k->flags &= ~KEY_FLAG_NO_PUBKEY;
if ((modulus[0] & 0x80))
{
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);
if (err)
{
- k->flags |= KEY_FLAGS_NO_PUBKEY;
+ k->flags |= KEY_FLAG_NO_PUBKEY;
return 1;
}
- k->flags |= KEY_FLAGS_VALID;
- k->flags &= ~KEY_FLAGS_NO_PUBKEY;
+ k->flags |= KEY_FLAG_VALID;
+ k->flags &= ~KEY_FLAG_NO_PUBKEY;
/* Found an ECC key. */
log_debug ("ECC: %ld %ld\n",
templ[0].ulValueLen,
@@ -444,7 +444,7 @@ examine_public_key (struct token *token, struct key *k, unsigned long keytype,
if (!err)
{
/* 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;
@@ -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);
if (!err && supported)
{
- k->flags |= KEY_FLAGS_USAGE_DECRYPT;
+ k->flags |= KEY_FLAG_USAGE_DECRYPT;
}
return 0;
@@ -599,7 +599,7 @@ check_public_keys (struct token *token)
{
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
&& memcmp (label, k->label, k->label_len) == 0
&& ((keytype == CKK_RSA && k->key_type == KEY_RSA)
@@ -719,8 +719,8 @@ learn_keys (struct token *token)
{
struct key *k = &token->key_list[i];
- if ((k->flags & KEY_FLAGS_NO_PUBKEY))
- k->flags &= ~KEY_FLAGS_NO_PUBKEY;
+ if ((k->flags & KEY_FLAG_NO_PUBKEY))
+ k->flags &= ~KEY_FLAG_NO_PUBKEY;
}
#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];
- if ((k->flags & KEY_FLAGS_VALID) == 0)
+ if ((k->flags & KEY_FLAG_VALID) == 0)
continue;
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->mask = 0;
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)
- iter->mask = KEY_FLAGS_USAGE_DECRYPT;
+ iter->mask = KEY_FLAG_USAGE_DECRYPT;
else
- iter->mask = KEY_FLAGS_USAGE_SIGN | KEY_FLAGS_USAGE_DECRYPT;
+ iter->mask = KEY_FLAG_USAGE_SIGN | KEY_FLAG_USAGE_DECRYPT;
}
static int
@@ -830,7 +830,7 @@ iter_find_key (struct iter_key *iter, struct key **r_key)
if (token && iter->j < token->num_keys)
{
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 */
*r_key = k;
@@ -1120,14 +1120,43 @@ token_sign (ctrl_t ctrl, assuan_context_t ctx,
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
-token_readkey (ctrl_t ctrl, assuan_context_t ctx,
- const char *keygrip, int opt_info,
- unsigned char **r_pk,
- size_t *r_pklen)
+token_readkey (ctrl_t ctrl, assuan_context_t ctx, const char *keygrip)
{
gpg_error_t err = 0;
+ struct key *k;
+ struct cryptoki *ck = ck_instance;
+ unsigned long r;
+
(void)ctrl;
+
+ r = find_key (ck, keygrip, &k);
+ if (r)
+ return gpg_error (GPG_ERR_NO_SECKEY);
+
return err;
}
@@ -1147,21 +1176,7 @@ token_keyinfo (ctrl_t ctrl, const char *keygrip, int opt_data, int cap)
if (r)
return gpg_error (GPG_ERR_NO_SECKEY);
- if ((k->flags & KEY_FLAGS_USAGE_SIGN))
- {
- if ((k->flags & KEY_FLAGS_USAGE_DECRYPT))
- usage = "se";
- else
- usage = "s";
- }
- else
- {
- if ((k->flags & KEY_FLAGS_USAGE_DECRYPT))
- usage = "e";
- else
- usage = "-";
- }
-
+ usage = get_usage_string (k);
send_keyinfo (ctrl, opt_data, keygrip,
k->label_len ? (const char *)k->label : "-",
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);
while (iter_find_key (&iter, &k))
{
- if ((k->flags & KEY_FLAGS_USAGE_SIGN))
- {
- if ((k->flags & KEY_FLAGS_USAGE_DECRYPT))
- usage = "se";
- else
- usage = "s";
- }
- else
- {
- if ((k->flags & KEY_FLAGS_USAGE_DECRYPT))
- usage = "e";
- else
- usage = "-";
- }
-
+ usage = get_usage_string (k);
send_keyinfo (ctrl, opt_data, k->keygrip,
k->label_len ? (const char *)k->label : "-",
k->id_len ? (const char *)k->id : "-",
diff --git a/tkd/tkdaemon.h b/tkd/tkdaemon.h
index 528117af1..85873ecbc 100644
--- a/tkd/tkdaemon.h
+++ b/tkd/tkdaemon.h
@@ -115,9 +115,7 @@ gpg_error_t token_sign (ctrl_t ctrl, assuan_context_t ctx,
unsigned char **r_outdata,
size_t *r_outdatalen);
gpg_error_t token_readkey (ctrl_t ctrl, assuan_context_t ctx,
- const char *keygrip, int opt_info,
- unsigned char **r_pk,
- size_t *r_pklen);
+ const char *keygrip);
gpg_error_t token_keyinfo (ctrl_t ctrl,
const char *keygrip, int opt_data, int cap);