From e0972d3d962548972872d889b362560e499340d1 Mon Sep 17 00:00:00 2001 From: Andrey Jivsov Date: Wed, 5 Jan 2011 17:33:17 -0800 Subject: Integrating http://code.google.com/p/gnupg-ecc/source/detail?r=15 . The following works: gpg2 --gen-key (ECC) gpg2 --list-keys gpg2 --list-packets ~/.gnupg/pubring.gpg gpg2 --list-packets ECDH doesn't work yet as the code must be re-written to adjust for gpg-agent refactoring. --- agent/cvt-openpgp.c | 54 +++++++++++++++++++++++++++++++++++++++++++++-------- agent/findkey.c | 10 ++++++++++ agent/protect.c | 35 ++++++++++++++++++++++++++-------- 3 files changed, 83 insertions(+), 16 deletions(-) (limited to 'agent') diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index e6a14c436..3dba79ebd 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -27,6 +27,7 @@ #include "agent.h" #include "i18n.h" #include "cvt-openpgp.h" +#include "../include/cipher.h" /* for PUBKEY_ALGO_ECDSA, PUBKEY_ALGO_ECDH */ /* Helper to pass data via the callback to do_unprotect. */ @@ -49,7 +50,12 @@ struct try_do_unprotect_arg_s gcry_sexp_t *r_key; }; - +/* TODO: it is also in misc, which is not linked with the agent */ +static int +map_pk_openpgp_to_gcry (int algo) +{ + return (algo==PUBKEY_ALGO_ECDSA ? GCRY_PK_ECDSA : (algo==PUBKEY_ALGO_ECDH ? GCRY_PK_ECDH : algo)); +} /* Compute the keygrip from the public key and store it at GRIP. */ static gpg_error_t @@ -80,6 +86,12 @@ get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip) "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]); break; + case GCRY_PK_ECDSA: + case GCRY_PK_ECDH: + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(ecc(c%m)(q%m)))", pkey[0], pkey[1]); + break; + default: err = gpg_error (GPG_ERR_PUBKEY_ALGO); break; @@ -94,7 +106,9 @@ get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip) /* Convert a secret key given as algorithm id and an array of key - parameters into our s-expression based format. */ + parameters into our s-expression based format. + pubkey_algo is a libgcrypt ID + */ static gpg_error_t convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey) { @@ -103,6 +117,8 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey) *r_key = NULL; + pubkey_algo = map_pk_openpgp_to_gcry( pubkey_algo ); + switch (pubkey_algo) { case GCRY_PK_DSA: @@ -128,6 +144,18 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey) skey[5]); break; + case GCRY_PK_ECDSA: + err = gcry_sexp_build (&s_skey, NULL, + "(private-key(ecdsa(c%m)(q%m)(d%m)))", + skey[0], skey[1], skey[2]); + break; + + case GCRY_PK_ECDH: + err = gcry_sexp_build (&s_skey, NULL, + "(private-key(ecdh(c%m)(q%m)(p%m)(d%m)))", + skey[0], skey[1], skey[2], skey[3]); + break; + default: err = gpg_error (GPG_ERR_PUBKEY_ALGO); break; @@ -202,6 +230,10 @@ do_unprotect (const char *passphrase, *r_key = NULL; + /* Unfortunately, the OpenPGP PK algorithm numbers need to be re-mapped for Libgcrypt + */ + pubkey_algo = map_pk_openpgp_to_gcry( pubkey_algo ); + /* Count the actual number of MPIs is in the array and set the remainder to NULL for easier processing later on. */ for (skeylen = 0; skey[skeylen]; skeylen++) @@ -219,9 +251,6 @@ do_unprotect (const char *passphrase, if (gcry_pk_test_algo (pubkey_algo)) { - /* The algorithm numbers are Libgcrypt numbers but fortunately - the OpenPGP algorithm numbers map one-to-one to the Libgcrypt - numbers. */ log_info (_("public key algorithm %d (%s) is not supported\n"), pubkey_algo, gcry_pk_algo_name (pubkey_algo)); return gpg_error (GPG_ERR_PUBKEY_ALGO); @@ -632,7 +661,7 @@ convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp, string = gcry_sexp_nth_string (list, 1); if (!string) goto bad_seckey; - pubkey_algo = gcry_pk_map_name (string); + pubkey_algo = gcry_pk_map_name (string); /* ligcrypt IDs */ xfree (string); if (gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey) @@ -999,6 +1028,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, } algo = gcry_pk_map_name (name); + log_debug ( "convert to openpgp begin for algo=%s\n", name ); xfree (name); switch (algo) @@ -1007,7 +1037,8 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, case GCRY_PK_ELG: algoname = "elg"; npkey = 3; elems = "pgyx"; break; case GCRY_PK_ELG_E: algoname = "elg"; npkey = 3; elems = "pgyx"; break; case GCRY_PK_DSA: algoname = "dsa"; npkey = 4; elems = "pqgyx"; break; - case GCRY_PK_ECDSA: algoname = "ecdsa"; npkey = 6; elems = "pabgnqd"; break; + case GCRY_PK_ECDSA: algoname = "ecdsa"; npkey = 2; elems = "cqd"; break; + case GCRY_PK_ECDH: algoname = "ecdh"; npkey = 3; elems = "cqpd"; break; default: algoname = ""; npkey = 0; elems = NULL; break; } assert (!elems || strlen (elems) < DIM (array) ); @@ -1027,6 +1058,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, err = apply_protection (array, npkey, nskey, passphrase, GCRY_CIPHER_AES, protect_iv, sizeof protect_iv, 3, GCRY_MD_SHA1, salt, s2k_count); + ///log_debug ( "convert to openpgp: after applying protection, err = %d\n", err ); /* Turn it into the transfer key S-expression. Note that we always return a protected key. */ if (!err) @@ -1037,7 +1069,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, int format_args_buf_int[1]; void *format_args[10+2]; size_t n; - gcry_sexp_t tmpkey, tmpsexp; + gcry_sexp_t tmpkey, tmpsexp = NULL; snprintf (countbuf, sizeof countbuf, "%lu", s2k_count); @@ -1056,6 +1088,8 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, put_membuf_str (&mbuf, ")\n"); put_membuf (&mbuf, "", 1); + ///log_debug ( "convert to openpgp: calling gcry_sexp_build\n" ); + tmpkey = NULL; { char *format = get_membuf (&mbuf, NULL); @@ -1065,6 +1099,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, err = gcry_sexp_build_array (&tmpkey, NULL, format, format_args); xfree (format); } + ///log_debug ( "convert to openpgp: calling gcry_sexp_build before err=%d\n", err ); if (!err) err = gcry_sexp_build (&tmpsexp, NULL, "(openpgp-private-key\n" @@ -1077,6 +1112,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, (int)sizeof protect_iv, protect_iv, (int)sizeof salt, salt, countbuf); + ///log_debug ( "convert to openpgp: after gcry_sexp_build, err = %d\n", err ); gcry_sexp_release (tmpkey); if (!err) err = make_canon_sexp_pad (tmpsexp, 0, r_transferkey, r_transferkeylen); @@ -1085,6 +1121,8 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, for (i=0; i < DIM (array); i++) gcry_mpi_release (array[i]); + + log_debug ( "convert to openpgp end with err=%d\n", err ); return err; } diff --git a/agent/findkey.c b/agent/findkey.c index 91fb8c14c..02e938e6e 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -726,6 +726,16 @@ key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list, algoname = "dsa"; elems = "pqgy"; } + else if (n==5 && !memcmp (name, "ecdsa", 5)) + { + algoname = "ecdsa"; + elems = "cq"; + } + else if (n==4 && !memcmp (name, "ecdh", 4)) + { + algoname = "ecdh"; + elems = "cqp"; + } else if (n==3 && !memcmp (name, "elg", 3)) { algoname = "elg"; diff --git a/agent/protect.c b/agent/protect.c index 795d06231..d14665363 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -52,6 +52,8 @@ static struct { { "rsa", "nedpqu", 2, 5 }, { "dsa", "pqgyx", 4, 4 }, { "elg", "pgyx", 3, 3 }, + { "ecdsa","cqd", 2, 2 }, + { "ecdh", "cqpd", 3, 3 }, { NULL } }; @@ -426,6 +428,9 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, unsigned char *p; gcry_md_hd_t md; + if (opt.debug & DBG_CRYPTO_VALUE) + log_info ("Protecting key=%s, passphrase=%s\n", plainkey, passphrase); + /* Create an S-expression with the protected-at timestamp. */ memcpy (timestamp_exp, "(12:protected-at15:", 19); gnupg_get_isotime (timestamp_exp+19); @@ -454,37 +459,51 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, for (infidx=0; protect_info[infidx].algo && !smatch (&s, n, protect_info[infidx].algo); infidx++) ; - if (!protect_info[infidx].algo) + if (!protect_info[infidx].algo) { + log_info ("Unsupported alg %d for protection\n", protect_info[infidx].algo); return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + } prot_begin = prot_end = NULL; for (i=0; (c=protect_info[infidx].parmlist[i]); i++) { if (i == protect_info[infidx].prot_from) prot_begin = s; - if (*s != '(') + if (*s != '(') { + log_info ("Unbalanced bracket in S-expression #1\n"); return gpg_error (GPG_ERR_INV_SEXP); + } depth++; s++; n = snext (&s); - if (!n) + if (!n) { + log_info ("Cannot get the length of S-expression field\n"); return gpg_error (GPG_ERR_INV_SEXP); - if (n != 1 || c != *s) + } + if (n != 1 || c != *s) { + log_info ("Invalid length in S-expression field\n"); return gpg_error (GPG_ERR_INV_SEXP); - s += n; + } + s += n; n = snext (&s); - if (!n) + if (!n) { + log_info ("Invalid fieled in S-expression field\n"); return gpg_error (GPG_ERR_INV_SEXP); + } s +=n; /* skip value */ - if (*s != ')') + if (*s != ')') { + log_info ("Unbalanced bracket in S-expression #2\n"); return gpg_error (GPG_ERR_INV_SEXP); + } depth--; if (i == protect_info[infidx].prot_to) prot_end = s; s++; } - if (*s != ')' || !prot_begin || !prot_end ) + if (*s != ')' || !prot_begin || !prot_end ) { + log_info ("Unbalanced bracket in S-expression #3\n"); return gpg_error (GPG_ERR_INV_SEXP); + } depth--; hash_end = s; s++; -- cgit v1.2.3 From b73d8ed06ffef8d2fd70ab2e48da9ef515472fe9 Mon Sep 17 00:00:00 2001 From: Andrey Jivsov Date: Wed, 12 Jan 2011 21:14:45 -0800 Subject: Fixed key generation with P-521. Confirmed that signature generation and verification work. --- agent/agent.h | 1 + agent/cvt-openpgp.c | 8 +------- agent/gpg-agent.c | 8 ++++++++ agent/pksign.c | 22 +++++++++++++++------- 4 files changed, 25 insertions(+), 14 deletions(-) (limited to 'agent') diff --git a/agent/agent.h b/agent/agent.h index 7716bb0c2..e31b6a78e 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -215,6 +215,7 @@ const char *get_agent_ssh_socket_name (void); void *get_agent_scd_notify_event (void); #endif void agent_sighup_action (void); +int map_pk_openpgp_to_gcry (int openpgp_algo); /*-- command.c --*/ gpg_error_t agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid); diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index 3dba79ebd..73c31f786 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -27,7 +27,6 @@ #include "agent.h" #include "i18n.h" #include "cvt-openpgp.h" -#include "../include/cipher.h" /* for PUBKEY_ALGO_ECDSA, PUBKEY_ALGO_ECDH */ /* Helper to pass data via the callback to do_unprotect. */ @@ -50,12 +49,7 @@ struct try_do_unprotect_arg_s gcry_sexp_t *r_key; }; -/* TODO: it is also in misc, which is not linked with the agent */ -static int -map_pk_openpgp_to_gcry (int algo) -{ - return (algo==PUBKEY_ALGO_ECDSA ? GCRY_PK_ECDSA : (algo==PUBKEY_ALGO_ECDH ? GCRY_PK_ECDH : algo)); -} + /* Compute the keygrip from the public key and store it at GRIP. */ static gpg_error_t diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index ca150b471..d85283a5e 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -51,6 +51,7 @@ #include "gc-opt-flags.h" #include "exechelp.h" #include "asshelp.h" +#include "../include/cipher.h" /* for PUBKEY_ALGO_ECDSA, PUBKEY_ALGO_ECDH */ enum cmd_and_opt_values { aNull = 0, @@ -2301,3 +2302,10 @@ check_for_running_agent (int silent, int mode) assuan_release (ctx); return 0; } + +/* TODO: it is also in misc, which is not linked with the agent */ +int +map_pk_openpgp_to_gcry (int algo) +{ + return (algo==PUBKEY_ALGO_ECDSA ? GCRY_PK_ECDSA : (algo==PUBKEY_ALGO_ECDH ? GCRY_PK_ECDH : algo)); +} diff --git a/agent/pksign.c b/agent/pksign.c index ac5f4e1a0..a6dbf2509 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -119,12 +119,15 @@ do_encode_dsa (const byte * md, size_t mdlen, int dsaalgo, gcry_sexp_t pkey, gpg_error_t err; gcry_sexp_t hash; unsigned int qbits; + int gcry_pkalgo; *r_hash = NULL; - if (dsaalgo == GCRY_PK_ECDSA) + gcry_pkalgo = map_pk_openpgp_to_gcry( dsaalgo ); + + if (gcry_pkalgo == GCRY_PK_ECDSA) qbits = gcry_pk_get_nbits (pkey); - else if (dsaalgo == GCRY_PK_DSA) + else if (gcry_pkalgo == GCRY_PK_DSA) qbits = get_dsa_qbits (pkey); else return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); @@ -143,20 +146,25 @@ do_encode_dsa (const byte * md, size_t mdlen, int dsaalgo, gcry_sexp_t pkey, if (qbits < 160) { log_error (_("%s key uses an unsafe (%u bit) hash\n"), - gcry_pk_algo_name (dsaalgo), qbits); + gcry_pk_algo_name (gcry_pkalgo), qbits); return gpg_error (GPG_ERR_INV_LENGTH); } /* Check if we're too short. Too long is safe as we'll automatically left-truncate. */ - if (mdlen < qbits/8) + + /* This check would require the use of SHA512 with ECDSA 512. I think this is overkill to fail in this case. + * Therefore, relax the check, but only for ECDSA keys. We may need to adjust it later for general case. + * ( Note that the check is really a bug for ECDSA 521 as the only hash that matches it is SHA 512, but 512 < 521 ). + */ + if( mdlen < ((gcry_pkalgo==GCRY_PK_ECDSA && qbits>521) ? 512 : qbits) ) { log_error (_("a %zu bit hash is not valid for a %u bit %s key\n"), - mdlen*8, + mdlen, gcry_pk_get_nbits (pkey), - gcry_pk_algo_name (dsaalgo)); + gcry_pk_algo_name (gcry_pkalgo)); /* FIXME: we need to check the requirements for ECDSA. */ - if (mdlen < 20 || dsaalgo == GCRY_PK_DSA) + if (mdlen < 20 || gcry_pkalgo == GCRY_PK_DSA) return gpg_error (GPG_ERR_INV_LENGTH); } -- cgit v1.2.3 From 90b0ff23b7e51332592668e4034967c1aac1c593 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 21 Jan 2011 12:00:57 +0100 Subject: Editorial changes and allow building with old libgcrypts. Changed order of some conditional to make to put the special case into the true branch. Indentation changes. Minor other changes to make the ECC code more similar to the rest of our code. It builds but many sefltests still fail. Need to fix that before using it with an ECDH enabled libgcrypt. [/] 2011-01-21 Werner Koch * configure.ac: Need Libgcrypt 1.4.6 due to AESWRAP. (HAVE_GCRY_PK_ECDH): Add new test. [agent/] 2011-01-21 Werner Koch * cvt-openpgp.c (GCRY_PK_ECDH) [!HAVE_GCRY_PK_ECDH]: New. [include/] 2011-01-21 Werner Koch * cipher.h (GCRY_PK_USAGE_CERT): Remove compatibility macros because we now require libgcrypt 1.4.6. (GCRY_PK_ECDH): Add replacement. --- agent/ChangeLog | 4 ++++ agent/cvt-openpgp.c | 31 +++++++++++++++---------------- agent/gpg-agent.c | 2 ++ agent/protect.c | 37 ++++++++++--------------------------- 4 files changed, 31 insertions(+), 43 deletions(-) (limited to 'agent') diff --git a/agent/ChangeLog b/agent/ChangeLog index ce1fdccd8..699282754 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,7 @@ +2011-01-21 Werner Koch + + * cvt-openpgp.c (GCRY_PK_ECDH) [!HAVE_GCRY_PK_ECDH]: New. + 2010-12-02 Werner Koch * gpg-agent.c (CHECK_OWN_SOCKET_INTERVAL) [W32CE]: Set to 60 diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index 73c31f786..02c2bc841 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -28,6 +28,13 @@ #include "i18n.h" #include "cvt-openpgp.h" +/* Macros for compatibility with older libgcrypt versions. */ +#ifndef HAVE_GCRY_PK_ECDSA +# define GCRY_PK_ECDH 302 +#endif + + + /* Helper to pass data via the callback to do_unprotect. */ struct try_do_unprotect_arg_s @@ -100,8 +107,8 @@ get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip) /* Convert a secret key given as algorithm id and an array of key - parameters into our s-expression based format. - pubkey_algo is a libgcrypt ID + parameters into our s-expression based format. Note that + PUBKEY_ALGO is a standard id and not an OpenPGP id. */ static gpg_error_t convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey) @@ -111,7 +118,8 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey) *r_key = NULL; - pubkey_algo = map_pk_openpgp_to_gcry( pubkey_algo ); + /* FIXME: This is not consistent with the above comment. */ + pubkey_algo = map_pk_openpgp_to_gcry (pubkey_algo); switch (pubkey_algo) { @@ -224,9 +232,9 @@ do_unprotect (const char *passphrase, *r_key = NULL; - /* Unfortunately, the OpenPGP PK algorithm numbers need to be re-mapped for Libgcrypt - */ - pubkey_algo = map_pk_openpgp_to_gcry( pubkey_algo ); + /* Unfortunately, the OpenPGP PK algorithm numbers need to be + re-mapped for Libgcrypt. */ + pubkey_algo = map_pk_openpgp_to_gcry (pubkey_algo); /* Count the actual number of MPIs is in the array and set the remainder to NULL for easier processing later on. */ @@ -655,7 +663,7 @@ convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp, string = gcry_sexp_nth_string (list, 1); if (!string) goto bad_seckey; - pubkey_algo = gcry_pk_map_name (string); /* ligcrypt IDs */ + pubkey_algo = gcry_pk_map_name (string); xfree (string); if (gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey) @@ -1022,7 +1030,6 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, } algo = gcry_pk_map_name (name); - log_debug ( "convert to openpgp begin for algo=%s\n", name ); xfree (name); switch (algo) @@ -1052,7 +1059,6 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, err = apply_protection (array, npkey, nskey, passphrase, GCRY_CIPHER_AES, protect_iv, sizeof protect_iv, 3, GCRY_MD_SHA1, salt, s2k_count); - ///log_debug ( "convert to openpgp: after applying protection, err = %d\n", err ); /* Turn it into the transfer key S-expression. Note that we always return a protected key. */ if (!err) @@ -1082,8 +1088,6 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, put_membuf_str (&mbuf, ")\n"); put_membuf (&mbuf, "", 1); - ///log_debug ( "convert to openpgp: calling gcry_sexp_build\n" ); - tmpkey = NULL; { char *format = get_membuf (&mbuf, NULL); @@ -1093,7 +1097,6 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, err = gcry_sexp_build_array (&tmpkey, NULL, format, format_args); xfree (format); } - ///log_debug ( "convert to openpgp: calling gcry_sexp_build before err=%d\n", err ); if (!err) err = gcry_sexp_build (&tmpsexp, NULL, "(openpgp-private-key\n" @@ -1106,7 +1109,6 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, (int)sizeof protect_iv, protect_iv, (int)sizeof salt, salt, countbuf); - ///log_debug ( "convert to openpgp: after gcry_sexp_build, err = %d\n", err ); gcry_sexp_release (tmpkey); if (!err) err = make_canon_sexp_pad (tmpsexp, 0, r_transferkey, r_transferkeylen); @@ -1116,8 +1118,5 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, for (i=0; i < DIM (array); i++) gcry_mpi_release (array[i]); - log_debug ( "convert to openpgp end with err=%d\n", err ); - return err; } - diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index d85283a5e..db9039278 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -2304,6 +2304,8 @@ check_for_running_agent (int silent, int mode) } /* TODO: it is also in misc, which is not linked with the agent */ +/* FIXME: The agent should not know about openpgp internals - weel + except for some stuff in cvt-openpgp. */ int map_pk_openpgp_to_gcry (int algo) { diff --git a/agent/protect.c b/agent/protect.c index d14665363..d0a5fe9e3 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -43,7 +43,7 @@ /* A table containing the information needed to create a protected - private key */ + private key. */ static struct { const char *algo; const char *parmlist; @@ -428,9 +428,6 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, unsigned char *p; gcry_md_hd_t md; - if (opt.debug & DBG_CRYPTO_VALUE) - log_info ("Protecting key=%s, passphrase=%s\n", plainkey, passphrase); - /* Create an S-expression with the protected-at timestamp. */ memcpy (timestamp_exp, "(12:protected-at15:", 19); gnupg_get_isotime (timestamp_exp+19); @@ -459,55 +456,41 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, for (infidx=0; protect_info[infidx].algo && !smatch (&s, n, protect_info[infidx].algo); infidx++) ; - if (!protect_info[infidx].algo) { - log_info ("Unsupported alg %d for protection\n", protect_info[infidx].algo); + if (!protect_info[infidx].algo) return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - } prot_begin = prot_end = NULL; for (i=0; (c=protect_info[infidx].parmlist[i]); i++) { if (i == protect_info[infidx].prot_from) prot_begin = s; - if (*s != '(') { - log_info ("Unbalanced bracket in S-expression #1\n"); + if (*s != '(') return gpg_error (GPG_ERR_INV_SEXP); - } depth++; s++; n = snext (&s); - if (!n) { - log_info ("Cannot get the length of S-expression field\n"); + if (!n) return gpg_error (GPG_ERR_INV_SEXP); - } - if (n != 1 || c != *s) { - log_info ("Invalid length in S-expression field\n"); + if (n != 1 || c != *s) return gpg_error (GPG_ERR_INV_SEXP); - } - s += n; + s += n; n = snext (&s); - if (!n) { - log_info ("Invalid fieled in S-expression field\n"); + if (!n) return gpg_error (GPG_ERR_INV_SEXP); - } s +=n; /* skip value */ - if (*s != ')') { - log_info ("Unbalanced bracket in S-expression #2\n"); + if (*s != ')') return gpg_error (GPG_ERR_INV_SEXP); - } depth--; if (i == protect_info[infidx].prot_to) prot_end = s; s++; } - if (*s != ')' || !prot_begin || !prot_end ) { - log_info ("Unbalanced bracket in S-expression #3\n"); + if (*s != ')' || !prot_begin || !prot_end ) return gpg_error (GPG_ERR_INV_SEXP); - } depth--; hash_end = s; s++; - /* skip to the end of the S-exp */ + /* Skip to the end of the S-expression. */ assert (depth == 1); rc = sskip (&s, &depth); if (rc) -- cgit v1.2.3 From 27929981fc23fabecf6af9fa1361361b821bb2fd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 21 Jan 2011 15:22:41 +0100 Subject: Make most of the selftests work. Note that there is still a problem with tests/openpgp/sigs.test while using the option --digest-algo SHA256. --- agent/ChangeLog | 2 ++ agent/pksign.c | 33 ++++++++++++++++++--------------- 2 files changed, 20 insertions(+), 15 deletions(-) (limited to 'agent') diff --git a/agent/ChangeLog b/agent/ChangeLog index 699282754..4b0712c8d 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,5 +1,7 @@ 2011-01-21 Werner Koch + * pksign.c (do_encode_dsa): Compare MDLEN to bytes. + * cvt-openpgp.c (GCRY_PK_ECDH) [!HAVE_GCRY_PK_ECDH]: New. 2010-12-02 Werner Koch diff --git a/agent/pksign.c b/agent/pksign.c index a6dbf2509..0414bc347 100644 --- a/agent/pksign.c +++ b/agent/pksign.c @@ -113,21 +113,21 @@ get_dsa_qbits (gcry_sexp_t key) /* Encode a message digest for use with an DSA algorithm. */ static gpg_error_t -do_encode_dsa (const byte * md, size_t mdlen, int dsaalgo, gcry_sexp_t pkey, +do_encode_dsa (const byte *md, size_t mdlen, int dsaalgo, gcry_sexp_t pkey, gcry_sexp_t *r_hash) { gpg_error_t err; gcry_sexp_t hash; unsigned int qbits; - int gcry_pkalgo; + int pkalgo; *r_hash = NULL; - gcry_pkalgo = map_pk_openpgp_to_gcry( dsaalgo ); + pkalgo = map_pk_openpgp_to_gcry (dsaalgo); - if (gcry_pkalgo == GCRY_PK_ECDSA) + if (pkalgo == GCRY_PK_ECDSA) qbits = gcry_pk_get_nbits (pkey); - else if (gcry_pkalgo == GCRY_PK_DSA) + else if (pkalgo == GCRY_PK_DSA) qbits = get_dsa_qbits (pkey); else return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); @@ -146,25 +146,28 @@ do_encode_dsa (const byte * md, size_t mdlen, int dsaalgo, gcry_sexp_t pkey, if (qbits < 160) { log_error (_("%s key uses an unsafe (%u bit) hash\n"), - gcry_pk_algo_name (gcry_pkalgo), qbits); + gcry_pk_algo_name (pkalgo), qbits); return gpg_error (GPG_ERR_INV_LENGTH); } /* Check if we're too short. Too long is safe as we'll - automatically left-truncate. */ - - /* This check would require the use of SHA512 with ECDSA 512. I think this is overkill to fail in this case. - * Therefore, relax the check, but only for ECDSA keys. We may need to adjust it later for general case. - * ( Note that the check is really a bug for ECDSA 521 as the only hash that matches it is SHA 512, but 512 < 521 ). + * automatically left-truncate. + * + * This check would require the use of SHA512 with ECDSA 512. I + * think this is overkill to fail in this case. Therefore, relax + * the check, but only for ECDSA keys. We may need to adjust it + * later for general case. (Note that the check is really a bug for + * ECDSA 521 as the only hash that matches it is SHA 512, but 512 < + * 521 ). */ - if( mdlen < ((gcry_pkalgo==GCRY_PK_ECDSA && qbits>521) ? 512 : qbits) ) + if (mdlen < ((pkalgo==GCRY_PK_ECDSA && qbits > 521) ? 512 : qbits)/8) { log_error (_("a %zu bit hash is not valid for a %u bit %s key\n"), - mdlen, + mdlen*8, gcry_pk_get_nbits (pkey), - gcry_pk_algo_name (gcry_pkalgo)); + gcry_pk_algo_name (pkalgo)); /* FIXME: we need to check the requirements for ECDSA. */ - if (mdlen < 20 || gcry_pkalgo == GCRY_PK_DSA) + if (mdlen < 20 || pkalgo == GCRY_PK_DSA) return gpg_error (GPG_ERR_INV_LENGTH); } -- cgit v1.2.3 From 0fb0bb8d9a960a2473ab70a021d20639a43227e0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 31 Jan 2011 09:27:06 +0100 Subject: Reworked the ECC changes to better fit into the Libgcrypt API. See ChangeLog for details. Key generation, signing and verification works. Encryption does not yet work. Requires latest Libgcrypt changes. --- agent/ChangeLog | 5 +++++ agent/protect.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'agent') diff --git a/agent/ChangeLog b/agent/ChangeLog index 7dace3aef..432803fa3 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,8 @@ +2011-01-27 Werner Koch + + * protect.c (protect_info): Adjust ECDSA and ECDH parameter names. + Add "ecc". + 2011-01-19 Werner Koch * trustlist.c (read_one_trustfile): Also chop an CR. diff --git a/agent/protect.c b/agent/protect.c index d0a5fe9e3..61ed8ee38 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -52,8 +52,9 @@ static struct { { "rsa", "nedpqu", 2, 5 }, { "dsa", "pqgyx", 4, 4 }, { "elg", "pgyx", 3, 3 }, - { "ecdsa","cqd", 2, 2 }, - { "ecdh", "cqpd", 3, 3 }, + { "ecdsa","pabgnqd", 6, 6 }, + { "ecdh", "pabgnqd", 6, 6 }, + { "ecc", "pabgnqd", 6, 6 }, { NULL } }; -- cgit v1.2.3 From 328a642aa5ed971870a2667b06307f760fa251dc Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 31 Jan 2011 15:44:24 +0100 Subject: Fixed the ECC interface to Libgcrypt to be ABI compatible with the previous version. Quite some changes were needed but in the end we have less code than before. Instead of trying to do everything with MPIs and pass them back and forth between Libgcrypt and GnuPG, we know use the S-expression based interface and make heavy use of our opaque MPI feature. Encryption, decryption, signing and verification work with self-generared keys. Import and export does not yet work; thus it was not possible to check the test keys at https://sites.google.com/site/brainhub/pgpecckeys . --- agent/ChangeLog | 3 ++- agent/findkey.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'agent') diff --git a/agent/ChangeLog b/agent/ChangeLog index 432803fa3..6338c56c5 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,7 +1,8 @@ -2011-01-27 Werner Koch +2011-01-31 Werner Koch * protect.c (protect_info): Adjust ECDSA and ECDH parameter names. Add "ecc". + * findkey.c (key_parms_from_sexp): Ditto. 2011-01-19 Werner Koch diff --git a/agent/findkey.c b/agent/findkey.c index 02e938e6e..108146693 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -729,12 +729,12 @@ key_parms_from_sexp (gcry_sexp_t s_key, gcry_sexp_t *r_list, else if (n==5 && !memcmp (name, "ecdsa", 5)) { algoname = "ecdsa"; - elems = "cq"; + elems = "pabgnq"; } else if (n==4 && !memcmp (name, "ecdh", 4)) { algoname = "ecdh"; - elems = "cqp"; + elems = "pabgnq"; } else if (n==3 && !memcmp (name, "elg", 3)) { -- cgit v1.2.3 From 4659c923a08002a72cb4bb5b3c4e6a02d7484767 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 2 Feb 2011 15:48:54 +0100 Subject: Sample ECC keys and message do now work. Import and export of secret keys does now work. Encryption has been fixed to be compatible with the sample messages. This version tests for new Libgcrypt function and thus needs to be build with a new Libgcrypt installed. --- agent/ChangeLog | 101 ++++++++++++++++++++++++++++------------------------ agent/cvt-openpgp.c | 86 ++++++++++++++++++++++---------------------- 2 files changed, 96 insertions(+), 91 deletions(-) (limited to 'agent') diff --git a/agent/ChangeLog b/agent/ChangeLog index 6338c56c5..d4a0de3a8 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,5 +1,12 @@ +2011-02-02 Werner Koch + + * cvt-openpgp.c (convert_secret_key): Remove algo mapping. + 2011-01-31 Werner Koch + * cvt-openpgp.c (convert_to_openpgp): Adjust to reverted Libgcrypt + ABI. + * protect.c (protect_info): Adjust ECDSA and ECDH parameter names. Add "ecc". * findkey.c (key_parms_from_sexp): Ditto. @@ -522,7 +529,7 @@ * genkey.c (agent_protect_and_store): Return RC and not 0. * protect.c (do_encryption): Fix ignored error code from malloc. Reported by Fabian Keil. - + 2009-06-17 Werner Koch * call-pinentry.c (agent_get_confirmation): Add arg WITH_CANCEL. @@ -546,7 +553,7 @@ * trustlist.c: Include estream.h. (agent_marktrusted): Replace stdio stream by estream functions. - * protect-tool.c (store_private_key): Use bin2hex. + * protect-tool.c (store_private_key): Use bin2hex. 2009-06-02 Werner Koch @@ -560,7 +567,7 @@ 2009-05-15 Werner Koch Fix bug #1053. - + * agent.h (lookup_ttl_t): New. * findkey.c (unprotect): Add arg LOOKUP_TTL. (agent_key_from_file): Ditto. @@ -638,7 +645,7 @@ (agent_istrusted): Add arg R_DISABLED. Change all callers. (agent_marktrusted): Do not ask if flagged as disabled. Reverse the order of the questions. Store the disabled flag. - + * gpg-agent.c (main): Save signal mask and open fds. Restore mask and close all fds prior to the exec. Fixes bug#1013. @@ -749,11 +756,11 @@ * command.c (cmd_geteventcounter): Mark unused arg. (cmd_listtrusted, cmd_pksign, cmd_pkdecrypt, cmd_genkey): Ditto. (cmd_updatestartuptty, post_cmd_notify): Ditto. - * command-ssh.c (add_control_entry) - (ssh_handler_request_identities, ssh_handler_remove_identity) - (ssh_handler_remove_all_identities, ssh_handler_lock) + * command-ssh.c (add_control_entry) + (ssh_handler_request_identities, ssh_handler_remove_identity) + (ssh_handler_remove_all_identities, ssh_handler_lock) (ssh_handler_unlock): Ditto. - * call-pinentry.c (pinentry_active_p, popup_message_thread) + * call-pinentry.c (pinentry_active_p, popup_message_thread) (agent_popup_message_stop): Ditto. * findkey.c (agent_public_key_from_file): Ditto. * genkey.c (check_passphrase_pattern): Ditto. @@ -872,7 +879,7 @@ * agent.h (struct server_control_s): Add XAUTHORITY and PINENTRY_USER_DATA. * gpg-agent.c: New option --xauthority. - (main, agent_init_default_ctrl) + (main, agent_init_default_ctrl) (agent_deinit_default_ctrl): Implemented * command.c (cmd_updatestartuptty): Ditto. * command-ssh.c (start_command_handler_ssh): Ditto. @@ -1032,7 +1039,7 @@ 2007-06-21 Werner Koch - * agent.h (ctrl_t): Remove. It is now declared in ../common/util.h. + * agent.h (ctrl_t): Remove. It is now declared in ../common/util.h. * gpg-agent.c (check_for_running_agent): New arg SILENT. Changed all callers. @@ -1065,7 +1072,7 @@ * preset-passphrase.c (main): Setup default socket name for simple-pwquery. (map_spwq_error): Remove. - (MAP_SPWQ_ERROR_IMPL): New. + (MAP_SPWQ_ERROR_IMPL): New. * call-pinentry.c (start_pinentry): Use gnupg_module_name. * call-scd.c (start_scd): Ditto. @@ -1127,7 +1134,7 @@ (main): Call the setup_libgcrypt_logging helper. * protect-tool.c (my_gcry_logger): Removed. (main): Call the setup_libgcrypt_logging helper. - + 2007-04-03 Werner Koch * trustlist.c (read_trustfiles): Take a missing trustlist as an @@ -1135,7 +1142,7 @@ 2007-03-20 Werner Koch - * protect-tool.c: New option --p12-charset. + * protect-tool.c: New option --p12-charset. * minip12.c (p12_build): Implement it. 2007-03-19 Werner Koch @@ -1170,7 +1177,7 @@ 2007-01-31 Werner Koch - * command-ssh.c (start_command_handler_ssh): + * command-ssh.c (start_command_handler_ssh): * Makefile.am (t_common_ldadd): Add LIBICONV. @@ -1298,7 +1305,7 @@ (agent_pksign_do): Use it here for the TLS algo. * agent.h (GCRY_MD_USER_TLS_MD5SHA1): New. * divert-scd.c (pksign): Add case for tls-md5sha1. - + * divert-scd.c (encode_md_for_card): Check that the algo is valid. 2006-10-04 Werner Koch @@ -1368,7 +1375,7 @@ Replaced all Assuan error codes by libgpg-error codes. Removed all map_to_assuan_status and map_assuan_err. - + * gpg-agent.c (main): Call assuan_set_assuan_err_source to have Assuan switch to gpg-error codes. * command.c (set_error): Adjusted. @@ -1412,7 +1419,7 @@ * minip12.c (oid_pkcs_12_keyBag): New. (parse_bag_encrypted_data): New arg R_RESULT. Support keybags and - return the key object. + return the key object. (p12_parse): Take new arg into account. Free RESULT on error. 2006-06-26 Werner Koch @@ -1480,7 +1487,7 @@ * call-scd.c (inq_needpin): Reworked to support the new KEYPADINFO. * query.c (start_pinentry): Keep track of the owner. - (popup_message_thread, agent_popup_message_start) + (popup_message_thread, agent_popup_message_start) (agent_popup_message_stop, agent_reset_query): New. * command.c (start_command_handler): Make sure a popup window gets closed. @@ -1531,7 +1538,7 @@ 2005-06-21 Werner Koch - * minip12.c (create_final): Cast size_t to ulong for printf. + * minip12.c (create_final): Cast size_t to ulong for printf. (build_key_bag, build_cert_bag, build_cert_sequence): Ditto. 2005-06-16 Werner Koch @@ -1546,7 +1553,7 @@ * protect.c (do_encryption): Ditto. (do_encryption): Made arg PROTBEGIN unsigned. Initialize RESULT and RESULTLEN even on error. - (merge_lists): Need to cast unsigned char * for strcpy. Initialize + (merge_lists): Need to cast unsigned char * for strcpy. Initialize RESULTand RESULTLEN even on error. (agent_unprotect): Likewise for strtoul. (make_shadow_info): Made P and INFO plain char. @@ -1606,7 +1613,7 @@ * command.c (cmd_updatestartuptty): New. * gpg-agent.c: New option --write-env-file. - + * gpg-agent.c (handle_connections): Make sure that the signals we are handling are not blocked.Block signals while creating new threads. @@ -1876,8 +1883,8 @@ (make_cstring): Ditto. (data_sign): Don't use a variable for the passphrase prompt, make it translatable. - (ssh_request_process): - + (ssh_request_process): + * findkey.c (modify_description): Renamed arguments for clarity, polished documentation. Make comment a C-string. Fixed case of @@ -2003,7 +2010,7 @@ 2004-12-21 Werner Koch * gpg-agent.c (main): Use default_homedir(). - * protect-tool.c (main): Ditto. + * protect-tool.c (main): Ditto. 2004-12-20 Werner Koch @@ -2029,7 +2036,7 @@ * query.c (initialize_module_query): New. * call-scd.c (initialize_module_call_scd): New. * gpg-agent.c (main): Call them. - + 2004-12-18 Werner Koch * gpg-agent.c (main): Remove special Pth initialize. @@ -2081,10 +2088,10 @@ to Moritz for pointing this out. 2004-09-25 Moritz Schulte - + * agent.h: Declare: agent_pksign_do. (struct server_control_s): New member: raw_value. - + * pksign.c (do_encode_md): New argument: raw_value; support generation of raw (non-pkcs1) data objects; adjust callers. (agent_pksign_do): New function, based on code ripped @@ -2092,7 +2099,7 @@ (agent_pksign): Use agent_pksign_do. * command.c (start_command_handler): Set ctrl.digest.raw_value. - + 2004-09-09 Werner Koch * gpg-agent.c (check_for_running_agent): New. @@ -2133,14 +2140,14 @@ * gpg-agent.c (handle_signal): Reload the trustlist on SIGHUP. (start_connection_thread): Hack to simulate a ticker. - * trustlist.c (agent_trustlist_housekeeping) + * trustlist.c (agent_trustlist_housekeeping) (agent_reload_trustlist): New. Protected all global functions here with a simple counter which is sufficient for Pth. 2004-05-03 Werner Koch * gpg-agent.c: Remove help texts for options lile --lc-ctype. - (main): New option --allow-mark-trusted. + (main): New option --allow-mark-trusted. * trustlist.c (agent_marktrusted): Use it here. 2004-04-30 Werner Koch @@ -2213,7 +2220,7 @@ string. Changed all callers. * minip12.c: Revamped the build part. - (p12_build): New args CERT and CERTLEN. + (p12_build): New args CERT and CERTLEN. 2004-02-18 Werner Koch @@ -2307,7 +2314,7 @@ * findkey.c (agent_key_from_file): Now return an error code so that we have more detailed error messages in the upper layers. - This fixes the handling of pinentry's cancel button. + This fixes the handling of pinentry's cancel button. * pksign.c (agent_pksign): Changed accordingly. * pkdecrypt.c (agent_pkdecrypt): Ditto. * command.c (cmd_passwd): Ditto. @@ -2334,12 +2341,12 @@ * pksign.c (do_encode_md): Allocate enough space. Cast md byte to unsigned char to prevent sign extension. - + 2003-08-14 Timo Schulz * pksign.c (do_encode_md): Due to the fact pkcs#1 padding is now in Libgcrypt, use the new interface. - + 2003-07-31 Werner Koch * Makefile.am (gpg_agent_LDADD): Added INTLLIBS. @@ -2389,7 +2396,7 @@ * gpg-agent.c (handle_connections): Adjusted for Pth 2.0 Adjusted for changes in the libgcrypt API. Some more fixes for the - libgpg-error stuff. + libgpg-error stuff. 2003-06-04 Werner Koch @@ -2468,11 +2475,11 @@ (agent_askpin,agent_get_passphrase,agent_get_confirmation): Add CTRL arg and pass it ot start_pinentry. * command.c (cmd_get_passphrase): Pass CTRL argument. - * trustlist.c (agent_marktrusted): Add CTRL argument + * trustlist.c (agent_marktrusted): Add CTRL argument * command.c (cmd_marktrusted): Pass CTRL argument - * divert-scd.c (ask_for_card): Add CTRL arg. + * divert-scd.c (ask_for_card): Add CTRL arg. (divert_pksign,divert_pkdecrypt): Ditto. Changed caller. - (getpin_cb): Use OPAQUE to pass the CTRL variable. Changed both + (getpin_cb): Use OPAQUE to pass the CTRL variable. Changed both users. * findkey.c (unprotect): Add CTRL arg. (agent_key_from_file): Ditto. @@ -2707,7 +2714,7 @@ convert it to hex here. * findkey.c (agent_write_private_key): New. * genkey.c (store_key): And use it here. - + * pkdecrypt.c (agent_pkdecrypt): Changed the way the diversion is done. * divert-scd.c (divert_pkdecrypt): Changed interface and implemented it. @@ -2737,7 +2744,7 @@ * protect.c (snext,sskip,smatch): Moved to * sexp-parse.h: New file. * divert-scd.c: New. - + 2002-02-27 Werner Koch * protect.c (agent_shadow_key): New. @@ -2765,7 +2772,7 @@ * gpg-agent.c: New option --default-cache-ttl. * cache.c (agent_put_cache): Use it. - + * cache.c: Add a few debug outputs. * protect.c (agent_private_key_type): New. @@ -2773,10 +2780,10 @@ * findkey.c (agent_key_from_file): Use it to decide whether we have to unprotect a key. (unprotect): Cache the passphrase. - + * findkey.c (agent_key_from_file,agent_key_available): The key files do now require a ".key" suffix to make a script's life - easier. + easier. * genkey.c (store_key): Ditto. 2002-01-31 Werner Koch @@ -2784,11 +2791,11 @@ * genkey.c (store_key): Protect the key. (agent_genkey): Ask for the passphrase. * findkey.c (unprotect): Actually unprotect the key. - * query.c (agent_askpin): Add an optional start_err_text. + * query.c (agent_askpin): Add an optional start_err_text. 2002-01-30 Werner Koch - * protect.c: New. + * protect.c: New. (hash_passphrase): Based on the GnuPG 1.0.6 version. * protect-tool.c: New @@ -2842,10 +2849,10 @@ * command.c (rc_to_assuan_status): Removed and changed all callers to use map_to_assuan_status. - + 2001-12-19 Werner Koch - * keyformat.txt: New. + * keyformat.txt: New. 2001-12-19 Marcus Brinkmann diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index 02c2bc841..690459330 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -37,7 +37,7 @@ /* Helper to pass data via the callback to do_unprotect. */ -struct try_do_unprotect_arg_s +struct try_do_unprotect_arg_s { int is_v4; int is_protected; @@ -87,10 +87,12 @@ get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip) "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]); break; - case GCRY_PK_ECDSA: - case GCRY_PK_ECDH: + case GCRY_PK_ECDSA: + case GCRY_PK_ECDH: err = gcry_sexp_build (&s_pkey, NULL, - "(public-key(ecc(c%m)(q%m)))", pkey[0], pkey[1]); + "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))", + pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], + pkey[5]); break; default: @@ -108,8 +110,7 @@ get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip) /* Convert a secret key given as algorithm id and an array of key parameters into our s-expression based format. Note that - PUBKEY_ALGO is a standard id and not an OpenPGP id. - */ + PUBKEY_ALGO has an gcrypt algorithm number. */ static gpg_error_t convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey) { @@ -118,9 +119,6 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey) *r_key = NULL; - /* FIXME: This is not consistent with the above comment. */ - pubkey_algo = map_pk_openpgp_to_gcry (pubkey_algo); - switch (pubkey_algo) { case GCRY_PK_DSA: @@ -147,15 +145,15 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey) break; case GCRY_PK_ECDSA: - err = gcry_sexp_build (&s_skey, NULL, - "(private-key(ecdsa(c%m)(q%m)(d%m)))", - skey[0], skey[1], skey[2]); - break; - case GCRY_PK_ECDH: + /* Although our code would work with "ecc" we explicitly use + "ecdh" or "ecdsa" to implicitly set the key capabilities. */ err = gcry_sexp_build (&s_skey, NULL, - "(private-key(ecdh(c%m)(q%m)(p%m)(d%m)))", - skey[0], skey[1], skey[2], skey[3]); + "(private-key(%s(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)" + "(d%m)))", + pubkey_algo == GCRY_PK_ECDSA?"ecdsa":"ecdh", + skey[0], skey[1], skey[2], skey[3], skey[4], + skey[5], skey[6]); break; default: @@ -184,7 +182,7 @@ hash_passphrase_and_set_key (const char *passphrase, keylen = gcry_cipher_get_algo_keylen (protect_algo); if (!keylen) return gpg_error (GPG_ERR_INTERNAL); - + key = xtrymalloc_secure (keylen); if (!key) return gpg_error_from_syserror (); @@ -204,7 +202,7 @@ static u16 checksum (const unsigned char *p, unsigned int n) { u16 a; - + for (a=0; n; n-- ) a += *p++; return a; @@ -272,7 +270,7 @@ do_unprotect (const char *passphrase, return gpg_error (GPG_ERR_MISSING_VALUE); if (nskey+1 >= skeysize) return gpg_error (GPG_ERR_BUFFER_TOO_SHORT); - + /* Check whether SKEY is at all protected. If it is not protected merely verify the checksum. */ if (!is_protected) @@ -284,7 +282,7 @@ do_unprotect (const char *passphrase, { if (!skey[i] || gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE)) return gpg_error (GPG_ERR_BAD_SECKEY); - + err = gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, skey[i]); if (!err) { @@ -301,7 +299,7 @@ do_unprotect (const char *passphrase, if (err) return err; } - + if (actual_csum != desired_csum) return gpg_error (GPG_ERR_CHECKSUM); return 0; @@ -324,7 +322,7 @@ do_unprotect (const char *passphrase, s2k_algo, gcry_md_algo_name (s2k_algo)); return gpg_error (GPG_ERR_DIGEST_ALGO); } - + err = gcry_cipher_open (&cipher_hd, protect_algo, GCRY_CIPHER_MODE_CFB, (GCRY_CIPHER_SECURE @@ -343,10 +341,10 @@ do_unprotect (const char *passphrase, { gcry_cipher_close (cipher_hd); return err; - } + } gcry_cipher_setiv (cipher_hd, protect_iv, protect_ivlen); - + actual_csum = 0; if (pkt_version >= 4) { @@ -379,15 +377,15 @@ do_unprotect (const char *passphrase, { /* This is the new SHA1 checksum method to detect tampering with the key as used by the Klima/Rosa attack. */ - desired_csum = 0; + desired_csum = 0; actual_csum = 1; /* Default to bad checksum. */ - if (ndata < 20) + if (ndata < 20) log_error ("not enough bytes for SHA-1 checksum\n"); - else + else { gcry_md_hd_t h; - + if (gcry_md_open (&h, GCRY_MD_SHA1, 1)) BUG(); /* Algo not available. */ gcry_md_write (h, data, ndata - 20); @@ -397,13 +395,13 @@ do_unprotect (const char *passphrase, gcry_md_close (h); } } - else + else { /* Old 16 bit checksum method. */ if (ndata < 2) { log_error ("not enough bytes for checksum\n"); - desired_csum = 0; + desired_csum = 0; actual_csum = 1; /* Mark checksum bad. */ } else @@ -417,7 +415,7 @@ do_unprotect (const char *passphrase, } } } - + /* Better check it here. Otherwise the gcry_mpi_scan would fail because the length may have an arbitrary value. */ if (desired_csum == actual_csum) @@ -468,7 +466,7 @@ do_unprotect (const char *passphrase, gcry_cipher_close (cipher_hd); return gpg_error (GPG_ERR_BAD_SECKEY); } - + buffer = xtrymalloc_secure (ndata); if (!buffer) { @@ -476,7 +474,7 @@ do_unprotect (const char *passphrase, gcry_cipher_close (cipher_hd); return err; } - + gcry_cipher_sync (cipher_hd); buffer[0] = p[0]; buffer[1] = p[1]; @@ -557,7 +555,7 @@ try_do_unprotect_cb (struct pin_entry_info_s *pi) pointed to by GRIP. On error NULL is stored at all return arguments. */ gpg_error_t -convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp, +convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp, unsigned char *grip, const char *prompt, const char *cache_nonce, unsigned char **r_key, char **r_passphrase) @@ -625,7 +623,7 @@ convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp, if (!protect_algo && !!strcmp (string, "IDEA")) protect_algo = GCRY_CIPHER_IDEA; xfree (string); - + value = gcry_sexp_nth_data (list, 3, &valuelen); if (!value || !valuelen || valuelen > sizeof iv) goto bad_seckey; @@ -848,7 +846,7 @@ convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp, bad_seckey: err = gpg_error (GPG_ERR_BAD_SECKEY); goto leave; - + outofmem: err = gpg_error (GPG_ERR_ENOMEM); goto leave; @@ -874,13 +872,13 @@ key_from_sexp (gcry_sexp_t sexp, const char *elems, gcry_mpi_t *array) } array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); gcry_sexp_release (l2); - if (!array[idx]) + if (!array[idx]) { err = gpg_error (GPG_ERR_INV_OBJ); /* Required parameter invalid. */ goto leave; } } - + leave: if (err) { @@ -1028,7 +1026,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, gcry_sexp_release (list); return gpg_error (GPG_ERR_INV_OBJ); /* Invalid structure of object. */ } - + algo = gcry_pk_map_name (name); xfree (name); @@ -1038,8 +1036,8 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, case GCRY_PK_ELG: algoname = "elg"; npkey = 3; elems = "pgyx"; break; case GCRY_PK_ELG_E: algoname = "elg"; npkey = 3; elems = "pgyx"; break; case GCRY_PK_DSA: algoname = "dsa"; npkey = 4; elems = "pqgyx"; break; - case GCRY_PK_ECDSA: algoname = "ecdsa"; npkey = 2; elems = "cqd"; break; - case GCRY_PK_ECDH: algoname = "ecdh"; npkey = 3; elems = "cqpd"; break; + case GCRY_PK_ECDSA: algoname = "ecdsa"; npkey = 6; elems = "pabgnqd"; break; + case GCRY_PK_ECDH: algoname = "ecdh"; npkey = 6; elems = "pabgnqd"; break; default: algoname = ""; npkey = 0; elems = NULL; break; } assert (!elems || strlen (elems) < DIM (array) ); @@ -1070,9 +1068,9 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, void *format_args[10+2]; size_t n; gcry_sexp_t tmpkey, tmpsexp = NULL; - + snprintf (countbuf, sizeof countbuf, "%lu", s2k_count); - + init_membuf (&mbuf, 50); put_membuf_str (&mbuf, "(skey"); for (i=j=0; i < npkey; i++) @@ -1105,7 +1103,7 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase, " %S\n" " (protection sha1 aes %b 1:3 sha1 %b %s))\n", algoname, - tmpkey, + tmpkey, (int)sizeof protect_iv, protect_iv, (int)sizeof salt, salt, countbuf); -- cgit v1.2.3 From 0b5bcb40cf17a0e1032c113af6024c08b47d7a5c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 3 Feb 2011 16:31:42 +0100 Subject: Finished ECC integration. Wrote the ChangeLog 2011-01-13 entry for Andrey's orginal work modulo the cleanups I did in the last week. Adjusted my own ChangeLog entries to be consistent with that entry. Nuked quite some trailing spaces; again sorry for that, I will better take care of not saving them in the future. "git diff -b" is useful to read the actual changes ;-). The ECC-INTEGRATION-2-1 branch can be closed now. --- agent/ChangeLog | 16 ++++++ agent/protect.c | 165 ++++++++++++++++++++++++++++---------------------------- 2 files changed, 98 insertions(+), 83 deletions(-) (limited to 'agent') diff --git a/agent/ChangeLog b/agent/ChangeLog index d4a0de3a8..c022852e8 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,19 @@ +2011-02-03 Werner Koch + + * protect.c (protect_info): Support ECC algos. + + * pksign.c (do_encode_dsa): Map public key algo number. Extend + DSA size check for ECDSA. + + * gpg-agent.c: Include cipher.h. + (map_pk_openpgp_to_gcry): New. + + * findkey.c (key_parms_from_sexp): Support ECDH. + + * cvt-openpgp.c (get_keygrip): Support ECC algorithms. + (convert_secret_key): Ditto. + (do_unprotect): Ditto. + 2011-02-02 Werner Koch * cvt-openpgp.c (convert_secret_key): Remove algo mapping. diff --git a/agent/protect.c b/agent/protect.c index 61ed8ee38..94de89311 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -1,6 +1,6 @@ /* protect.c - Un/Protect a secret key * Copyright (C) 1998, 1999, 2000, 2001, 2002, - * 2003, 2007, 2009 Free Software Foundation, Inc. + * 2003, 2007, 2009, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -85,14 +85,14 @@ calibrate_get_time (struct calibrate_time_s *data) #ifdef HAVE_W32_SYSTEM # ifdef HAVE_W32CE_SYSTEM GetThreadTimes (GetCurrentThread (), -# else +# else GetProcessTimes (GetCurrentProcess (), # endif &data->creation_time, &data->exit_time, &data->kernel_time, &data->user_time); #else struct tms tmp; - + times (&tmp); data->ticks = tmp.tms_utime; #endif @@ -103,12 +103,12 @@ static unsigned long calibrate_elapsed_time (struct calibrate_time_s *starttime) { struct calibrate_time_s stoptime; - + calibrate_get_time (&stoptime); #ifdef HAVE_W32_SYSTEM { unsigned long long t1, t2; - + t1 = (((unsigned long long)starttime->kernel_time.dwHighDateTime << 32) + starttime->kernel_time.dwLowDateTime); t1 += (((unsigned long long)starttime->user_time.dwHighDateTime << 32) @@ -145,7 +145,7 @@ calibrate_s2k_count_one (unsigned long count) /* Measure the time we need to do the hash operations and deduce an - S2K count which requires about 100ms of time. */ + S2K count which requires about 100ms of time. */ static unsigned long calibrate_s2k_count (void) { @@ -197,7 +197,7 @@ get_standard_s2k_count (void) /* Calculate the MIC for a private key or shared secret S-expression. SHA1HASH should point to a 20 byte buffer. This function is suitable for all algorithms. */ -static int +static int calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash) { const unsigned char *hash_begin, *hash_end; @@ -211,13 +211,13 @@ calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash) s++; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); if (smatch (&s, n, "private-key")) is_shared_secret = 0; else if (smatch (&s, n, "shared-secret")) is_shared_secret = 1; else - return gpg_error (GPG_ERR_UNKNOWN_SEXP); + return gpg_error (GPG_ERR_UNKNOWN_SEXP); if (*s != '(') return gpg_error (GPG_ERR_UNKNOWN_SEXP); hash_begin = s; @@ -226,7 +226,7 @@ calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash) s++; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); s += n; /* Skip the algorithm name. */ } @@ -235,18 +235,18 @@ calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash) s++; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); s += n; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); s += n; if ( *s != ')' ) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); s++; } if (*s != ')') - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); s++; hash_end = s; @@ -269,7 +269,7 @@ calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash) (d #046129F..[some bytes not shown]..81#) (p #00e861b..[some bytes not shown]..f1#) (q #00f7a7c..[some bytes not shown]..61#) - (u #304559a..[some bytes not shown]..9b#) + (u #304559a..[some bytes not shown]..9b#) the returned block is the S-Expression: @@ -277,7 +277,7 @@ calculate_mic (const unsigned char *plainkey, unsigned char *sha1hash) */ static int -do_encryption (const unsigned char *protbegin, size_t protlen, +do_encryption (const unsigned char *protbegin, size_t protlen, const char *passphrase, const unsigned char *sha1hash, unsigned char **result, size_t *resultlen) { @@ -330,14 +330,14 @@ do_encryption (const unsigned char *protbegin, size_t protlen, { unsigned char *key; size_t keylen = PROT_CIPHER_KEYLEN; - + key = gcry_malloc_secure (keylen); if (!key) rc = out_of_core (); else { rc = hash_passphrase (passphrase, GCRY_MD_SHA1, - 3, iv+2*blklen, + 3, iv+2*blklen, get_standard_s2k_count (), key, keylen); if (!rc) rc = gcry_cipher_setkey (hd, key, keylen); @@ -357,7 +357,7 @@ do_encryption (const unsigned char *protbegin, size_t protlen, p += 20; *p++ = ')'; *p++ = ')'; - memcpy (p, iv+blklen, blklen); + memcpy (p, iv+blklen, blklen); p += blklen; assert ( p - outbuf == outlen); rc = gcry_cipher_encrypt (hd, outbuf, enclen, NULL, 0); @@ -375,7 +375,7 @@ do_encryption (const unsigned char *protbegin, size_t protlen, (protected openpgp-s2k3-sha1-aes-cbc ((sha1 salt no_of_iterations) 16byte_iv) encrypted_octet_string) - + in canoncical format of course. We use asprintf and %n modifier and dummy values as placeholders. */ { @@ -385,7 +385,7 @@ do_encryption (const unsigned char *protbegin, size_t protlen, p = xtryasprintf ("(9:protected%d:%s((4:sha18:%n_8bytes_%u:%s)%d:%n%*s)%d:%n%*s)", (int)strlen (modestr), modestr, - &saltpos, + &saltpos, (unsigned int)strlen (countbuf), countbuf, blklen, &ivpos, blklen, "", enclen, &encpos, enclen, ""); @@ -411,7 +411,7 @@ do_encryption (const unsigned char *protbegin, size_t protlen, /* Protect the key encoded in canonical format in PLAINKEY. We assume a valid S-Exp here. */ -int +int agent_protect (const unsigned char *plainkey, const char *passphrase, unsigned char **result, size_t *resultlen) { @@ -442,9 +442,9 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, s++; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); if (!smatch (&s, n, "private-key")) - return gpg_error (GPG_ERR_UNKNOWN_SEXP); + return gpg_error (GPG_ERR_UNKNOWN_SEXP); if (*s != '(') return gpg_error (GPG_ERR_UNKNOWN_SEXP); depth++; @@ -452,13 +452,13 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, s++; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); for (infidx=0; protect_info[infidx].algo && !smatch (&s, n, protect_info[infidx].algo); infidx++) ; if (!protect_info[infidx].algo) - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); prot_begin = prot_end = NULL; for (i=0; (c=protect_info[infidx].parmlist[i]); i++) @@ -471,23 +471,23 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, s++; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); if (n != 1 || c != *s) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); s += n; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); s +=n; /* skip value */ if (*s != ')') - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); depth--; if (i == protect_info[infidx].prot_to) prot_end = s; s++; } if (*s != ')' || !prot_begin || !prot_end ) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); depth--; hash_end = s; s++; @@ -499,10 +499,10 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, assert (!depth); real_end = s-1; - + /* Hash the stuff. Because the timestamp_exp won't get protected, we can't simply hash a continuous buffer but need to use several - md_writes. */ + md_writes. */ rc = gcry_md_open (&md, GCRY_MD_SHA1, 0 ); if (rc) return rc; @@ -555,8 +555,8 @@ agent_protect (const unsigned char *plainkey, const char *passphrase, /* Do the actual decryption and check the return list for consistency. */ static int -do_decryption (const unsigned char *protected, size_t protectedlen, - const char *passphrase, +do_decryption (const unsigned char *protected, size_t protectedlen, + const char *passphrase, const unsigned char *s2ksalt, unsigned long s2kcount, const unsigned char *iv, size_t ivlen, unsigned char **result) @@ -585,7 +585,7 @@ do_decryption (const unsigned char *protected, size_t protectedlen, { unsigned char *key; size_t keylen = PROT_CIPHER_KEYLEN; - + key = gcry_malloc_secure (keylen); if (!key) rc = out_of_core (); @@ -633,7 +633,7 @@ do_decryption (const unsigned char *protected, size_t protectedlen, calculation but then be removed. */ static int merge_lists (const unsigned char *protectedkey, - size_t replacepos, + size_t replacepos, const unsigned char *cleartext, unsigned char *sha1hash, unsigned char **result, size_t *resultlen, @@ -644,7 +644,7 @@ merge_lists (const unsigned char *protectedkey, const unsigned char *s; const unsigned char *startpos, *endpos; int i, rc; - + *result = NULL; *resultlen = 0; *cutoff = 0; @@ -707,7 +707,7 @@ merge_lists (const unsigned char *protectedkey, goto invalid_sexp; n = snext (&s); if (!smatch (&s, n, "sha1")) - goto invalid_sexp; + goto invalid_sexp; n = snext (&s); if (n != 20) goto invalid_sexp; @@ -720,7 +720,7 @@ merge_lists (const unsigned char *protectedkey, /* append the parameter list */ memcpy (p, startpos, endpos - startpos); p += endpos - startpos; - + /* Skip over the protected list element in the original list. */ s = protectedkey + replacepos; assert (*s == '('); @@ -758,7 +758,7 @@ merge_lists (const unsigned char *protectedkey, *cutoff = p - newlist; memcpy (p, startpos, endpos - startpos); p += endpos - startpos; - + /* ready */ *result = newlist; @@ -781,14 +781,14 @@ merge_lists (const unsigned char *protectedkey, /* Unprotect the key encoded in canonical format. We assume a valid S-Exp here. If a protected-at item is available, its value will be stored at protocted_at unless this is NULL. */ -int +int agent_unprotect (const unsigned char *protectedkey, const char *passphrase, - gnupg_isotime_t protected_at, + gnupg_isotime_t protected_at, unsigned char **result, size_t *resultlen) { int rc; const unsigned char *s; - const unsigned char *protect_list; + const unsigned char *protect_list; size_t n; int infidx, i; unsigned char sha1hash[20], sha1hash2[20]; @@ -810,21 +810,21 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, s++; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); if (!smatch (&s, n, "protected-private-key")) - return gpg_error (GPG_ERR_UNKNOWN_SEXP); + return gpg_error (GPG_ERR_UNKNOWN_SEXP); if (*s != '(') return gpg_error (GPG_ERR_UNKNOWN_SEXP); s++; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); for (infidx=0; protect_info[infidx].algo && !smatch (&s, n, protect_info[infidx].algo); infidx++) ; if (!protect_info[infidx].algo) - return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); /* See wether we have a protected-at timestamp. */ @@ -859,7 +859,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, /* Now find the list with the protected information. Here is an example for such a list: - (protected openpgp-s2k3-sha1-aes-cbc + (protected openpgp-s2k3-sha1-aes-cbc ((sha1 ) ) ) */ @@ -872,7 +872,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, s++; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); if (smatch (&s, n, "protected")) break; s += n; @@ -884,7 +884,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, /* found */ n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); if (!smatch (&s, n, "openpgp-s2k3-sha1-" PROT_CIPHER_STRING "-cbc")) return gpg_error (GPG_ERR_UNSUPPORTED_PROTECTION); if (*s != '(' || s[1] != '(') @@ -892,7 +892,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, s += 2; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); if (!smatch (&s, n, "sha1")) return gpg_error (GPG_ERR_UNSUPPORTED_PROTECTION); n = snext (&s); @@ -908,7 +908,7 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, is nothing we should worry about */ if (s[n] != ')' ) return gpg_error (GPG_ERR_INV_SEXP); - + /* Old versions of gpg-agent used the funny floating point number in a byte encoding as specified by OpenPGP. However this is not needed and thus we now store it as a plain unsigned integer. We @@ -938,8 +938,8 @@ agent_unprotect (const unsigned char *protectedkey, const char *passphrase, s++; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); - + return gpg_error (GPG_ERR_INV_SEXP); + cleartext = NULL; /* Avoid cc warning. */ rc = do_decryption (s, n, passphrase, s2ksalt, s2kcount, @@ -1014,7 +1014,7 @@ agent_private_key_type (const unsigned char *privatekey) store this key in the caller provided buffer KEY. The caller must provide an HASHALGO, a valid S2KMODE (see rfc-2440) and depending on that mode an S2KSALT of 8 random bytes and an S2KCOUNT. - + Returns an error code on failure. */ static int hash_passphrase (const char *passphrase, int hashalgo, @@ -1034,7 +1034,7 @@ hash_passphrase (const char *passphrase, int hashalgo, return gpg_error (GPG_ERR_INV_VALUE); if ((s2kmode == 1 ||s2kmode == 3) && !s2ksalt) return gpg_error (GPG_ERR_INV_VALUE); - + rc = gcry_md_open (&md, hashalgo, GCRY_MD_FLAG_SECURE); if (rc) return rc; @@ -1068,7 +1068,7 @@ hash_passphrase (const char *passphrase, int hashalgo, } if (count < 8) gcry_md_write (md, s2ksalt, count); - else + else { gcry_md_write (md, s2ksalt, 8); count -= 8; @@ -1077,7 +1077,7 @@ hash_passphrase (const char *passphrase, int hashalgo, } else gcry_md_write (md, passphrase, pwlen); - + gcry_md_final (md); i = gcry_md_get_algo_dlen (hashalgo); if (i > keylen - used) @@ -1097,7 +1097,7 @@ s2k_hash_passphrase (const char *passphrase, int hashalgo, unsigned int s2kcount, unsigned char *key, size_t keylen) { - return hash_passphrase (passphrase, hashalgo, s2kmode, s2ksalt, + return hash_passphrase (passphrase, hashalgo, s2kmode, s2ksalt, (16ul + (s2kcount & 15)) << ((s2kcount >> 4) + 6), key, keylen); } @@ -1140,7 +1140,7 @@ make_shadow_info (const char *serialno, const char *idstring) S-expression is returned in an allocated buffer RESULT will point to. The input parameters are expected to be valid canonicalized S-expressions */ -int +int agent_shadow_key (const unsigned char *pubkey, const unsigned char *shadow_info, unsigned char **result) @@ -1162,16 +1162,16 @@ agent_shadow_key (const unsigned char *pubkey, s++; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); if (!smatch (&s, n, "public-key")) - return gpg_error (GPG_ERR_UNKNOWN_SEXP); + return gpg_error (GPG_ERR_UNKNOWN_SEXP); if (*s != '(') return gpg_error (GPG_ERR_UNKNOWN_SEXP); depth++; s++; - n = snext (&s); + n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); s += n; /* skip over the algorithm name */ while (*s != ')') @@ -1181,15 +1181,15 @@ agent_shadow_key (const unsigned char *pubkey, depth++; s++; n = snext (&s); - if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); s += n; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); s +=n; /* skip value */ if (*s != ')') - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); depth--; s++; } @@ -1221,7 +1221,7 @@ agent_shadow_key (const unsigned char *pubkey, /* Parse a canonical encoded shadowed key and return a pointer to the inner list with the shadow_info */ -int +int agent_get_shadow_info (const unsigned char *shadowkey, unsigned char const **shadow_info) { @@ -1236,16 +1236,16 @@ agent_get_shadow_info (const unsigned char *shadowkey, s++; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); if (!smatch (&s, n, "shadowed-private-key")) - return gpg_error (GPG_ERR_UNKNOWN_SEXP); + return gpg_error (GPG_ERR_UNKNOWN_SEXP); if (*s != '(') return gpg_error (GPG_ERR_UNKNOWN_SEXP); depth++; s++; - n = snext (&s); + n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); s += n; /* skip over the algorithm name */ for (;;) @@ -1257,24 +1257,24 @@ agent_get_shadow_info (const unsigned char *shadowkey, depth++; s++; n = snext (&s); - if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); if (smatch (&s, n, "shadowed")) break; s += n; n = snext (&s); if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); s +=n; /* skip value */ if (*s != ')') - return gpg_error (GPG_ERR_INV_SEXP); + return gpg_error (GPG_ERR_INV_SEXP); depth--; s++; } /* Found the shadowed list, S points to the protocol */ n = snext (&s); - if (!n) - return gpg_error (GPG_ERR_INV_SEXP); + if (!n) + return gpg_error (GPG_ERR_INV_SEXP); if (smatch (&s, n, "t1-v1")) { if (*s != '(') @@ -1294,7 +1294,7 @@ agent_get_shadow_info (const unsigned char *shadowkey, parameters addresses. If the serial number or the ID string is not required, NULL may be passed for them. */ gpg_error_t -parse_shadow_info (const unsigned char *shadow_info, +parse_shadow_info (const unsigned char *shadow_info, char **r_hexsn, char **r_idstr) { const unsigned char *s; @@ -1331,7 +1331,7 @@ parse_shadow_info (const unsigned char *shadow_info, } return gpg_error (GPG_ERR_INV_SEXP); } - + if (r_idstr) { *r_idstr = xtrymalloc (n+1); @@ -1350,4 +1350,3 @@ parse_shadow_info (const unsigned char *shadow_info, return 0; } - -- cgit v1.2.3