aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNIIBE Yutaka <[email protected]>2023-03-22 06:28:56 +0000
committerNIIBE Yutaka <[email protected]>2023-03-22 23:35:20 +0000
commit30d4eb97db8562bb62367a66003fae7fa9107938 (patch)
treeab592892b9702a1ab67d3bd623d99c8c12d1ea8d
parentMerge branch 'master' into gniibe/t6364 (diff)
downloadgnupg-30d4eb97db8562bb62367a66003fae7fa9107938.tar.gz
gnupg-30d4eb97db8562bb62367a66003fae7fa9107938.zip
tkd: Support READCERT command.gniibe/t6364
Signed-off-by: NIIBE Yutaka <[email protected]>
-rw-r--r--tkd/command.c26
-rw-r--r--tkd/pkcs11.c98
-rw-r--r--tkd/tkdaemon.h3
3 files changed, 91 insertions, 36 deletions
diff --git a/tkd/command.c b/tkd/command.c
index a78ede3b7..2a583ace2 100644
--- a/tkd/command.c
+++ b/tkd/command.c
@@ -297,6 +297,31 @@ cmd_readkey (assuan_context_t ctx, char *line)
return err;
}
+static const char hlp_readcert[] =
+ "READCERT <keygrip>\n"
+ "\n"
+ "Return the certificate for the given KEYGRIP.";
+static gpg_error_t
+cmd_readcert (assuan_context_t ctx, char *line)
+{
+ ctrl_t ctrl = assuan_get_pointer (ctx);
+ gpg_error_t err;
+ const char *keygrip;
+
+ line = xtrystrdup (line); /* Need a copy of the line. */
+ if (!line)
+ return gpg_error_from_syserror ();
+
+ keygrip = skip_options (line);
+ if (strlen (keygrip) != 40)
+ err = gpg_error (GPG_ERR_INV_ID);
+
+ err = tkd_readcert (ctrl, ctx, keygrip);
+
+ xfree (line);
+ return err;
+}
+
static const char hlp_pksign[] =
"PKSIGN [--hash=[sha{256,384,512}|none]] <keygrip>\n"
"\n"
@@ -469,6 +494,7 @@ register_commands (assuan_context_t ctx)
{ "PKSIGN", cmd_pksign, hlp_pksign },
{ "KILLTKD", cmd_killtkd, hlp_killtkd },
{ "KEYINFO", cmd_keyinfo, hlp_keyinfo },
+ { "READCERT", cmd_readcert, hlp_readcert },
{ "GETINFO", cmd_getinfo, hlp_getinfo },
{ "RESTART", cmd_restart, hlp_restart },
{ NULL }
diff --git a/tkd/pkcs11.c b/tkd/pkcs11.c
index 33c19ecdd..c89113cab 100644
--- a/tkd/pkcs11.c
+++ b/tkd/pkcs11.c
@@ -622,72 +622,73 @@ check_public_keys (struct token *token)
return 0;
}
-#if 0
static long
-get_certificate (struct token *token)
+get_certificate (struct token *token,
+ unsigned char **r_cert, size_t *r_certlen)
{
- unsigned long err = 0;
+ unsigned long r = 0;
struct cryptoki *ck = token->ck;
struct ck_attribute templ[1];
unsigned long class;
unsigned char certificate[4096];
- unsigned long cert_len;
- int certificate_available;
-
- ck_object_handle_t obj;
- int i;
+ int certificate_available = 0;
+ unsigned char *cert;
+ size_t certlen;
class = CKO_CERTIFICATE;
templ[0].type = CKA_CLASS;
templ[0].pValue = (void *)&class;
templ[0].ulValueLen = sizeof (class);
- err = ck->f->C_FindObjectsInit (token->session, templ, 1);
- if (!err)
+ r = ck->f->C_FindObjectsInit (token->session, templ, 1);
+ if (!r)
{
+ ck_object_handle_t obj;
+
while (TRUE)
{
unsigned long any;
/* Portable way to get objects... is get it one by one. */
- err = ck->f->C_FindObjects (token->session, &obj, 1, &any);
- if (err || any == 0)
+ r = ck->f->C_FindObjects (token->session, &obj, 1, &any);
+ if (r || any == 0)
break;
templ[0].type = CKA_VALUE;
templ[0].pValue = (void *)certificate;
templ[0].ulValueLen = sizeof (certificate);
- err = ck->f->C_GetAttributeValue (token->session, obj, templ, 1);
- if (err)
- certificate_available = 0;
- else
+ r = ck->f->C_GetAttributeValue (token->session, obj, templ, 1);
+ if (!r)
{
certificate_available = 1;
- cert_len = templ[0].ulValueLen;
-
- puts ("Certificate available:");
- for (i = 0; i < cert_len; i++)
- {
- printf ("%02x", certificate[i]);
- if ((i % 16) == 15)
- puts ("");
- }
- puts ("");
+ break;
}
}
- err = ck->f->C_FindObjectsFinal (token->session);
- if (err)
+ r = ck->f->C_FindObjectsFinal (token->session);
+ if (r)
{
return -1;
}
}
+ if (!certificate_available)
+ return -1;
+
+ certlen = templ[0].ulValueLen;
+ cert = xtrymalloc (certlen);
+ if (!cert)
+ {
+ return gpg_error_from_syserror ();
+ }
+
+ memcpy (cert, certificate, certlen);
+ *r_cert = cert;
+ *r_certlen = certlen;
return 0;
}
-#endif
static long
learn_keys (struct token *token)
@@ -717,12 +718,6 @@ learn_keys (struct token *token)
k->flags &= ~KEY_FLAG_NO_PUBKEY;
}
-#if 0
- /* Another way to get raw public key material is get it from the
- certificate, if available. */
- get_certificate (token);
-#endif
-
return 0;
}
@@ -1359,6 +1354,39 @@ tkd_readkey (ctrl_t ctrl, assuan_context_t ctx, const char *keygrip)
}
gpg_error_t
+tkd_readcert (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;
+ unsigned char *cert;
+ size_t certlen;
+
+ (void)ctrl;
+ (void)ctx;
+
+ if (!ck->handle)
+ {
+ err = tkd_init (ctrl, ctx, 0);
+ if (err)
+ return err;
+ }
+
+ r = find_key (ck, keygrip, &k);
+ if (r)
+ return gpg_error (GPG_ERR_NO_SECKEY);
+
+ if (get_certificate (k->token, &cert, &certlen))
+ return gpg_error (GPG_ERR_NOT_FOUND);
+
+ err = assuan_send_data (ctx, cert, certlen);
+ xfree (cert);
+ return err;
+}
+
+
+gpg_error_t
tkd_keyinfo (ctrl_t ctrl, assuan_context_t ctx, const char *keygrip,
int opt_data, int cap)
{
diff --git a/tkd/tkdaemon.h b/tkd/tkdaemon.h
index 5d2a15fea..181cd71ef 100644
--- a/tkd/tkdaemon.h
+++ b/tkd/tkdaemon.h
@@ -121,6 +121,7 @@ gpg_error_t tkd_readkey (ctrl_t ctrl, assuan_context_t ctx,
const char *keygrip);
gpg_error_t tkd_keyinfo (ctrl_t ctrl, assuan_context_t ctx,
const char *keygrip, int opt_data, int cap);
-
+gpg_error_t tkd_readcert (ctrl_t ctrl, assuan_context_t ctx,
+ const char *keygrip);
#endif /*TKDAEMON_H*/