From 12c0c36151109c65239a86ea3b687ca7b0cfac1c Mon Sep 17 00:00:00 2001 From: Moritz Schulte Date: Sat, 7 Aug 2004 20:36:53 +0000 Subject: [PATCH] 2004-08-07 Moritz Schulte * command-ssh.c (ssh_key_to_sexp_buffer): New argument: comment; integrate into S-Exp. (ssh_identity_register): New argument: comment; pass to ssh_key_to_sexp_buffer(). (ssh_handler_add_identity): Pass comment to ssh_identity_register(). (ssh_identity_register): Allocate description dynamically, insert comment; new variable: description_length; removed variable: i. (data_sign): Do not calculate key grip for integration in description; removed variable: i. * findkey.c (modify_description): New function. (agent_key_from_file): New variables: comment, comment_sexp, comment_length, desc_text_modified; extract comment from S-Exp, pass modified version to unprotect(). --- agent/ChangeLog | 18 ++++++ agent/command-ssh.c | 50 ++++++++-------- agent/findkey.c | 135 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 176 insertions(+), 27 deletions(-) diff --git a/agent/ChangeLog b/agent/ChangeLog index bf741f33e..67da75962 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,21 @@ +2004-08-07 Moritz Schulte + + * command-ssh.c (ssh_key_to_sexp_buffer): New argument: comment; + integrate into S-Exp. + (ssh_identity_register): New argument: comment; pass to + ssh_key_to_sexp_buffer(). + (ssh_handler_add_identity): Pass comment to + ssh_identity_register(). + (ssh_identity_register): Allocate description dynamically, insert + comment; new variable: description_length; removed variable: i. + (data_sign): Do not calculate key grip for integration in + description; removed variable: i. + + * findkey.c (modify_description): New function. + (agent_key_from_file): New variables: comment, comment_sexp, + comment_length, desc_text_modified; extract comment from S-Exp, + pass modified version to unprotect(). + 2004-07-30 Moritz Schulte * command-ssh.c: Updated Libgpg-stream (more support for secure diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 6f8b1db71..2535b58b1 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -985,15 +985,8 @@ data_sign (CTRL ctrl, unsigned char **sig, size_t *sig_n) size_t sig_blob_n = 0; size_t bytes_read = 0; char description[] = - "Please provide the passphrase for key " - "`0123456789012345678901234567890123456789':"; - char key_grip[41]; - unsigned int i = 0; + "Please provide the passphrase for key `%c':"; - for (i = 0; i < 20; i++) - sprintf (&key_grip[i * 2], "%02X", (unsigned char) ctrl->keygrip[i]); - strncpy (strchr (description, '0'), key_grip, 40); - err = agent_pksign_do (ctrl, description, &signature_sexp, 0); if (err) goto out; @@ -1174,7 +1167,8 @@ ssh_handler_sign_request (ctrl_t ctrl, } static gpg_err_code_t -ssh_key_to_sexp_buffer (ssh_key_secret_t *key, const char *passphrase, +ssh_key_to_sexp_buffer (ssh_key_secret_t *key, + const char *comment, const char *passphrase, unsigned char **buffer, size_t *buffer_n) { gpg_err_code_t err = GPG_ERR_NO_ERROR; @@ -1190,13 +1184,15 @@ ssh_key_to_sexp_buffer (ssh_key_secret_t *key, const char *passphrase, " (d %m)" " (p %m)" " (q %m)" - " (u %m)))", + " (u %m))" + " (comment %s))", key->material.rsa.n, key->material.rsa.e, key->material.rsa.d, key->material.rsa.p, key->material.rsa.q, - key->material.rsa.u); + key->material.rsa.u, + comment ? comment : ""); if (err) goto out; @@ -1256,18 +1252,15 @@ get_passphrase (char *description, size_t passphrase_n, char *passphrase) } static gpg_err_code_t -ssh_identity_register (ssh_key_secret_t *key, int ttl) +ssh_identity_register (ssh_key_secret_t *key, const char *comment, int ttl) { gpg_err_code_t err = GPG_ERR_NO_ERROR; unsigned char key_grip_raw[21] = { 0 }; unsigned char *buffer = NULL; unsigned int buffer_n = 0; char passphrase[100] = { 0 }; - char description[] = - "Please provide the passphrase, which should " - "be used for protecting the received secret key " - "`0123456789012345678901234567890123456789':"; - unsigned int i = 0; + size_t description_length = 0; + char *description = NULL; char key_grip[41]; int ret = 0; @@ -1282,16 +1275,25 @@ ssh_identity_register (ssh_key_secret_t *key, int ttl) if (! ret) goto out; - for (i = 0; i < 20; i++) - sprintf (&key_grip[i * 2], "%02X", key_grip_raw[i]); - strncpy (strchr (description, '0'), key_grip, 40); + description_length = 95 + (comment ? strlen (comment) : 0); + description = malloc (description_length); + if (! description) + { + err = gpg_err_code_from_errno (errno); + goto out; + } + else + sprintf (description, + "Please provide the passphrase, which should be used " + "for protecting the received secret key `%s':", + comment ? comment : ""); - err = get_passphrase (description, - sizeof (passphrase), passphrase); + err = get_passphrase (description, sizeof (passphrase), passphrase); + free (description); if (err) goto out; - err = ssh_key_to_sexp_buffer (key, passphrase, &buffer, &buffer_n); + err = ssh_key_to_sexp_buffer (key, comment, passphrase, &buffer, &buffer_n); if (err) goto out; @@ -1391,7 +1393,7 @@ ssh_handler_add_identity (ctrl_t ctrl, /* FIXME: are constraints used correctly? */ - err = ssh_identity_register (&key, death); + err = ssh_identity_register (&key, comment, death); if (err) goto out; diff --git a/agent/findkey.c b/agent/findkey.c index 9866b54b9..e57a5c6c5 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -136,6 +136,109 @@ try_unprotect_cb (struct pin_entry_info_s *pi) } +/* Modify a Key description, replacing certain special format + characters. */ +static int +modify_description (const char *description, + const char *comment, size_t comment_length, + char **description_modified) +{ + size_t description_length = strlen (description); + size_t description_new_length = description_length; + gpg_error_t err = GPG_ERR_NO_ERROR; + char *description_new = NULL; + unsigned int i = 0, j = 0; + unsigned int special = 0; + + /* Calculate length. */ + for (i = 0; i < description_length; i++) + { + if (description[i] == '%') + special = 1; + else + { + if (special) + { + description_new_length -= 2; + switch (description[i]) + { + case 'c': + /* Comment. */ + description_new_length += comment_length; + break; + + case 'g': + /* Key grip. */ + description_new_length += 40; + break; + + case '%': + description_new_length += 1; + break; + } + special = 0; + } + } + } + + /* Allocate. */ + description_new = malloc (description_new_length + 1); + if (! description_new) + { + err = gpg_error_from_errno (errno); + goto out; + } + + /* Fill. */ + for (i = j = 0; i < description_length; i++) + { + if (description[i] == '%') + special = 1; + else + { + if (special) + { + switch (description[i]) + { + case 'c': + /* Comment. */ + if (comment) + { + strncpy (description_new + j, comment, comment_length); + j += comment_length; + } + break; + + case 'g': + /* Key grip. */ + /* FIXME */ + break; + + case '%': + description_new[j] = '%'; + j++; + break; + } + special = 0; + } + else + { + description_new[j] = description[i]; + j++; + } + } + } + description_new[j] = 0; + + out: + + *description_modified = description_new; + + return err; +} + + + /* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP should be the hex encoded keygrip of that key to be used with the caching mechanism. DESC_TEXT may be set to override the default @@ -220,6 +323,10 @@ agent_key_from_file (CTRL ctrl, const char *desc_text, gcry_sexp_t s_skey; char hexgrip[40+4+1]; int got_shadow_info = 0; + const char *comment = NULL; + gcry_sexp_t comment_sexp = NULL; + char *desc_text_modified = NULL; + size_t comment_length = 0; *result = NULL; if (shadow_info) @@ -264,12 +371,26 @@ agent_key_from_file (CTRL ctrl, const char *desc_text, xfree (fname); fclose (fp); xfree (buf); + if (rc) { log_error ("failed to build S-Exp (off=%u): %s\n", (unsigned int)erroff, gpg_strerror (rc)); return rc; } + + comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0); + if (comment_sexp) + { + comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length); + if (! comment) + { + rc = GPG_ERR_INV_SEXP; + gcry_sexp_release (s_skey); + return rc; + } + } + len = gcry_sexp_sprint (s_skey, GCRYSEXP_FMT_CANON, NULL, 0); assert (len); buf = xtrymalloc (len); @@ -288,10 +409,18 @@ agent_key_from_file (CTRL ctrl, const char *desc_text, case PRIVATE_KEY_CLEAR: break; /* no unprotection needed */ case PRIVATE_KEY_PROTECTED: - rc = unprotect (ctrl, desc_text, &buf, grip, ignore_cache); + rc = modify_description (desc_text, + comment, comment_length, &desc_text_modified); if (rc) - log_error ("failed to unprotect the secret key: %s\n", - gpg_strerror (rc)); + log_error ("failed to modify description: %s\n", gpg_strerror (rc)); + else + { + rc = unprotect (ctrl, desc_text_modified, &buf, grip, ignore_cache); + xfree (desc_text_modified); + if (rc) + log_error ("failed to unprotect the secret key: %s\n", + gpg_strerror (rc)); + } break; case PRIVATE_KEY_SHADOWED: if (shadow_info)