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. --- g10/keygen.c | 281 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 252 insertions(+), 29 deletions(-) (limited to 'g10/keygen.c') diff --git a/g10/keygen.c b/g10/keygen.c index ec7e7e79c..f7f152659 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -42,6 +42,8 @@ #include "i18n.h" #include "keyserver-internal.h" #include "call-agent.h" +#include "pkglue.h" +#include "gcrypt.h" /* The default algorithms. If you change them remember to change them also in gpg.c:gpgconf_list. You should also check that the value @@ -49,10 +51,6 @@ #define DEFAULT_STD_ALGO GCRY_PK_RSA #define DEFAULT_STD_KEYSIZE 2048 -#define KEYGEN_FLAG_NO_PROTECTION 1 -#define KEYGEN_FLAG_TRANSIENT_KEY 2 - - #define MAX_PREFS 30 enum para_name { @@ -1130,17 +1128,15 @@ key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, } - -/* Common code for the key generation fucntion gen_xxx. */ static int -common_gen (const char *keyparms, int algo, const char *algoelem, - kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey, - int keygen_flags, char **cache_nonce_addr) +common_key_gen (const char *keyparms, int algo, const char *algoelem, + int keygen_flags, char **cache_nonce_addr, PKT_public_key **pk_out) { int err; - PACKET *pkt; PKT_public_key *pk; gcry_sexp_t s_key; + + *pk_out = NULL; err = agent_genkey (NULL, cache_nonce_addr, keyparms, !!(keygen_flags & KEYGEN_FLAG_NO_PROTECTION), &s_key); @@ -1158,10 +1154,7 @@ common_gen (const char *keyparms, int algo, const char *algoelem, return err; } - pk->timestamp = timestamp; pk->version = 4; - if (expireval) - pk->expiredate = pk->timestamp + expireval; pk->pubkey_algo = algo; err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem); @@ -1174,21 +1167,45 @@ common_gen (const char *keyparms, int algo, const char *algoelem, } gcry_sexp_release (s_key); - pkt = xtrycalloc (1, sizeof *pkt); - if (!pkt) - { - err = gpg_error_from_syserror (); - free_public_key (pk); - return err; - } - - pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY; - pkt->pkt.public_key = pk; - add_kbnode (pub_root, new_kbnode (pkt)); + *pk_out = pk; return 0; } +/* Common code for the key generation fucntion gen_xxx. */ +static int +common_gen (const char *keyparms, int algo, const char *algoelem, + kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey, + int keygen_flags, char **cache_nonce_addr) +{ + PKT_public_key *pk; + int err; + + err = common_key_gen( keyparms, algo, algoelem, keygen_flags, cache_nonce_addr, &pk ); + + if( !err ) { + PACKET *pkt; + + pk->timestamp = timestamp; + if (expireval) + pk->expiredate = pk->timestamp + expireval; + + pkt = xtrycalloc (1, sizeof *pkt); + if (!pkt) + { + err = gpg_error_from_syserror (); + free_public_key (pk); + return err; + } + + pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY; + pkt->pkt.public_key = pk; + + add_kbnode (pub_root, new_kbnode (pkt)); + } + + return err; +} /* * Generate an Elgamal key. @@ -1326,6 +1343,186 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, return err; } +/* Returns allocated ECC key generation S-explression + call gcry_sexp_release ( out ) to free it. + */ +static int +delme__pk_ecc_build_sexp( int qbits, int algo, int is_long_term, gcry_sexp_t *out ) { + gcry_mpi_t kek_params; + char *kek_params_s; + int rc; + + if( is_long_term && algo == PUBKEY_ALGO_ECDH ) + kek_params = pk_ecdh_default_params_to_mpi( qbits ); + else + kek_params = NULL; + + if( kek_params ) { + kek_params_s = mpi2hex( kek_params ); + mpi_release( kek_params ); + } + + rc = gcry_sexp_build (out, NULL, + algo == PUBKEY_ALGO_ECDSA ? + "(genkey(ecdsa(nbits %d)(qbits %d)))" : + "(genkey(ecdh(nbits %d)(qbits %d)(transient-key %d)(kek-params %s)))", + (int)qbits, (int)qbits, (int)(is_long_term==0), kek_params_s); + xfree( kek_params_s ); + if (rc) { + log_debug("ec gen gcry_sexp_build failed: %s\n", gpg_strerror (rc)); + return rc; + } + return 0; +} + +static char * +pk_ecc_build_key_params( int qbits, int algo, int transient ) { + byte *kek_params = NULL; + size_t kek_params_size; + char nbitsstr[35]; + char qbitsstr[35]; + char *keyparms; + int n; + + /* KEK parameters are only needed for long term key generation */ + if( !transient && algo == PUBKEY_ALGO_ECDH ) + kek_params = pk_ecdh_default_params( qbits, &kek_params_size ); + else + kek_params = NULL; + + snprintf (nbitsstr, sizeof nbitsstr, "%u", qbits); + snprintf (qbitsstr, sizeof qbitsstr, "%u", qbits); + if( algo == PUBKEY_ALGO_ECDSA || kek_params == NULL ) + keyparms = xtryasprintf ( + "(genkey(%s(nbits %zu:%s)(qbits %zu:%s)(transient-key 1:%d)))", + algo == PUBKEY_ALGO_ECDSA ? "ecdsa" : "ecdh", + strlen (nbitsstr), nbitsstr, + strlen (qbitsstr), qbitsstr, + transient ); + else { + assert( kek_params != NULL ); + keyparms = xtryasprintf ( + "(genkey(ecdh(nbits %zu:%s)(qbits %zu:%s)(transient-key 1:%d)(kek-params %u:", + strlen (nbitsstr), nbitsstr, + strlen (qbitsstr), qbitsstr, + transient, + (unsigned)kek_params_size ); + if( keyparms != NULL ) { + n = strlen(keyparms); + keyparms = xtryrealloc( keyparms, n + kek_params_size + 4 ); + } + if( keyparms == NULL ) { + xfree( kek_params ); + return NULL; + } + memcpy( keyparms+n, kek_params, kek_params_size ); + xfree( kek_params ); + memcpy( keyparms+n+kek_params_size, ")))", 4 ); + } + return keyparms; +} + +/* This common function is used in this file and also to generate ephemeral keys for ECDH. + * Caller must call free_public_key and free_secret_key */ +int +pk_ecc_keypair_gen( PKT_public_key **pk_out, int algo, int keygen_flags, char **cache_nonce_addr, unsigned nbits) { + int err; + unsigned int qbits; + char *keyparms; + // PUBKEY_ALGO_ECDH, PUBKEY_ALGO_ECDSA + static const char * const ec_pub_params[2] = { "cqp", "cq" }; + //static const char * const ec_priv_params[2] = { "cqpd", "cqd" }; + + assert( algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH ); + assert( PUBKEY_ALGO_ECDSA == PUBKEY_ALGO_ECDH + 1 ); + + *pk_out = NULL; + + if( pubkey_get_npkey (PUBKEY_ALGO_ECDSA) != 2 || pubkey_get_nskey (PUBKEY_ALGO_ECDSA) != 3 || + pubkey_get_npkey (PUBKEY_ALGO_ECDH) != 3 || pubkey_get_nskey (PUBKEY_ALGO_ECDH) != 4 ) + { + log_info(_("incompatible version of gcrypt library (expect named curve logic for ECC)\n") ); + return GPG_ERR_EPROGMISMATCH; + } + + if ( nbits != 256 && nbits != 384 && nbits != 521 ) + { + log_info(_("keysize invalid; using 256 bits instead of passed in %d\n"), nbits ); + } + + /* + Figure out a q size based on the key size. See gen_dsa for more details. + Due to 8-bit rounding we may get 528 here instead of 521 + */ + nbits = qbits = (nbits < 521 ? nbits : 521 ); + + keyparms = pk_ecc_build_key_params(qbits, algo, !!((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION)) ); + if (!keyparms) { + err = gpg_error_from_syserror (); + log_error ("ec pk_ecc_build_key_params failed: %s\n", gpg_strerror (err) ); + } + else + { + err = common_key_gen (keyparms, algo, ec_pub_params[algo-PUBKEY_ALGO_ECDH], + keygen_flags, cache_nonce_addr, pk_out); + xfree (keyparms); + } + +#if 0 + /* always allocase seckey_info for EC keys. TODO: is this needed? */ + if( *pk_out ) { + struct seckey_info *ski; + + (*pk_out)->seckey_info = ski = xtrycalloc (1, sizeof *ski); + if (!(*pk_out)->seckey_info) { + free_public_key(*pk_out); + *pk_out = NULL; + return gpg_error_from_syserror (); + } + + ski->is_protected = 0; + ski->algo = 0; + } +#endif + + return err; +} + + +/**************** + * Generate an ECC OpenPGP key + */ +static gpg_error_t +gen_ecc (int algo, unsigned int nbits, KBNODE pub_root, + u32 timestamp, u32 expireval, int is_subkey, + int keygen_flags, char **cache_nonce_addr) +{ + int rc; + PACKET *pkt; + PKT_public_key *pk; + + rc = pk_ecc_keypair_gen( &pk, algo, keygen_flags, cache_nonce_addr, nbits ); + if( rc ) + return rc; + + /* the rest is very similar to common_gen */ + + pk->timestamp = timestamp; + if (expireval) + pk->expiredate = pk->timestamp + expireval; + + //assert( pk->seckey_info != NULL ); + /// TODO: the new agent-based model doesn't return private portion here (the pkey array is allocated, but private MPIs are NULL, so this will cause a crash... ) + ///pk->seckey_info->csum = checksum_mpi ( pk->pkey[algo==PUBKEY_ALGO_ECDSA ? 2 : 3] ); /* corresponds to 'd' in 'cqd' or 'cqpd' */ + + pkt = xmalloc_clear(sizeof *pkt); + pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY; + pkt->pkt.public_key = pk; + add_kbnode(pub_root, new_kbnode( pkt )); + + return 0; +} + /* * Generate an RSA key. @@ -1557,6 +1754,8 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage) tty_printf (_(" (%d) RSA (set your own capabilities)\n"), 8 ); } + tty_printf (_(" (%d) ECDSA and ECDH\n"), 9 ); + for(;;) { *r_usage = 0; @@ -1613,6 +1812,12 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage) *r_usage = ask_key_flags (algo, addmode); break; } + else if (algo == 9) + { + algo = PUBKEY_ALGO_ECDSA; + *r_subkey_algo = PUBKEY_ALGO_ECDH; + break; + } else tty_printf (_("Invalid selection.\n")); } @@ -1657,13 +1862,20 @@ ask_keysize (int algo, unsigned int primary_keysize) max=3072; break; + case PUBKEY_ALGO_ECDSA: + case PUBKEY_ALGO_ECDH: + min=256; + def=256; + max=521; + break; + case PUBKEY_ALGO_RSA: min=1024; break; } tty_printf(_("%s keys may be between %u and %u bits long.\n"), - gcry_pk_algo_name (algo), min, max); + openpgp_pk_algo_name (algo), min, max); for(;;) { @@ -1682,7 +1894,7 @@ ask_keysize (int algo, unsigned int primary_keysize) if(nbitsmax) tty_printf(_("%s keysizes must be in the range %u-%u\n"), - gcry_pk_algo_name (algo), min, max); + openpgp_pk_algo_name (algo), min, max); else break; } @@ -1692,10 +1904,18 @@ ask_keysize (int algo, unsigned int primary_keysize) leave: if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) { - nbits = ((nbits + 63) / 64) * 64; - if (!autocomp) - tty_printf(_("rounded up to %u bits\n"), nbits ); + if( !(algo == PUBKEY_ALGO_ECDSA && nbits==521) ) { + nbits = ((nbits + 63) / 64) * 64; + if (!autocomp) + tty_printf(_("rounded up to %u bits\n"), nbits ); + } } + else if( algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA ) { + if( nbits != 256 && nbits != 384 && nbits != 521 ) { + nbits = min; + tty_printf(_("unsupported ECDH value, corrected to the minimum %u bits\n"), nbits ); + } + } else if( (nbits % 32) ) { nbits = ((nbits + 31) / 32) * 32; @@ -2185,6 +2405,9 @@ do_create (int algo, unsigned int nbits, KBNODE pub_root, else if (algo == PUBKEY_ALGO_DSA) err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey, keygen_flags, cache_nonce_addr); + else if( algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH ) + err = gen_ecc (algo, nbits, pub_root, timestamp, expiredate, is_subkey, + keygen_flags, cache_nonce_addr); else if (algo == PUBKEY_ALGO_RSA) err = gen_rsa (algo, nbits, pub_root, timestamp, expiredate, is_subkey, keygen_flags, cache_nonce_addr); -- 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. --- g10/keygen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'g10/keygen.c') diff --git a/g10/keygen.c b/g10/keygen.c index f7f152659..e75da792e 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -18,6 +18,7 @@ * along with this program; if not, see . */ +#warning wk: check these changes. #include #include #include @@ -43,7 +44,6 @@ #include "keyserver-internal.h" #include "call-agent.h" #include "pkglue.h" -#include "gcrypt.h" /* The default algorithms. If you change them remember to change them also in gpg.c:gpgconf_list. You should also check that the value -- cgit v1.2.3 From 638dca5dbc7e119ff5a05dbdb109fbc171624605 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 25 Jan 2011 16:54:18 +0100 Subject: Editorial cleanups of keygen.c Also fixed a regression introduced by me in pubkey_enc.c. Added extra checks. Removed unused code. --- g10/keygen.c | 331 +++++++++++++++++++++++------------------------------------ 1 file changed, 129 insertions(+), 202 deletions(-) (limited to 'g10/keygen.c') diff --git a/g10/keygen.c b/g10/keygen.c index e75da792e..366bedf0e 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1,6 +1,6 @@ /* keygen.c - generate a key pair - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - * 2006, 2007, 2009, 2010 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + * 2007, 2009, 2010, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -18,7 +18,6 @@ * along with this program; if not, see . */ -#warning wk: check these changes. #include #include #include @@ -51,6 +50,11 @@ #define DEFAULT_STD_ALGO GCRY_PK_RSA #define DEFAULT_STD_KEYSIZE 2048 +/* Flag bits used during key generation. */ +#define KEYGEN_FLAG_NO_PROTECTION 1 +#define KEYGEN_FLAG_TRANSIENT_KEY 2 + +/* Maximum number of supported algorithm preferences. */ #define MAX_PREFS 30 enum para_name { @@ -1128,16 +1132,17 @@ key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, } +/* Common code for the key generation fucntion gen_xxx. */ static int -common_key_gen (const char *keyparms, int algo, const char *algoelem, - int keygen_flags, char **cache_nonce_addr, PKT_public_key **pk_out) +common_gen (const char *keyparms, int algo, const char *algoelem, + kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey, + int keygen_flags, char **cache_nonce_addr) { int err; + PACKET *pkt; PKT_public_key *pk; gcry_sexp_t s_key; - *pk_out = NULL; - err = agent_genkey (NULL, cache_nonce_addr, keyparms, !!(keygen_flags & KEYGEN_FLAG_NO_PROTECTION), &s_key); if (err) @@ -1154,7 +1159,10 @@ common_key_gen (const char *keyparms, int algo, const char *algoelem, return err; } + pk->timestamp = timestamp; pk->version = 4; + if (expireval) + pk->expiredate = pk->timestamp + expireval; pk->pubkey_algo = algo; err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem); @@ -1167,45 +1175,21 @@ common_key_gen (const char *keyparms, int algo, const char *algoelem, } gcry_sexp_release (s_key); - *pk_out = pk; + pkt = xtrycalloc (1, sizeof *pkt); + if (!pkt) + { + err = gpg_error_from_syserror (); + free_public_key (pk); + return err; + } + + pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY; + pkt->pkt.public_key = pk; + add_kbnode (pub_root, new_kbnode (pkt)); return 0; } -/* Common code for the key generation fucntion gen_xxx. */ -static int -common_gen (const char *keyparms, int algo, const char *algoelem, - kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey, - int keygen_flags, char **cache_nonce_addr) -{ - PKT_public_key *pk; - int err; - - err = common_key_gen( keyparms, algo, algoelem, keygen_flags, cache_nonce_addr, &pk ); - - if( !err ) { - PACKET *pkt; - - pk->timestamp = timestamp; - if (expireval) - pk->expiredate = pk->timestamp + expireval; - - pkt = xtrycalloc (1, sizeof *pkt); - if (!pkt) - { - err = gpg_error_from_syserror (); - free_public_key (pk); - return err; - } - - pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY; - pkt->pkt.public_key = pk; - - add_kbnode (pub_root, new_kbnode (pkt)); - } - - return err; -} /* * Generate an Elgamal key. @@ -1343,40 +1327,14 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, return err; } -/* Returns allocated ECC key generation S-explression - call gcry_sexp_release ( out ) to free it. - */ -static int -delme__pk_ecc_build_sexp( int qbits, int algo, int is_long_term, gcry_sexp_t *out ) { - gcry_mpi_t kek_params; - char *kek_params_s; - int rc; - if( is_long_term && algo == PUBKEY_ALGO_ECDH ) - kek_params = pk_ecdh_default_params_to_mpi( qbits ); - else - kek_params = NULL; - - if( kek_params ) { - kek_params_s = mpi2hex( kek_params ); - mpi_release( kek_params ); - } - - rc = gcry_sexp_build (out, NULL, - algo == PUBKEY_ALGO_ECDSA ? - "(genkey(ecdsa(nbits %d)(qbits %d)))" : - "(genkey(ecdh(nbits %d)(qbits %d)(transient-key %d)(kek-params %s)))", - (int)qbits, (int)qbits, (int)(is_long_term==0), kek_params_s); - xfree( kek_params_s ); - if (rc) { - log_debug("ec gen gcry_sexp_build failed: %s\n", gpg_strerror (rc)); - return rc; - } - return 0; -} -static char * -pk_ecc_build_key_params( int qbits, int algo, int transient ) { +/* Create an S-expression string out QBITS, ALGO and the TRANSIENT + flag. On success a malloced string is returned, on failure NULL + and ERRNO is set. */ +static char * +pk_ecc_build_key_params (int qbits, int algo, int transient) +{ byte *kek_params = NULL; size_t kek_params_size; char nbitsstr[35]; @@ -1384,142 +1342,105 @@ pk_ecc_build_key_params( int qbits, int algo, int transient ) { char *keyparms; int n; - /* KEK parameters are only needed for long term key generation */ - if( !transient && algo == PUBKEY_ALGO_ECDH ) - kek_params = pk_ecdh_default_params( qbits, &kek_params_size ); + /* KEK parameters are only needed for long term key generation. */ + if (!transient && algo == PUBKEY_ALGO_ECDH) + kek_params = pk_ecdh_default_params (qbits, &kek_params_size); else kek_params = NULL; snprintf (nbitsstr, sizeof nbitsstr, "%u", qbits); snprintf (qbitsstr, sizeof qbitsstr, "%u", qbits); - if( algo == PUBKEY_ALGO_ECDSA || kek_params == NULL ) - keyparms = xtryasprintf ( - "(genkey(%s(nbits %zu:%s)(qbits %zu:%s)(transient-key 1:%d)))", - algo == PUBKEY_ALGO_ECDSA ? "ecdsa" : "ecdh", - strlen (nbitsstr), nbitsstr, - strlen (qbitsstr), qbitsstr, - transient ); - else { - assert( kek_params != NULL ); - keyparms = xtryasprintf ( - "(genkey(ecdh(nbits %zu:%s)(qbits %zu:%s)(transient-key 1:%d)(kek-params %u:", - strlen (nbitsstr), nbitsstr, - strlen (qbitsstr), qbitsstr, - transient, - (unsigned)kek_params_size ); - if( keyparms != NULL ) { - n = strlen(keyparms); - keyparms = xtryrealloc( keyparms, n + kek_params_size + 4 ); + if (algo == PUBKEY_ALGO_ECDSA || !kek_params) + { + keyparms = xtryasprintf ("(genkey(%s(nbits %zu:%s)" + /**/ "(qbits %zu:%s)" + /**/ "(transient-key 1:%d)))", + algo == PUBKEY_ALGO_ECDSA ? "ecdsa" : "ecdh", + strlen (nbitsstr), nbitsstr, + strlen (qbitsstr), qbitsstr, + transient); } - if( keyparms == NULL ) { - xfree( kek_params ); - return NULL; + else + { + assert (kek_params); + + keyparms = xtryasprintf ("(genkey(ecdh(nbits %zu:%s)" + /**/ "(qbits %zu:%s)" + /**/ "(transient-key 1:%d)" + /**/ "(kek-params %zu:", + strlen (nbitsstr), nbitsstr, + strlen (qbitsstr), qbitsstr, + transient, + kek_params_size); + if (keyparms) + { + n = strlen (keyparms); + keyparms = xtryrealloc (keyparms, n + kek_params_size + 4); + } + if (!keyparms) + { + xfree (kek_params); + return NULL; + } + memcpy (keyparms+n, kek_params, kek_params_size); + xfree (kek_params); + memcpy (keyparms+n+kek_params_size, ")))", 4); } - memcpy( keyparms+n, kek_params, kek_params_size ); - xfree( kek_params ); - memcpy( keyparms+n+kek_params_size, ")))", 4 ); - } return keyparms; } -/* This common function is used in this file and also to generate ephemeral keys for ECDH. - * Caller must call free_public_key and free_secret_key */ -int -pk_ecc_keypair_gen( PKT_public_key **pk_out, int algo, int keygen_flags, char **cache_nonce_addr, unsigned nbits) { + +/* + * Generate an ECC key + */ +static gpg_error_t +gen_ecc (int algo, unsigned int nbits, KBNODE pub_root, + u32 timestamp, u32 expireval, int is_subkey, + int keygen_flags, char **cache_nonce_addr) +{ int err; unsigned int qbits; char *keyparms; - // PUBKEY_ALGO_ECDH, PUBKEY_ALGO_ECDSA - static const char * const ec_pub_params[2] = { "cqp", "cq" }; - //static const char * const ec_priv_params[2] = { "cqpd", "cqd" }; - assert( algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH ); - assert( PUBKEY_ALGO_ECDSA == PUBKEY_ALGO_ECDH + 1 ); + assert (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH); - *pk_out = NULL; - - if( pubkey_get_npkey (PUBKEY_ALGO_ECDSA) != 2 || pubkey_get_nskey (PUBKEY_ALGO_ECDSA) != 3 || - pubkey_get_npkey (PUBKEY_ALGO_ECDH) != 3 || pubkey_get_nskey (PUBKEY_ALGO_ECDH) != 4 ) - { - log_info(_("incompatible version of gcrypt library (expect named curve logic for ECC)\n") ); - return GPG_ERR_EPROGMISMATCH; - } + if (pubkey_get_npkey (PUBKEY_ALGO_ECDSA) != 2 + || pubkey_get_nskey (PUBKEY_ALGO_ECDSA) != 3 + || pubkey_get_npkey (PUBKEY_ALGO_ECDH) != 3 + || pubkey_get_nskey (PUBKEY_ALGO_ECDH) != 4) + { + log_error ("broken version of Libgcrypt\n"); + return gpg_error (GPG_ERR_INTERNAL); /* ABI silently changed. */ + } - if ( nbits != 256 && nbits != 384 && nbits != 521 ) + if (nbits != 256 && nbits != 384 && nbits != 521) { - log_info(_("keysize invalid; using 256 bits instead of passed in %d\n"), nbits ); + log_info (_("keysize invalid; using %u bits\n"), 256); + /* FIXME: Where do we set it to 256? */ } - /* - Figure out a q size based on the key size. See gen_dsa for more details. - Due to 8-bit rounding we may get 528 here instead of 521 - */ + /* Figure out a Q size based on the key size. See gen_dsa for more + details. Due to 8-bit rounding we may get 528 here instead of 521. */ nbits = qbits = (nbits < 521 ? nbits : 521 ); - keyparms = pk_ecc_build_key_params(qbits, algo, !!((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION)) ); - if (!keyparms) { - err = gpg_error_from_syserror (); - log_error ("ec pk_ecc_build_key_params failed: %s\n", gpg_strerror (err) ); - } + keyparms = pk_ecc_build_key_params + (qbits, algo, !!( (keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION)) ); + if (!keyparms) + { + err = gpg_error_from_syserror (); + log_error ("ecc pk_ecc_build_key_params failed: %s\n", + gpg_strerror (err)); + } else { - err = common_key_gen (keyparms, algo, ec_pub_params[algo-PUBKEY_ALGO_ECDH], - keygen_flags, cache_nonce_addr, pk_out); + err = common_gen (keyparms, algo, + algo == PUBKEY_ALGO_ECDSA? "cq" : "cqp", + pub_root, timestamp, expireval, is_subkey, + keygen_flags, cache_nonce_addr); xfree (keyparms); } -#if 0 - /* always allocase seckey_info for EC keys. TODO: is this needed? */ - if( *pk_out ) { - struct seckey_info *ski; - - (*pk_out)->seckey_info = ski = xtrycalloc (1, sizeof *ski); - if (!(*pk_out)->seckey_info) { - free_public_key(*pk_out); - *pk_out = NULL; - return gpg_error_from_syserror (); - } - - ski->is_protected = 0; - ski->algo = 0; - } -#endif - - return err; -} - - -/**************** - * Generate an ECC OpenPGP key - */ -static gpg_error_t -gen_ecc (int algo, unsigned int nbits, KBNODE pub_root, - u32 timestamp, u32 expireval, int is_subkey, - int keygen_flags, char **cache_nonce_addr) -{ - int rc; - PACKET *pkt; - PKT_public_key *pk; - - rc = pk_ecc_keypair_gen( &pk, algo, keygen_flags, cache_nonce_addr, nbits ); - if( rc ) - return rc; - - /* the rest is very similar to common_gen */ - - pk->timestamp = timestamp; - if (expireval) - pk->expiredate = pk->timestamp + expireval; - - //assert( pk->seckey_info != NULL ); - /// TODO: the new agent-based model doesn't return private portion here (the pkey array is allocated, but private MPIs are NULL, so this will cause a crash... ) - ///pk->seckey_info->csum = checksum_mpi ( pk->pkey[algo==PUBKEY_ALGO_ECDSA ? 2 : 3] ); /* corresponds to 'd' in 'cqd' or 'cqpd' */ - - pkt = xmalloc_clear(sizeof *pkt); - pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY; - pkt->pkt.public_key = pk; - add_kbnode(pub_root, new_kbnode( pkt )); - return 0; } @@ -1755,7 +1676,7 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage) } tty_printf (_(" (%d) ECDSA and ECDH\n"), 9 ); - + for(;;) { *r_usage = 0; @@ -1877,7 +1798,7 @@ ask_keysize (int algo, unsigned int primary_keysize) tty_printf(_("%s keys may be between %u and %u bits long.\n"), openpgp_pk_algo_name (algo), min, max); - for(;;) + for (;;) { char *prompt, *answer; @@ -1899,28 +1820,34 @@ ask_keysize (int algo, unsigned int primary_keysize) break; } - tty_printf(_("Requested keysize is %u bits\n"), nbits ); + tty_printf (_("Requested keysize is %u bits\n"), nbits); leave: - if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) + if (algo == PUBKEY_ALGO_DSA && (nbits % 64)) { - if( !(algo == PUBKEY_ALGO_ECDSA && nbits==521) ) { - nbits = ((nbits + 63) / 64) * 64; - if (!autocomp) - tty_printf(_("rounded up to %u bits\n"), nbits ); - } + nbits = ((nbits + 63) / 64) * 64; + if (!autocomp) + tty_printf (_("rounded up to %u bits\n"), nbits); } - else if( algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA ) { - if( nbits != 256 && nbits != 384 && nbits != 521 ) { - nbits = min; - tty_printf(_("unsupported ECDH value, corrected to the minimum %u bits\n"), nbits ); - } - } - else if( (nbits % 32) ) + else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA) + { + if (nbits != 256 && nbits != 384 && nbits != 521) + { + if (nbits < 256) + nbits = 256; + else if (nbits < 384) + nbits = 384; + else + nbits = 521; + if (!autocomp) + tty_printf (_("rounded to %u bits\n"), nbits); + } + } + else if ((nbits % 32)) { nbits = ((nbits + 31) / 32) * 32; if (!autocomp) - tty_printf(_("rounded up to %u bits\n"), nbits ); + tty_printf (_("rounded up to %u bits\n"), nbits ); } return nbits; @@ -2405,7 +2332,7 @@ do_create (int algo, unsigned int nbits, KBNODE pub_root, else if (algo == PUBKEY_ALGO_DSA) err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey, keygen_flags, cache_nonce_addr); - else if( algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH ) + else if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH) err = gen_ecc (algo, nbits, pub_root, timestamp, expiredate, is_subkey, keygen_flags, cache_nonce_addr); else if (algo == PUBKEY_ALGO_RSA) -- cgit v1.2.3 From 302c5a826c0fd0b2aab85ad3c287b65429db2066 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 25 Jan 2011 17:48:51 +0100 Subject: More ECDH code cleanups --- g10/keygen.c | 57 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 25 deletions(-) (limited to 'g10/keygen.c') diff --git a/g10/keygen.c b/g10/keygen.c index 366bedf0e..b42121b28 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1329,7 +1329,7 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, -/* Create an S-expression string out QBITS, ALGO and the TRANSIENT +/* Create an S-expression string out of QBITS, ALGO and the TRANSIENT flag. On success a malloced string is returned, on failure NULL and ERRNO is set. */ static char * @@ -1337,56 +1337,63 @@ pk_ecc_build_key_params (int qbits, int algo, int transient) { byte *kek_params = NULL; size_t kek_params_size; - char nbitsstr[35]; char qbitsstr[35]; - char *keyparms; - int n; + char *result; + size_t n; /* KEK parameters are only needed for long term key generation. */ if (!transient && algo == PUBKEY_ALGO_ECDH) - kek_params = pk_ecdh_default_params (qbits, &kek_params_size); + { + kek_params = pk_ecdh_default_params (qbits, &kek_params_size); + if (!kek_params) + return NULL; + } else kek_params = NULL; - snprintf (nbitsstr, sizeof nbitsstr, "%u", qbits); snprintf (qbitsstr, sizeof qbitsstr, "%u", qbits); if (algo == PUBKEY_ALGO_ECDSA || !kek_params) { - keyparms = xtryasprintf ("(genkey(%s(nbits %zu:%s)" + result = xtryasprintf ("(genkey(%s(nbits %zu:%s)" /**/ "(qbits %zu:%s)" /**/ "(transient-key 1:%d)))", algo == PUBKEY_ALGO_ECDSA ? "ecdsa" : "ecdh", - strlen (nbitsstr), nbitsstr, + strlen (qbitsstr), qbitsstr, strlen (qbitsstr), qbitsstr, transient); } else { - assert (kek_params); + char *tmpstr; - keyparms = xtryasprintf ("(genkey(ecdh(nbits %zu:%s)" - /**/ "(qbits %zu:%s)" - /**/ "(transient-key 1:%d)" - /**/ "(kek-params %zu:", - strlen (nbitsstr), nbitsstr, - strlen (qbitsstr), qbitsstr, - transient, - kek_params_size); - if (keyparms) + assert (kek_params); + tmpstr = xtryasprintf ("(genkey(ecdh(nbits %zu:%s)" + /**/ "(qbits %zu:%s)" + /**/ "(transient-key 1:%d)" + /**/ "(kek-params %zu:", + strlen (qbitsstr), qbitsstr, + strlen (qbitsstr), qbitsstr, + transient, + kek_params_size); + if (!tmpstr) { - n = strlen (keyparms); - keyparms = xtryrealloc (keyparms, n + kek_params_size + 4); + xfree (kek_params); + return NULL; } - if (!keyparms) + /* Append the binary KEK parmas. */ + n = strlen (tmpstr); + result = xtryrealloc (tmpstr, n + kek_params_size + 4); + if (!result) { + xfree (tmpstr); xfree (kek_params); return NULL; } - memcpy (keyparms+n, kek_params, kek_params_size); - xfree (kek_params); - memcpy (keyparms+n+kek_params_size, ")))", 4); + memcpy (result + n, kek_params, kek_params_size); + strcpy (result + n + kek_params_size, ")))"); } - return keyparms; + xfree (kek_params); + return result; } -- 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. --- g10/keygen.c | 229 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 125 insertions(+), 104 deletions(-) (limited to 'g10/keygen.c') diff --git a/g10/keygen.c b/g10/keygen.c index b42121b28..4d911f0b9 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1081,7 +1081,107 @@ write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk, } +static gpg_error_t +ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo) +{ + gpg_error_t err; + gcry_sexp_t list, l2; + char *curve; + int i; + const char *oidstr; + unsigned int nbits; + + array[0] = NULL; + array[1] = NULL; + array[2] = NULL; + + list = gcry_sexp_find_token (sexp, "public-key", 0); + if (!list) + return gpg_error (GPG_ERR_INV_OBJ); + l2 = gcry_sexp_cadr (list); + gcry_sexp_release (list); + list = l2; + if (!list) + return gpg_error (GPG_ERR_NO_OBJ); + + l2 = gcry_sexp_find_token (list, "curve", 0); + if (!l2) + { + err = gpg_error (GPG_ERR_NO_OBJ); + goto leave; + } + curve = gcry_sexp_nth_string (l2, 1); + if (!curve) + { + err = gpg_error (GPG_ERR_NO_OBJ); + goto leave; + } + gcry_sexp_release (l2); + if (!strcmp (curve, "NIST P-256")) + { + oidstr = "1.2.840.10045.3.1.7"; + nbits = 256; + } + else if (!strcmp (curve, "NIST P-384")) + { + oidstr = "1.3.132.0.34"; + nbits = 384; + } + else if (!strcmp (curve, "NIST P-521")) + { + oidstr = "1.3.132.0.35"; + nbits = 521; + } + else + { + err = gpg_error (GPG_ERR_INV_OBJ); + goto leave; + } + err = openpgp_oid_from_str (oidstr, &array[0]); + if (err) + goto leave; + + l2 = gcry_sexp_find_token (list, "q", 0); + if (!l2) + { + err = gpg_error (GPG_ERR_NO_OBJ); + goto leave; + } + array[1] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l2); + if (!array[1]) + { + err = gpg_error (GPG_ERR_INV_OBJ); + goto leave; + } + gcry_sexp_release (list); + if (algo == PUBKEY_ALGO_ECDH) + { + array[2] = pk_ecdh_default_params (nbits); + if (!array[2]) + { + err = gpg_error_from_syserror (); + goto leave; + } + } + + leave: + if (err) + { + for (i=0; i < 3; i++) + { + gcry_mpi_release (array[i]); + array[i] = NULL; + } + } + return 0; +} + + +/* Extract key parameters from SEXP and store them in ARRAY. ELEMS is + a string where each character denotes a parameter name. TOPNAME is + the name of the top element above the elements. */ static int key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, const char *elems) @@ -1165,7 +1265,10 @@ common_gen (const char *keyparms, int algo, const char *algoelem, pk->expiredate = pk->timestamp + expireval; pk->pubkey_algo = algo; - err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem); + if (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH) + err = ecckey_from_sexp (pk->pkey, s_key, algo); + else + err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem); if (err) { log_error ("key_from_sexp failed: %s\n", gpg_strerror (err) ); @@ -1173,7 +1276,6 @@ common_gen (const char *keyparms, int algo, const char *algoelem, free_public_key (pk); return err; } - gcry_sexp_release (s_key); pkt = xtrycalloc (1, sizeof *pkt); if (!pkt) @@ -1329,126 +1431,45 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, -/* Create an S-expression string out of QBITS, ALGO and the TRANSIENT - flag. On success a malloced string is returned, on failure NULL - and ERRNO is set. */ -static char * -pk_ecc_build_key_params (int qbits, int algo, int transient) -{ - byte *kek_params = NULL; - size_t kek_params_size; - char qbitsstr[35]; - char *result; - size_t n; - - /* KEK parameters are only needed for long term key generation. */ - if (!transient && algo == PUBKEY_ALGO_ECDH) - { - kek_params = pk_ecdh_default_params (qbits, &kek_params_size); - if (!kek_params) - return NULL; - } - else - kek_params = NULL; - - snprintf (qbitsstr, sizeof qbitsstr, "%u", qbits); - if (algo == PUBKEY_ALGO_ECDSA || !kek_params) - { - result = xtryasprintf ("(genkey(%s(nbits %zu:%s)" - /**/ "(qbits %zu:%s)" - /**/ "(transient-key 1:%d)))", - algo == PUBKEY_ALGO_ECDSA ? "ecdsa" : "ecdh", - strlen (qbitsstr), qbitsstr, - strlen (qbitsstr), qbitsstr, - transient); - } - else - { - char *tmpstr; - - assert (kek_params); - tmpstr = xtryasprintf ("(genkey(ecdh(nbits %zu:%s)" - /**/ "(qbits %zu:%s)" - /**/ "(transient-key 1:%d)" - /**/ "(kek-params %zu:", - strlen (qbitsstr), qbitsstr, - strlen (qbitsstr), qbitsstr, - transient, - kek_params_size); - if (!tmpstr) - { - xfree (kek_params); - return NULL; - } - /* Append the binary KEK parmas. */ - n = strlen (tmpstr); - result = xtryrealloc (tmpstr, n + kek_params_size + 4); - if (!result) - { - xfree (tmpstr); - xfree (kek_params); - return NULL; - } - memcpy (result + n, kek_params, kek_params_size); - strcpy (result + n + kek_params_size, ")))"); - } - xfree (kek_params); - return result; -} - - /* * Generate an ECC key */ static gpg_error_t -gen_ecc (int algo, unsigned int nbits, KBNODE pub_root, +gen_ecc (int algo, unsigned int nbits, kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey, int keygen_flags, char **cache_nonce_addr) { - int err; - unsigned int qbits; + gpg_error_t err; + const char *curve; char *keyparms; assert (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH); - if (pubkey_get_npkey (PUBKEY_ALGO_ECDSA) != 2 - || pubkey_get_nskey (PUBKEY_ALGO_ECDSA) != 3 - || pubkey_get_npkey (PUBKEY_ALGO_ECDH) != 3 - || pubkey_get_nskey (PUBKEY_ALGO_ECDH) != 4) - { - log_error ("broken version of Libgcrypt\n"); - return gpg_error (GPG_ERR_INTERNAL); /* ABI silently changed. */ - } - - if (nbits != 256 && nbits != 384 && nbits != 521) - { - log_info (_("keysize invalid; using %u bits\n"), 256); - /* FIXME: Where do we set it to 256? */ - } - - /* Figure out a Q size based on the key size. See gen_dsa for more - details. Due to 8-bit rounding we may get 528 here instead of 521. */ - nbits = qbits = (nbits < 521 ? nbits : 521 ); - - keyparms = pk_ecc_build_key_params - (qbits, algo, !!( (keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) - && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION)) ); + /* For now we may only use one of the 3 NISY curves. */ + if (nbits <= 256) + curve = "NIST P-256"; + else if (nbits <= 384) + curve = "NIST P-384"; + else + curve = "NIST P-521"; + + keyparms = xtryasprintf ("(genkey(%s(curve %zu:%s)%s))", + algo == PUBKEY_ALGO_ECDSA ? "ecdsa" : "ecdh", + strlen (curve), curve, + ((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) + && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? + "(transient-key)" : "" ); if (!keyparms) - { - err = gpg_error_from_syserror (); - log_error ("ecc pk_ecc_build_key_params failed: %s\n", - gpg_strerror (err)); - } + err = gpg_error_from_syserror (); else { - err = common_gen (keyparms, algo, - algo == PUBKEY_ALGO_ECDSA? "cq" : "cqp", + err = common_gen (keyparms, algo, "", pub_root, timestamp, expireval, is_subkey, keygen_flags, cache_nonce_addr); xfree (keyparms); } - return 0; + return err; } @@ -2428,7 +2449,7 @@ get_parameter_algo( struct para_data_s *para, enum para_name key, || !strcmp (r->u.value, "ELG")) i = GCRY_PK_ELG_E; else - i = gcry_pk_map_name (r->u.value); + i = map_pk_gcry_to_openpgp (gcry_pk_map_name (r->u.value)); if (i == PUBKEY_ALGO_RSA_E || i == PUBKEY_ALGO_RSA_S) i = 0; /* we don't want to allow generation of these algorithms */ -- 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. --- g10/keygen.c | 57 ++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 17 deletions(-) (limited to 'g10/keygen.c') diff --git a/g10/keygen.c b/g10/keygen.c index 4d911f0b9..d8535fa61 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1080,6 +1080,40 @@ write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk, return err; } +/* Map the Libgcrypt ECC curve NAME to an OID. If R_NBITS is not NULL + store the bit size of the curve there. Returns NULL for unknown + curve names. */ +const char * +gpg_curve_to_oid (const char *name, unsigned int *r_nbits) +{ + unsigned int nbits = 0; + const char *oidstr; + + if (!name) + oidstr = NULL; + else if (!strcmp (name, "NIST P-256")) + { + oidstr = "1.2.840.10045.3.1.7"; + nbits = 256; + } + else if (!strcmp (name, "NIST P-384")) + { + oidstr = "1.3.132.0.34"; + nbits = 384; + } + else if (!strcmp (name, "NIST P-521")) + { + oidstr = "1.3.132.0.35"; + nbits = 521; + } + else + oidstr = NULL; + + if (r_nbits) + *r_nbits = nbits; + return oidstr; +} + static gpg_error_t ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo) @@ -1117,23 +1151,11 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo) goto leave; } gcry_sexp_release (l2); - if (!strcmp (curve, "NIST P-256")) - { - oidstr = "1.2.840.10045.3.1.7"; - nbits = 256; - } - else if (!strcmp (curve, "NIST P-384")) - { - oidstr = "1.3.132.0.34"; - nbits = 384; - } - else if (!strcmp (curve, "NIST P-521")) - { - oidstr = "1.3.132.0.35"; - nbits = 521; - } - else + oidstr = gpg_curve_to_oid (curve, &nbits); + if (!oidstr) { + /* That can't happen because we used one of the curves + gpg_curve_to_oid knows about. */ err = gpg_error (GPG_ERR_INV_OBJ); goto leave; } @@ -1445,7 +1467,8 @@ gen_ecc (int algo, unsigned int nbits, kbnode_t pub_root, assert (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH); - /* For now we may only use one of the 3 NISY curves. */ + /* For now we may only use one of the 3 NIST curves. See also + gpg_curve_to_oid. */ if (nbits <= 256) curve = "NIST P-256"; else if (nbits <= 384) -- 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. --- g10/keygen.c | 265 ++++++++++++++++++++++++++++++----------------------------- 1 file changed, 133 insertions(+), 132 deletions(-) (limited to 'g10/keygen.c') diff --git a/g10/keygen.c b/g10/keygen.c index d8535fa61..fdae6fb83 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -55,7 +55,7 @@ #define KEYGEN_FLAG_TRANSIENT_KEY 2 /* Maximum number of supported algorithm preferences. */ -#define MAX_PREFS 30 +#define MAX_PREFS 30 enum para_name { pKEYTYPE, @@ -148,7 +148,7 @@ print_status_key_created (int letter, PKT_public_key *pk, const char *handle) byte array[MAX_FINGERPRINT_LEN], *s; char *buf, *p; size_t i, n; - + if (!handle) handle = ""; @@ -216,7 +216,7 @@ do_add_key_flags (PKT_signature *sig, unsigned int use) if (use & PUBKEY_USAGE_AUTH) buf[0] |= 0x20; - if (!buf[0]) + if (!buf[0]) return; build_sig_subpkt (sig, SIGSUBPKT_KEY_FLAGS, buf, 1); @@ -229,14 +229,14 @@ keygen_add_key_expire (PKT_signature *sig, void *opaque) PKT_public_key *pk = opaque; byte buf[8]; u32 u; - + if (pk->expiredate) { if (pk->expiredate > pk->timestamp) u = pk->expiredate - pk->timestamp; else u = 1; - + buf[0] = (u >> 24) & 0xff; buf[1] = (u >> 16) & 0xff; buf[2] = (u >> 8) & 0xff; @@ -258,7 +258,7 @@ static int keygen_add_key_flags_and_expire (PKT_signature *sig, void *opaque) { struct opaque_data_usage_and_pk *oduap = opaque; - + do_add_key_flags (sig, oduap->usage); return keygen_add_key_expire (sig, oduap->pk); } @@ -325,7 +325,7 @@ keygen_set_std_prefs (const char *string,int personal) gpg -r pgpkey -r gpgkey ---gives--> AES256 gpg -r gpgkey -r pgpkey ---gives--> AES - + Note that by using --personal-cipher-preferences it is possible to prefer AES128. */ @@ -392,7 +392,7 @@ keygen_set_std_prefs (const char *string,int personal) strcat(dummy_string,"Z1 "); any_compress = 1; } - + /* In case we have no compress algo at all, declare that we prefer no compresssion. */ if (!any_compress) @@ -676,18 +676,18 @@ int keygen_upd_std_prefs (PKT_signature *sig, void *opaque) { (void)opaque; - + if (!prefs_initialized) keygen_set_std_prefs (NULL, 0); - - if (nsym_prefs) + + if (nsym_prefs) build_sig_subpkt (sig, SIGSUBPKT_PREF_SYM, sym_prefs, nsym_prefs); else { delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_SYM); delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_SYM); } - + if (nhash_prefs) build_sig_subpkt (sig, SIGSUBPKT_PREF_HASH, hash_prefs, nhash_prefs); else @@ -703,7 +703,7 @@ keygen_upd_std_prefs (PKT_signature *sig, void *opaque) delete_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_COMPR); delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PREF_COMPR); } - + /* Make sure that the MDC feature flag is set if needed. */ add_feature_mdc (sig,mdc_available); add_keyserver_modify (sig,ks_modify); @@ -721,12 +721,12 @@ int keygen_add_std_prefs (PKT_signature *sig, void *opaque) { PKT_public_key *pk = opaque; - + do_add_key_flags (sig, pk->pubkey_usage); keygen_add_key_expire (sig, opaque ); keygen_upd_std_prefs (sig, opaque); keygen_add_keyserver_url (sig,NULL); - + return 0; } @@ -840,7 +840,7 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk, /* Get it into a binary packed form. */ IOBUF backsig_out = iobuf_temp(); PACKET backsig_pkt; - + init_packet (&backsig_pkt); backsig_pkt.pkttype = PKT_SIGNATURE; backsig_pkt.pkt.signature = backsig; @@ -852,15 +852,15 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk, { size_t pktlen = 0; byte *buf = iobuf_get_temp_buffer (backsig_out); - + /* Remove the packet header. */ if(buf[0]&0x40) { if (buf[1] < 192) { pktlen = buf[1]; - buf += 2; - } + buf += 2; + } else if(buf[1] < 224) { pktlen = (buf[1]-192)*256; @@ -881,34 +881,34 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk, else { int mark = 1; - + switch (buf[0]&3) { case 3: BUG (); break; - + case 2: pktlen = buf[mark++] << 24; pktlen |= buf[mark++] << 16; - + case 1: pktlen |= buf[mark++] << 8; - + case 0: pktlen |= buf[mark++]; } - + buf += mark; } - + /* Now make the binary blob into a subpacket. */ build_sig_subpkt (sig, SIGSUBPKT_SIGNATURE, buf, pktlen); iobuf_close (backsig_out); } } - + return err; } @@ -949,7 +949,7 @@ write_direct_sig (KBNODE root, PKT_public_key *psk, log_error ("make_keysig_packet failed: %s\n", g10_errstr (err) ); return err; } - + pkt = xmalloc_clear (sizeof *pkt); pkt->pkttype = PKT_SIGNATURE; pkt->pkt.signature = sig; @@ -990,7 +990,7 @@ write_selfsigs (KBNODE root, PKT_public_key *psk, /* The usage has not yet been set - do it now. */ pk->pubkey_usage = use; - + /* We have to cache the key, so that the verification of the signature creation is able to retrieve the public key. */ cache_public_key (pk); @@ -999,7 +999,7 @@ write_selfsigs (KBNODE root, PKT_public_key *psk, err = make_keysig_packet (&sig, pk, uid, NULL, psk, 0x13, 0, 0, timestamp, 0, keygen_add_std_prefs, pk, cache_nonce); - if (err) + if (err) { log_error ("make_keysig_packet failed: %s\n", g10_errstr (err)); return err; @@ -1041,10 +1041,10 @@ write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk, /* We have to cache the key, so that the verification of the * signature creation is able to retrieve the public key. */ cache_public_key (pri_pk); - + /* Find the last subkey. */ sub_pk = NULL; - for (node = root; node; node = node->next ) + for (node = root; node; node = node->next ) { if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) sub_pk = node->pkt->pkt.public_key; @@ -1055,11 +1055,11 @@ write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk, /* Make the signature. */ oduap.usage = use; oduap.pk = sub_pk; - err = make_keysig_packet (&sig, pri_pk, NULL, sub_pk, pri_psk, 0x18, + err = make_keysig_packet (&sig, pri_pk, NULL, sub_pk, pri_psk, 0x18, 0, 0, timestamp, 0, keygen_add_key_flags_and_expire, &oduap, cache_nonce); - if (err) + if (err) { log_error ("make_keysig_packet failed: %s\n", g10_errstr (err)); return err; @@ -1072,7 +1072,7 @@ write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk, if (err) return err; } - + pkt = xmalloc_clear ( sizeof *pkt ); pkt->pkttype = PKT_SIGNATURE; pkt->pkt.signature = sig; @@ -1203,7 +1203,7 @@ ecckey_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, int algo) /* Extract key parameters from SEXP and store them in ARRAY. ELEMS is a string where each character denotes a parameter name. TOPNAME is - the name of the top element above the elements. */ + the name of the top element above the elements. */ static int key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, const char *elems) @@ -1232,7 +1232,7 @@ key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, } array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); gcry_sexp_release (l2); - if (!array[idx]) + if (!array[idx]) { rc = gpg_error (GPG_ERR_INV_OBJ); /* required parameter invalid */ goto leave; @@ -1272,7 +1272,7 @@ common_gen (const char *keyparms, int algo, const char *algoelem, log_error ("agent_genkey failed: %s\n", gpg_strerror (err) ); return err; } - + pk = xtrycalloc (1, sizeof *pk); if (!pk) { @@ -1283,7 +1283,7 @@ common_gen (const char *keyparms, int algo, const char *algoelem, pk->timestamp = timestamp; pk->version = 4; - if (expireval) + if (expireval) pk->expiredate = pk->timestamp + expireval; pk->pubkey_algo = algo; @@ -1291,14 +1291,15 @@ common_gen (const char *keyparms, int algo, const char *algoelem, err = ecckey_from_sexp (pk->pkey, s_key, algo); else err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem); - if (err) + if (err) { log_error ("key_from_sexp failed: %s\n", gpg_strerror (err) ); gcry_sexp_release (s_key); free_public_key (pk); return err; } - + gcry_sexp_release (s_key); + pkt = xtrycalloc (1, sizeof *pkt); if (!pkt) { @@ -1326,7 +1327,7 @@ gen_elg (int algo, unsigned int nbits, KBNODE pub_root, int err; char *keyparms; char nbitsstr[35]; - + assert (is_ELGAMAL (algo)); if (nbits < 512) @@ -1355,7 +1356,7 @@ gen_elg (int algo, unsigned int nbits, KBNODE pub_root, err = gpg_error_from_syserror (); else { - err = common_gen (keyparms, algo, "pgy", + err = common_gen (keyparms, algo, "pgy", pub_root, timestamp, expireval, is_subkey, keygen_flags, cache_nonce_addr); xfree (keyparms); @@ -1369,7 +1370,7 @@ gen_elg (int algo, unsigned int nbits, KBNODE pub_root, * Generate an DSA key */ static gpg_error_t -gen_dsa (unsigned int nbits, KBNODE pub_root, +gen_dsa (unsigned int nbits, KBNODE pub_root, u32 timestamp, u32 expireval, int is_subkey, int keygen_flags, char **cache_nonce_addr) { @@ -1379,7 +1380,7 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, char nbitsstr[35]; char qbitsstr[35]; - if ( nbits < 512) + if ( nbits < 512) { nbits = 1024; log_info(_("keysize invalid; using %u bits\n"), nbits ); @@ -1406,26 +1407,26 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, /* Figure out a q size based on the key size. FIPS 180-3 says: - + L = 1024, N = 160 L = 2048, N = 224 L = 2048, N = 256 L = 3072, N = 256 - + 2048/256 is an odd pair since there is also a 2048/224 and 3072/256. Matching sizes is not a very exact science. - + We'll do 256 qbits for nbits over 2047, 224 for nbits over 1024 but less than 2048, and 160 for 1024 (DSA1). */ - + if (nbits > 2047) qbits = 256; else if ( nbits > 1024) qbits = 224; else qbits = 160; - + if (qbits != 160 ) log_info (_("WARNING: some OpenPGP programs can't" " handle a DSA key with this digest size\n")); @@ -1442,7 +1443,7 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, err = gpg_error_from_syserror (); else { - err = common_gen (keyparms, PUBKEY_ALGO_DSA, "pqgy", + err = common_gen (keyparms, PUBKEY_ALGO_DSA, "pqgy", pub_root, timestamp, expireval, is_subkey, keygen_flags, cache_nonce_addr); xfree (keyparms); @@ -1473,10 +1474,10 @@ gen_ecc (int algo, unsigned int nbits, kbnode_t pub_root, curve = "NIST P-256"; else if (nbits <= 384) curve = "NIST P-384"; - else + else curve = "NIST P-521"; - keyparms = xtryasprintf ("(genkey(%s(curve %zu:%s)%s))", + keyparms = xtryasprintf ("(genkey(%s(curve %zu:%s)%s))", algo == PUBKEY_ALGO_ECDSA ? "ecdsa" : "ecdh", strlen (curve), curve, ((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) @@ -1496,7 +1497,7 @@ gen_ecc (int algo, unsigned int nbits, kbnode_t pub_root, } -/* +/* * Generate an RSA key. */ static int @@ -1513,12 +1514,12 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root, if (!nbits) nbits = DEFAULT_STD_KEYSIZE; - if (nbits < 1024) + if (nbits < 1024) { nbits = 1024; log_info (_("keysize invalid; using %u bits\n"), nbits ); } - + if ((nbits % 32)) { nbits = ((nbits + 31) / 32) * 32; @@ -1526,7 +1527,7 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root, } snprintf (nbitsstr, sizeof nbitsstr, "%u", nbits); - keyparms = xtryasprintf ("(genkey(rsa(nbits %zu:%s)%s))", + keyparms = xtryasprintf ("(genkey(rsa(nbits %zu:%s)%s))", strlen (nbitsstr), nbitsstr, ((keygen_flags & KEYGEN_FLAG_TRANSIENT_KEY) && (keygen_flags & KEYGEN_FLAG_NO_PROTECTION))? @@ -1535,7 +1536,7 @@ gen_rsa (int algo, unsigned int nbits, KBNODE pub_root, err = gpg_error_from_syserror (); else { - err = common_gen (keyparms, algo, "ne", + err = common_gen (keyparms, algo, "ne", pub_root, timestamp, expireval, is_subkey, keygen_flags, cache_nonce_addr); xfree (keyparms); @@ -1704,7 +1705,7 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage) if (!r_subkey_algo) r_subkey_algo = &dummy_algo; - + tty_printf (_("Please select what kind of key you want:\n")); if (!addmode) @@ -1725,7 +1726,7 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage) tty_printf (_(" (%d) DSA (set your own capabilities)\n"), 7 ); tty_printf (_(" (%d) RSA (set your own capabilities)\n"), 8 ); } - + tty_printf (_(" (%d) ECDSA and ECDH\n"), 9 ); for(;;) @@ -1793,7 +1794,7 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage) else tty_printf (_("Invalid selection.\n")); } - + return algo; } @@ -1863,7 +1864,7 @@ ask_keysize (int algo, unsigned int primary_keysize) nbits = *answer? atoi (answer): def; xfree(prompt); xfree(answer); - + if(nbitsmax) tty_printf(_("%s keysizes must be in the range %u-%u\n"), openpgp_pk_algo_name (algo), min, max); @@ -1923,7 +1924,7 @@ parse_expire_string( const char *string ) u32 abs_date = 0; u32 curtime = make_timestamp (); time_t tt; - + if (!*string) seconds = 0; else if (!strncmp (string, "seconds=", 8)) @@ -1937,7 +1938,7 @@ parse_expire_string( const char *string ) seconds = atoi (string) * 86400L * mult; else seconds = (u32)(-1); - + return seconds; } @@ -1947,7 +1948,7 @@ static u32 parse_creation_string (const char *string) { u32 seconds; - + if (!*string) seconds = 0; else if ( !strncmp (string, "seconds=", 8) ) @@ -2242,7 +2243,7 @@ ask_user_id (int mode, KBNODE keyblock) lower and uppercase. Below you will find the matching string which should be translated accordingly and the letter changed to match the one in the answer string. - + n = Change name c = Change comment e = Change email @@ -2403,7 +2404,7 @@ PKT_user_id * generate_user_id (KBNODE keyblock) { char *p; - + p = ask_user_id (1, keyblock); if (!p) return NULL; /* Canceled. */ @@ -2415,7 +2416,7 @@ static void release_parameter_list (struct para_data_s *r) { struct para_data_s *r2; - + for (; r ; r = r2) { r2 = r->next; @@ -2423,7 +2424,7 @@ release_parameter_list (struct para_data_s *r) xfree (r->u.dek); else if (r->key == pPASSPHRASE_S2K ) xfree (r->u.s2k); - + xfree (r); } } @@ -2446,7 +2447,7 @@ get_parameter_value( struct para_data_s *para, enum para_name key ) } static int -get_parameter_algo( struct para_data_s *para, enum para_name key, +get_parameter_algo( struct para_data_s *para, enum para_name key, int *r_default) { int i; @@ -2479,7 +2480,7 @@ get_parameter_algo( struct para_data_s *para, enum para_name key, return i; } -/* +/* * Parse the usage parameter and set the keyflags. Returns -1 on * error, 0 for no usage given or 1 for usage available. */ @@ -2493,7 +2494,7 @@ parse_parameter_usage (const char *fname, if( !r ) return 0; /* none (this is an optional parameter)*/ - + use = 0; pn = r->u.value; while ( (p = strsep (&pn, " \t,")) ) { @@ -2581,7 +2582,7 @@ get_parameter_u32( struct para_data_s *para, enum para_name key ) return r->u.expire; if( r->key == pKEYUSAGE || r->key == pSUBKEYUSAGE ) return r->u.usage; - + return (unsigned int)strtoul( r->u.value, NULL, 10 ); } @@ -2775,7 +2776,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname, para = r; } - if (canceled) + if (canceled) { log_error ("%s:%d: key generation canceled\n", fname, r->lnr ); return -1; @@ -2791,7 +2792,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname, * but because we do this always, why not here. */ STRING2KEY *s2k; DEK *dek; - + s2k = xmalloc_secure ( sizeof *s2k ); s2k->mode = opt.s2k_mode; s2k->hash_algo = S2K_DIGEST_ALGO; @@ -2801,7 +2802,7 @@ proc_parameter_file( struct para_data_s *para, const char *fname, set_next_passphrase (NULL ); assert (dek); memset (r->u.value, 0, strlen(r->u.value)); - + r = xmalloc_clear (sizeof *r); r->key = pPASSPHRASE_S2K; r->u.s2k = s2k; @@ -2958,7 +2959,7 @@ read_parameter_file( const char *fname ) else if( !ascii_strcasecmp( keyword, "%commit" ) ) { outctrl.lnr = lnr; if (proc_parameter_file( para, fname, &outctrl, 0 )) - print_status_key_not_created + print_status_key_not_created (get_parameter_value (para, pHANDLE)); release_parameter_list( para ); para = NULL; @@ -3052,7 +3053,7 @@ read_parameter_file( const char *fname ) /* Must invalidate that ugly cache to actually close it. */ if (outctrl.pub.fname) - iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, + iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)outctrl.pub.fname); xfree( outctrl.pub.fname ); @@ -3073,7 +3074,7 @@ read_parameter_file( const char *fname ) * imported to the card and a backup file created by gpg-agent. */ void -generate_keypair (const char *fname, const char *card_serialno, +generate_keypair (const char *fname, const char *card_serialno, int card_backup_key) { unsigned int nbits; @@ -3085,16 +3086,16 @@ generate_keypair (const char *fname, const char *card_serialno, struct para_data_s *para = NULL; struct para_data_s *r; struct output_control_s outctrl; - + memset( &outctrl, 0, sizeof( outctrl ) ); - + if (opt.batch && card_serialno) { /* We don't yet support unattended key generation. */ log_error (_("can't do this in batch mode\n")); return; } - + if (opt.batch) { read_parameter_file( fname ); @@ -3109,9 +3110,9 @@ generate_keypair (const char *fname, const char *card_serialno, strcpy( r->u.value, card_serialno); r->next = para; para = r; - + algo = PUBKEY_ALGO_RSA; - + r = xcalloc (1, sizeof *r + 20 ); r->key = pKEYTYPE; sprintf( r->u.value, "%d", algo ); @@ -3122,7 +3123,7 @@ generate_keypair (const char *fname, const char *card_serialno, strcpy (r->u.value, "sign"); r->next = para; para = r; - + r = xcalloc (1, sizeof *r + 20 ); r->key = pSUBKEYTYPE; sprintf( r->u.value, "%d", algo ); @@ -3133,7 +3134,7 @@ generate_keypair (const char *fname, const char *card_serialno, strcpy (r->u.value, "encrypt"); r->next = para; para = r; - + r = xcalloc (1, sizeof *r + 20 ); r->key = pAUTHKEYTYPE; sprintf( r->u.value, "%d", algo ); @@ -3152,11 +3153,11 @@ generate_keypair (const char *fname, const char *card_serialno, } else { - int subkey_algo; + int subkey_algo; algo = ask_algo (0, &subkey_algo, &use); if (subkey_algo) - { + { /* Create primary and subkey at once. */ both = 1; r = xmalloc_clear( sizeof *r + 20 ); @@ -3175,7 +3176,7 @@ generate_keypair (const char *fname, const char *card_serialno, strcpy( r->u.value, "sign" ); r->next = para; para = r; - + r = xmalloc_clear( sizeof *r + 20 ); r->key = pSUBKEYTYPE; sprintf( r->u.value, "%d", subkey_algo); @@ -3187,14 +3188,14 @@ generate_keypair (const char *fname, const char *card_serialno, r->next = para; para = r; } - else + else { r = xmalloc_clear( sizeof *r + 20 ); r->key = pKEYTYPE; sprintf( r->u.value, "%d", algo ); r->next = para; para = r; - + if (use) { r = xmalloc_clear( sizeof *r + 25 ); @@ -3216,7 +3217,7 @@ generate_keypair (const char *fname, const char *card_serialno, r->next = para; para = r; } - + expire = ask_expire_interval(0,NULL); r = xmalloc_clear( sizeof *r + 20 ); r->key = pKEYEXPIRE; @@ -3230,7 +3231,7 @@ generate_keypair (const char *fname, const char *card_serialno, para = r; uid = ask_user_id (0, NULL); - if( !uid ) + if( !uid ) { log_error(_("Key generation canceled.\n")); release_parameter_list( para ); @@ -3241,7 +3242,7 @@ generate_keypair (const char *fname, const char *card_serialno, strcpy( r->u.value, uid ); r->next = para; para = r; - + proc_parameter_file( para, "[internal]", &outctrl, !!card_serialno); release_parameter_list( para ); } @@ -3276,7 +3277,7 @@ generate_raw_key (int algo, unsigned int nbits, u32 created_at, log_info (_("keysize invalid; using %u bits\n"), nbits ); } - if ((nbits % 32)) + if ((nbits % 32)) { nbits = ((nbits + 31) / 32) * 32; log_info(_("keysize rounded up to %u bits\n"), nbits ); @@ -3314,16 +3315,16 @@ generate_raw_key (int algo, unsigned int nbits, u32 created_at, } rc = key_from_sexp (sk->skey, s_key, "private-key", "nedpqu"); gcry_sexp_release (s_key); - if (rc) + if (rc) { log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) ); goto leave; } - + for (i=npkey; i < nskey; i++) sk->csum += checksum_mpi (sk->skey[i]); - if (r_sk_unprotected) + if (r_sk_unprotected) *r_sk_unprotected = copy_secret_key (NULL, sk); rc = genhelp_protect (dek, s2k, sk); @@ -3377,10 +3378,10 @@ do_generate_keypair (struct para_data_s *para, log_info("dry-run mode - key generation skipped\n"); return; } - - if ( outctrl->use_files ) + + if ( outctrl->use_files ) { - if ( outctrl->pub.newfname ) + if ( outctrl->pub.newfname ) { iobuf_close(outctrl->pub.stream); outctrl->pub.stream = NULL; @@ -3390,8 +3391,8 @@ do_generate_keypair (struct para_data_s *para, xfree( outctrl->pub.fname ); outctrl->pub.fname = outctrl->pub.newfname; outctrl->pub.newfname = NULL; - - if (is_secured_filename (outctrl->pub.fname) ) + + if (is_secured_filename (outctrl->pub.fname) ) { outctrl->pub.stream = NULL; gpg_err_set_errno (EPERM); @@ -3420,7 +3421,7 @@ do_generate_keypair (struct para_data_s *para, structure we create is known in advance we simply generate a linked list. The first packet is a dummy packet which we flag as deleted. The very first packet must always be a KEY packet. */ - + start_tree (&pub_root); timestamp = get_parameter_u32 (para, pKEYCREATIONDATE); @@ -3441,7 +3442,7 @@ do_generate_keypair (struct para_data_s *para, get_parameter_uint( para, pKEYLENGTH ), pub_root, timestamp, - get_parameter_u32( para, pKEYEXPIRE ), 0, + get_parameter_u32( para, pKEYEXPIRE ), 0, outctrl->keygen_flags, &cache_nonce); else err = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root, @@ -3490,7 +3491,7 @@ do_generate_keypair (struct para_data_s *para, { err = do_create (get_parameter_algo (para, pSUBKEYTYPE, NULL), get_parameter_uint (para, pSUBKEYLENGTH), - pub_root, + pub_root, timestamp, get_parameter_u32 (para, pSUBKEYEXPIRE), 1, outctrl->keygen_flags, &cache_nonce); @@ -3498,7 +3499,7 @@ do_generate_keypair (struct para_data_s *para, if (!err) { kbnode_t node; - + for (node = pub_root; node; node = node->next) if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) sub_psk = node->pkt->pkt.public_key; @@ -3542,26 +3543,26 @@ do_generate_keypair (struct para_data_s *para, KEYDB_HANDLE pub_hd = keydb_new (); err = keydb_locate_writable (pub_hd, NULL); - if (err) + if (err) log_error (_("no writable public keyring found: %s\n"), g10_errstr (err)); - + if (!err && opt.verbose) { log_info (_("writing public key to `%s'\n"), keydb_get_resource_name (pub_hd)); } - - if (!err) + + if (!err) { err = keydb_insert_keyblock (pub_hd, pub_root); if (err) log_error (_("error writing public keyring `%s': %s\n"), keydb_get_resource_name (pub_hd), g10_errstr(err)); } - + keydb_release (pub_hd); - + if (!err) { int no_enc_rsa; @@ -3581,14 +3582,14 @@ do_generate_keypair (struct para_data_s *para, update_ownertrust (pk, ((get_ownertrust (pk) & ~TRUST_MASK) | TRUST_ULTIMATE )); - if (!opt.batch) + if (!opt.batch) { tty_printf (_("public and secret key created and signed.\n") ); tty_printf ("\n"); list_keyblock (pub_root, 0, 1, NULL); } - - + + if (!opt.batch && (get_parameter_algo (para, pKEYTYPE, NULL) == PUBKEY_ALGO_DSA || no_enc_rsa ) @@ -3613,12 +3614,12 @@ do_generate_keypair (struct para_data_s *para, } else { - PKT_public_key *pk = find_kbnode (pub_root, + PKT_public_key *pk = find_kbnode (pub_root, PKT_PUBLIC_KEY)->pkt->pkt.public_key; print_status_key_created (did_sub? 'B':'P', pk, get_parameter_value (para, pHANDLE)); } - + release_kbnode (pub_root); xfree (cache_nonce); } @@ -3643,7 +3644,7 @@ generate_subkeypair (KBNODE keyblock) /* Break out the primary key. */ node = find_kbnode (keyblock, PKT_PUBLIC_KEY); - if (!node) + if (!node) { log_error ("Oops; primary key missing in keyblock!\n"); err = gpg_error (GPG_ERR_BUG); @@ -3667,7 +3668,7 @@ generate_subkeypair (KBNODE keyblock) } } - if (pri_psk->version < 4) + if (pri_psk->version < 4) { log_info (_("NOTE: creating subkeys for v3 keys " "is not OpenPGP compliant\n")); @@ -3695,7 +3696,7 @@ generate_subkeypair (KBNODE keyblock) { err = gpg_error (GPG_ERR_CANCELED); goto leave; - } + } err = do_create (algo, nbits, keyblock, cur_time, expire, 1, 0, NULL); if (err) @@ -3803,7 +3804,7 @@ generate_card_subkeypair (kbnode_t pub_keyblock, if (!err) { PKT_public_key *sub_pk = NULL; - + for (node = pub_keyblock; node; node = node->next) if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY) sub_pk = node->pkt->pkt.public_key; @@ -3848,7 +3849,7 @@ write_keyblock( IOBUF out, KBNODE node ) /* Note that timestamp is an in/out arg. */ static gpg_error_t -gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root, +gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root, u32 *timestamp, u32 expireval) { #ifdef ENABLE_CARD_SUPPORT @@ -3869,11 +3870,11 @@ gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root, xfree (pk); return gpg_error_from_syserror (); } - + /* Note: SCD knows the serialnumber, thus there is no point in passing it. */ err = agent_scd_genkey (&info, keyno, 1, NULL, *timestamp); - /* The code below is not used because we force creation of - * the a card key (3rd arg). + /* The code below is not used because we force creation of + * the a card key (3rd arg). * if (gpg_err_code (rc) == GPG_ERR_EEXIST) * { * tty_printf ("\n"); @@ -3898,7 +3899,7 @@ gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root, xfree (pk); return err; } - + if (*timestamp != info.created_at) log_info ("NOTE: the key does not use the suggested creation date\n"); *timestamp = info.created_at; @@ -3909,7 +3910,7 @@ gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root, pk->expiredate = pk->timestamp + expireval; pk->pubkey_algo = algo; pk->pkey[0] = info.n; - pk->pkey[1] = info.e; + pk->pkey[1] = info.e; pkt->pkttype = is_primary ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY; pkt->pkt.public_key = pk; @@ -3937,11 +3938,11 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary, size_t n; int i; unsigned int nbits; - + /* Get the size of the key directly from the card. */ { struct agent_card_info_s info; - + memset (&info, 0, sizeof info); if (!agent_scd_getattr ("KEY-ATTR", &info) && info.key_attr[1].algo) @@ -4007,7 +4008,7 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary, else fp = iobuf_create (fname); umask (oldmask); - if (!fp) + if (!fp) { rc = gpg_error_from_syserror (); log_error (_("can't create backup file `%s': %s\n"), @@ -4033,7 +4034,7 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary, { unsigned char array[MAX_FINGERPRINT_LEN]; char *fprbuf, *p; - + iobuf_close (fp); iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname); log_info (_("NOTE: backup of card key saved to `%s'\n"), fname); @@ -4150,7 +4151,7 @@ save_unprotected_key_to_card (PKT_public_key *sk, int keyno) p = stpcpy (stpcpy (stpcpy (p, numbuf), numbuf2), "))"); /* Fixme: Unfortunately we don't have the serialnumber available - - thus we can't pass it down to the agent. */ + thus we can't pass it down to the agent. */ rc = agent_scd_writekey (keyno, NULL, sexp, p - sexp); leave: -- cgit v1.2.3