From 7bbc07fde07f3fd57077887498bdff488ec96438 Mon Sep 17 00:00:00 2001 From: Andrey Jivsov Date: Wed, 5 Jan 2011 17:31:47 -0800 Subject: [PATCH 01/26] Make sure that --disable-optimization works in its attempt to replace -Ox with -O0. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index b6ed4b34c..975733080 100644 --- a/configure.ac +++ b/configure.ac @@ -1466,7 +1466,7 @@ AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable compiler optimization]), [if test $enableval = no ; then - CFLAGS=`echo $CFLAGS | sed 's/-O[[0-9]]//'` + CFLAGS=`echo $CFLAGS | sed s/-O[[1-9]]\ /-O0\ /g` fi]) # From e0972d3d962548972872d889b362560e499340d1 Mon Sep 17 00:00:00 2001 From: Andrey Jivsov Date: Wed, 5 Jan 2011 17:33:17 -0800 Subject: [PATCH 02/26] 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 +++- common/convert.c | 27 +++ common/util.h | 1 + configure.ac | 6 +- dirmngr/Makefile.am | 2 +- g10/Makefile.am | 6 +- g10/armor.c | 2 +- g10/build-packet.c | 46 ++++- g10/call-agent.c | 3 + g10/call-agent.h | 1 + g10/ecdh.c | 477 +++++++++++++++++++++++++++++++++++++++++++ g10/encrypt.c | 11 +- g10/export.c | 12 ++ g10/getkey.c | 5 +- g10/gpg.c | 4 +- g10/keygen.c | 281 ++++++++++++++++++++++--- g10/keyid.c | 26 ++- g10/main.h | 13 +- g10/mainproc.c | 6 +- g10/misc.c | 147 ++++++++++++- g10/parse-packet.c | 115 ++++++++--- g10/passphrase.c | 6 +- g10/pkglue.c | 151 +++++++++++++- g10/pkglue.h | 12 +- g10/pubkey-enc.c | 62 ++++-- g10/seskey.c | 69 +++++-- g10/sign.c | 38 ++-- g10/verify-stubs.c | 30 +++ g13/utils.c | 4 +- g13/utils.h | 2 +- include/cipher.h | 2 + kbx/keybox-openpgp.c | 7 +- 34 files changed, 1497 insertions(+), 176 deletions(-) create mode 100644 g10/ecdh.c create mode 100644 g10/verify-stubs.c 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++; diff --git a/common/convert.c b/common/convert.c index aa3a3a809..0a0c46f8e 100644 --- a/common/convert.c +++ b/common/convert.c @@ -23,6 +23,7 @@ #include #include "util.h" +#include "gcrypt.h" #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A')) @@ -245,5 +246,31 @@ hex2str_alloc (const char *hexstring, size_t *r_count) return result; } +/* returns hex representation of the MPI; + * caller must free with xfree + * Returns NULL on error, never throws + */ +char *mpi2hex( gcry_mpi_t m ) { + size_t nbytes; + size_t nbytes2; + int rc; + byte *p; + nbytes = (mpi_get_nbits ( m )+7)/8; + if( nbytes == 0 ) + return NULL; + p = xtrymalloc( nbytes*3+1 ); + if( p==NULL ) + return NULL; + rc = gcry_mpi_print (GCRYMPI_FMT_USG, p+2*nbytes+1, nbytes, &nbytes2, m); + if( rc ) { + xfree( p ); + return NULL; + } + + bin2hex( p+2*nbytes+1, nbytes2, p ); + p[nbytes2*2] = '\0'; +//printf("%s:%d>>>> Created the string %s from %d bytes %02x %02x ..., MPI was %d bytes\n", __FILE__, __LINE__, p, nbytes2, p[2*nbytes+1], p[2*nbytes+2], nbytes); + return p; +} diff --git a/common/util.h b/common/util.h index 7c58b15c5..44a72d90c 100644 --- a/common/util.h +++ b/common/util.h @@ -192,6 +192,7 @@ gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata, int hex2bin (const char *string, void *buffer, size_t length); int hexcolon2bin (const char *string, void *buffer, size_t length); char *bin2hex (const void *buffer, size_t length, char *stringbuf); +char *mpi2hex (gcry_mpi_t m); char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf); const char *hex2str (const char *hexstring, char *buffer, size_t bufsize, size_t *buflen); diff --git a/configure.ac b/configure.ac index 975733080..12545e260 100644 --- a/configure.ac +++ b/configure.ac @@ -24,7 +24,7 @@ min_automake_version="1.10" # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [2.1.0]) +m4_define([my_version], [2.2.0]) m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ @@ -43,7 +43,7 @@ development_version=no NEED_GPG_ERROR_VERSION=1.8 NEED_LIBGCRYPT_API=1 -NEED_LIBGCRYPT_VERSION=1.4.0 +NEED_LIBGCRYPT_VERSION=1.6.0 NEED_LIBASSUAN_API=2 NEED_LIBASSUAN_VERSION=2.0.0 @@ -1466,7 +1466,7 @@ AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable compiler optimization]), [if test $enableval = no ; then - CFLAGS=`echo $CFLAGS | sed s/-O[[1-9]]\ /-O0\ /g` + CFLAGS=`echo $CFLAGS | sed s%-O[[1-9]]%-O0\ %g` fi]) # diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index 5b1fe30be..0285fc8f8 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -61,7 +61,7 @@ endif dirmngr_LDADD = $(libcommonpth) ../gl/libgnu.a $(DNSLIBS) $(LIBASSUAN_LIBS) \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(PTH_LIBS) $(LIBINTL) $(LIBICONV) if !USE_LDAPWRAPPER -dirmngr_LDADD += $(LDAPLIBS) +dirmngr_LDADD += $(LDAPLIBS) -llber endif dirmngr_LDFLAGS = $(extra_bin_ldflags) diff --git a/g10/Makefile.am b/g10/Makefile.am index c8fc4821e..b82fe07f3 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -72,7 +72,8 @@ common_source = \ plaintext.c \ sig-check.c \ keylist.c \ - pkglue.c pkglue.h + pkglue.c pkglue.h \ + ecdh.c gpg2_SOURCES = gpg.c \ server.c \ @@ -109,7 +110,8 @@ gpg2_SOURCES = gpg.c \ gpgv2_SOURCES = gpgv.c \ $(common_source) \ - verify.c + verify.c \ + verify-stubs.c #gpgd_SOURCES = gpgd.c \ # ks-proto.h \ diff --git a/g10/armor.c b/g10/armor.c index a6195fc3d..8cfd35c1f 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -1079,7 +1079,7 @@ armor_filter( void *opaque, int control, iobuf_writestr(a,afx->eol); if( !opt.no_version ) { - iobuf_writestr(a, "Version: GnuPG v" VERSION " (" + iobuf_writestr(a, "Version: GnuPG v" VERSION "-ecc (" PRINTABLE_OS_NAME ")" ); iobuf_writestr(a,afx->eol); } diff --git a/g10/build-packet.c b/g10/build-packet.c index 83d6c7a73..3a2c206c8 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -178,6 +178,16 @@ mpi_write (iobuf_t out, gcry_mpi_t a) return rc; } +/* + * Write the name OID, encoded as an mpi, to OUT. The format of the content of the MPI is + * one byte LEN, following by LEN bytes that are DER representation of an ASN.1 OID. + * This is true for each of the 3 following functions. + */ +#define iobuf_name_oid_write iobuf_write_size_body_mpi +/* Write the value of KEK fields for ECDH. */ +#define ecdh_kek_params_write iobuf_write_size_body_mpi +/* Write the value of encrypted filed for ECDH. */ +#define ecdh_esk_write iobuf_write_size_body_mpi /**************** @@ -290,10 +300,24 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) } assert (npkey < nskey); - /* Writing the public parameters is easy. */ - for (i=0; i < npkey; i++ ) - if ((err = mpi_write (a, pk->pkey[i]))) - goto leave; + if( pk->pubkey_algo != PUBKEY_ALGO_ECDSA && pk->pubkey_algo != PUBKEY_ALGO_ECDH ) { + /* Writing the public parameters is easy, */ + for (i=0; i < npkey; i++ ) + if ((err = mpi_write (a, pk->pkey[i]))) + goto leave; + } + else { + /* ... except we do an adjustment for ECC OID and possibly KEK params for ECDH */ + if( (err=iobuf_name_oid_write(a, pk->pkey[0])) || /* DER of OID with preceeding length byte */ + (err = mpi_write (a, pk->pkey[1])) ) /* point Q, the public key */ + { + goto leave; + } + if( pk->pubkey_algo == PUBKEY_ALGO_ECDH && (err=ecdh_kek_params_write(a,pk->pkey[2]))) { /* one more public field for ECDH */ + goto leave; + } + /* followed by possibly protected private scalar */ + } if (pk->seckey_info) { @@ -458,8 +482,18 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) n = pubkey_get_nenc( enc->pubkey_algo ); if ( !n ) write_fake_data( a, enc->data[0] ); - for (i=0; i < n && !rc ; i++ ) - rc = mpi_write(a, enc->data[i] ); + + if( enc->pubkey_algo != PUBKEY_ALGO_ECDH ) { + for (i=0; i < n && !rc ; i++ ) + rc = mpi_write(a, enc->data[i] ); + } + else { + /* the second field persists as a LEN+field structure, even though it is + * stored for uniformity as an MPI internally */ + assert( n==2 ); + rc = mpi_write(a, enc->data[0] ); + if( !rc ) rc = ecdh_esk_write(a, enc->data[1] ); + } if (!rc) { diff --git a/g10/call-agent.c b/g10/call-agent.c index 9528e1427..25f9a537e 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -1744,6 +1744,7 @@ inq_ciphertext_cb (void *opaque, const char *line) gpg_error_t agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, gcry_sexp_t s_ciphertext, + const byte sk_fp[MAX_FINGERPRINT_LEN], unsigned char **r_buf, size_t *r_buflen) { gpg_error_t err; @@ -1751,6 +1752,8 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, membuf_t data; size_t n, len; char *p, *buf, *endp; + + /*TODO: use sk_fp */ if (!keygrip || strlen(keygrip) != 40 || !s_ciphertext || !r_buf || !r_buflen) return gpg_error (GPG_ERR_INV_VALUE); diff --git a/g10/call-agent.h b/g10/call-agent.h index e09c30990..45e593bb8 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -168,6 +168,7 @@ gpg_error_t agent_pksign (ctrl_t ctrl, const char *cache_nonce, /* Decrypt a ciphertext. */ gpg_error_t agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, gcry_sexp_t s_ciphertext, + const byte sk_fp[MAX_FINGERPRINT_LEN], unsigned char **r_buf, size_t *r_buflen); /* Retrieve a key encryption key. */ diff --git a/g10/ecdh.c b/g10/ecdh.c new file mode 100644 index 000000000..6615b75a4 --- /dev/null +++ b/g10/ecdh.c @@ -0,0 +1,477 @@ +/* ecdh.c - ECDH public key operations used in public key glue code + * Copyright (C) 2000, 2003 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "gpg.h" +#include "util.h" +#include "pkglue.h" +#include "main.h" +#include "options.h" + +gcry_mpi_t +pk_ecdh_default_params_to_mpi( int qbits ) { + gpg_error_t err; + gcry_mpi_t result; + /* Defaults are the strongest possible choices. Performance is not an issue here, only interoperability. */ + byte kek_params[4] = { + 3 /*size of following field*/, + 1 /*fixed version for KDF+AESWRAP*/, + DIGEST_ALGO_SHA512 /* KEK MD */, + CIPHER_ALGO_AES256 /*KEK AESWRAP alg*/ + }; + int i; + + static const struct { + int qbits; + int openpgp_hash_id; + int openpgp_cipher_id; + } kek_params_table[] = { + { 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES }, + { 384, DIGEST_ALGO_SHA384, CIPHER_ALGO_AES256 }, + { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 } // 528 is 521 rounded to the 8 bit boundary + }; + + for( i=0; i= qbits ) { + kek_params[2] = kek_params_table[i].openpgp_hash_id; + kek_params[3] = kek_params_table[i].openpgp_cipher_id; + break; + } + } + if( DBG_CIPHER ) + log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params) ); + + err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, kek_params, sizeof(kek_params), NULL); + if (err) + log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); + + return result; +} + +/* returns allocated (binary) KEK parameters; the size is returned in sizeout. + * The caller must free returned value with xfree. + * Returns NULL on error + */ +byte * +pk_ecdh_default_params( int qbits, size_t *sizeout ) { + gpg_error_t err; + gcry_mpi_t result; + /* Defaults are the strongest possible choices. Performance is not an issue here, only interoperability. */ + byte kek_params[4] = { + 3 /*size of following field*/, + 1 /*fixed version for KDF+AESWRAP*/, + DIGEST_ALGO_SHA512 /* KEK MD */, + CIPHER_ALGO_AES256 /*KEK AESWRAP alg*/ + }; + int i; + + static const struct { + int qbits; + int openpgp_hash_id; + int openpgp_cipher_id; + } kek_params_table[] = { + { 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES }, + { 384, DIGEST_ALGO_SHA384, CIPHER_ALGO_AES256 }, + { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 } // 528 is 521 rounded to the 8 bit boundary + }; + + byte *p; + + *sizeout = 0; + + for( i=0; i= qbits ) { + kek_params[2] = kek_params_table[i].openpgp_hash_id; + kek_params[3] = kek_params_table[i].openpgp_cipher_id; + break; + } + } + if( DBG_CIPHER ) + log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params) ); + + p = xtrymalloc( sizeof(kek_params) ); + if( p == NULL ) + return NULL; + memcpy( p, kek_params, sizeof(kek_params) ); + *sizeout = sizeof(kek_params); + return p; +} + +/* Encrypts/decrypts 'data' with a key derived from shared_mpi ECC point using FIPS SP 800-56A compliant method, which is + * key derivation + key wrapping. The direction is determined by the first parameter (is_encrypt=1 --> this is encryption). + * The result is returned in out as a size+value MPI. + * TODO: memory leaks (x_secret). + */ +static int +pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi, + const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t * pkey, gcry_mpi_t *out) +{ + byte *secret_x; + int secret_x_size; + byte kdf_params[256]; + int kdf_params_size=0; + int nbits; + int kdf_hash_algo; + int kdf_encr_algo; + int rc; + + *out = NULL; + + nbits = pubkey_nbits( PUBKEY_ALGO_ECDH, pkey ); + + { + size_t nbytes; + /* extract x component of the shared point: this is the actual shared secret */ + nbytes = (mpi_get_nbits (pkey[1] /* public point */)+7)/8; + secret_x = xmalloc_secure( nbytes ); + rc = gcry_mpi_print (GCRYMPI_FMT_USG, secret_x, nbytes, &nbytes, shared_mpi); + if( rc ) { + xfree( secret_x ); + log_error ("ec ephemeral export of shared point failed: %s\n", gpg_strerror (rc) ); + return rc; + } + secret_x_size = (nbits+7)/8; + assert( nbytes > secret_x_size ); + memmove( secret_x, secret_x+1, secret_x_size ); + memset( secret_x+secret_x_size, 0, nbytes-secret_x_size ); + + if( DBG_CIPHER ) + log_printhex ("ecdh shared secret X is:", secret_x, secret_x_size ); + } + + /*** We have now the shared secret bytes in secret_x ***/ + + /* At this point we are done with PK encryption and the rest of the function uses symmetric + * key encryption techniques to protect the input 'data'. The following two sections will + * simply replace current secret_x with a value derived from it. This will become a KEK. + */ + { + IOBUF obuf = iobuf_temp(); + rc = iobuf_write_size_body_mpi ( obuf, pkey[2] ); /* KEK params */ + + kdf_params_size = iobuf_temp_to_buffer( obuf, kdf_params, sizeof(kdf_params) ); + + if( DBG_CIPHER ) + log_printhex ("ecdh KDF public key params are:", kdf_params, kdf_params_size ); + + if( kdf_params_size != 4 || kdf_params[0] != 3 || kdf_params[1] != 1 ) /* expect 4 bytes 03 01 hash_alg symm_alg */ + return GPG_ERR_BAD_PUBKEY; + + kdf_hash_algo = kdf_params[2]; + kdf_encr_algo = kdf_params[3]; + + if( DBG_CIPHER ) + log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n", gcry_md_algo_name (kdf_hash_algo), openpgp_cipher_algo_name (kdf_encr_algo) ); + + if( kdf_hash_algo != GCRY_MD_SHA256 && kdf_hash_algo != GCRY_MD_SHA384 && kdf_hash_algo != GCRY_MD_SHA512 ) + return GPG_ERR_BAD_PUBKEY; + if( kdf_encr_algo != GCRY_CIPHER_AES128 && kdf_encr_algo != GCRY_CIPHER_AES192 && kdf_encr_algo != GCRY_CIPHER_AES256 ) + return GPG_ERR_BAD_PUBKEY; + } + + /* build kdf_params */ + { + IOBUF obuf; + + obuf = iobuf_temp(); + /* variable-length field 1, curve name OID */ + rc = iobuf_write_size_body_mpi ( obuf, pkey[0] ); + /* fixed-length field 2 */ + iobuf_put (obuf, PUBKEY_ALGO_ECDH); + /* variable-length field 3, KDF params */ + rc = (rc ? rc : iobuf_write_size_body_mpi ( obuf, pkey[2] )); + /* fixed-length field 4 */ + iobuf_write (obuf, "Anonymous Sender ", 20); + /* fixed-length field 5, recipient fp */ + iobuf_write (obuf, pk_fp, 20); + + kdf_params_size = iobuf_temp_to_buffer( obuf, kdf_params, sizeof(kdf_params) ); + iobuf_close( obuf ); + if( rc ) { + return rc; + } + if( DBG_CIPHER ) + log_printhex ("ecdh KDF message params are:", kdf_params, kdf_params_size ); + } + + /* Derive a KEK (key wrapping key) using kdf_params and secret_x. */ + { + gcry_md_hd_t h; + int old_size; + + rc = gcry_md_open (&h, kdf_hash_algo, 0); + if(rc) + log_bug ("gcry_md_open failed for algo %d: %s", + kdf_hash_algo, gpg_strerror (gcry_error(rc))); + gcry_md_write(h, "\x00\x00\x00\x01", 4); /* counter = 1 */ + gcry_md_write(h, secret_x, secret_x_size); /* x of the point X */ + gcry_md_write(h, kdf_params, kdf_params_size); /* KDF parameters */ + + gcry_md_final (h); + + assert( gcry_md_get_algo_dlen (kdf_hash_algo) >= 32 ); + + memcpy (secret_x, gcry_md_read (h, kdf_hash_algo), gcry_md_get_algo_dlen (kdf_hash_algo)); + gcry_md_close (h); + + old_size = secret_x_size; + assert( old_size >= gcry_cipher_get_algo_keylen( kdf_encr_algo ) ); + secret_x_size = gcry_cipher_get_algo_keylen( kdf_encr_algo ); + assert( secret_x_size <= gcry_md_get_algo_dlen (kdf_hash_algo) ); + + memset( secret_x+secret_x_size, old_size-secret_x_size, 0 ); /* we could have allocated more, so clean the tail before returning */ + if( DBG_CIPHER ) + log_printhex ("ecdh KEK is:", secret_x, secret_x_size ); + } + + /* And, finally, aeswrap with key secret_x */ + { + gcry_cipher_hd_t hd; + size_t nbytes; + + byte *data_buf; + int data_buf_size; + + gcry_mpi_t result; + + rc = gcry_cipher_open (&hd, kdf_encr_algo, GCRY_CIPHER_MODE_AESWRAP, 0); + if (rc) + { + log_error( "ecdh failed to initialize AESWRAP: %s\n", gpg_strerror (rc)); + return rc; + } + + rc = gcry_cipher_setkey (hd, secret_x, secret_x_size); + xfree( secret_x ); + if (rc) + { + gcry_cipher_close (hd); + log_error("ecdh failed in gcry_cipher_setkey: %s\n", gpg_strerror (rc)); + return rc; + } + + data_buf_size = (gcry_mpi_get_nbits(data)+7)/8; + assert( (data_buf_size & 7) == (is_encrypt ? 0 : 1) ); + + data_buf = xmalloc_secure( 1 + 2*data_buf_size + 8 ); + if( !data_buf ) { + gcry_cipher_close (hd); + return GPG_ERR_ENOMEM; + } + + if( is_encrypt ) { + byte *in = data_buf+1+data_buf_size+8; + + /* write data MPI into the end of data_buf. data_buf is size aeswrap data */ + rc = gcry_mpi_print (GCRYMPI_FMT_USG, in, data_buf_size, &nbytes, data/*in*/); + if( rc ) { + log_error("ecdh failed to export DEK: %s\n", gpg_strerror (rc)); + gcry_cipher_close (hd); + xfree( data_buf ); + return rc; + } + + if( DBG_CIPHER ) + log_printhex ("ecdh encrypting :", in, data_buf_size ); + + rc = gcry_cipher_encrypt (hd, data_buf+1, data_buf_size+8, in, data_buf_size); + memset( in, 0, data_buf_size); + gcry_cipher_close (hd); + if(rc) + { + log_error("ecdh failed in gcry_cipher_encrypt: %s\n", gpg_strerror (rc)); + xfree( data_buf ); + return rc; + } + data_buf[0] = data_buf_size+8; + + if( DBG_CIPHER ) + log_printhex ("ecdh encrypted to:", data_buf+1, data_buf[0] ); + + rc = gcry_mpi_scan ( &result, GCRYMPI_FMT_USG, data_buf, 1+data_buf[0], NULL); /* (byte)size + aeswrap of DEK */ + xfree( data_buf ); + if(rc) + { + log_error("ecdh failed to create an MPI: %s\n", gpg_strerror (rc)); + return rc; + } + + *out = result; + } + else { + byte *in; + + rc = gcry_mpi_print (GCRYMPI_FMT_USG, data_buf, data_buf_size, &nbytes, data/*in*/); + if( nbytes != data_buf_size || data_buf[0] != data_buf_size-1 ) { + log_error("ecdh inconsistent size\n"); + xfree( data_buf ); + return GPG_ERR_BAD_MPI; + } + in = data_buf+data_buf_size; + data_buf_size = data_buf[0]; + + if( DBG_CIPHER ) + log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size ); + + rc = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1, data_buf_size ); + gcry_cipher_close (hd); + if(rc) + { + log_error("ecdh failed in gcry_cipher_decrypt: %s\n", gpg_strerror (rc)); + xfree( data_buf ); + return rc; + } + + data_buf_size-=8; + + if( DBG_CIPHER ) + log_printhex ("ecdh decrypted to :", in, data_buf_size ); + + /* padding is removed later */ + //if( in[data_buf_size-1] > 8 ) { + // log_error("ecdh failed at decryption: invalid padding. %02x > 8\n", in[data_buf_size-1] ); + // return GPG_ERR_BAD_KEY; + //} + + rc = gcry_mpi_scan ( &result, GCRYMPI_FMT_USG, in, data_buf_size, NULL); + xfree( data_buf ); + if(rc) + { + log_error("ecdh failed to create a plain text MPI: %s\n", gpg_strerror (rc)); + return rc; + } + + *out = result; + } + } + + return rc; +} + +/* Perform ECDH encryption, which involves ECDH key generation. + */ +int +pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t * pkey) +{ + gcry_sexp_t s_ciph, s_data, s_pkey; + + PKT_public_key *pk_eph; + int nbits; + int rc; + + nbits = pubkey_nbits( PUBKEY_ALGO_ECDH, pkey ); + + /*** Generate an ephemeral key ***/ + + rc = pk_ecc_keypair_gen( &pk_eph, PUBKEY_ALGO_ECDH, KEYGEN_FLAG_TRANSIENT_KEY | KEYGEN_FLAG_NO_PROTECTION /*this is ephemeral*/, "", nbits ); + if( rc ) + return rc; + if( DBG_CIPHER ) { + unsigned char *buffer; + if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, pk_eph->pkey[1])) + BUG (); + log_debug("ephemeral key MPI #0: %s\n", buffer); + gcry_free( buffer ); + } + free_public_key (pk_eph); + + /*** Done with ephemeral key generation. + * Now use ephemeral secret to get the shared secret. ***/ + + rc = gcry_sexp_build (&s_pkey, NULL, + "(public-key(ecdh(c%m)(q%m)(p%m)))", pkey[0], pkey[1], pkey[2]); + if (rc) + BUG (); + + /* put the data into a simple list */ + if (gcry_sexp_build (&s_data, NULL, "%m", pk_eph->pkey[3])) /* ephemeral scalar goes as data */ + BUG (); + + /* pass it to libgcrypt */ + rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); + gcry_sexp_release (s_data); + gcry_sexp_release (s_pkey); + if (rc) + return rc; + + /* finally, perform encryption */ + + { + gcry_mpi_t shared = mpi_from_sexp (s_ciph, "a"); /* ... and get the shared point */ + gcry_sexp_release (s_ciph); + resarr[0] = pk_eph->pkey[1]; /* ephemeral public key */ + + if( DBG_CIPHER ) { + unsigned char *buffer; + if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, resarr[0])) + BUG (); + log_debug("ephemeral key MPI: %s\n", buffer); + gcry_free( buffer ); + } + + rc = pk_ecdh_encrypt_with_shared_point ( 1 /*=encrypton*/, shared, pk_fp, data, pkey, resarr+1 ); + mpi_release( shared ); + } + + return rc; +} + +/* Perform ECDH decryption. + */ +int +pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t *data, gcry_mpi_t * skey) { + gcry_sexp_t s_skey, s_data, s_ciph; + int rc; + + if (!data[0] || !data[1]) + return gpg_error (GPG_ERR_BAD_MPI); + + rc = gcry_sexp_build (&s_skey, NULL, + "(public-key(ecdh(c%m)(q%m)(p%m)))", + skey[0]/*curve*/, data[0]/*ephemeral key*/, skey[2]/*KDF params*/); + if (rc) + BUG (); + + /* put the data into a simple list */ + if (gcry_sexp_build (&s_data, NULL, "%m", skey[3])) /* static private key (scalar) goes as data */ + BUG (); + + rc = gcry_pk_encrypt (&s_ciph, s_data, s_skey); /* encrypting ephemeral key with our private scalar yields the shared point */ + gcry_sexp_release (s_skey); + gcry_sexp_release (s_data); + if (rc) + return rc; + + { + gcry_mpi_t shared = mpi_from_sexp (s_ciph, "a"); /* get the shared point */ + gcry_sexp_release (s_ciph); + rc = pk_ecdh_encrypt_with_shared_point ( 0 /*=decryption*/, shared, sk_fp, data[1]/*encr data as an MPI*/, skey, result ); + mpi_release( shared ); + } + + return rc; +} + + diff --git a/g10/encrypt.c b/g10/encrypt.c index 55f9b27fb..3c16309d0 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -876,7 +876,9 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out) for ( ; pk_list; pk_list = pk_list->next ) { gcry_mpi_t frame; - + byte fp[MAX_FINGERPRINT_LEN]; + size_t fpn; + pk = pk_list->pk; print_pubkey_algo_note ( pk->pubkey_algo ); @@ -892,6 +894,9 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out) compliance_failure(); } + fingerprint_from_pk( pk, fp, &fpn ); + assert( fpn == 20 ); + /* Okay, what's going on: We have the session key somewhere in * the structure DEK and want to encode this session key in an * integer value of n bits. pubkey_nbits gives us the number of @@ -904,9 +909,9 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out) * for Elgamal). We don't need frame anymore because we have * everything now in enc->data which is the passed to * build_packet(). */ - frame = encode_session_key (dek, + frame = encode_session_key (pk->pubkey_algo, dek, pubkey_nbits (pk->pubkey_algo, pk->pkey)); - rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, pk->pkey); + rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, fp, pk->pkey); gcry_mpi_release (frame); if (rc) log_error ("pubkey_encrypt failed: %s\n", gpg_strerror (rc) ); diff --git a/g10/export.c b/g10/export.c index 91c6a73d7..82d97511f 100644 --- a/g10/export.c +++ b/g10/export.c @@ -1161,6 +1161,18 @@ build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent) /* iobuf_put (out,')'); iobuf_put (out,'\n'); */ /* (*indent)--; */ /* } */ +/* + else if (sk->pubkey_algo == PUBKEY_ALGO_ECDSA && !sk->is_protected) + { + write_sexp_line (out, indent, "(ecdsa\n"); + (*indent)++; + write_sexp_keyparm (out, indent, "c", sk->skey[0]); iobuf_put (out,'\n'); + write_sexp_keyparm (out, indent, "q", sk->skey[6]); iobuf_put (out,'\n'); + write_sexp_keyparm (out, indent, "d", sk->skey[7]); + iobuf_put (out,')'); iobuf_put (out,'\n'); + (*indent)--; + } +*/ /* else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected) */ /* { */ /* write_sexp_line (out, indent, "(elg\n"); */ diff --git a/g10/getkey.c b/g10/getkey.c index f114920d2..65f5829dc 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -138,7 +138,10 @@ cache_public_key (PKT_public_key * pk) return; if (is_ELGAMAL (pk->pubkey_algo) - || pk->pubkey_algo == PUBKEY_ALGO_DSA || is_RSA (pk->pubkey_algo)) + || pk->pubkey_algo == PUBKEY_ALGO_DSA + || pk->pubkey_algo == PUBKEY_ALGO_ECDSA + || pk->pubkey_algo == PUBKEY_ALGO_ECDH + || is_RSA (pk->pubkey_algo)) { keyid_from_pk (pk, keyid); } diff --git a/g10/gpg.c b/g10/gpg.c index 4a17b2905..23b193402 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -813,7 +813,7 @@ my_strusage( int level ) const char *p; switch( level ) { - case 11: p = "gpg (GnuPG)"; + case 11: p = "gpg (GnuPG) ecc"; break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; @@ -857,7 +857,7 @@ my_strusage( int level ) case 34: if (!pubkeys) pubkeys = build_list (_("Pubkey: "), 0, - gcry_pk_algo_name, + openpgp_pk_algo_name, openpgp_pk_test_algo ); p = pubkeys; break; 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); diff --git a/g10/keyid.c b/g10/keyid.c index 62ce03685..2a9bd1988 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -57,6 +57,8 @@ pubkey_letter( int algo ) case PUBKEY_ALGO_ELGAMAL_E: return 'g'; case PUBKEY_ALGO_ELGAMAL: return 'G' ; case PUBKEY_ALGO_DSA: return 'D' ; + case PUBKEY_ALGO_ECDSA: return 'E' ; // ECC DSA (sign only) + case PUBKEY_ALGO_ECDH: return 'e' ; // ECC DH (encrypt only) default: return '?'; } } @@ -74,6 +76,8 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) unsigned int nbits; size_t nbytes; int npkey = pubkey_get_npkey (pk->pubkey_algo); + /* name OID, MPI of public point, [for ECDH only: KEK params] */ + enum gcry_mpi_format ecc_pub_format[3] = {GCRYMPI_FMT_USG, GCRYMPI_FMT_PGP, GCRYMPI_FMT_USG}; /* Two extra bytes for the expiration date in v3 */ if(pk->version<4) @@ -90,11 +94,13 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) { for(i=0; i < npkey; i++ ) { - if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, pk->pkey[i])) + const enum gcry_mpi_format fmt = + ((pk->pubkey_algo==PUBKEY_ALGO_ECDSA || pk->pubkey_algo==PUBKEY_ALGO_ECDH) ? ecc_pub_format[i] : GCRYMPI_FMT_PGP); + + if (gcry_mpi_print (fmt, NULL, 0, &nbytes, pk->pkey[i])) BUG (); pp[i] = xmalloc (nbytes); - if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes, - &nbytes, pk->pkey[i])) + if (gcry_mpi_print (fmt, pp[i], nbytes, &nbytes, pk->pkey[i])) BUG (); nn[i] = nbytes; n += nn[i]; @@ -712,6 +718,20 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array) pk->pkey[0], pk->pkey[1]); break; + case PUBKEY_ALGO_ECDSA: + case PUBKEY_ALGO_ECDH: + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(ecc(c%m)(q%m)))", + pk->pkey[0], pk->pkey[1]); + break; +/* + case PUBKEY_ALGO_ECDH: + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(ecdh(c%m)(q%m)(p%m)))", + pk->pkey[0], pk->pkey[1], pk->pkey[2]); + break; +*/ + default: err = gpg_error (GPG_ERR_PUBKEY_ALGO); break; diff --git a/g10/main.h b/g10/main.h index b673cf559..e336e5ce6 100644 --- a/g10/main.h +++ b/g10/main.h @@ -93,11 +93,12 @@ int map_cipher_openpgp_to_gcry (int algo); int openpgp_cipher_blocklen (int algo); int openpgp_cipher_test_algo( int algo ); const char *openpgp_cipher_algo_name (int algo); +int map_pk_openpgp_to_gcry (int algo); int openpgp_pk_test_algo( int algo ); int openpgp_pk_test_algo2 ( int algo, unsigned int use ); int openpgp_pk_algo_usage ( int algo ); -const char *openpgp_pk_algo_name (int algo); int openpgp_md_test_algo( int algo ); +const char *openpgp_pk_algo_name (int algo); const char *openpgp_md_algo_name (int algo); #ifdef USE_IDEA @@ -157,6 +158,10 @@ int pubkey_get_nsig( int algo ); int pubkey_get_nenc( int algo ); unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey ); int mpi_print (estream_t stream, gcry_mpi_t a, int mode); +int iobuf_write_size_body_mpi (iobuf_t out, gcry_mpi_t a); +int iobuf_read_size_body(iobuf_t inp, byte *body, int body_max_size, int pktlen, gcry_mpi_t *out); + +int ecdsa_qbits_from_Q( int qbits ); /*-- status.c --*/ void set_status_fd ( int fd ); @@ -251,6 +256,10 @@ gpg_error_t generate_card_subkeypair (kbnode_t pub_keyblock, int save_unprotected_key_to_card (PKT_public_key *sk, int keyno); #endif +#define KEYGEN_FLAG_NO_PROTECTION 1 +#define KEYGEN_FLAG_TRANSIENT_KEY 2 +int pk_ecc_keypair_gen( PKT_public_key **pk_out, int algo, int keygen_flags, char **cache_nonce_addr, unsigned nbits); + /*-- openfile.c --*/ int overwrite_filep( const char *fname ); char *make_outfile_name( const char *iname ); @@ -261,7 +270,7 @@ void try_make_homedir( const char *fname ); /*-- seskey.c --*/ void make_session_key( DEK *dek ); -gcry_mpi_t encode_session_key( DEK *dek, unsigned nbits ); +gcry_mpi_t encode_session_key( int openpgp_pk_algo, DEK *dek, unsigned nbits ); gcry_mpi_t encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo ); diff --git a/g10/mainproc.c b/g10/mainproc.c index 72cefce43..dcbc4b45a 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -384,6 +384,8 @@ proc_pubkey_enc( CTX c, PACKET *pkt ) } else if( is_ELGAMAL(enc->pubkey_algo) || enc->pubkey_algo == PUBKEY_ALGO_DSA + || enc->pubkey_algo == PUBKEY_ALGO_ECDSA + || enc->pubkey_algo == PUBKEY_ALGO_ECDH || is_RSA(enc->pubkey_algo) || enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL) { /* Note that we also allow type 20 Elgamal keys for decryption. @@ -450,7 +452,7 @@ print_pkenc_list( struct kidlist_item *list, int failed ) if ( !failed && list->reason ) continue; - algstr = gcry_pk_algo_name ( list->pubkey_algo ); + algstr = openpgp_pk_algo_name ( list->pubkey_algo ); pk = xmalloc_clear( sizeof *pk ); if( !algstr ) @@ -1616,7 +1618,7 @@ check_sig_and_print( CTX c, KBNODE node ) /* (Indendation below not yet changed to GNU style.) */ - astr = gcry_pk_algo_name ( sig->pubkey_algo ); + astr = openpgp_pk_algo_name ( sig->pubkey_algo ); if(keystrlen()>8) { log_info(_("Signature made %s\n"),asctimestamp(sig->timestamp)); diff --git a/g10/misc.c b/g10/misc.c index 1725258c5..a09636b60 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -64,6 +64,7 @@ #include "call-agent.h" #include "i18n.h" +#include static int string_count_chr (const char *string, int c) @@ -294,7 +295,7 @@ print_pubkey_algo_note( int algo ) { warn=1; log_info (_("WARNING: using experimental public key algorithm %s\n"), - gcry_pk_algo_name (algo)); + openpgp_cipher_algo_name (algo)); } } else if (algo == 20) @@ -365,6 +366,12 @@ map_cipher_gcry_to_openpgp (int algo) } } +int +map_pk_openpgp_to_gcry (int algo) +{ + return (algo==PUBKEY_ALGO_ECDSA ? GCRY_PK_ECDSA : (algo==PUBKEY_ALGO_ECDH ? GCRY_PK_ECDH : algo)); +} + /* Return the block length of an OpenPGP cipher algorithm. */ int @@ -409,7 +416,13 @@ openpgp_cipher_test_algo( int algo ) const char * openpgp_cipher_algo_name (int algo) { - return gnupg_cipher_algo_name (map_cipher_openpgp_to_gcry (algo)); + return gcry_cipher_algo_name (map_cipher_openpgp_to_gcry (algo)); +} + +const char * +openpgp_pk_algo_name (int algo) +{ + return gcry_pk_algo_name ( algo == PUBKEY_ALGO_ECDSA ? GCRY_PK_ECDSA : ( algo == PUBKEY_ALGO_ECDH ? GCRY_PK_ECDH : algo ) ); } int @@ -424,7 +437,13 @@ openpgp_pk_test_algo( int algo ) if (algo < 0 || algo > 110) return gpg_error (GPG_ERR_PUBKEY_ALGO); - return gcry_pk_test_algo (algo); + + if( algo == PUBKEY_ALGO_ECDSA ) + algo = GCRY_PK_ECDSA; + else if( algo == PUBKEY_ALGO_ECDH ) + algo = GCRY_PK_ECDH; + + return gcry_pk_test_algo ( algo ); } int @@ -442,7 +461,12 @@ openpgp_pk_test_algo2( int algo, unsigned int use ) if (algo < 0 || algo > 110) return gpg_error (GPG_ERR_PUBKEY_ALGO); - return gcry_pk_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, &use_buf); + if( algo == PUBKEY_ALGO_ECDSA ) + algo = GCRY_PK_ECDSA; + else if( algo == PUBKEY_ALGO_ECDH ) + algo = GCRY_PK_ECDH; + + return gcry_pk_algo_info ( algo, GCRYCTL_TEST_ALGO, NULL, &use_buf); } int @@ -457,6 +481,7 @@ openpgp_pk_algo_usage ( int algo ) | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH); break; case PUBKEY_ALGO_RSA_E: + case PUBKEY_ALGO_ECDH: use = PUBKEY_USAGE_ENC; break; case PUBKEY_ALGO_RSA_S: @@ -472,6 +497,8 @@ openpgp_pk_algo_usage ( int algo ) case PUBKEY_ALGO_DSA: use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH; break; + case PUBKEY_ALGO_ECDSA: + use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH; default: break; } @@ -480,7 +507,7 @@ openpgp_pk_algo_usage ( int algo ) /* Map the OpenPGP pubkey algorithm whose ID is contained in ALGO to a string representation of the algorithm name. For unknown algorithm - IDs this function returns "?". */ + IDs this function returns "?". const char * openpgp_pk_algo_name (int algo) { @@ -498,6 +525,7 @@ openpgp_pk_algo_name (int algo) default: return "?"; } } +*/ int @@ -1348,6 +1376,10 @@ pubkey_get_npkey( int algo ) if (algo == GCRY_PK_ELG_E) algo = GCRY_PK_ELG; + else if (algo == PUBKEY_ALGO_ECDSA) + algo = GCRY_PK_ECDSA; + else if (algo == PUBKEY_ALGO_ECDH) + algo = GCRY_PK_ECDH; if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &n)) n = 0; return n; @@ -1361,6 +1393,10 @@ pubkey_get_nskey( int algo ) if (algo == GCRY_PK_ELG_E) algo = GCRY_PK_ELG; + else if (algo == PUBKEY_ALGO_ECDSA) + algo = GCRY_PK_ECDSA; + else if (algo == PUBKEY_ALGO_ECDH) + algo = GCRY_PK_ECDH; if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &n )) n = 0; return n; @@ -1374,6 +1410,10 @@ pubkey_get_nsig( int algo ) if (algo == GCRY_PK_ELG_E) algo = GCRY_PK_ELG; + else if (algo == PUBKEY_ALGO_ECDSA) + algo = GCRY_PK_ECDSA; + else if (algo == PUBKEY_ALGO_ECDH) + algo = GCRY_PK_ECDH; if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSIGN, NULL, &n)) n = 0; return n; @@ -1387,6 +1427,10 @@ pubkey_get_nenc( int algo ) if (algo == GCRY_PK_ELG_E) algo = GCRY_PK_ELG; + else if (algo == PUBKEY_ALGO_ECDSA) + algo = GCRY_PK_ECDSA; + else if (algo == PUBKEY_ALGO_ECDH) + algo = GCRY_PK_ECDH; if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NENCR, NULL, &n )) n = 0; return n; @@ -1400,6 +1444,8 @@ pubkey_nbits( int algo, gcry_mpi_t *key ) int rc, nbits; gcry_sexp_t sexp; + assert( algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH ); + if( algo == GCRY_PK_DSA ) { rc = gcry_sexp_build ( &sexp, NULL, "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", @@ -1415,6 +1461,11 @@ pubkey_nbits( int algo, gcry_mpi_t *key ) "(public-key(rsa(n%m)(e%m)))", key[0], key[1] ); } + else if( algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH ) { + rc = gcry_sexp_build ( &sexp, NULL, + "(public-key(ecc(c%m)(q%m)))", + key[0], key[1] /* not affecting the size calculation, so use 'ecc' == 'ecdsa' */ ); + } else return 0; @@ -1455,3 +1506,89 @@ mpi_print (estream_t fp, gcry_mpi_t a, int mode) return n; } +/* + * Write a special size+body mpi a, to OUT. The format of the content of the MPI is + * one byte LEN, following by LEN bytes + */ +int +iobuf_write_size_body_mpi (iobuf_t out, gcry_mpi_t a) +{ + byte buffer[256]; /* Fixed buffer for a public parameter, max possible */ + size_t nbytes = (mpi_get_nbits (a)+7)/8; + int rc; + + if( nbytes > sizeof(buffer) ) { + log_error("mpi with size+body is too large (%u bytes)\n", nbytes); + return gpg_error (GPG_ERR_TOO_LARGE); + } + + rc = gcry_mpi_print (GCRYMPI_FMT_USG, buffer, sizeof(buffer), &nbytes, a); + if( rc ) { + log_error("Failed to exported size+body mpi\n"); + return rc; + } + if( nbytes < 2 || buffer[0] != nbytes-1 ) { + if( nbytes > 2 ) + log_error("Internal size mismatch in mpi size+body: %02x != %02x (other bytes: %02x %02x ... %02x %02x)\n", + buffer[0], nbytes-1, buffer[1], buffer[2], buffer[nbytes-2], buffer[nbytes-1]); + else + log_error("Internal size mismatch in mpi size+body: only %d bytes\n", nbytes ); + return gpg_error (GPG_ERR_INV_DATA); + } + return iobuf_write( out, buffer, nbytes ); +} + +/* + * Read a special size+body from inp into body[body_max_size] and return it in a buffer and as MPI. + * On success the number of consumed bytes will body[0]+1. + * The format of the content of the returned MPI is one byte LEN, following by LEN bytes. + * Caller is expected to pre-allocate fixed-size 255 byte buffer (or smaller when appropriate). + */ +int +iobuf_read_size_body( iobuf_t inp, byte *body, int body_max_size, int pktlen, gcry_mpi_t *out ) { + unsigned n; + int rc; + gcry_mpi_t result; + + *out = NULL; + + if( (n = iobuf_readbyte(inp)) == -1 ) { + return G10ERR_INVALID_PACKET; + } + if( n >= body_max_size || n < 2) { + log_error("invalid size+body field\n"); + return G10ERR_INVALID_PACKET; + } + body[0] = n; + if( (n = iobuf_read(inp, body+1, n)) == -1 ) { + log_error("invalid size+body field\n"); + return G10ERR_INVALID_PACKET; + } + if( n+1 > pktlen ) { + log_error("size+body field is larger than the packet\n"); + return G10ERR_INVALID_PACKET; + } + rc = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, body, n+1, NULL); + if (rc) + log_fatal ("mpi_scan failed: %s\n", gpg_strerror (rc)); + + *out = result; + + return rc; +} + + +/* pkey[1] or skey[1] is Q for ECDSA, which is an uncompressed point, i.e. 04 */ +int ecdsa_qbits_from_Q( int qbits ) { + if( qbits%8>3 ) { + log_error(_("ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n")); + return 0; + } + qbits -= qbits%8; + qbits /= 2; + return qbits; +} + + + + diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 3714739d4..42d680ac5 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -939,20 +939,40 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, } else { - for (i = 0; i < ndata; i++) - { - n = pktlen; - k->data[i] = mpi_read (inp, &n, 0); - pktlen -= n; - if (list_mode) - { - es_fprintf (listfp, "\tdata: "); - mpi_print (listfp, k->data[i], mpi_print_mode); - es_putc ('\n', listfp); - } - if (!k->data[i]) - rc = gpg_error (GPG_ERR_INV_PACKET); - } + if( k->pubkey_algo != PUBKEY_ALGO_ECDH ) { + for (i = 0; i < ndata; i++) + { + n = pktlen; + k->data[i] = mpi_read (inp, &n, 0); + pktlen -= n; + if (list_mode) + { + es_fprintf (listfp, "\tdata: "); + mpi_print (listfp, k->data[i], mpi_print_mode); + es_putc ('\n', listfp); + } + if (!k->data[i]) + rc = gpg_error (GPG_ERR_INV_PACKET); + } + } + else + { + byte encr_buf[255]; + assert( ndata == 2 ); + n = pktlen; k->data[0] = mpi_read(inp, &n, 0); pktlen -=n; + rc = iobuf_read_size_body( inp, encr_buf, sizeof(encr_buf), pktlen, k->data+1 ); + if( rc ) + goto leave; + if( list_mode ) { + es_fprintf (listfp, "\tdata: "); + mpi_print(listfp, k->data[0], mpi_print_mode ); + es_putc ('\n', listfp); + es_fprintf (listfp, "\tdata: [% 3d bytes] ", encr_buf[0]); + mpi_print(listfp, k->data[1], mpi_print_mode ); + es_putc ('\n', listfp); + } + pktlen -= (encr_buf[0]+1); + } } leave: @@ -1926,20 +1946,61 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, else { /* Fill in public key parameters. */ - for (i = 0; i < npkey; i++) - { - n = pktlen; - pk->pkey[i] = mpi_read (inp, &n, 0); - pktlen -= n; - if (list_mode) - { - es_fprintf (listfp, "\tpkey[%d]: ", i); - mpi_print (listfp, pk->pkey[i], mpi_print_mode); - es_putc ('\n', listfp); + if( algorithm != PUBKEY_ALGO_ECDSA && algorithm != PUBKEY_ALGO_ECDH ) { + for (i = 0; i < npkey; i++) + { + n = pktlen; + pk->pkey[i] = mpi_read (inp, &n, 0); + pktlen -= n; + if (list_mode) + { + es_fprintf (listfp, "\tpkey[%d]: ", i); + mpi_print (listfp, pk->pkey[i], mpi_print_mode); + es_putc ('\n', listfp); + } + if (!pk->pkey[i]) + err = gpg_error (GPG_ERR_INV_PACKET); + } + } + else { + /* note that the code in this function ignores the errors */ + byte name_oid[256]; + err = iobuf_read_size_body( inp, name_oid, sizeof(name_oid), pktlen, pk->pkey+0 ); + if( err ) + goto leave; + n = name_oid[0]; + if( list_mode ) + es_fprintf (listfp, "\tpkey[0]: curve OID [%d] ...%02x %02x\n", + n, name_oid[1+n-2], name_oid[1+n-1] ); + pktlen -= (n+1); + /* set item [1], which corresponds to the public key; these two fields are all we need to uniquely define the key */ + // log_debug("Parsing ecc public key in the public packet, pktlen=%lu\n", pktlen); + n = pktlen; pk->pkey[1] = mpi_read( inp, &n, 0 ); pktlen -=n; + if( pk->pkey[1]==NULL ) + err = gpg_error(G10ERR_INVALID_PACKET); + else if( list_mode ) { + es_fprintf (listfp, "\tpkey[1]: "); + mpi_print(listfp, pk->pkey[1], mpi_print_mode); + es_putc ('\n', listfp); } - if (!pk->pkey[i]) - err = gpg_error (GPG_ERR_INV_PACKET); - } + /* One more field for ECDH */ + if( algorithm == PUBKEY_ALGO_ECDH ) { +#define kek_params name_oid + err = iobuf_read_size_body( inp, kek_params, sizeof(kek_params), pktlen, pk->pkey+2 ); + if( err ) + goto leave; + n = kek_params[0]; + if( kek_params[1] != 1 ) { + log_error("invalid ecdh KEK parameters field type in private key: understand type 1, but found 0x%02x\n", kek_params[1]); + err = gpg_error(G10ERR_INVALID_PACKET); + goto leave; + } + if( list_mode ) + es_fprintf (listfp, "\tpkey[2]: KEK params type=01 hash:%d sym-algo:%d\n", kek_params[1+n-2], kek_params[1+n-1] ); + pktlen -= (n+1); +#undef kek_params + } + } if (err) goto leave; } diff --git a/g10/passphrase.c b/g10/passphrase.c index 9f1218b6b..f29fca72f 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -323,7 +323,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, { char *uid; size_t uidlen; - const char *algo_name = gcry_pk_algo_name ( pk->pubkey_algo ); + const char *algo_name = openpgp_pk_algo_name ( pk->pubkey_algo ); const char *timestr; char *maink; @@ -585,7 +585,7 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, if ( !get_pubkey( pk, keyid ) ) { - const char *s = gcry_pk_algo_name ( pk->pubkey_algo ); + const char *s = openpgp_pk_algo_name ( pk->pubkey_algo ); tty_printf (_("%u-bit %s key, ID %s, created %s"), nbits_from_pk( pk ), s?s:"?", keystr(keyid), @@ -690,7 +690,7 @@ gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped) char *desc; const char *prompt; - algo_name = gcry_pk_algo_name (pk->pubkey_algo); + algo_name = openpgp_pk_algo_name (pk->pubkey_algo); timestr = strtimestamp (pk->timestamp); uid = get_user_id (pk->keyid, &uidlen); diff --git a/g10/pkglue.c b/g10/pkglue.c index 14a27535f..f78591940 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -27,9 +27,10 @@ #include "gpg.h" #include "util.h" #include "pkglue.h" +#include "main.h" -static gcry_mpi_t +gcry_mpi_t mpi_from_sexp (gcry_sexp_t sexp, const char * item) { gcry_sexp_t list; @@ -44,6 +45,70 @@ mpi_from_sexp (gcry_sexp_t sexp, const char * item) } +/**************** + * Emulate our old PK interface here - sometime in the future we might + * change the internal design to directly fit to libgcrypt. + */ +int +pk_sign (int algo, gcry_mpi_t * data, gcry_mpi_t hash, gcry_mpi_t * skey) +{ + gcry_sexp_t s_sig, s_hash, s_skey; + int rc; + int gcry_pkalgo = map_pk_openpgp_to_gcry( algo ); + + /* make a sexp from skey */ + if (gcry_pkalgo == GCRY_PK_DSA) + { + rc = gcry_sexp_build (&s_skey, NULL, + "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", + skey[0], skey[1], skey[2], skey[3], skey[4]); + } + else if (gcry_pkalgo == GCRY_PK_RSA || gcry_pkalgo == GCRY_PK_RSA_S) + { + rc = gcry_sexp_build (&s_skey, NULL, + "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", + skey[0], skey[1], skey[2], skey[3], skey[4], + skey[5]); + } + else if (gcry_pkalgo == GCRY_PK_ELG || gcry_pkalgo == GCRY_PK_ELG_E) + { + rc = gcry_sexp_build (&s_skey, NULL, + "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", + skey[0], skey[1], skey[2], skey[3]); + } + else if (gcry_pkalgo == GCRY_PK_ECDSA) + { + rc = gcry_sexp_build (&s_skey, NULL, + "(private-key(ecdsa(c%m)(q%m)(d%m)))", + skey[0], skey[1], skey[2] ); + } + else + return GPG_ERR_PUBKEY_ALGO; + + if (rc) + BUG (); + + /* put hash into a S-Exp s_hash */ + if (gcry_sexp_build (&s_hash, NULL, "%m", hash)) + BUG (); + + rc = gcry_pk_sign (&s_sig, s_hash, s_skey); + gcry_sexp_release (s_hash); + gcry_sexp_release (s_skey); + + if (rc) + ; + else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S) + data[0] = mpi_from_sexp (s_sig, "s"); + else + { + data[0] = mpi_from_sexp (s_sig, "r"); + data[1] = mpi_from_sexp (s_sig, "s"); + } + + gcry_sexp_release (s_sig); + return rc; +} /**************** * Emulate our old PK interface here - sometime in the future we might @@ -54,25 +119,31 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) { gcry_sexp_t s_sig, s_hash, s_pkey; int rc; + const int gcry_pkalgo = map_pk_openpgp_to_gcry( algo ); /* make a sexp from pkey */ - if (algo == GCRY_PK_DSA) + if (gcry_pkalgo == GCRY_PK_DSA) { rc = gcry_sexp_build (&s_pkey, NULL, "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", pkey[0], pkey[1], pkey[2], pkey[3]); } - else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) + else if (gcry_pkalgo == GCRY_PK_ELG || gcry_pkalgo == GCRY_PK_ELG_E) { rc = gcry_sexp_build (&s_pkey, NULL, "(public-key(elg(p%m)(g%m)(y%m)))", pkey[0], pkey[1], pkey[2]); } - else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S) + else if (gcry_pkalgo == GCRY_PK_RSA || gcry_pkalgo == GCRY_PK_RSA_S) { rc = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]); } + else if (gcry_pkalgo == GCRY_PK_ECDSA) /* same as GCRY_PK_ECDH */ + { + rc = gcry_sexp_build (&s_pkey, NULL, + "(public-key(ecdsa(c%m)(q%m)))", pkey[0], pkey[1]); + } else return GPG_ERR_PUBKEY_ALGO; @@ -85,7 +156,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) /* Put data into a S-Exp s_sig. */ s_sig = NULL; - if (algo == GCRY_PK_DSA) + if (gcry_pkalgo == GCRY_PK_DSA) { if (!data[0] || !data[1]) rc = gpg_error (GPG_ERR_BAD_MPI); @@ -93,7 +164,15 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]); } - else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) + else if (gcry_pkalgo == GCRY_PK_ECDSA) + { + if (!data[0] || !data[1]) + rc = gpg_error (GPG_ERR_BAD_MPI); + else + rc = gcry_sexp_build (&s_sig, NULL, + "(sig-val(ecdsa(r%m)(s%m)))", data[0], data[1]); + } + else if (gcry_pkalgo == GCRY_PK_ELG || gcry_pkalgo == GCRY_PK_ELG_E) { if (!data[0] || !data[1]) rc = gpg_error (GPG_ERR_BAD_MPI); @@ -101,7 +180,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(elg(r%m)(s%m)))", data[0], data[1]); } - else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S) + else if (gcry_pkalgo == GCRY_PK_RSA || gcry_pkalgo == GCRY_PK_RSA_S) { if (!data[0]) rc = gpg_error (GPG_ERR_BAD_MPI); @@ -128,7 +207,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) * change the internal design to directly fit to libgcrypt. */ int -pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, gcry_mpi_t * pkey) +pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t * pkey) { gcry_sexp_t s_ciph, s_data, s_pkey; int rc; @@ -146,6 +225,10 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, gcry_mpi_t * pkey) "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]); } + else if (algo == PUBKEY_ALGO_ECDH) + { + return pk_ecdh_encrypt( resarr, pk_fp, data, pkey ); + } else return GPG_ERR_PUBKEY_ALGO; @@ -166,7 +249,7 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, gcry_mpi_t * pkey) else { /* add better error handling or make gnupg use S-Exp directly */ resarr[0] = mpi_from_sexp (s_ciph, "a"); - if (algo != GCRY_PK_RSA && algo != GCRY_PK_RSA_E) + if (algo != GCRY_PK_RSA && algo != GCRY_PK_RSA_E && algo != PUBKEY_ALGO_ECDH) resarr[1] = mpi_from_sexp (s_ciph, "b"); } @@ -181,7 +264,7 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, gcry_mpi_t * pkey) * change the internal design to directly fit to libgcrypt. */ int -pk_decrypt (int algo, gcry_mpi_t * result, gcry_mpi_t * data, +pk_decrypt (int algo, gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t * data, gcry_mpi_t * skey) { gcry_sexp_t s_skey, s_data, s_plain; @@ -202,6 +285,9 @@ pk_decrypt (int algo, gcry_mpi_t * result, gcry_mpi_t * data, skey[0], skey[1], skey[2], skey[3], skey[4], skey[5]); } + else if( algo == PUBKEY_ALGO_ECDH ) { + return pk_ecdh_decrypt( result, sk_fp, data, skey ); + } else return GPG_ERR_PUBKEY_ALGO; @@ -244,3 +330,48 @@ pk_decrypt (int algo, gcry_mpi_t * result, gcry_mpi_t * data, return 0; } + +/* Check whether SKEY is a suitable secret key. */ +int +pk_check_secret_key (int algo, gcry_mpi_t *skey) +{ + gcry_sexp_t s_skey; + int rc; + const int gcry_pkalgo = map_pk_openpgp_to_gcry( algo ); + + if (gcry_pkalgo == GCRY_PK_DSA) + { + rc = gcry_sexp_build (&s_skey, NULL, + "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", + skey[0], skey[1], skey[2], skey[3], skey[4]); + } + else if (gcry_pkalgo == GCRY_PK_ELG || gcry_pkalgo == GCRY_PK_ELG_E) + { + rc = gcry_sexp_build (&s_skey, NULL, + "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", + skey[0], skey[1], skey[2], skey[3]); + } + else if (gcry_pkalgo == GCRY_PK_RSA + || gcry_pkalgo == GCRY_PK_RSA_S || gcry_pkalgo == GCRY_PK_RSA_E) + { + rc = gcry_sexp_build (&s_skey, NULL, + "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", + skey[0], skey[1], skey[2], skey[3], skey[4], + skey[5]); + } + else if (gcry_pkalgo == GCRY_PK_ECDSA || gcry_pkalgo == GCRY_PK_ECDH) + { + rc = gcry_sexp_build (&s_skey, NULL, + "(private-key(ecdsa(c%m)(q%m)(d%m)))", + skey[0], skey[1], skey[2] ); + } + else + return GPG_ERR_PUBKEY_ALGO; + + if (!rc) + { + rc = gcry_pk_testkey (s_skey); + gcry_sexp_release (s_skey); + } + return rc; +} diff --git a/g10/pkglue.h b/g10/pkglue.h index f97def153..0d5194818 100644 --- a/g10/pkglue.h +++ b/g10/pkglue.h @@ -20,13 +20,23 @@ #ifndef GNUPG_G10_PKGLUE_H #define GNUPG_G10_PKGLUE_H +gcry_mpi_t mpi_from_sexp (gcry_sexp_t sexp, const char * item); + +int pk_sign (int algo, gcry_mpi_t *data, gcry_mpi_t hash, + gcry_mpi_t *skey); int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey); int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, + const byte fp[MAX_FINGERPRINT_LEN], gcry_mpi_t *pkey); -int pk_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data, +int pk_decrypt (int algo, gcry_mpi_t *result, const byte fp[MAX_FINGERPRINT_LEN], gcry_mpi_t *data, gcry_mpi_t *skey); int pk_check_secret_key (int algo, gcry_mpi_t *skey); +int pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t * pkey); +int pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t *data, gcry_mpi_t * skey); + +gcry_mpi_t pk_ecdh_default_params_to_mpi( int qbits ); +byte *pk_ecdh_default_params( int qbits, size_t *sizeout ); #endif /*GNUPG_G10_PKGLUE_H*/ diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 312b591e9..a5224e20a 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -145,6 +145,8 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) gcry_sexp_t s_data; char *desc; char *keygrip; + byte fp[MAX_FINGERPRINT_LEN]; + size_t fpn; /* Get the keygrip. */ err = hexkeygrip_from_pk (sk, &keygrip); @@ -174,9 +176,12 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) if (err) goto leave; + fingerprint_from_pk( sk, fp, &fpn ); + assert( fpn == 20 ); + /* Decrypt. */ desc = gpg_format_keydesc (sk, 0, 1); - err = agent_pkdecrypt (NULL, keygrip, desc, s_data, &frame, &nframe); + err = agent_pkdecrypt (NULL, keygrip, desc, s_data, fp, &frame, &nframe); xfree (desc); gcry_sexp_release (s_data); if (err) @@ -202,28 +207,41 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) if (DBG_CIPHER) log_printhex ("DEK frame:", frame, nframe); n = 0; - if (!card) - { - if (n + 7 > nframe) - { - err = gpg_error (G10ERR_WRONG_SECKEY); - goto leave; - } - if (frame[n] == 1 && frame[nframe - 1] == 2) - { - log_info (_("old encoding of the DEK is not supported\n")); - err = gpg_error (G10ERR_CIPHER_ALGO); - goto leave; - } - if (frame[n] != 2) /* Something went wrong. */ - { - err = gpg_error (G10ERR_WRONG_SECKEY); - goto leave; - } - for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes. */ - ; - n++; /* Skip the zero byte. */ + + if( sk->pubkey_algo != PUBKEY_ALGO_ECDH ) { + if (!card) + { + if (n + 7 > nframe) + { + err = gpg_error (G10ERR_WRONG_SECKEY); + goto leave; + } + if (frame[n] == 1 && frame[nframe - 1] == 2) + { + log_info (_("old encoding of the DEK is not supported\n")); + err = gpg_error (G10ERR_CIPHER_ALGO); + goto leave; + } + if (frame[n] != 2) /* Something went wrong. */ + { + err = gpg_error (G10ERR_WRONG_SECKEY); + goto leave; + } + for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes. */ + ; + n++; /* Skip the zero byte. */ + } + } + else { + /* Allow double padding for the benefit of DEK size concealment. + * Higher than this is wasteful. + */ + if( frame[nframe-1] > 8*2 || nframe <= 8 ) { + err = G10ERR_WRONG_SECKEY; goto leave; } + nframe -= frame[nframe-1]; /* remove padding */ + assert( n==0 ); /* used just bellow */ + } if (n + 4 > nframe) { diff --git a/g10/seskey.c b/g10/seskey.c index ee5584c66..4cc9158c9 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -27,6 +27,7 @@ #include "gpg.h" #include "util.h" #include "cipher.h" +#include "options.h" #include "main.h" #include "i18n.h" @@ -73,15 +74,48 @@ make_session_key( DEK *dek ) * returns: A mpi with the session key (caller must free) */ gcry_mpi_t -encode_session_key (DEK *dek, unsigned int nbits) +encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) { size_t nframe = (nbits+7) / 8; byte *p; byte *frame; int i,n; - u16 csum; + u16 csum = 0; gcry_mpi_t a; + if( DBG_CIPHER ) + log_debug("encode_session_key: encoding %d byte DEK", dek->keylen); + + for( p = dek->key, i=0; i < dek->keylen; i++ ) + csum += *p++; + + /* Shortcut for ECDH. It's padding is minimal to simply make the output be a multiple of 8 bytes. */ + if( openpgp_pk_algo == PUBKEY_ALGO_ECDH ) { + /* pad to 8 byte granulatiry; the padding byte is the number of padded bytes. + * A DEK(k bytes) CSUM(2 bytes) 0x 0x 0x 0x ... 0x + * +---- x times ---+ + */ + nframe = ( 1 + dek->keylen + 2 /* the value so far is always odd */ + 7 ) & (~7); + assert( !(nframe%8) && nframe > 1 + dek->keylen + 2 ); /* alg+key+csum fit and the size is congruent to 8 */ + frame = xmalloc_secure( nframe ); + n = 0; + frame[n++] = dek->algo; + memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen; + frame[n++] = csum >>8; + frame[n++] = csum; + i = nframe - n; /* number padded bytes */ + memset( frame+n, i, i );/* use it as the value of each padded byte */ + assert( n+i == nframe ); + + if( DBG_CIPHER ) + log_debug("encode_session_key: [%d] %02x %02x %02x ... %02x %02x %02x", nframe, frame[0],frame[1],frame[2], frame[nframe-3],frame[nframe-2],frame[nframe-1]); + + if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, nframe, &nframe)) + BUG(); + xfree(frame); + return a; + } + /* The current limitation is that we can only use a session key * whose length is a multiple of BITS_PER_MPI_LIMB * I think we can live with that. @@ -103,9 +137,6 @@ encode_session_key (DEK *dek, unsigned int nbits) * cipher algorithm (20 is used with blowfish160). * CSUM is the 16 bit checksum over the DEK */ - csum = 0; - for( p = dek->key, i=0; i < dek->keylen; i++ ) - csum += *p++; frame = xmalloc_secure( nframe ); n = 0; @@ -161,8 +192,8 @@ do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits, gcry_mpi_t a; if( len + asnlen + 4 > nframe ) - log_bug("can't encode a %d bit MD into a %d bits frame\n", - (int)(len*8), (int)nbits); + log_bug("can't encode a %d bit MD into a %d bits frame, algo=%d\n", + (int)(len*8), (int)nbits, algo); /* We encode the MD in this way: * @@ -209,16 +240,23 @@ gcry_mpi_t encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) { gcry_mpi_t frame; + int gcry_pkalgo; assert (hash_algo); assert (pk); - if (pk->pubkey_algo == GCRY_PK_DSA) + gcry_pkalgo = map_pk_openpgp_to_gcry( pk->pubkey_algo ); + + if (gcry_pkalgo == GCRY_PK_DSA || gcry_pkalgo == GCRY_PK_ECDSA ) { /* It's a DSA signature, so find out the size of q. */ size_t qbytes = gcry_mpi_get_nbits (pk->pkey[1]); + /* pkey[1] is Q for ECDSA, which is an uncompressed point, i.e. 04 */ + if( gcry_pkalgo==GCRY_PK_ECDSA ) + qbytes = ecdsa_qbits_from_Q( qbytes ); + /* Make sure it is a multiple of 8 bits. */ if(qbytes%8) @@ -236,7 +274,8 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) DSA. ;) */ if (qbytes < 160) { - log_error (_("DSA key %s uses an unsafe (%zu bit) hash\n"), + log_error (_("%s key %s uses an unsafe (%zu bit) hash\n"), + gcry_pk_algo_name( gcry_pkalgo ), keystr_from_pk (pk), qbytes); return NULL; } @@ -245,10 +284,16 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) /* Check if we're too short. Too long is safe as we'll automatically left-truncate. */ - if (gcry_md_get_algo_dlen (hash_algo) < qbytes) + /* This checks 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 will never pass for ECDSA 521 anyway as the only hash that intended to match it is SHA 512, but 512 < 521 ). + */ + //if (gcry_md_get_algo_dlen (hash_algo) < qbytes ) + if (gcry_md_get_algo_dlen (hash_algo) < ((gcry_pkalgo==GCRY_PK_ECDSA && qbytes>(521)/8) ? 512/8 : qbytes) ) { - log_error (_("DSA key %s requires a %zu bit or larger hash\n"), - keystr_from_pk(pk), qbytes*8); + log_error (_("%s key %s requires a %zu bit or larger hash, used hash-algo=%d\n"), + gcry_pk_algo_name( gcry_pkalgo ), + keystr_from_pk(pk), qbytes*8, hash_algo); return NULL; } diff --git a/g10/sign.c b/g10/sign.c index 5c00424a6..ccf796446 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -227,21 +227,6 @@ hash_sigversion_to_magic (gcry_md_hd_t md, const PKT_signature *sig) } } - -static gcry_mpi_t -mpi_from_sexp (gcry_sexp_t sexp, const char * item) -{ - gcry_sexp_t list; - gcry_mpi_t data; - - list = gcry_sexp_find_token (sexp, item, 0); - assert (list); - data = gcry_sexp_nth_mpi (list, 1, 0); - assert (data); - gcry_sexp_release (list); - return data; -} - /* Perform the sign operation. If CACHE_NONCE is given the agent is advised to use that cached passphrase fro the key. */ static int @@ -418,7 +403,7 @@ match_dsa_hash (unsigned int qbytes) if (qbytes <= 48) return DIGEST_ALGO_SHA384; - if (qbytes <= 64) + if (qbytes <= 66 ) /* 66 corresponds to 521 (64 to 512) */ return DIGEST_ALGO_SHA512; return DEFAULT_DIGEST_ALGO; @@ -451,9 +436,13 @@ hash_for (PKT_public_key *pk) { return recipient_digest_algo; } - else if (pk->pubkey_algo == PUBKEY_ALGO_DSA) + else if(pk->pubkey_algo==PUBKEY_ALGO_DSA || pk->pubkey_algo==PUBKEY_ALGO_ECDSA ) { - unsigned int qbytes = gcry_mpi_get_nbits (pk->pkey[1]) / 8; + unsigned int qbytes = gcry_mpi_get_nbits (pk->pkey[1]); + + if( pk->pubkey_algo==PUBKEY_ALGO_ECDSA ) + qbytes = ecdsa_qbits_from_Q(qbytes); + qbytes = qbytes/8; /* It's a DSA key, so find a hash that is the same size as q or larger. If q is 160, assume it is an old DSA key and use a @@ -935,10 +924,13 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_DSA) + if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_DSA || sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA ) { - int temp_hashlen = gcry_mpi_get_nbits - (sk_rover->pk->pkey[1])+7/8; + int temp_hashlen = gcry_mpi_get_nbits(sk_rover->pk->pkey[1]); + + if( sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA ) + temp_hashlen = ecdsa_qbits_from_Q( temp_hashlen ); + temp_hashlen = (temp_hashlen+7)/8; /* Pick a hash that is large enough for our largest q */ @@ -1494,7 +1486,9 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, && pk->version<4 && sigversion<4) digest_algo = DIGEST_ALGO_MD5; else if(pksk->pubkey_algo==PUBKEY_ALGO_DSA) - digest_algo = match_dsa_hash (gcry_mpi_get_nbits (pksk->pkey[1])/8); + digest_algo = match_dsa_hash (gcry_mpi_get_nbits (pksk->pkey[1])/8 ); + else if(pksk->pubkey_algo==PUBKEY_ALGO_ECDSA ) + digest_algo = match_dsa_hash (ecdsa_qbits_from_Q( gcry_mpi_get_nbits (pksk->pkey[1]) ) / 8); else digest_algo = DIGEST_ALGO_SHA1; } diff --git a/g10/verify-stubs.c b/g10/verify-stubs.c new file mode 100644 index 000000000..d1f0aa105 --- /dev/null +++ b/g10/verify-stubs.c @@ -0,0 +1,30 @@ +/* To satisfy the linker for the gpgv target + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, + * 2007 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include + +#include +#include "gpg.h" +#include "main.h" + +int +pk_ecc_keypair_gen( PKT_public_key **pk_out, int algo, int keygen_flags, char **cache_nonce_addr, unsigned nbits) { + return GPG_ERR_NOT_IMPLEMENTED; +} diff --git a/g13/utils.c b/g13/utils.c index ef0c572a6..1ea7f3275 100644 --- a/g13/utils.c +++ b/g13/utils.c @@ -176,5 +176,7 @@ next_tuple (tupledesc_t tupledesc, unsigned int *r_tag, size_t *r_length) } return NULL; -} +} + + diff --git a/g13/utils.h b/g13/utils.h index ef718d60d..528ce16ce 100644 --- a/g13/utils.h +++ b/g13/utils.h @@ -38,7 +38,7 @@ const void *find_tuple (tupledesc_t tupledesc, unsigned int tag, size_t *r_length); const void *next_tuple (tupledesc_t tupledesc, unsigned int *r_tag, size_t *r_length); - +char *mpi2hex( gcry_mpi_t m ); #endif /*G13_UTILS_H*/ diff --git a/include/cipher.h b/include/cipher.h index 8e198283d..65cd59e76 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -56,6 +56,8 @@ #define PUBKEY_ALGO_RSA_S /* 3 */ GCRY_PK_RSA_S /* RSA sign only. */ #define PUBKEY_ALGO_ELGAMAL_E /* 16 */ GCRY_PK_ELG_E /* Elgamal encr only */ #define PUBKEY_ALGO_DSA /* 17 */ GCRY_PK_DSA +#define PUBKEY_ALGO_ECDH 18 /* corresponds to GCRY_PK_ECDH ECC DH; encrypt only */ +#define PUBKEY_ALGO_ECDSA 19 /* corresponds to GCRY_PK_ECDSA ECC DSA; sign only */ #define PUBKEY_ALGO_ELGAMAL /* 20 */ GCRY_PK_ELG /* Elgamal encr+sign */ #define PUBKEY_USAGE_SIG GCRY_PK_USAGE_SIGN /* Good for signatures. */ diff --git a/kbx/keybox-openpgp.c b/kbx/keybox-openpgp.c index 0968cf8b3..6c9410e05 100644 --- a/kbx/keybox-openpgp.c +++ b/kbx/keybox-openpgp.c @@ -186,7 +186,7 @@ next_packet (unsigned char const **bufptr, size_t *buflen, } -/* Parse a key packet and store the ionformation in KI. */ +/* Parse a key packet and store the information in KI. */ static gpg_error_t parse_key (const unsigned char *data, size_t datalen, struct _keybox_openpgp_key_info *ki) @@ -243,6 +243,11 @@ parse_key (const unsigned char *data, size_t datalen, case 17: /* DSA */ npkey = 4; break; + case 18: /* ECDH */ + npkey = 3; + case 19: /* ECDSA */ + npkey = 2; + break; default: /* Unknown algorithm. */ return gpg_error (GPG_ERR_UNKNOWN_ALGORITHM); } From ded546b4b5cc2caafa654d94ac8f69a23960427e Mon Sep 17 00:00:00 2001 From: Andrey Jivsov Date: Thu, 6 Jan 2011 15:44:01 -0800 Subject: [PATCH 03/26] Milestone: Data signing/verification and key signing/verification work with ECDSA. --- configure.ac | 2 +- g10/parse-packet.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 12545e260..575c1ec08 100644 --- a/configure.ac +++ b/configure.ac @@ -1466,7 +1466,7 @@ AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable compiler optimization]), [if test $enableval = no ; then - CFLAGS=`echo $CFLAGS | sed s%-O[[1-9]]%-O0\ %g` + CFLAGS=`echo $CFLAGS | sed s/-O[[1-9]]\ /-O0\ /g` fi]) # diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 42d680ac5..d43ab2cba 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -967,7 +967,7 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, es_fprintf (listfp, "\tdata: "); mpi_print(listfp, k->data[0], mpi_print_mode ); es_putc ('\n', listfp); - es_fprintf (listfp, "\tdata: [% 3d bytes] ", encr_buf[0]); + es_fprintf (listfp, "\tdata: [% 3d bytes] ", encr_buf[0]+1); mpi_print(listfp, k->data[1], mpi_print_mode ); es_putc ('\n', listfp); } From b0c55d08a8c835fd58d3c0d1f9f412b74c1b5678 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 10 Jan 2011 11:37:57 +0100 Subject: [PATCH 04/26] Fix bug #1311. --- NEWS | 3 +++ common/ChangeLog | 5 +++++ common/session-env.c | 5 +++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 2cdf854bf..215373345 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,9 @@ Noteworthy changes in version 2.1.0beta2 (unreleased) * Fixed CRL loading under W32 (bug#1010). + * Fixed TTY management for pinentries and session variable update + problem. + Noteworthy changes in version 2.1.0beta1 (2010-10-26) ----------------------------------------------------- diff --git a/common/ChangeLog b/common/ChangeLog index de96b8dc8..6a6f6e071 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,8 @@ +2011-01-10 Werner Koch + + * session-env.c (update_var): Fix same value detection. Fixes + bug#1311. + 2010-12-17 Werner Koch * asshelp.c (lock_spawning): Add arg VERBOSE. Improve timeout diff --git a/common/session-env.c b/common/session-env.c index 2dcf425b6..d719a7b87 100644 --- a/common/session-env.c +++ b/common/session-env.c @@ -183,10 +183,11 @@ update_var (session_env_t se, const char *string, size_t namelen, else if (!strncmp (se->array[idx]->name, string, namelen) && strlen (se->array[idx]->name) == namelen) { - /* Check if the value is the same; no need to update it, - except for updating the default flag. */ if (strlen (se->array[idx]->value) == valuelen) { + /* The new value has the same length. We can update it + in-place. */ + memcpy (se->array[idx]->value, value, valuelen); se->array[idx]->is_default = !!set_default; return 0; } From 5761a9ba74e41f52660e20a1de700fe784c97832 Mon Sep 17 00:00:00 2001 From: Andrey Jivsov Date: Mon, 10 Jan 2011 20:24:14 -0800 Subject: [PATCH 05/26] 'g10/gpg2 --encrypt --debug 15 -r ecdsa -a -o _e.asc _' and 'g10/gpg2 --debug 15 _e.asc', as well as decoding of an old message posted on https://sites.google.com/site/brainhub/pgpecckeys work. This is the milestone 2 that brings in ECDH support from http://code.google.com/p/gnupg-ecc/source/detail?r=15 . This corresponds to the commit 899386826c85f1e757e75bcc5d5b2159d05676a0 in libgcrypt --- g10/call-agent.c | 3 -- g10/call-agent.h | 1 - g10/ecdh.c | 82 ++++++++++++++++++++---------------------------- g10/pkglue.c | 74 ------------------------------------------- g10/pkglue.h | 4 +-- g10/pubkey-enc.c | 40 +++++++++++++++++++++-- 6 files changed, 73 insertions(+), 131 deletions(-) diff --git a/g10/call-agent.c b/g10/call-agent.c index 25f9a537e..dc2ace0e5 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -1744,7 +1744,6 @@ inq_ciphertext_cb (void *opaque, const char *line) gpg_error_t agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, gcry_sexp_t s_ciphertext, - const byte sk_fp[MAX_FINGERPRINT_LEN], unsigned char **r_buf, size_t *r_buflen) { gpg_error_t err; @@ -1753,8 +1752,6 @@ agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, size_t n, len; char *p, *buf, *endp; - /*TODO: use sk_fp */ - if (!keygrip || strlen(keygrip) != 40 || !s_ciphertext || !r_buf || !r_buflen) return gpg_error (GPG_ERR_INV_VALUE); *r_buf = NULL; diff --git a/g10/call-agent.h b/g10/call-agent.h index 45e593bb8..e09c30990 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -168,7 +168,6 @@ gpg_error_t agent_pksign (ctrl_t ctrl, const char *cache_nonce, /* Decrypt a ciphertext. */ gpg_error_t agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc, gcry_sexp_t s_ciphertext, - const byte sk_fp[MAX_FINGERPRINT_LEN], unsigned char **r_buf, size_t *r_buflen); /* Retrieve a key encryption key. */ diff --git a/g10/ecdh.c b/g10/ecdh.c index 6615b75a4..091a28cde 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -76,8 +76,6 @@ pk_ecdh_default_params_to_mpi( int qbits ) { */ byte * pk_ecdh_default_params( int qbits, size_t *sizeout ) { - gpg_error_t err; - gcry_mpi_t result; /* Defaults are the strongest possible choices. Performance is not an issue here, only interoperability. */ byte kek_params[4] = { 3 /*size of following field*/, @@ -370,6 +368,29 @@ pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi, return rc; } + +static gcry_mpi_t +gen_k (unsigned nbits) +{ + gcry_mpi_t k; + + k = gcry_mpi_snew (nbits); + if (DBG_CIPHER) + log_debug ("choosing a random k of %u bits\n", nbits); + + gcry_mpi_randomize (k, nbits-1, GCRY_STRONG_RANDOM); + + if( DBG_CIPHER ) { + unsigned char *buffer; + if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, k)) + BUG (); + log_debug("ephemeral scalar MPI #0: %s\n", buffer); + gcry_free( buffer ); + } + + return k; +} + /* Perform ECDH encryption, which involves ECDH key generation. */ int @@ -377,25 +398,17 @@ pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcr { gcry_sexp_t s_ciph, s_data, s_pkey; - PKT_public_key *pk_eph; int nbits; int rc; + gcry_mpi_t k; nbits = pubkey_nbits( PUBKEY_ALGO_ECDH, pkey ); - - /*** Generate an ephemeral key ***/ - rc = pk_ecc_keypair_gen( &pk_eph, PUBKEY_ALGO_ECDH, KEYGEN_FLAG_TRANSIENT_KEY | KEYGEN_FLAG_NO_PROTECTION /*this is ephemeral*/, "", nbits ); - if( rc ) - return rc; - if( DBG_CIPHER ) { - unsigned char *buffer; - if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, pk_eph->pkey[1])) - BUG (); - log_debug("ephemeral key MPI #0: %s\n", buffer); - gcry_free( buffer ); - } - free_public_key (pk_eph); + /*** Generate an ephemeral key, actually, a scalar ***/ + + k = gen_k (nbits); + if( k == NULL ) + BUG (); /*** Done with ephemeral key generation. * Now use ephemeral secret to get the shared secret. ***/ @@ -406,7 +419,7 @@ pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcr BUG (); /* put the data into a simple list */ - if (gcry_sexp_build (&s_data, NULL, "%m", pk_eph->pkey[3])) /* ephemeral scalar goes as data */ + if (gcry_sexp_build (&s_data, NULL, "%m", k)) /* ephemeral scalar goes as data */ BUG (); /* pass it to libgcrypt */ @@ -421,7 +434,7 @@ pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcr { gcry_mpi_t shared = mpi_from_sexp (s_ciph, "a"); /* ... and get the shared point */ gcry_sexp_release (s_ciph); - resarr[0] = pk_eph->pkey[1]; /* ephemeral public key */ + resarr[0] = mpi_from_sexp (s_ciph, "b"); /* ephemeral public key */ if( DBG_CIPHER ) { unsigned char *buffer; @@ -441,37 +454,10 @@ pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcr /* Perform ECDH decryption. */ int -pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t *data, gcry_mpi_t * skey) { - gcry_sexp_t s_skey, s_data, s_ciph; - int rc; - - if (!data[0] || !data[1]) +pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey) { + if (!data) return gpg_error (GPG_ERR_BAD_MPI); - - rc = gcry_sexp_build (&s_skey, NULL, - "(public-key(ecdh(c%m)(q%m)(p%m)))", - skey[0]/*curve*/, data[0]/*ephemeral key*/, skey[2]/*KDF params*/); - if (rc) - BUG (); - - /* put the data into a simple list */ - if (gcry_sexp_build (&s_data, NULL, "%m", skey[3])) /* static private key (scalar) goes as data */ - BUG (); - - rc = gcry_pk_encrypt (&s_ciph, s_data, s_skey); /* encrypting ephemeral key with our private scalar yields the shared point */ - gcry_sexp_release (s_skey); - gcry_sexp_release (s_data); - if (rc) - return rc; - - { - gcry_mpi_t shared = mpi_from_sexp (s_ciph, "a"); /* get the shared point */ - gcry_sexp_release (s_ciph); - rc = pk_ecdh_encrypt_with_shared_point ( 0 /*=decryption*/, shared, sk_fp, data[1]/*encr data as an MPI*/, skey, result ); - mpi_release( shared ); - } - - return rc; + return pk_ecdh_encrypt_with_shared_point ( 0 /*=decryption*/, shared, sk_fp, data/*encr data as an MPI*/, skey, result ); } diff --git a/g10/pkglue.c b/g10/pkglue.c index f78591940..9050cc241 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -257,80 +257,6 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, const byte pk_fp[MAX return rc; } - - -/**************** - * Emulate our old PK interface here - sometime in the future we might - * change the internal design to directly fit to libgcrypt. - */ -int -pk_decrypt (int algo, gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t * data, - gcry_mpi_t * skey) -{ - gcry_sexp_t s_skey, s_data, s_plain; - int rc; - - *result = NULL; - /* make a sexp from skey */ - if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", - skey[0], skey[1], skey[2], skey[3]); - } - else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", - skey[0], skey[1], skey[2], skey[3], skey[4], - skey[5]); - } - else if( algo == PUBKEY_ALGO_ECDH ) { - return pk_ecdh_decrypt( result, sk_fp, data, skey ); - } - else - return GPG_ERR_PUBKEY_ALGO; - - if (rc) - BUG (); - - /* put data into a S-Exp s_data */ - if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) - { - if (!data[0] || !data[1]) - rc = gpg_error (GPG_ERR_BAD_MPI); - else - rc = gcry_sexp_build (&s_data, NULL, - "(enc-val(elg(a%m)(b%m)))", data[0], data[1]); - } - else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E) - { - if (!data[0]) - rc = gpg_error (GPG_ERR_BAD_MPI); - else - rc = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", data[0]); - } - else - BUG (); - - if (rc) - BUG (); - - rc = gcry_pk_decrypt (&s_plain, s_data, s_skey); - gcry_sexp_release (s_skey); - gcry_sexp_release (s_data); - if (rc) - return rc; - - *result = gcry_sexp_nth_mpi (s_plain, 0, 0); - gcry_sexp_release (s_plain); - if (!*result) - return -1; /* oops */ - - return 0; -} - - /* Check whether SKEY is a suitable secret key. */ int pk_check_secret_key (int algo, gcry_mpi_t *skey) diff --git a/g10/pkglue.h b/g10/pkglue.h index 0d5194818..a1c821dcd 100644 --- a/g10/pkglue.h +++ b/g10/pkglue.h @@ -33,8 +33,8 @@ int pk_decrypt (int algo, gcry_mpi_t *result, const byte fp[MAX_FINGERPRINT_LEN] gcry_mpi_t *skey); int pk_check_secret_key (int algo, gcry_mpi_t *skey); -int pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t * pkey); -int pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t *data, gcry_mpi_t * skey); +int pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t * pkey); +int pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey); gcry_mpi_t pk_ecdh_default_params_to_mpi( int qbits ); byte *pk_ecdh_default_params( int qbits, size_t *sizeout ); diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index a5224e20a..24411e8a1 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -147,14 +147,16 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) char *keygrip; byte fp[MAX_FINGERPRINT_LEN]; size_t fpn; + const int gcry_pkalgo = map_pk_openpgp_to_gcry( sk->pubkey_algo ); /* Get the keygrip. */ err = hexkeygrip_from_pk (sk, &keygrip); if (err) goto leave; + /* Convert the data to an S-expression. */ - if (sk->pubkey_algo == GCRY_PK_ELG || sk->pubkey_algo == GCRY_PK_ELG_E) + if (gcry_pkalgo == GCRY_PK_ELG ||gcry_pkalgo == GCRY_PK_ELG_E) { if (!enc->data[0] || !enc->data[1]) err = gpg_error (GPG_ERR_BAD_MPI); @@ -162,7 +164,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))", enc->data[0], enc->data[1]); } - else if (sk->pubkey_algo == GCRY_PK_RSA || sk->pubkey_algo == GCRY_PK_RSA_E) + else if (gcry_pkalgo == GCRY_PK_RSA || gcry_pkalgo == GCRY_PK_RSA_E) { if (!enc->data[0]) err = gpg_error (GPG_ERR_BAD_MPI); @@ -170,6 +172,14 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", enc->data[0]); } + else if (gcry_pkalgo == GCRY_PK_ECDH ) + { + if (!enc->data[0] || !enc->data[1]) + err = gpg_error (GPG_ERR_BAD_MPI); + else + err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(a%m)(b%m)))", + enc->data[0], enc->data[1]); + } else err = gpg_error (GPG_ERR_BUG); @@ -181,7 +191,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) /* Decrypt. */ desc = gpg_format_keydesc (sk, 0, 1); - err = agent_pkdecrypt (NULL, keygrip, desc, s_data, fp, &frame, &nframe); + err = agent_pkdecrypt (NULL, keygrip, desc, s_data, &frame, &nframe); xfree (desc); gcry_sexp_release (s_data); if (err) @@ -233,6 +243,30 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) } } else { + gcry_mpi_t shared_mpi; + gcry_mpi_t decoded; + + /* at the beginning the frame is the bytes of shared point MPI */ + + err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL); + if (err) { + log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); + goto leave; + } + + err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/, shared_mpi, sk->pkey); + mpi_release( shared_mpi ); + if( err ) + goto leave; + + /* reuse nframe, which size is sufficient to include the session key */ + err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, decoded); + mpi_release( decoded ); + if( err ) + goto leave; + + /* Now the frame is the bytes decrypted but padded session key */ + /* Allow double padding for the benefit of DEK size concealment. * Higher than this is wasteful. */ From b73d8ed06ffef8d2fd70ab2e48da9ef515472fe9 Mon Sep 17 00:00:00 2001 From: Andrey Jivsov Date: Wed, 12 Jan 2011 21:14:45 -0800 Subject: [PATCH 06/26] 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 +++++++++++++++------- g10/seskey.c | 4 ++-- 5 files changed, 27 insertions(+), 16 deletions(-) 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); } diff --git a/g10/seskey.c b/g10/seskey.c index 4cc9158c9..e50cf5c02 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -288,7 +288,6 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) * Therefore, relax the check, but only for ECDSA keys. We may need to adjust it later for general case. * ( Note that the check will never pass for ECDSA 521 anyway as the only hash that intended to match it is SHA 512, but 512 < 521 ). */ - //if (gcry_md_get_algo_dlen (hash_algo) < qbytes ) if (gcry_md_get_algo_dlen (hash_algo) < ((gcry_pkalgo==GCRY_PK_ECDSA && qbytes>(521)/8) ? 512/8 : qbytes) ) { log_error (_("%s key %s requires a %zu bit or larger hash, used hash-algo=%d\n"), @@ -297,8 +296,9 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) return NULL; } + /* Note that in case of ECDSA 521 hash is always smaller than the key size */ if (gcry_mpi_scan (&frame, GCRYMPI_FMT_USG, - gcry_md_read (md, hash_algo), qbytes, &qbytes)) + gcry_md_read (md, hash_algo), gcry_md_get_algo_dlen (hash_algo), &qbytes)) BUG(); } else From a66772aa6309a0e632ff802fd6dcfb034b61c5cf Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 10 Jan 2011 14:38:32 +0100 Subject: [PATCH 07/26] Add ignore file --- .gitignore | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..699581b44 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +Makefile.in +aclocal.m4 +autom4te.cache/ +configure +config.h.in +config.h +common/audit-events.h +common/status-codes.h +doc/gnupg.info* +doc/stamp-vti +doc/version.texi +po/gnupg2.pot From 90b0ff23b7e51332592668e4034967c1aac1c593 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 21 Jan 2011 12:00:57 +0100 Subject: [PATCH 08/26] 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. --- ChangeLog | 5 + agent/ChangeLog | 4 + agent/cvt-openpgp.c | 31 ++- agent/gpg-agent.c | 2 + agent/protect.c | 37 +--- common/convert.c | 11 +- configure.ac | 18 +- dirmngr/Makefile.am | 2 +- g10/armor.c | 2 +- g10/build-packet.c | 87 +++++---- g10/ecdh.c | 451 +++++++++++++++++++++++++------------------ g10/encrypt.c | 4 +- g10/export.c | 22 +-- g10/gpg.c | 2 +- g10/keygen.c | 2 +- g10/keyid.c | 37 ++-- g10/main.h | 16 +- g10/misc.c | 133 +++++++------ g10/parse-packet.c | 194 ++++++++++--------- g10/pkglue.c | 111 +++-------- g10/pkglue.h | 16 +- g10/pubkey-enc.c | 116 +++++------ g10/seskey.c | 271 ++++++++++++++------------ g10/sign.c | 30 +-- g10/verify-stubs.c | 9 +- g13/utils.c | 4 +- include/ChangeLog | 6 + include/cipher.h | 12 +- kbx/keybox-openpgp.c | 1 + 29 files changed, 873 insertions(+), 763 deletions(-) diff --git a/ChangeLog b/ChangeLog index 656fe7212..287e4d1c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-01-21 Werner Koch + + * configure.ac: Need Libgcrypt 1.4.6 due to AESWRAP. + (HAVE_GCRY_PK_ECDH): Add new test. + 2011-01-03 Werner Koch * README.SVN: Rename to README.GIT. 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) diff --git a/common/convert.c b/common/convert.c index 0a0c46f8e..5df6b335e 100644 --- a/common/convert.c +++ b/common/convert.c @@ -23,7 +23,7 @@ #include #include "util.h" -#include "gcrypt.h" +#include "gcrypt.h" /* FIXME: really needed? */ #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A')) @@ -250,7 +250,10 @@ hex2str_alloc (const char *hexstring, size_t *r_count) * caller must free with xfree * Returns NULL on error, never throws */ -char *mpi2hex( gcry_mpi_t m ) { +char * +mpi2hex( gcry_mpi_t m ) +{ +#warning we have code for this in libcrypt size_t nbytes; size_t nbytes2; int rc; @@ -270,7 +273,9 @@ char *mpi2hex( gcry_mpi_t m ) { bin2hex( p+2*nbytes+1, nbytes2, p ); p[nbytes2*2] = '\0'; -//printf("%s:%d>>>> Created the string %s from %d bytes %02x %02x ..., MPI was %d bytes\n", __FILE__, __LINE__, p, nbytes2, p[2*nbytes+1], p[2*nbytes+2], nbytes); + /*printf("%s:%d>>>> Created the string %s from %d bytes %02x %02x + ..., MPI was %d bytes\n", __FILE__, __LINE__, p, nbytes2, + p[2*nbytes+1], p[2*nbytes+2], nbytes); */ return p; } diff --git a/configure.ac b/configure.ac index 575c1ec08..ef6d2f9d7 100644 --- a/configure.ac +++ b/configure.ac @@ -24,7 +24,7 @@ min_automake_version="1.10" # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [2.2.0]) +m4_define([my_version], [2.1.0]) m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ @@ -43,7 +43,7 @@ development_version=no NEED_GPG_ERROR_VERSION=1.8 NEED_LIBGCRYPT_API=1 -NEED_LIBGCRYPT_VERSION=1.6.0 +NEED_LIBGCRYPT_VERSION=1.4.6 NEED_LIBASSUAN_API=2 NEED_LIBASSUAN_VERSION=2.0.0 @@ -724,6 +724,20 @@ AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION", AM_PATH_LIBGCRYPT("$NEED_LIBGCRYPT_API:$NEED_LIBGCRYPT_VERSION", have_libgcrypt=yes,have_libgcrypt=no) +AC_CACHE_CHECK([whether Libgcrypt support ECDH], gnupg_cv_gcry_pk_ecdh, + [ _gnupg_gcry_save_cflags=$CFLAGS + CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS" + AC_TRY_COMPILE( + [#include ], + [ return GCRY_PK_ECDH; ], + gnupg_cv_gcry_pk_ecdh=yes, + gnupg_cv_gcry_pk_ecdh=no) + CFLAGS=$_gnupg_gcry_save_cflags]) +if test "$gnupg_cv_gcry_pk_ecdh" = yes; then + AC_DEFINE([HAVE_GCRY_PK_ECDH], 1, + [Define if gcrypt.h has the enum value for ECDH.]) +fi + # # libassuan is used for IPC diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index 0285fc8f8..128d7c383 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -61,7 +61,7 @@ endif dirmngr_LDADD = $(libcommonpth) ../gl/libgnu.a $(DNSLIBS) $(LIBASSUAN_LIBS) \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(PTH_LIBS) $(LIBINTL) $(LIBICONV) if !USE_LDAPWRAPPER -dirmngr_LDADD += $(LDAPLIBS) -llber +dirmngr_LDADD += $(LDAPLIBS) -llber #FIXME: Test for liblber first. endif dirmngr_LDFLAGS = $(extra_bin_ldflags) diff --git a/g10/armor.c b/g10/armor.c index 8cfd35c1f..a6195fc3d 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -1079,7 +1079,7 @@ armor_filter( void *opaque, int control, iobuf_writestr(a,afx->eol); if( !opt.no_version ) { - iobuf_writestr(a, "Version: GnuPG v" VERSION "-ecc (" + iobuf_writestr(a, "Version: GnuPG v" VERSION " (" PRINTABLE_OS_NAME ")" ); iobuf_writestr(a,afx->eol); } diff --git a/g10/build-packet.c b/g10/build-packet.c index 3a2c206c8..d138e0614 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -178,21 +178,20 @@ mpi_write (iobuf_t out, gcry_mpi_t a) return rc; } -/* - * Write the name OID, encoded as an mpi, to OUT. The format of the content of the MPI is - * one byte LEN, following by LEN bytes that are DER representation of an ASN.1 OID. - * This is true for each of the 3 following functions. - */ +/* Write the name OID, encoded as an mpi, to OUT. The format of the + * content of the MPI is one byte LEN, following by LEN bytes that are + * DER representation of an ASN.1 OID. This is true for each of the 3 + * following functions. */ #define iobuf_name_oid_write iobuf_write_size_body_mpi + /* Write the value of KEK fields for ECDH. */ #define ecdh_kek_params_write iobuf_write_size_body_mpi -/* Write the value of encrypted filed for ECDH. */ + +/* Write the value of encrypted filed for ECDH. */ #define ecdh_esk_write iobuf_write_size_body_mpi -/**************** - * calculate the length of a packet described by PKT - */ +/* Calculate the length of a packet described by PKT. */ u32 calc_packet_length( PACKET *pkt ) { @@ -300,24 +299,35 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) } assert (npkey < nskey); - if( pk->pubkey_algo != PUBKEY_ALGO_ECDSA && pk->pubkey_algo != PUBKEY_ALGO_ECDH ) { - /* Writing the public parameters is easy, */ - for (i=0; i < npkey; i++ ) - if ((err = mpi_write (a, pk->pkey[i]))) - goto leave; - } - else { - /* ... except we do an adjustment for ECC OID and possibly KEK params for ECDH */ - if( (err=iobuf_name_oid_write(a, pk->pkey[0])) || /* DER of OID with preceeding length byte */ - (err = mpi_write (a, pk->pkey[1])) ) /* point Q, the public key */ + /* Writing the public parameters is easy. Except if we do an + adjustment for ECC OID and possibly KEK params for ECDH. */ + if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA + || pk->pubkey_algo == PUBKEY_ALGO_ECDH) { - goto leave; + /* Write DER of OID with preceeding length byte. */ + err = iobuf_name_oid_write (a, pk->pkey[0]); + if (err) + goto leave; + /* Write point Q, the public key. */ + err = mpi_write (a, pk->pkey[1]); + if (err) + goto leave; + + /* Write one more public field for ECDH. */ + if (pk->pubkey_algo == PUBKEY_ALGO_ECDH) + { + err = ecdh_kek_params_write(a,pk->pkey[2]); + if (err) + goto leave; + } } - if( pk->pubkey_algo == PUBKEY_ALGO_ECDH && (err=ecdh_kek_params_write(a,pk->pkey[2]))) { /* one more public field for ECDH */ - goto leave; + else + { + for (i=0; i < npkey; i++ ) + if ((err = mpi_write (a, pk->pkey[i]))) + goto leave; } - /* followed by possibly protected private scalar */ - } + if (pk->seckey_info) { @@ -483,22 +493,25 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) if ( !n ) write_fake_data( a, enc->data[0] ); - if( enc->pubkey_algo != PUBKEY_ALGO_ECDH ) { - for (i=0; i < n && !rc ; i++ ) - rc = mpi_write(a, enc->data[i] ); - } - else { - /* the second field persists as a LEN+field structure, even though it is - * stored for uniformity as an MPI internally */ - assert( n==2 ); - rc = mpi_write(a, enc->data[0] ); - if( !rc ) rc = ecdh_esk_write(a, enc->data[1] ); - } + if (enc->pubkey_algo == PUBKEY_ALGO_ECDH ) + { + /* The second field persists as a LEN+field structure, even + * though it is stored for uniformity as an MPI internally. */ + assert (n == 2); + rc = mpi_write (a, enc->data[0]); + if (!rc) + rc = ecdh_esk_write (a, enc->data[1]); + } + else + { + for (i=0; i < n && !rc ; i++ ) + rc = mpi_write(a, enc->data[i] ); + } if (!rc) { - write_header(out, ctb, iobuf_get_temp_length(a) ); - rc = iobuf_write_temp( out, a ); + write_header (out, ctb, iobuf_get_temp_length(a) ); + rc = iobuf_write_temp (out, a); } iobuf_close(a); return rc; diff --git a/g10/ecdh.c b/g10/ecdh.c index 091a28cde..cb251fef2 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -1,5 +1,5 @@ /* ecdh.c - ECDH public key operations used in public key glue code - * Copyright (C) 2000, 2003 Free Software Foundation, Inc. + * Copyright (C) 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -31,10 +31,12 @@ #include "options.h" gcry_mpi_t -pk_ecdh_default_params_to_mpi( int qbits ) { +pk_ecdh_default_params_to_mpi (int qbits) +{ gpg_error_t err; gcry_mpi_t result; - /* Defaults are the strongest possible choices. Performance is not an issue here, only interoperability. */ + /* Defaults are the strongest possible choices. Performance is not + an issue here, only interoperability. */ byte kek_params[4] = { 3 /*size of following field*/, 1 /*fixed version for KDF+AESWRAP*/, @@ -50,41 +52,49 @@ pk_ecdh_default_params_to_mpi( int qbits ) { } kek_params_table[] = { { 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES }, { 384, DIGEST_ALGO_SHA384, CIPHER_ALGO_AES256 }, - { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 } // 528 is 521 rounded to the 8 bit boundary + + /* Note: 528 is 521 rounded to the 8 bit boundary */ + { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 } }; - for( i=0; i= qbits ) { - kek_params[2] = kek_params_table[i].openpgp_hash_id; - kek_params[3] = kek_params_table[i].openpgp_cipher_id; - break; + for (i=0; i= qbits) + { + kek_params[2] = kek_params_table[i].openpgp_hash_id; + kek_params[3] = kek_params_table[i].openpgp_cipher_id; + break; + } } - } - if( DBG_CIPHER ) - log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params) ); + if (DBG_CIPHER) + log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params) ); - err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, kek_params, sizeof(kek_params), NULL); + err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, + kek_params, sizeof(kek_params), NULL); if (err) log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); return result; } -/* returns allocated (binary) KEK parameters; the size is returned in sizeout. - * The caller must free returned value with xfree. - * Returns NULL on error + +/* Returns allocated (binary) KEK parameters; the size is returned in + * sizeout. The caller must free the returned value with xfree. + * Returns NULL on error. */ byte * -pk_ecdh_default_params( int qbits, size_t *sizeout ) { - /* Defaults are the strongest possible choices. Performance is not an issue here, only interoperability. */ +pk_ecdh_default_params (int qbits, size_t *sizeout) +{ + /* Defaults are the strongest possible choices. Performance is not + an issue here, only interoperability. */ byte kek_params[4] = { 3 /*size of following field*/, 1 /*fixed version for KDF+AESWRAP*/, DIGEST_ALGO_SHA512 /* KEK MD */, - CIPHER_ALGO_AES256 /*KEK AESWRAP alg*/ + CIPHER_ALGO_AES256 /* KEK AESWRAP alg */ }; int i; - + static const struct { int qbits; int openpgp_hash_id; @@ -92,39 +102,48 @@ pk_ecdh_default_params( int qbits, size_t *sizeout ) { } kek_params_table[] = { { 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES }, { 384, DIGEST_ALGO_SHA384, CIPHER_ALGO_AES256 }, - { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 } // 528 is 521 rounded to the 8 bit boundary + /* Note: 528 is 521 rounded to the 8 bit boundary */ + { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 } }; byte *p; *sizeout = 0; - - for( i=0; i= qbits ) { - kek_params[2] = kek_params_table[i].openpgp_hash_id; - kek_params[3] = kek_params_table[i].openpgp_cipher_id; - break; + + for (i=0; i= qbits) + { + kek_params[2] = kek_params_table[i].openpgp_hash_id; + kek_params[3] = kek_params_table[i].openpgp_cipher_id; + break; + } } - } - if( DBG_CIPHER ) - log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params) ); + if (DBG_CIPHER ) + log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params)); - p = xtrymalloc( sizeof(kek_params) ); - if( p == NULL ) + p = xtrymalloc (sizeof(kek_params)); + if (!p) return NULL; - memcpy( p, kek_params, sizeof(kek_params) ); + memcpy (p, kek_params, sizeof(kek_params)); *sizeout = sizeof(kek_params); return p; } -/* Encrypts/decrypts 'data' with a key derived from shared_mpi ECC point using FIPS SP 800-56A compliant method, which is - * key derivation + key wrapping. The direction is determined by the first parameter (is_encrypt=1 --> this is encryption). - * The result is returned in out as a size+value MPI. + +/* Encrypts/decrypts 'data' with a key derived from shared_mpi ECC + * point using FIPS SP 800-56A compliant method, which is key + * derivation + key wrapping. The direction is determined by the first + * parameter (is_encrypt=1 --> this is encryption). The result is + * returned in out as a size+value MPI. + * * TODO: memory leaks (x_secret). */ static int -pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi, - const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t * pkey, gcry_mpi_t *out) +pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, + const byte pk_fp[MAX_FINGERPRINT_LEN], + gcry_mpi_t data, gcry_mpi_t *pkey, + gcry_mpi_t *out) { byte *secret_x; int secret_x_size; @@ -141,55 +160,70 @@ pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi, { size_t nbytes; - /* extract x component of the shared point: this is the actual shared secret */ + /* Extract x component of the shared point: this is the actual + shared secret */ nbytes = (mpi_get_nbits (pkey[1] /* public point */)+7)/8; secret_x = xmalloc_secure( nbytes ); - rc = gcry_mpi_print (GCRYMPI_FMT_USG, secret_x, nbytes, &nbytes, shared_mpi); - if( rc ) { - xfree( secret_x ); - log_error ("ec ephemeral export of shared point failed: %s\n", gpg_strerror (rc) ); - return rc; - } + rc = gcry_mpi_print (GCRYMPI_FMT_USG, secret_x, nbytes, + &nbytes, shared_mpi); + if (rc) + { + xfree (secret_x); + log_error ("ec ephemeral export of shared point failed: %s\n", + gpg_strerror (rc)); + return rc; + } secret_x_size = (nbits+7)/8; - assert( nbytes > secret_x_size ); - memmove( secret_x, secret_x+1, secret_x_size ); - memset( secret_x+secret_x_size, 0, nbytes-secret_x_size ); + assert (nbytes > secret_x_size); + memmove (secret_x, secret_x+1, secret_x_size); + memset (secret_x+secret_x_size, 0, nbytes-secret_x_size); - if( DBG_CIPHER ) - log_printhex ("ecdh shared secret X is:", secret_x, secret_x_size ); + if (DBG_CIPHER) + log_printhex ("ecdh shared secret X is:", secret_x, secret_x_size ); } - /*** We have now the shared secret bytes in secret_x ***/ + /*** We have now the shared secret bytes in secret_x. ***/ - /* At this point we are done with PK encryption and the rest of the function uses symmetric - * key encryption techniques to protect the input 'data'. The following two sections will - * simply replace current secret_x with a value derived from it. This will become a KEK. + /* At this point we are done with PK encryption and the rest of the + * function uses symmetric key encryption techniques to protect the + * input 'data'. The following two sections will simply replace + * current secret_x with a value derived from it. This will become + * a KEK. */ { IOBUF obuf = iobuf_temp(); rc = iobuf_write_size_body_mpi ( obuf, pkey[2] ); /* KEK params */ + + kdf_params_size = iobuf_temp_to_buffer (obuf, + kdf_params, sizeof(kdf_params)); - kdf_params_size = iobuf_temp_to_buffer( obuf, kdf_params, sizeof(kdf_params) ); + if (DBG_CIPHER) + log_printhex ("ecdh KDF public key params are:", + kdf_params, kdf_params_size ); - if( DBG_CIPHER ) - log_printhex ("ecdh KDF public key params are:", kdf_params, kdf_params_size ); - - if( kdf_params_size != 4 || kdf_params[0] != 3 || kdf_params[1] != 1 ) /* expect 4 bytes 03 01 hash_alg symm_alg */ + /* Expect 4 bytes 03 01 hash_alg symm_alg. */ + if (kdf_params_size != 4 || kdf_params[0] != 3 || kdf_params[1] != 1) return GPG_ERR_BAD_PUBKEY; kdf_hash_algo = kdf_params[2]; kdf_encr_algo = kdf_params[3]; - if( DBG_CIPHER ) - log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n", gcry_md_algo_name (kdf_hash_algo), openpgp_cipher_algo_name (kdf_encr_algo) ); + if (DBG_CIPHER) + log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n", + gcry_md_algo_name (kdf_hash_algo), + openpgp_cipher_algo_name (kdf_encr_algo)); - if( kdf_hash_algo != GCRY_MD_SHA256 && kdf_hash_algo != GCRY_MD_SHA384 && kdf_hash_algo != GCRY_MD_SHA512 ) + if (kdf_hash_algo != GCRY_MD_SHA256 + && kdf_hash_algo != GCRY_MD_SHA384 + && kdf_hash_algo != GCRY_MD_SHA512) return GPG_ERR_BAD_PUBKEY; - if( kdf_encr_algo != GCRY_CIPHER_AES128 && kdf_encr_algo != GCRY_CIPHER_AES192 && kdf_encr_algo != GCRY_CIPHER_AES256 ) + if (kdf_encr_algo != GCRY_CIPHER_AES128 + && kdf_encr_algo != GCRY_CIPHER_AES192 + && kdf_encr_algo != GCRY_CIPHER_AES256) return GPG_ERR_BAD_PUBKEY; } - /* build kdf_params */ + /* Build kdf_params. */ { IOBUF obuf; @@ -205,13 +239,15 @@ pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi, /* fixed-length field 5, recipient fp */ iobuf_write (obuf, pk_fp, 20); - kdf_params_size = iobuf_temp_to_buffer( obuf, kdf_params, sizeof(kdf_params) ); - iobuf_close( obuf ); - if( rc ) { + kdf_params_size = iobuf_temp_to_buffer (obuf, + kdf_params, sizeof(kdf_params)); + iobuf_close (obuf); + if (rc) return rc; - } - if( DBG_CIPHER ) - log_printhex ("ecdh KDF message params are:", kdf_params, kdf_params_size ); + + if(DBG_CIPHER) + log_printhex ("ecdh KDF message params are:", + kdf_params, kdf_params_size ); } /* Derive a KEK (key wrapping key) using kdf_params and secret_x. */ @@ -231,7 +267,8 @@ pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi, assert( gcry_md_get_algo_dlen (kdf_hash_algo) >= 32 ); - memcpy (secret_x, gcry_md_read (h, kdf_hash_algo), gcry_md_get_algo_dlen (kdf_hash_algo)); + memcpy (secret_x, gcry_md_read (h, kdf_hash_algo), + gcry_md_get_algo_dlen (kdf_hash_algo)); gcry_md_close (h); old_size = secret_x_size; @@ -239,12 +276,13 @@ pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi, secret_x_size = gcry_cipher_get_algo_keylen( kdf_encr_algo ); assert( secret_x_size <= gcry_md_get_algo_dlen (kdf_hash_algo) ); - memset( secret_x+secret_x_size, old_size-secret_x_size, 0 ); /* we could have allocated more, so clean the tail before returning */ - if( DBG_CIPHER ) + /* We could have allocated more, so clean the tail before returning. */ + memset( secret_x+secret_x_size, old_size-secret_x_size, 0 ); + if (DBG_CIPHER) log_printhex ("ecdh KEK is:", secret_x, secret_x_size ); - } - - /* And, finally, aeswrap with key secret_x */ + } + + /* And, finally, aeswrap with key secret_x. */ { gcry_cipher_hd_t hd; size_t nbytes; @@ -256,115 +294,134 @@ pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi, rc = gcry_cipher_open (&hd, kdf_encr_algo, GCRY_CIPHER_MODE_AESWRAP, 0); if (rc) - { - log_error( "ecdh failed to initialize AESWRAP: %s\n", gpg_strerror (rc)); - return rc; - } + { + log_error ("ecdh failed to initialize AESWRAP: %s\n", + gpg_strerror (rc)); + return rc; + } rc = gcry_cipher_setkey (hd, secret_x, secret_x_size); xfree( secret_x ); if (rc) - { - gcry_cipher_close (hd); - log_error("ecdh failed in gcry_cipher_setkey: %s\n", gpg_strerror (rc)); - return rc; - } + { + gcry_cipher_close (hd); + log_error ("ecdh failed in gcry_cipher_setkey: %s\n", + gpg_strerror (rc)); + return rc; + } data_buf_size = (gcry_mpi_get_nbits(data)+7)/8; - assert( (data_buf_size & 7) == (is_encrypt ? 0 : 1) ); + assert ((data_buf_size & 7) == (is_encrypt ? 0 : 1)); - data_buf = xmalloc_secure( 1 + 2*data_buf_size + 8 ); - if( !data_buf ) { - gcry_cipher_close (hd); - return GPG_ERR_ENOMEM; - } - - if( is_encrypt ) { - byte *in = data_buf+1+data_buf_size+8; - - /* write data MPI into the end of data_buf. data_buf is size aeswrap data */ - rc = gcry_mpi_print (GCRYMPI_FMT_USG, in, data_buf_size, &nbytes, data/*in*/); - if( rc ) { - log_error("ecdh failed to export DEK: %s\n", gpg_strerror (rc)); - gcry_cipher_close (hd); - xfree( data_buf ); - return rc; - } - - if( DBG_CIPHER ) - log_printhex ("ecdh encrypting :", in, data_buf_size ); - - rc = gcry_cipher_encrypt (hd, data_buf+1, data_buf_size+8, in, data_buf_size); - memset( in, 0, data_buf_size); - gcry_cipher_close (hd); - if(rc) + data_buf = xtrymalloc_secure( 1 + 2*data_buf_size + 8); + if (!data_buf) { - log_error("ecdh failed in gcry_cipher_encrypt: %s\n", gpg_strerror (rc)); - xfree( data_buf ); - return rc; + gcry_cipher_close (hd); + return GPG_ERR_ENOMEM; } - data_buf[0] = data_buf_size+8; - if( DBG_CIPHER ) + if (is_encrypt) + { + byte *in = data_buf+1+data_buf_size+8; + + /* Write data MPI into the end of data_buf. data_buf is size + aeswrap data. */ + rc = gcry_mpi_print (GCRYMPI_FMT_USG, in, + data_buf_size, &nbytes, data/*in*/); + if (rc) + { + log_error ("ecdh failed to export DEK: %s\n", gpg_strerror (rc)); + gcry_cipher_close (hd); + xfree (data_buf); + return rc; + } + + if (DBG_CIPHER) + log_printhex ("ecdh encrypting :", in, data_buf_size ); + + rc = gcry_cipher_encrypt (hd, data_buf+1, data_buf_size+8, + in, data_buf_size); + memset (in, 0, data_buf_size); + gcry_cipher_close (hd); + if (rc) + { + log_error ("ecdh failed in gcry_cipher_encrypt: %s\n", + gpg_strerror (rc)); + xfree (data_buf); + return rc; + } + data_buf[0] = data_buf_size+8; + + if (DBG_CIPHER) log_printhex ("ecdh encrypted to:", data_buf+1, data_buf[0] ); - rc = gcry_mpi_scan ( &result, GCRYMPI_FMT_USG, data_buf, 1+data_buf[0], NULL); /* (byte)size + aeswrap of DEK */ - xfree( data_buf ); - if(rc) - { - log_error("ecdh failed to create an MPI: %s\n", gpg_strerror (rc)); - return rc; - } - - *out = result; - } - else { - byte *in; - - rc = gcry_mpi_print (GCRYMPI_FMT_USG, data_buf, data_buf_size, &nbytes, data/*in*/); - if( nbytes != data_buf_size || data_buf[0] != data_buf_size-1 ) { - log_error("ecdh inconsistent size\n"); + rc = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, + data_buf, 1+data_buf[0], NULL); + /* (byte)size + aeswrap of DEK */ xfree( data_buf ); - return GPG_ERR_BAD_MPI; + if (rc) + { + log_error ("ecdh failed to create an MPI: %s\n", gpg_strerror (rc)); + return rc; + } + + *out = result; } + else + { + byte *in; + + rc = gcry_mpi_print (GCRYMPI_FMT_USG, data_buf, data_buf_size, + &nbytes, data/*in*/); + if (nbytes != data_buf_size || data_buf[0] != data_buf_size-1) + { + log_error ("ecdh inconsistent size\n"); + xfree (data_buf); + return GPG_ERR_BAD_MPI; + } in = data_buf+data_buf_size; data_buf_size = data_buf[0]; - - if( DBG_CIPHER ) - log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size ); - rc = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1, data_buf_size ); + if (DBG_CIPHER) + log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size); + + rc = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1, + data_buf_size); gcry_cipher_close (hd); - if(rc) - { - log_error("ecdh failed in gcry_cipher_decrypt: %s\n", gpg_strerror (rc)); - xfree( data_buf ); - return rc; - } + if (rc) + { + log_error ("ecdh failed in gcry_cipher_decrypt: %s\n", + gpg_strerror (rc)); + xfree (data_buf); + return rc; + } - data_buf_size-=8; + data_buf_size -= 8; - if( DBG_CIPHER ) - log_printhex ("ecdh decrypted to :", in, data_buf_size ); + if (DBG_CIPHER) + log_printhex ("ecdh decrypted to :", in, data_buf_size); - /* padding is removed later */ - //if( in[data_buf_size-1] > 8 ) { - // log_error("ecdh failed at decryption: invalid padding. %02x > 8\n", in[data_buf_size-1] ); - // return GPG_ERR_BAD_KEY; - //} + /* Padding is removed later. */ + /* if (in[data_buf_size-1] > 8 ) */ + /* { */ + /* log_error("ecdh failed at decryption: invalid padding. %02x > 8\n", */ + /* in[data_buf_size-1] ); */ + /* return GPG_ERR_BAD_KEY; */ + /* } */ rc = gcry_mpi_scan ( &result, GCRYMPI_FMT_USG, in, data_buf_size, NULL); - xfree( data_buf ); - if(rc) - { - log_error("ecdh failed to create a plain text MPI: %s\n", gpg_strerror (rc)); - return rc; - } - + xfree (data_buf); + if (rc) + { + log_error ("ecdh failed to create a plain text MPI: %s\n", + gpg_strerror (rc)); + return rc; + } + *out = result; - } + } } - + return rc; } @@ -380,21 +437,22 @@ gen_k (unsigned nbits) gcry_mpi_randomize (k, nbits-1, GCRY_STRONG_RANDOM); - if( DBG_CIPHER ) { - unsigned char *buffer; - if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, k)) - BUG (); - log_debug("ephemeral scalar MPI #0: %s\n", buffer); - gcry_free( buffer ); - } + if (DBG_CIPHER) + { + unsigned char *buffer; + if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, k)) + BUG (); + log_debug("ephemeral scalar MPI #0: %s\n", buffer); + gcry_free( buffer ); + } return k; } -/* Perform ECDH encryption, which involves ECDH key generation. - */ +/* Perform ECDH encryption, which involves ECDH key generation. */ int -pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t * pkey) +pk_ecdh_encrypt (gcry_mpi_t *resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], + gcry_mpi_t data, gcry_mpi_t * pkey) { gcry_sexp_t s_ciph, s_data, s_pkey; @@ -402,9 +460,9 @@ pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcr int rc; gcry_mpi_t k; - nbits = pubkey_nbits( PUBKEY_ALGO_ECDH, pkey ); + nbits = pubkey_nbits (PUBKEY_ALGO_ECDH, pkey); - /*** Generate an ephemeral key, actually, a scalar ***/ + /*** Generate an ephemeral key, actually, a scalar. ***/ k = gen_k (nbits); if( k == NULL ) @@ -414,50 +472,63 @@ pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcr * Now use ephemeral secret to get the shared secret. ***/ rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(ecdh(c%m)(q%m)(p%m)))", pkey[0], pkey[1], pkey[2]); + "(public-key(ecdh(c%m)(q%m)(p%m)))", + pkey[0], pkey[1], pkey[2]); if (rc) BUG (); - /* put the data into a simple list */ - if (gcry_sexp_build (&s_data, NULL, "%m", k)) /* ephemeral scalar goes as data */ + /* Put the data into a simple list. */ + /* Ephemeral scalar goes as data. */ + if (gcry_sexp_build (&s_data, NULL, "%m", k)) BUG (); - /* pass it to libgcrypt */ + /* Pass it to libgcrypt. */ rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); gcry_sexp_release (s_data); gcry_sexp_release (s_pkey); if (rc) return rc; - /* finally, perform encryption */ + /* Finally, perform encryption. */ { - gcry_mpi_t shared = mpi_from_sexp (s_ciph, "a"); /* ... and get the shared point */ - gcry_sexp_release (s_ciph); - resarr[0] = mpi_from_sexp (s_ciph, "b"); /* ephemeral public key */ + /* ... and get the shared point/ */ + gcry_mpi_t shared; - if( DBG_CIPHER ) { + shared = mpi_from_sexp (s_ciph, "a"); + gcry_sexp_release (s_ciph); + /* Ephemeral public key. */ + resarr[0] = mpi_from_sexp (s_ciph, "b"); + + if (DBG_CIPHER) + { unsigned char *buffer; + if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, resarr[0])) BUG (); log_debug("ephemeral key MPI: %s\n", buffer); gcry_free( buffer ); - } - - rc = pk_ecdh_encrypt_with_shared_point ( 1 /*=encrypton*/, shared, pk_fp, data, pkey, resarr+1 ); - mpi_release( shared ); + } + + rc = pk_ecdh_encrypt_with_shared_point (1 /*=encrypton*/, shared, + pk_fp, data, pkey, resarr+1); + mpi_release (shared); } - + return rc; } -/* Perform ECDH decryption. - */ + +/* Perform ECDH decryption. */ int -pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey) { +pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], + gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey) +{ if (!data) return gpg_error (GPG_ERR_BAD_MPI); - return pk_ecdh_encrypt_with_shared_point ( 0 /*=decryption*/, shared, sk_fp, data/*encr data as an MPI*/, skey, result ); + return pk_ecdh_encrypt_with_shared_point (0 /*=decryption*/, shared, + sk_fp, data/*encr data as an MPI*/, + skey, result); } diff --git a/g10/encrypt.c b/g10/encrypt.c index 3c16309d0..f52921582 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -894,8 +894,8 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out) compliance_failure(); } - fingerprint_from_pk( pk, fp, &fpn ); - assert( fpn == 20 ); + fingerprint_from_pk (pk, fp, &fpn); + assert (fpn == 20); /* Okay, what's going on: We have the session key somewhere in * the structure DEK and want to encode this session key in an diff --git a/g10/export.c b/g10/export.c index 82d97511f..74a7b0c51 100644 --- a/g10/export.c +++ b/g10/export.c @@ -1161,18 +1161,16 @@ build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent) /* iobuf_put (out,')'); iobuf_put (out,'\n'); */ /* (*indent)--; */ /* } */ -/* - else if (sk->pubkey_algo == PUBKEY_ALGO_ECDSA && !sk->is_protected) - { - write_sexp_line (out, indent, "(ecdsa\n"); - (*indent)++; - write_sexp_keyparm (out, indent, "c", sk->skey[0]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "q", sk->skey[6]); iobuf_put (out,'\n'); - write_sexp_keyparm (out, indent, "d", sk->skey[7]); - iobuf_put (out,')'); iobuf_put (out,'\n'); - (*indent)--; - } -*/ + /* else if (sk->pubkey_algo == PUBKEY_ALGO_ECDSA && !sk->is_protected) */ + /* { */ + /* write_sexp_line (out, indent, "(ecdsa\n"); */ + /* (*indent)++; */ + /* write_sexp_keyparm (out, indent, "c", sk->skey[0]); iobuf_put (out,'\n'); */ + /* write_sexp_keyparm (out, indent, "q", sk->skey[6]); iobuf_put (out,'\n'); */ + /* write_sexp_keyparm (out, indent, "d", sk->skey[7]); */ + /* iobuf_put (out,')'); iobuf_put (out,'\n'); */ + /* (*indent)--; */ + /* } */ /* else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected) */ /* { */ /* write_sexp_line (out, indent, "(elg\n"); */ diff --git a/g10/gpg.c b/g10/gpg.c index 23b193402..3794aa2b7 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -813,7 +813,7 @@ my_strusage( int level ) const char *p; switch( level ) { - case 11: p = "gpg (GnuPG) ecc"; + case 11: p = "gpg (GnuPG)"; break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; 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 diff --git a/g10/keyid.c b/g10/keyid.c index 2a9bd1988..0405b8b2f 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -54,11 +54,11 @@ pubkey_letter( int algo ) case PUBKEY_ALGO_RSA: return 'R' ; case PUBKEY_ALGO_RSA_E: return 'r' ; case PUBKEY_ALGO_RSA_S: return 's' ; - case PUBKEY_ALGO_ELGAMAL_E: return 'g'; + case PUBKEY_ALGO_ELGAMAL_E: return 'g' ; case PUBKEY_ALGO_ELGAMAL: return 'G' ; case PUBKEY_ALGO_DSA: return 'D' ; - case PUBKEY_ALGO_ECDSA: return 'E' ; // ECC DSA (sign only) - case PUBKEY_ALGO_ECDH: return 'e' ; // ECC DH (encrypt only) + case PUBKEY_ALGO_ECDSA: return 'E' ; /* ECC DSA (sign only) */ + case PUBKEY_ALGO_ECDH: return 'e' ; /* ECC DH (encrypt only) */ default: return '?'; } } @@ -76,8 +76,6 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) unsigned int nbits; size_t nbytes; int npkey = pubkey_get_npkey (pk->pubkey_algo); - /* name OID, MPI of public point, [for ECDH only: KEK params] */ - enum gcry_mpi_format ecc_pub_format[3] = {GCRYMPI_FMT_USG, GCRYMPI_FMT_PGP, GCRYMPI_FMT_USG}; /* Two extra bytes for the expiration date in v3 */ if(pk->version<4) @@ -92,11 +90,17 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) } else { - for(i=0; i < npkey; i++ ) + for (i=0; i < npkey; i++ ) { - const enum gcry_mpi_format fmt = - ((pk->pubkey_algo==PUBKEY_ALGO_ECDSA || pk->pubkey_algo==PUBKEY_ALGO_ECDH) ? ecc_pub_format[i] : GCRYMPI_FMT_PGP); - + enum gcry_mpi_format fmt; + + if ((pk->pubkey_algo == PUBKEY_ALGO_ECDSA + || pk->pubkey_algo == PUBKEY_ALGO_ECDH) + && (i == 0 || i == 2)) + fmt = GCRYMPI_FMT_USG; /* Name of OID or KEK parms. */ + else + fmt = GCRYMPI_FMT_PGP; + if (gcry_mpi_print (fmt, NULL, 0, &nbytes, pk->pkey[i])) BUG (); pp[i] = xmalloc (nbytes); @@ -106,7 +110,7 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) n += nn[i]; } } - + gcry_md_putc ( md, 0x99 ); /* ctb */ /* What does it mean if n is greater than than 0xFFFF ? */ gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */ @@ -724,13 +728,12 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array) "(public-key(ecc(c%m)(q%m)))", pk->pkey[0], pk->pkey[1]); break; -/* - case PUBKEY_ALGO_ECDH: - err = gcry_sexp_build (&s_pkey, NULL, - "(public-key(ecdh(c%m)(q%m)(p%m)))", - pk->pkey[0], pk->pkey[1], pk->pkey[2]); - break; -*/ + + /* case PUBKEY_ALGO_ECDH: */ + /* err = gcry_sexp_build (&s_pkey, NULL, */ + /* "(public-key(ecdh(c%m)(q%m)(p%m)))", */ + /* pk->pkey[0], pk->pkey[1], pk->pkey[2]); */ + /* break; */ default: err = gpg_error (GPG_ERR_PUBKEY_ALGO); diff --git a/g10/main.h b/g10/main.h index e336e5ce6..c7980ac9a 100644 --- a/g10/main.h +++ b/g10/main.h @@ -87,9 +87,12 @@ u16 checksum_mpi( gcry_mpi_t a ); u32 buffer_to_u32( const byte *buffer ); const byte *get_session_marker( size_t *rlen ); int map_cipher_openpgp_to_gcry (int algo); -#define openpgp_cipher_open(_a,_b,_c,_d) gcry_cipher_open((_a),map_cipher_openpgp_to_gcry((_b)),(_c),(_d)) -#define openpgp_cipher_get_algo_keylen(_a) gcry_cipher_get_algo_keylen(map_cipher_openpgp_to_gcry((_a))) -#define openpgp_cipher_get_algo_blklen(_a) gcry_cipher_get_algo_blklen(map_cipher_openpgp_to_gcry((_a))) +#define openpgp_cipher_open(_a,_b,_c,_d) \ + gcry_cipher_open((_a),map_cipher_openpgp_to_gcry((_b)),(_c),(_d)) +#define openpgp_cipher_get_algo_keylen(_a) \ + gcry_cipher_get_algo_keylen(map_cipher_openpgp_to_gcry((_a))) +#define openpgp_cipher_get_algo_blklen(_a) \ + gcry_cipher_get_algo_blklen(map_cipher_openpgp_to_gcry((_a))) int openpgp_cipher_blocklen (int algo); int openpgp_cipher_test_algo( int algo ); const char *openpgp_cipher_algo_name (int algo); @@ -159,7 +162,8 @@ int pubkey_get_nenc( int algo ); unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey ); int mpi_print (estream_t stream, gcry_mpi_t a, int mode); int iobuf_write_size_body_mpi (iobuf_t out, gcry_mpi_t a); -int iobuf_read_size_body(iobuf_t inp, byte *body, int body_max_size, int pktlen, gcry_mpi_t *out); +int iobuf_read_size_body (iobuf_t inp, byte *body, int body_max_size, + int pktlen, gcry_mpi_t *out); int ecdsa_qbits_from_Q( int qbits ); @@ -258,7 +262,9 @@ int save_unprotected_key_to_card (PKT_public_key *sk, int keyno); #define KEYGEN_FLAG_NO_PROTECTION 1 #define KEYGEN_FLAG_TRANSIENT_KEY 2 -int pk_ecc_keypair_gen( PKT_public_key **pk_out, int algo, int keygen_flags, char **cache_nonce_addr, unsigned nbits); +int pk_ecc_keypair_gen (PKT_public_key **pk_out, int algo, + int keygen_flags, char **cache_nonce_addr, + unsigned nbits); /*-- openfile.c --*/ int overwrite_filep( const char *fname ); diff --git a/g10/misc.c b/g10/misc.c index a09636b60..6f77119fe 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -1,6 +1,6 @@ /* misc.c - miscellaneous functions * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - * 2008, 2009 Free Software Foundation, Inc. + * 2008, 2009, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -366,10 +366,17 @@ map_cipher_gcry_to_openpgp (int algo) } } +/* Map OpenPGP public key algorithm numbers to those used by + Libgcrypt. */ int map_pk_openpgp_to_gcry (int algo) { - return (algo==PUBKEY_ALGO_ECDSA ? GCRY_PK_ECDSA : (algo==PUBKEY_ALGO_ECDH ? GCRY_PK_ECDH : algo)); + switch (algo) + { + case PUBKEY_ALGO_ECDSA: return GCRY_PK_ECDSA; + case PUBKEY_ALGO_ECDH: return GCRY_PK_ECDH; + default: return algo; + } } @@ -416,13 +423,7 @@ openpgp_cipher_test_algo( int algo ) const char * openpgp_cipher_algo_name (int algo) { - return gcry_cipher_algo_name (map_cipher_openpgp_to_gcry (algo)); -} - -const char * -openpgp_pk_algo_name (int algo) -{ - return gcry_pk_algo_name ( algo == PUBKEY_ALGO_ECDSA ? GCRY_PK_ECDSA : ( algo == PUBKEY_ALGO_ECDH ? GCRY_PK_ECDH : algo ) ); + return gnupg_cipher_algo_name (map_cipher_openpgp_to_gcry (algo)); } int @@ -438,12 +439,7 @@ openpgp_pk_test_algo( int algo ) if (algo < 0 || algo > 110) return gpg_error (GPG_ERR_PUBKEY_ALGO); - if( algo == PUBKEY_ALGO_ECDSA ) - algo = GCRY_PK_ECDSA; - else if( algo == PUBKEY_ALGO_ECDH ) - algo = GCRY_PK_ECDH; - - return gcry_pk_test_algo ( algo ); + return gcry_pk_test_algo (map_pk_openpgp_to_gcry (algo)); } int @@ -461,12 +457,8 @@ openpgp_pk_test_algo2( int algo, unsigned int use ) if (algo < 0 || algo > 110) return gpg_error (GPG_ERR_PUBKEY_ALGO); - if( algo == PUBKEY_ALGO_ECDSA ) - algo = GCRY_PK_ECDSA; - else if( algo == PUBKEY_ALGO_ECDH ) - algo = GCRY_PK_ECDH; - - return gcry_pk_algo_info ( algo, GCRYCTL_TEST_ALGO, NULL, &use_buf); + return gcry_pk_algo_info (map_pk_openpgp_to_gcry (algo), + GCRYCTL_TEST_ALGO, NULL, &use_buf); } int @@ -507,10 +499,12 @@ openpgp_pk_algo_usage ( int algo ) /* Map the OpenPGP pubkey algorithm whose ID is contained in ALGO to a string representation of the algorithm name. For unknown algorithm - IDs this function returns "?". + IDs this function returns "?". */ const char * openpgp_pk_algo_name (int algo) { + /* We use fixed strings to have pretty names instead of those from + libgcrypt. */ switch (algo) { case PUBKEY_ALGO_RSA: @@ -522,10 +516,13 @@ openpgp_pk_algo_name (int algo) case PUBKEY_ALGO_DSA: return "dsa"; - default: return "?"; + case PUBKEY_ALGO_ECDSA:return "ecdsa"; + + case PUBKEY_ALGO_ECDH: return "ecdh"; + + default: gcry_pk_algo_name (map_pk_openpgp_to_gcry (algo)); } } -*/ int @@ -1444,6 +1441,7 @@ pubkey_nbits( int algo, gcry_mpi_t *key ) int rc, nbits; gcry_sexp_t sexp; +#warning Why this assert assert( algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH ); if( algo == GCRY_PK_DSA ) { @@ -1506,10 +1504,12 @@ mpi_print (estream_t fp, gcry_mpi_t a, int mode) return n; } + /* - * Write a special size+body mpi a, to OUT. The format of the content of the MPI is - * one byte LEN, following by LEN bytes + * Write a special size+body mpi A, to OUT. The format of the content + * of the MPI is one byte LEN, following by LEN bytes. */ +/* FIXME: Rename this function: it is not in iobuf.c */ int iobuf_write_size_body_mpi (iobuf_t out, gcry_mpi_t a) { @@ -1538,57 +1538,68 @@ iobuf_write_size_body_mpi (iobuf_t out, gcry_mpi_t a) return iobuf_write( out, buffer, nbytes ); } + /* - * Read a special size+body from inp into body[body_max_size] and return it in a buffer and as MPI. - * On success the number of consumed bytes will body[0]+1. - * The format of the content of the returned MPI is one byte LEN, following by LEN bytes. - * Caller is expected to pre-allocate fixed-size 255 byte buffer (or smaller when appropriate). + * Read a special size+body from inp into body[body_max_size] and + * return it in a buffer and as MPI. On success the number of + * consumed bytes will body[0]+1. The format of the content of the + * returned MPI is one byte LEN, following by LEN bytes. Caller is + * expected to pre-allocate fixed-size 255 byte buffer (or smaller + * when appropriate). */ +/* FIXME: Rename this function: it is not in iobuf.c */ int -iobuf_read_size_body( iobuf_t inp, byte *body, int body_max_size, int pktlen, gcry_mpi_t *out ) { +iobuf_read_size_body (iobuf_t inp, byte *body, int body_max_size, + int pktlen, gcry_mpi_t *out ) +{ unsigned n; int rc; gcry_mpi_t result; *out = NULL; - if( (n = iobuf_readbyte(inp)) == -1 ) { - return G10ERR_INVALID_PACKET; - } - if( n >= body_max_size || n < 2) { - log_error("invalid size+body field\n"); - return G10ERR_INVALID_PACKET; - } + if( (n = iobuf_readbyte(inp)) == -1 ) + { + return G10ERR_INVALID_PACKET; + } + if ( n >= body_max_size || n < 2) + { + log_error("invalid size+body field\n"); + return G10ERR_INVALID_PACKET; + } body[0] = n; - if( (n = iobuf_read(inp, body+1, n)) == -1 ) { - log_error("invalid size+body field\n"); - return G10ERR_INVALID_PACKET; - } - if( n+1 > pktlen ) { - log_error("size+body field is larger than the packet\n"); - return G10ERR_INVALID_PACKET; - } + if ((n = iobuf_read(inp, body+1, n)) == -1) + { + log_error("invalid size+body field\n"); + return G10ERR_INVALID_PACKET; + } + if (n+1 > pktlen) + { + log_error("size+body field is larger than the packet\n"); + return G10ERR_INVALID_PACKET; + } rc = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, body, n+1, NULL); if (rc) log_fatal ("mpi_scan failed: %s\n", gpg_strerror (rc)); - + *out = result; - + return rc; } -/* pkey[1] or skey[1] is Q for ECDSA, which is an uncompressed point, i.e. 04 */ -int ecdsa_qbits_from_Q( int qbits ) { - if( qbits%8>3 ) { - log_error(_("ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n")); - return 0; - } - qbits -= qbits%8; - qbits /= 2; - return qbits; +/* pkey[1] or skey[1] is Q for ECDSA, which is an uncompressed point, + i.e. 04 */ +int +ecdsa_qbits_from_Q (int qbits ) +{ + if ((qbits%8) > 3) + { + log_error(_("ECDSA public key is expected to be in SEC encoding " + "multiple of 8 bits\n")); + return 0; + } + qbits -= qbits%8; + qbits /= 2; + return qbits; } - - - - diff --git a/g10/parse-packet.c b/g10/parse-packet.c index d43ab2cba..5df336e55 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -939,40 +939,47 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, } else { - if( k->pubkey_algo != PUBKEY_ALGO_ECDH ) { - for (i = 0; i < ndata; i++) - { - n = pktlen; - k->data[i] = mpi_read (inp, &n, 0); - pktlen -= n; - if (list_mode) - { - es_fprintf (listfp, "\tdata: "); - mpi_print (listfp, k->data[i], mpi_print_mode); - es_putc ('\n', listfp); - } - if (!k->data[i]) - rc = gpg_error (GPG_ERR_INV_PACKET); - } - } - else + if (k->pubkey_algo == PUBKEY_ALGO_ECDH) { - byte encr_buf[255]; - assert( ndata == 2 ); - n = pktlen; k->data[0] = mpi_read(inp, &n, 0); pktlen -=n; - rc = iobuf_read_size_body( inp, encr_buf, sizeof(encr_buf), pktlen, k->data+1 ); - if( rc ) - goto leave; - if( list_mode ) { - es_fprintf (listfp, "\tdata: "); - mpi_print(listfp, k->data[0], mpi_print_mode ); - es_putc ('\n', listfp); - es_fprintf (listfp, "\tdata: [% 3d bytes] ", encr_buf[0]+1); - mpi_print(listfp, k->data[1], mpi_print_mode ); - es_putc ('\n', listfp); - } - pktlen -= (encr_buf[0]+1); - } + byte encr_buf[255]; + + assert (ndata == 2); + n = pktlen; + k->data[0] = mpi_read (inp, &n, 0); + pktlen -= n; + rc = iobuf_read_size_body (inp, encr_buf, sizeof(encr_buf), + pktlen, k->data+1); + if (rc) + goto leave; + + if (list_mode) + { + es_fprintf (listfp, "\tdata: "); + mpi_print (listfp, k->data[0], mpi_print_mode ); + es_putc ('\n', listfp); + es_fprintf (listfp, "\tdata: [% 3d bytes] ", encr_buf[0]+1); + mpi_print (listfp, k->data[1], mpi_print_mode ); + es_putc ('\n', listfp); + } + pktlen -= (encr_buf[0]+1); + } + else + { + for (i = 0; i < ndata; i++) + { + n = pktlen; + k->data[i] = mpi_read (inp, &n, 0); + pktlen -= n; + if (list_mode) + { + es_fprintf (listfp, "\tdata: "); + mpi_print (listfp, k->data[i], mpi_print_mode); + es_putc ('\n', listfp); + } + if (!k->data[i]) + rc = gpg_error (GPG_ERR_INV_PACKET); + } + } } leave: @@ -1946,61 +1953,74 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, else { /* Fill in public key parameters. */ - if( algorithm != PUBKEY_ALGO_ECDSA && algorithm != PUBKEY_ALGO_ECDH ) { - for (i = 0; i < npkey; i++) - { - n = pktlen; - pk->pkey[i] = mpi_read (inp, &n, 0); - pktlen -= n; - if (list_mode) - { - es_fprintf (listfp, "\tpkey[%d]: ", i); - mpi_print (listfp, pk->pkey[i], mpi_print_mode); - es_putc ('\n', listfp); - } - if (!pk->pkey[i]) - err = gpg_error (GPG_ERR_INV_PACKET); - } - } - else { - /* note that the code in this function ignores the errors */ - byte name_oid[256]; - err = iobuf_read_size_body( inp, name_oid, sizeof(name_oid), pktlen, pk->pkey+0 ); - if( err ) - goto leave; - n = name_oid[0]; - if( list_mode ) - es_fprintf (listfp, "\tpkey[0]: curve OID [%d] ...%02x %02x\n", - n, name_oid[1+n-2], name_oid[1+n-1] ); - pktlen -= (n+1); - /* set item [1], which corresponds to the public key; these two fields are all we need to uniquely define the key */ - // log_debug("Parsing ecc public key in the public packet, pktlen=%lu\n", pktlen); - n = pktlen; pk->pkey[1] = mpi_read( inp, &n, 0 ); pktlen -=n; - if( pk->pkey[1]==NULL ) - err = gpg_error(G10ERR_INVALID_PACKET); - else if( list_mode ) { - es_fprintf (listfp, "\tpkey[1]: "); - mpi_print(listfp, pk->pkey[1], mpi_print_mode); - es_putc ('\n', listfp); + if (algorithm == PUBKEY_ALGO_ECDSA && algorithm == PUBKEY_ALGO_ECDH) + { + /* FIXME: The code in this function ignores the errors. */ + byte name_oid[256]; + + err = iobuf_read_size_body (inp, name_oid, sizeof(name_oid), + pktlen, pk->pkey+0); + if (err) + goto leave; + n = name_oid[0]; + if (list_mode) + es_fprintf (listfp, "\tpkey[0]: curve OID [%d] ...%02x %02x\n", + n, name_oid[1+n-2], name_oid[1+n-1]); + pktlen -= (n+1); + /* Set item [1], which corresponds to the public key; these + two fields are all we need to uniquely define the key/ */ + n = pktlen; + pk->pkey[1] = mpi_read( inp, &n, 0 ); + pktlen -=n; + if (!pk->pkey[1]) + err = gpg_error (GPG_ERR_INV_PACKET); + else if (list_mode) + { + es_fprintf (listfp, "\tpkey[1]: "); + mpi_print (listfp, pk->pkey[1], mpi_print_mode); + es_putc ('\n', listfp); } - /* One more field for ECDH */ - if( algorithm == PUBKEY_ALGO_ECDH ) { -#define kek_params name_oid - err = iobuf_read_size_body( inp, kek_params, sizeof(kek_params), pktlen, pk->pkey+2 ); - if( err ) - goto leave; - n = kek_params[0]; - if( kek_params[1] != 1 ) { - log_error("invalid ecdh KEK parameters field type in private key: understand type 1, but found 0x%02x\n", kek_params[1]); - err = gpg_error(G10ERR_INVALID_PACKET); - goto leave; - } - if( list_mode ) - es_fprintf (listfp, "\tpkey[2]: KEK params type=01 hash:%d sym-algo:%d\n", kek_params[1+n-2], kek_params[1+n-1] ); - pktlen -= (n+1); -#undef kek_params - } - } + /* One more field for ECDH. */ + if (algorithm == PUBKEY_ALGO_ECDH) + { + /* (NAMEOID holds the KEK params.) */ + err = iobuf_read_size_body (inp, name_oid, sizeof(name_oid), + pktlen, pk->pkey+2); + if (err) + goto leave; + n = name_oid[0]; + if (name_oid[1] != 1) + { + log_error ("invalid ecdh KEK parameters field type in " + "private key: understand type 1, " + "but found 0x%02x\n", name_oid[1]); + err = gpg_error (GPG_ERR_INV_PACKET); + goto leave; + } + if (list_mode) + es_fprintf (listfp, "\tpkey[2]: KEK params type=01 " + "hash:%d sym-algo:%d\n", + name_oid[1+n-2], name_oid[1+n-1]); + pktlen -= (n+1); + } + } + else + { + for (i = 0; i < npkey; i++) + { + n = pktlen; + pk->pkey[i] = mpi_read (inp, &n, 0); + pktlen -= n; + if (list_mode) + { + es_fprintf (listfp, "\tpkey[%d]: ", i); + mpi_print (listfp, pk->pkey[i], mpi_print_mode); + es_putc ('\n', listfp); + } + if (!pk->pkey[i]) + err = gpg_error (GPG_ERR_INV_PACKET); + } + } if (err) goto leave; } diff --git a/g10/pkglue.c b/g10/pkglue.c index 9050cc241..f5c85976f 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -1,5 +1,5 @@ /* pkglue.c - public key operations glue code - * Copyright (C) 2000, 2003 Free Software Foundation, Inc. + * Copyright (C) 2000, 2003, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -29,7 +29,8 @@ #include "pkglue.h" #include "main.h" - +/* FIXME: Better chnage the fucntion name because mpi_ is used by + gcrypt macros. */ gcry_mpi_t mpi_from_sexp (gcry_sexp_t sexp, const char * item) { @@ -45,101 +46,37 @@ mpi_from_sexp (gcry_sexp_t sexp, const char * item) } -/**************** - * Emulate our old PK interface here - sometime in the future we might - * change the internal design to directly fit to libgcrypt. - */ -int -pk_sign (int algo, gcry_mpi_t * data, gcry_mpi_t hash, gcry_mpi_t * skey) -{ - gcry_sexp_t s_sig, s_hash, s_skey; - int rc; - int gcry_pkalgo = map_pk_openpgp_to_gcry( algo ); - - /* make a sexp from skey */ - if (gcry_pkalgo == GCRY_PK_DSA) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", - skey[0], skey[1], skey[2], skey[3], skey[4]); - } - else if (gcry_pkalgo == GCRY_PK_RSA || gcry_pkalgo == GCRY_PK_RSA_S) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", - skey[0], skey[1], skey[2], skey[3], skey[4], - skey[5]); - } - else if (gcry_pkalgo == GCRY_PK_ELG || gcry_pkalgo == GCRY_PK_ELG_E) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", - skey[0], skey[1], skey[2], skey[3]); - } - else if (gcry_pkalgo == GCRY_PK_ECDSA) - { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(ecdsa(c%m)(q%m)(d%m)))", - skey[0], skey[1], skey[2] ); - } - else - return GPG_ERR_PUBKEY_ALGO; - - if (rc) - BUG (); - - /* put hash into a S-Exp s_hash */ - if (gcry_sexp_build (&s_hash, NULL, "%m", hash)) - BUG (); - - rc = gcry_pk_sign (&s_sig, s_hash, s_skey); - gcry_sexp_release (s_hash); - gcry_sexp_release (s_skey); - - if (rc) - ; - else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S) - data[0] = mpi_from_sexp (s_sig, "s"); - else - { - data[0] = mpi_from_sexp (s_sig, "r"); - data[1] = mpi_from_sexp (s_sig, "s"); - } - - gcry_sexp_release (s_sig); - return rc; -} /**************** * Emulate our old PK interface here - sometime in the future we might * change the internal design to directly fit to libgcrypt. */ int -pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) +pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey) { gcry_sexp_t s_sig, s_hash, s_pkey; int rc; - const int gcry_pkalgo = map_pk_openpgp_to_gcry( algo ); + const int pkalgo = map_pk_openpgp_to_gcry (algo); - /* make a sexp from pkey */ - if (gcry_pkalgo == GCRY_PK_DSA) + /* Make a sexp from pkey. */ + if (pkalgo == GCRY_PK_DSA) { rc = gcry_sexp_build (&s_pkey, NULL, "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", pkey[0], pkey[1], pkey[2], pkey[3]); } - else if (gcry_pkalgo == GCRY_PK_ELG || gcry_pkalgo == GCRY_PK_ELG_E) + else if (pkalgo == GCRY_PK_ELG || pkalgo == GCRY_PK_ELG_E) { rc = gcry_sexp_build (&s_pkey, NULL, "(public-key(elg(p%m)(g%m)(y%m)))", pkey[0], pkey[1], pkey[2]); } - else if (gcry_pkalgo == GCRY_PK_RSA || gcry_pkalgo == GCRY_PK_RSA_S) + else if (pkalgo == GCRY_PK_RSA || pkalgo == GCRY_PK_RSA_S) { rc = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]); } - else if (gcry_pkalgo == GCRY_PK_ECDSA) /* same as GCRY_PK_ECDH */ + else if (pkalgo == GCRY_PK_ECDSA) /* Same as GCRY_PK_ECDH */ { rc = gcry_sexp_build (&s_pkey, NULL, "(public-key(ecdsa(c%m)(q%m)))", pkey[0], pkey[1]); @@ -150,13 +87,13 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) if (rc) BUG (); /* gcry_sexp_build should never fail. */ - /* put hash into a S-Exp s_hash */ + /* Put hash into a S-Exp s_hash. */ if (gcry_sexp_build (&s_hash, NULL, "%m", hash)) BUG (); /* gcry_sexp_build should never fail. */ /* Put data into a S-Exp s_sig. */ s_sig = NULL; - if (gcry_pkalgo == GCRY_PK_DSA) + if (pkalgo == GCRY_PK_DSA) { if (!data[0] || !data[1]) rc = gpg_error (GPG_ERR_BAD_MPI); @@ -164,7 +101,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]); } - else if (gcry_pkalgo == GCRY_PK_ECDSA) + else if (pkalgo == GCRY_PK_ECDSA) { if (!data[0] || !data[1]) rc = gpg_error (GPG_ERR_BAD_MPI); @@ -172,7 +109,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(ecdsa(r%m)(s%m)))", data[0], data[1]); } - else if (gcry_pkalgo == GCRY_PK_ELG || gcry_pkalgo == GCRY_PK_ELG_E) + else if (pkalgo == GCRY_PK_ELG || pkalgo == GCRY_PK_ELG_E) { if (!data[0] || !data[1]) rc = gpg_error (GPG_ERR_BAD_MPI); @@ -180,7 +117,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(elg(r%m)(s%m)))", data[0], data[1]); } - else if (gcry_pkalgo == GCRY_PK_RSA || gcry_pkalgo == GCRY_PK_RSA_S) + else if (pkalgo == GCRY_PK_RSA || pkalgo == GCRY_PK_RSA_S) { if (!data[0]) rc = gpg_error (GPG_ERR_BAD_MPI); @@ -207,12 +144,13 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey) * change the internal design to directly fit to libgcrypt. */ int -pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t * pkey) +pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, + const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t *pkey) { gcry_sexp_t s_ciph, s_data, s_pkey; int rc; - /* make a sexp from pkey */ + /* Make a sexp from pkey. */ if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E) { rc = gcry_sexp_build (&s_pkey, NULL, @@ -227,7 +165,7 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, const byte pk_fp[MAX } else if (algo == PUBKEY_ALGO_ECDH) { - return pk_ecdh_encrypt( resarr, pk_fp, data, pkey ); + return pk_ecdh_encrypt (resarr, pk_fp, data, pkey); } else return GPG_ERR_PUBKEY_ALGO; @@ -235,11 +173,11 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, const byte pk_fp[MAX if (rc) BUG (); - /* put the data into a simple list */ + /* Put the data into a simple list. */ if (gcry_sexp_build (&s_data, NULL, "%m", data)) BUG (); - /* pass it to libgcrypt */ + /* Pass it to libgcrypt. */ rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); gcry_sexp_release (s_data); gcry_sexp_release (s_pkey); @@ -247,9 +185,11 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, const byte pk_fp[MAX if (rc) ; else - { /* add better error handling or make gnupg use S-Exp directly */ + { /* Add better error handling or make gnupg use S-Exp directly. */ resarr[0] = mpi_from_sexp (s_ciph, "a"); - if (algo != GCRY_PK_RSA && algo != GCRY_PK_RSA_E && algo != PUBKEY_ALGO_ECDH) + if (algo != GCRY_PK_RSA + && algo != GCRY_PK_RSA_E + && algo != PUBKEY_ALGO_ECDH) resarr[1] = mpi_from_sexp (s_ciph, "b"); } @@ -257,6 +197,7 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, const byte pk_fp[MAX return rc; } + /* Check whether SKEY is a suitable secret key. */ int pk_check_secret_key (int algo, gcry_mpi_t *skey) diff --git a/g10/pkglue.h b/g10/pkglue.h index a1c821dcd..0ceb43f55 100644 --- a/g10/pkglue.h +++ b/g10/pkglue.h @@ -1,5 +1,5 @@ /* pkglue.h - public key operations definitions - * Copyright (C) 2003 Free Software Foundation, Inc. + * Copyright (C) 2003, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -22,21 +22,19 @@ gcry_mpi_t mpi_from_sexp (gcry_sexp_t sexp, const char * item); -int pk_sign (int algo, gcry_mpi_t *data, gcry_mpi_t hash, - gcry_mpi_t *skey); int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey); int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, const byte fp[MAX_FINGERPRINT_LEN], gcry_mpi_t *pkey); -int pk_decrypt (int algo, gcry_mpi_t *result, const byte fp[MAX_FINGERPRINT_LEN], gcry_mpi_t *data, - gcry_mpi_t *skey); int pk_check_secret_key (int algo, gcry_mpi_t *skey); -int pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t * pkey); -int pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey); +int pk_ecdh_encrypt (gcry_mpi_t *resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], + gcry_mpi_t data, gcry_mpi_t * pkey); +int pk_ecdh_decrypt (gcry_mpi_t *result, const byte sk_fp[MAX_FINGERPRINT_LEN], + gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey); -gcry_mpi_t pk_ecdh_default_params_to_mpi( int qbits ); -byte *pk_ecdh_default_params( int qbits, size_t *sizeout ); +gcry_mpi_t pk_ecdh_default_params_to_mpi (int qbits); +byte *pk_ecdh_default_params (int qbits, size_t *sizeout); #endif /*GNUPG_G10_PKGLUE_H*/ diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 24411e8a1..ddca41ec4 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -218,68 +218,72 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) log_printhex ("DEK frame:", frame, nframe); n = 0; - if( sk->pubkey_algo != PUBKEY_ALGO_ECDH ) { - if (!card) - { - if (n + 7 > nframe) - { - err = gpg_error (G10ERR_WRONG_SECKEY); - goto leave; - } - if (frame[n] == 1 && frame[nframe - 1] == 2) - { - log_info (_("old encoding of the DEK is not supported\n")); - err = gpg_error (G10ERR_CIPHER_ALGO); - goto leave; - } - if (frame[n] != 2) /* Something went wrong. */ - { - err = gpg_error (G10ERR_WRONG_SECKEY); - goto leave; - } - for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes. */ - ; - n++; /* Skip the zero byte. */ - } - } - else { - gcry_mpi_t shared_mpi; - gcry_mpi_t decoded; + if (sk->pubkey_algo == PUBKEY_ALGO_ECDH) + { + gcry_mpi_t shared_mpi; + gcry_mpi_t decoded; + + /* At the beginning the frame are the bytes of shared point MPI. */ + err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL); + if (err) + { + log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); + goto leave; + } - /* at the beginning the frame is the bytes of shared point MPI */ - - err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL); - if (err) { - log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); - goto leave; + err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/, + shared_mpi, sk->pkey); + mpi_release (shared_mpi); + if(err) + goto leave; + + /* Reuse NFRAME, which size is sufficient to include the session key. */ + err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, decoded); + mpi_release (decoded); + if (err) + goto leave; + + /* Now the frame are the bytes decrypted but padded session key. */ + + /* Allow double padding for the benefit of DEK size concealment. + Higher than this is wasteful. */ + if (frame[nframe-1] > 8*2 || nframe <= 8) + { + err = gpg_error (GPG_ERR_WRONG_SECKEY); + goto leave; + } + nframe -= frame[nframe-1]; /* Remove padding. */ + assert (n); /* (used just below) */ } - - err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/, shared_mpi, sk->pkey); - mpi_release( shared_mpi ); - if( err ) - goto leave; - - /* reuse nframe, which size is sufficient to include the session key */ - err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, decoded); - mpi_release( decoded ); - if( err ) - goto leave; - - /* Now the frame is the bytes decrypted but padded session key */ - - /* Allow double padding for the benefit of DEK size concealment. - * Higher than this is wasteful. - */ - if( frame[nframe-1] > 8*2 || nframe <= 8 ) { - err = G10ERR_WRONG_SECKEY; goto leave; + else + { + if (!card) + { + if (n + 7 > nframe) + { + err = gpg_error (GPG_ERR_WRONG_SECKEY); + goto leave; + } + if (frame[n] == 1 && frame[nframe - 1] == 2) + { + log_info (_("old encoding of the DEK is not supported\n")); + err = gpg_error (GPG_ERR_CIPHER_ALGO); + goto leave; + } + if (frame[n] != 2) /* Something went wrong. */ + { + err = gpg_error (GPG_ERR_WRONG_SECKEY); + goto leave; + } + for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes. */ + ; + n++; /* Skip the zero byte. */ + } } - nframe -= frame[nframe-1]; /* remove padding */ - assert( n==0 ); /* used just bellow */ - } if (n + 4 > nframe) { - err = gpg_error (G10ERR_WRONG_SECKEY); + err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; } diff --git a/g10/seskey.c b/g10/seskey.c index e50cf5c02..fa6765dc6 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -1,6 +1,6 @@ /* seskey.c - make sesssion keys etc. * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, - * 2006, 2009 Free Software Foundation, Inc. + * 2006, 2009, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -76,109 +76,125 @@ make_session_key( DEK *dek ) gcry_mpi_t encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) { - size_t nframe = (nbits+7) / 8; - byte *p; - byte *frame; - int i,n; - u16 csum = 0; - gcry_mpi_t a; + size_t nframe = (nbits+7) / 8; + byte *p; + byte *frame; + int i,n; + u16 csum; + gcry_mpi_t a; + + if (DBG_CIPHER) + log_debug ("encode_session_key: encoding %d byte DEK", dek->keylen); - if( DBG_CIPHER ) - log_debug("encode_session_key: encoding %d byte DEK", dek->keylen); + csum = 0; + for (p = dek->key, i=0; i < dek->keylen; i++) + csum += *p++; - for( p = dek->key, i=0; i < dek->keylen; i++ ) - csum += *p++; + /* Shortcut for ECDH. It's padding is minimal to simply make the + output be a multiple of 8 bytes. */ + if (openpgp_pk_algo == PUBKEY_ALGO_ECDH) + { + /* Pad to 8 byte granulatiry; the padding byte is the number of + * padded bytes. + * + * A DEK(k bytes) CSUM(2 bytes) 0x 0x 0x 0x ... 0x + * +---- x times ---+ + */ + nframe = (( 1 + dek->keylen + 2 /* The value so far is always odd. */ + + 7 ) & (~7)); + + /* alg+key+csum fit and the size is congruent to 8. */ + assert (!(nframe%8) && nframe > 1 + dek->keylen + 2 ); + + frame = xmalloc_secure (nframe); + n = 0; + frame[n++] = dek->algo; + memcpy (frame+n, dek->key, dek->keylen); + n += dek->keylen; + frame[n++] = csum >> 8; + frame[n++] = csum; + i = nframe - n; /* Number of padded bytes. */ + memset (frame+n, i, i); /* Use it as the value of each padded byte. */ + assert (n+i == nframe); - /* Shortcut for ECDH. It's padding is minimal to simply make the output be a multiple of 8 bytes. */ - if( openpgp_pk_algo == PUBKEY_ALGO_ECDH ) { - /* pad to 8 byte granulatiry; the padding byte is the number of padded bytes. - * A DEK(k bytes) CSUM(2 bytes) 0x 0x 0x 0x ... 0x - * +---- x times ---+ - */ - nframe = ( 1 + dek->keylen + 2 /* the value so far is always odd */ + 7 ) & (~7); - assert( !(nframe%8) && nframe > 1 + dek->keylen + 2 ); /* alg+key+csum fit and the size is congruent to 8 */ - frame = xmalloc_secure( nframe ); - n = 0; - frame[n++] = dek->algo; - memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen; - frame[n++] = csum >>8; - frame[n++] = csum; - i = nframe - n; /* number padded bytes */ - memset( frame+n, i, i );/* use it as the value of each padded byte */ - assert( n+i == nframe ); - - if( DBG_CIPHER ) - log_debug("encode_session_key: [%d] %02x %02x %02x ... %02x %02x %02x", nframe, frame[0],frame[1],frame[2], frame[nframe-3],frame[nframe-2],frame[nframe-1]); - - if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, nframe, &nframe)) - BUG(); - xfree(frame); - return a; + if (DBG_CIPHER) + log_debug ("encode_session_key: " + "[%d] %02x %02x %02x ... %02x %02x %02x\n", + nframe, frame[0], frame[1], frame[2], + frame[nframe-3], frame[nframe-2], frame[nframe-1]); + + if (gcry_mpi_scan (&a, GCRYMPI_FMT_USG, frame, nframe, &nframe)) + BUG(); + xfree(frame); + return a; } + + /* The current limitation is that we can only use a session key + * whose length is a multiple of BITS_PER_MPI_LIMB + * I think we can live with that. + */ + if (dek->keylen + 7 > nframe || !nframe) + log_bug ("can't encode a %d bit key in a %d bits frame\n", + dek->keylen*8, nbits ); + + /* We encode the session key in this way: + * + * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) + * + * (But how can we store the leading 0 - the external representaion + * of MPIs doesn't allow leading zeroes =:-) + * + * RND are non-zero random bytes. + * A is the cipher algorithm + * DEK is the encryption key (session key) length k depends on the + * cipher algorithm (20 is used with blowfish160). + * CSUM is the 16 bit checksum over the DEK + */ - /* The current limitation is that we can only use a session key - * whose length is a multiple of BITS_PER_MPI_LIMB - * I think we can live with that. - */ - if( dek->keylen + 7 > nframe || !nframe ) - log_bug("can't encode a %d bit key in a %d bits frame\n", - dek->keylen*8, nbits ); - - /* We encode the session key in this way: - * - * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) - * - * (But how can we store the leading 0 - the external representaion - * of MPIs doesn't allow leading zeroes =:-) - * - * RND are non-zero random bytes. - * A is the cipher algorithm - * DEK is the encryption key (session key) length k depends on the - * cipher algorithm (20 is used with blowfish160). - * CSUM is the 16 bit checksum over the DEK - */ - - frame = xmalloc_secure( nframe ); - n = 0; - frame[n++] = 0; - frame[n++] = 2; - i = nframe - 6 - dek->keylen; - assert( i > 0 ); - p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM); - /* Replace zero bytes by new values. */ - for(;;) { - int j, k; - byte *pp; - - /* count the zero bytes */ - for(j=k=0; j < i; j++ ) - if( !p[j] ) - k++; - if( !k ) - break; /* okay: no zero bytes */ - k += k/128 + 3; /* better get some more */ - pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM); - for(j=0; j < i && k ;) { - if( !p[j] ) - p[j] = pp[--k]; - if (p[j]) - j++; + frame = xmalloc_secure( nframe ); + n = 0; + frame[n++] = 0; + frame[n++] = 2; + i = nframe - 6 - dek->keylen; + assert( i > 0 ); + p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM); + /* Replace zero bytes by new values. */ + for (;;) + { + int j, k; + byte *pp; + + /* Count the zero bytes. */ + for (j=k=0; j < i; j++ ) + if (!p[j]) + k++; + if (!k) + break; /* Okay: no zero bytes. */ + k += k/128 + 3; /* Better get some more. */ + pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM); + for (j=0; j < i && k ;) + { + if (!p[j]) + p[j] = pp[--k]; + if (p[j]) + j++; } - xfree(pp); + xfree (pp); } - memcpy( frame+n, p, i ); - xfree(p); - n += i; - frame[n++] = 0; - frame[n++] = dek->algo; - memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen; - frame[n++] = csum >>8; - frame[n++] = csum; - assert( n == nframe ); - if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe)) - BUG(); - xfree(frame); - return a; + memcpy (frame+n, p, i); + xfree (p); + n += i; + frame[n++] = 0; + frame[n++] = dek->algo; + memcpy (frame+n, dek->key, dek->keylen ); + n += dek->keylen; + frame[n++] = csum >>8; + frame[n++] = csum; + assert (n == nframe); + if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe)) + BUG(); + xfree (frame); + return a; } @@ -192,8 +208,8 @@ do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits, gcry_mpi_t a; if( len + asnlen + 4 > nframe ) - log_bug("can't encode a %d bit MD into a %d bits frame, algo=%d\n", - (int)(len*8), (int)nbits, algo); + log_bug ("can't encode a %d bit MD into a %d bits frame, algo=%d\n", + (int)(len*8), (int)nbits, algo); /* We encode the MD in this way: * @@ -240,26 +256,27 @@ gcry_mpi_t encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) { gcry_mpi_t frame; - int gcry_pkalgo; + int pkalgo; assert (hash_algo); assert (pk); - gcry_pkalgo = map_pk_openpgp_to_gcry( pk->pubkey_algo ); + pkalgo = map_pk_openpgp_to_gcry (pk->pubkey_algo); - if (gcry_pkalgo == GCRY_PK_DSA || gcry_pkalgo == GCRY_PK_ECDSA ) + if (pkalgo == GCRY_PK_DSA || pkalgo == GCRY_PK_ECDSA) { - /* It's a DSA signature, so find out the size of q. */ + /* It's a DSA signature, so find out the size of q. */ size_t qbytes = gcry_mpi_get_nbits (pk->pkey[1]); - /* pkey[1] is Q for ECDSA, which is an uncompressed point, i.e. 04 */ - if( gcry_pkalgo==GCRY_PK_ECDSA ) - qbytes = ecdsa_qbits_from_Q( qbytes ); - + /* pkey[1] is Q for ECDSA, which is an uncompressed point, + i.e. 04 */ + if (pkalgo == GCRY_PK_ECDSA) + qbytes = ecdsa_qbits_from_Q (qbytes); + /* Make sure it is a multiple of 8 bits. */ - - if(qbytes%8) + + if (qbytes%8) { log_error(_("DSA requires the hash length to be a" " multiple of 8 bits\n")); @@ -275,30 +292,38 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) if (qbytes < 160) { log_error (_("%s key %s uses an unsafe (%zu bit) hash\n"), - gcry_pk_algo_name( gcry_pkalgo ), - keystr_from_pk (pk), qbytes); + gcry_pk_algo_name (pkalgo), keystr_from_pk (pk), qbytes); return NULL; } - + qbytes /= 8; /* Check if we're too short. Too long is safe as we'll - automatically left-truncate. */ - /* This checks 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 will never pass for ECDSA 521 anyway as the only hash that intended to match it is SHA 512, but 512 < 521 ). - */ - if (gcry_md_get_algo_dlen (hash_algo) < ((gcry_pkalgo==GCRY_PK_ECDSA && qbytes>(521)/8) ? 512/8 : qbytes) ) + automatically left-truncate. + + FIXME: Check against FIPS. + This checks 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 will + never pass for ECDSA 521 anyway as the only hash that + intended to match it is SHA 512, but 512 < 521). */ + if (gcry_md_get_algo_dlen (hash_algo) + < ((pkalgo == GCRY_PK_ECDSA && qbytes > (521)/8) ? 512/8 : qbytes)) { - log_error (_("%s key %s requires a %zu bit or larger hash, used hash-algo=%d\n"), - gcry_pk_algo_name( gcry_pkalgo ), - keystr_from_pk(pk), qbytes*8, hash_algo); + log_error (_("%s key %s requires a %zu bit or larger hash " + "(hash is %s\n"), + gcry_pk_algo_name (pkalgo), + keystr_from_pk(pk), qbytes*8, + gcry_md_algo_name (hash_algo)); return NULL; } - /* Note that in case of ECDSA 521 hash is always smaller than the key size */ + /* Note that in case of ECDSA 521 hash is always smaller than + the key size. */ if (gcry_mpi_scan (&frame, GCRYMPI_FMT_USG, - gcry_md_read (md, hash_algo), gcry_md_get_algo_dlen (hash_algo), &qbytes)) + gcry_md_read (md, hash_algo), + gcry_md_get_algo_dlen (hash_algo), &qbytes)) BUG(); } else diff --git a/g10/sign.c b/g10/sign.c index ccf796446..30dc66d5f 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -436,14 +436,15 @@ hash_for (PKT_public_key *pk) { return recipient_digest_algo; } - else if(pk->pubkey_algo==PUBKEY_ALGO_DSA || pk->pubkey_algo==PUBKEY_ALGO_ECDSA ) + else if (pk->pubkey_algo == PUBKEY_ALGO_DSA + || pk->pubkey_algo == PUBKEY_ALGO_ECDSA) { unsigned int qbytes = gcry_mpi_get_nbits (pk->pkey[1]); - if( pk->pubkey_algo==PUBKEY_ALGO_ECDSA ) - qbytes = ecdsa_qbits_from_Q(qbytes); + if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA) + qbytes = ecdsa_qbits_from_Q (qbytes); qbytes = qbytes/8; - + /* It's a DSA key, so find a hash that is the same size as q or larger. If q is 160, assume it is an old DSA key and use a 160-bit hash unless --enable-dsa2 is set, in which case act @@ -924,12 +925,14 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { - if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_DSA || sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA ) + if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_DSA + || sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA) { - int temp_hashlen = gcry_mpi_get_nbits(sk_rover->pk->pkey[1]); + int temp_hashlen = (gcry_mpi_get_nbits + (sk_rover->pk->pkey[1])); - if( sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA ) - temp_hashlen = ecdsa_qbits_from_Q( temp_hashlen ); + if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA) + temp_hashlen = ecdsa_qbits_from_Q (temp_hashlen); temp_hashlen = (temp_hashlen+7)/8; /* Pick a hash that is large enough for our @@ -1482,13 +1485,14 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, if(opt.cert_digest_algo) digest_algo=opt.cert_digest_algo; - else if(pksk->pubkey_algo==PUBKEY_ALGO_RSA + else if(pksk->pubkey_algo == PUBKEY_ALGO_RSA && pk->version<4 && sigversion<4) digest_algo = DIGEST_ALGO_MD5; - else if(pksk->pubkey_algo==PUBKEY_ALGO_DSA) - digest_algo = match_dsa_hash (gcry_mpi_get_nbits (pksk->pkey[1])/8 ); - else if(pksk->pubkey_algo==PUBKEY_ALGO_ECDSA ) - digest_algo = match_dsa_hash (ecdsa_qbits_from_Q( gcry_mpi_get_nbits (pksk->pkey[1]) ) / 8); + else if(pksk->pubkey_algo == PUBKEY_ALGO_DSA) + digest_algo = match_dsa_hash (gcry_mpi_get_nbits (pksk->pkey[1])/8); + else if(pksk->pubkey_algo == PUBKEY_ALGO_ECDSA ) + digest_algo = match_dsa_hash (ecdsa_qbits_from_Q + (gcry_mpi_get_nbits (pksk->pkey[1]))/8); else digest_algo = DIGEST_ALGO_SHA1; } diff --git a/g10/verify-stubs.c b/g10/verify-stubs.c index d1f0aa105..c4c657b9f 100644 --- a/g10/verify-stubs.c +++ b/g10/verify-stubs.c @@ -1,6 +1,5 @@ /* To satisfy the linker for the gpgv target - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, - * 2007 Free Software Foundation, Inc. + * Copyright (C) 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -25,6 +24,8 @@ #include "main.h" int -pk_ecc_keypair_gen( PKT_public_key **pk_out, int algo, int keygen_flags, char **cache_nonce_addr, unsigned nbits) { - return GPG_ERR_NOT_IMPLEMENTED; +pk_ecc_keypair_gen (PKT_public_key **pk_out, int algo, int keygen_flags, + char **cache_nonce_addr, unsigned nbits) +{ + return GPG_ERR_NOT_IMPLEMENTED; } diff --git a/g13/utils.c b/g13/utils.c index 1ea7f3275..4b374df10 100644 --- a/g13/utils.c +++ b/g13/utils.c @@ -176,7 +176,5 @@ next_tuple (tupledesc_t tupledesc, unsigned int *r_tag, size_t *r_length) } return NULL; -} - - +} diff --git a/include/ChangeLog b/include/ChangeLog index 339800f37..7c1b372ab 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,9 @@ +2011-01-21 Werner Koch + + * cipher.h (GCRY_PK_USAGE_CERT): Remove comaptibility macros + because we now require libgcrypt 1.4.6. + (GCRY_PK_ECDH): Add replacement. + 2009-08-20 Daiki Ueno (wk) * cipher.h (struct DEK): Add field S2K_CACHEID. diff --git a/include/cipher.h b/include/cipher.h index 65cd59e76..03d38da5b 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -1,6 +1,6 @@ /* cipher.h - Definitions for OpenPGP * Copyright (C) 1998, 1999, 2000, 2001, 2006, - * 2007 Free Software Foundation, Inc. + * 2007, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -23,10 +23,8 @@ #include /* Macros for compatibility with older libgcrypt versions. */ -#ifndef GCRY_PK_USAGE_CERT -# define GCRY_PK_USAGE_CERT 4 -# define GCRY_PK_USAGE_AUTH 8 -# define GCRY_PK_USAGE_UNKN 128 +#ifndef HAVE_GCRY_PK_ECDSA +# define GCRY_PK_ECDH 302 #endif @@ -56,8 +54,8 @@ #define PUBKEY_ALGO_RSA_S /* 3 */ GCRY_PK_RSA_S /* RSA sign only. */ #define PUBKEY_ALGO_ELGAMAL_E /* 16 */ GCRY_PK_ELG_E /* Elgamal encr only */ #define PUBKEY_ALGO_DSA /* 17 */ GCRY_PK_DSA -#define PUBKEY_ALGO_ECDH 18 /* corresponds to GCRY_PK_ECDH ECC DH; encrypt only */ -#define PUBKEY_ALGO_ECDSA 19 /* corresponds to GCRY_PK_ECDSA ECC DSA; sign only */ +#define PUBKEY_ALGO_ECDH 18 +#define PUBKEY_ALGO_ECDSA 19 #define PUBKEY_ALGO_ELGAMAL /* 20 */ GCRY_PK_ELG /* Elgamal encr+sign */ #define PUBKEY_USAGE_SIG GCRY_PK_USAGE_SIGN /* Good for signatures. */ diff --git a/kbx/keybox-openpgp.c b/kbx/keybox-openpgp.c index 6c9410e05..f1de685cf 100644 --- a/kbx/keybox-openpgp.c +++ b/kbx/keybox-openpgp.c @@ -245,6 +245,7 @@ parse_key (const unsigned char *data, size_t datalen, break; case 18: /* ECDH */ npkey = 3; + break; case 19: /* ECDSA */ npkey = 2; break; From 27929981fc23fabecf6af9fa1361361b821bb2fd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 21 Jan 2011 15:22:41 +0100 Subject: [PATCH 09/26] 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 ++++++++++++++++++--------------- g10/ChangeLog | 4 ++++ g10/misc.c | 20 +------------------- g10/sign.c | 3 +++ include/ChangeLog | 2 +- 6 files changed, 29 insertions(+), 35 deletions(-) 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); } diff --git a/g10/ChangeLog b/g10/ChangeLog index 0c8cbd418..75415f466 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,7 @@ +2011-01-21 Werner Koch + + * misc.c (openpgp_pk_algo_name): Always use the gcrypt function. + 2010-12-09 Werner Koch * tdbio.c (tdbio_set_dbname) [W32CE]: Take care of missing errno. diff --git a/g10/misc.c b/g10/misc.c index 6f77119fe..bdd797c16 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -503,25 +503,7 @@ openpgp_pk_algo_usage ( int algo ) const char * openpgp_pk_algo_name (int algo) { - /* We use fixed strings to have pretty names instead of those from - libgcrypt. */ - switch (algo) - { - case PUBKEY_ALGO_RSA: - case PUBKEY_ALGO_RSA_E: - case PUBKEY_ALGO_RSA_S: return "rsa"; - - case PUBKEY_ALGO_ELGAMAL: - case PUBKEY_ALGO_ELGAMAL_E: return "elg"; - - case PUBKEY_ALGO_DSA: return "dsa"; - - case PUBKEY_ALGO_ECDSA:return "ecdsa"; - - case PUBKEY_ALGO_ECDH: return "ecdh"; - - default: gcry_pk_algo_name (map_pk_openpgp_to_gcry (algo)); - } + return gcry_pk_algo_name (map_pk_openpgp_to_gcry (algo)); } diff --git a/g10/sign.c b/g10/sign.c index 30dc66d5f..cbb3c62e8 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -298,6 +298,9 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig, { PKT_public_key *pk = xmalloc_clear (sizeof *pk); + log_debug ("checking created signature algo=%d\n", mdalgo); + log_printhex ("md:", dp, gcry_md_get_algo_dlen (mdalgo)); + if (get_pubkey (pk, sig->keyid )) err = gpg_error (GPG_ERR_NO_PUBKEY); else diff --git a/include/ChangeLog b/include/ChangeLog index 7c1b372ab..8dd88ffbb 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,6 +1,6 @@ 2011-01-21 Werner Koch - * cipher.h (GCRY_PK_USAGE_CERT): Remove comaptibility macros + * cipher.h (GCRY_PK_USAGE_CERT): Remove compatibility macros because we now require libgcrypt 1.4.6. (GCRY_PK_ECDH): Add replacement. From c3db7705c049e31e678ff87e230b8160aa0027f1 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Fri, 21 Jan 2011 15:58:07 +0100 Subject: [PATCH 10/26] Truncate the DSA hash; fixes regression. Removed left over debug code. --- g10/ChangeLog | 2 ++ g10/seskey.c | 10 ++++++---- g10/sign.c | 3 --- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 75415f466..8e79587d8 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,5 +1,7 @@ 2011-01-21 Werner Koch + * seskey.c (encode_md_value): Truncate the DSA hash again. + * misc.c (openpgp_pk_algo_name): Always use the gcrypt function. 2010-12-09 Werner Koch diff --git a/g10/seskey.c b/g10/seskey.c index fa6765dc6..2d7918d39 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -319,11 +319,13 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) return NULL; } - /* Note that in case of ECDSA 521 hash is always smaller than - the key size. */ + /* By passing QBYTES as length to mpi_scan, we do the truncation + of the hash. + + Note that in case of ECDSA 521 the hash is always smaller + than the key size. */ if (gcry_mpi_scan (&frame, GCRYMPI_FMT_USG, - gcry_md_read (md, hash_algo), - gcry_md_get_algo_dlen (hash_algo), &qbytes)) + gcry_md_read (md, hash_algo), qbytes, &qbytes)) BUG(); } else diff --git a/g10/sign.c b/g10/sign.c index cbb3c62e8..30dc66d5f 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -298,9 +298,6 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig, { PKT_public_key *pk = xmalloc_clear (sizeof *pk); - log_debug ("checking created signature algo=%d\n", mdalgo); - log_printhex ("md:", dp, gcry_md_get_algo_dlen (mdalgo)); - if (get_pubkey (pk, sig->keyid )) err = gpg_error (GPG_ERR_NO_PUBKEY); else From b3adbb576e88a12ee9e7ea790a72ad5f1bff4c78 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 24 Jan 2011 12:02:35 +0100 Subject: [PATCH 11/26] Fix regression introduced by "editing only change". Signing and verification using a new key works again. --- g10/parse-packet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 5df336e55..334a9a82b 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1953,7 +1953,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, else { /* Fill in public key parameters. */ - if (algorithm == PUBKEY_ALGO_ECDSA && algorithm == PUBKEY_ALGO_ECDH) + if (algorithm == PUBKEY_ALGO_ECDSA || algorithm == PUBKEY_ALGO_ECDH) { /* FIXME: The code in this function ignores the errors. */ byte name_oid[256]; From e9d9e96d8ba464a1652552c33636819eed1e9f9a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 24 Jan 2011 15:50:37 +0100 Subject: [PATCH 12/26] Fix ECDH configure test --- common/ChangeLog | 5 ----- configure.ac | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/common/ChangeLog b/common/ChangeLog index 61f6b292b..0150658e0 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -50,11 +50,6 @@ * session-env.c (update_var): Fix same value detection. Fixes bug#1311. -2011-01-10 Werner Koch - - * session-env.c (update_var): Fix same value detection. Fixes - bug#1311. - 2010-12-17 Werner Koch * asshelp.c (lock_spawning): Add arg VERBOSE. Improve timeout diff --git a/configure.ac b/configure.ac index a944e80ac..e24117b28 100644 --- a/configure.ac +++ b/configure.ac @@ -746,7 +746,7 @@ AC_CACHE_CHECK([whether Libgcrypt support ECDH], gnupg_cv_gcry_pk_ecdh, [ _gnupg_gcry_save_cflags=$CFLAGS CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS" AC_TRY_COMPILE( - [#include ], + [#include ], [ return GCRY_PK_ECDH; ], gnupg_cv_gcry_pk_ecdh=yes, gnupg_cv_gcry_pk_ecdh=no) From b9958bba10f40a348d40c173701d15cb6b0a7f66 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 24 Jan 2011 18:16:03 +0100 Subject: [PATCH 13/26] Fix another stupid bug ECDH detection bug Again reported by Johan van Selst. Let's see whether this one is okay. --- include/cipher.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/cipher.h b/include/cipher.h index 03d38da5b..311020857 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -23,7 +23,7 @@ #include /* Macros for compatibility with older libgcrypt versions. */ -#ifndef HAVE_GCRY_PK_ECDSA +#ifndef HAVE_GCRY_PK_ECDH # define GCRY_PK_ECDH 302 #endif From 638dca5dbc7e119ff5a05dbdb109fbc171624605 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 25 Jan 2011 16:54:18 +0100 Subject: [PATCH 14/26] Editorial cleanups of keygen.c Also fixed a regression introduced by me in pubkey_enc.c. Added extra checks. Removed unused code. --- g10/ChangeLog | 18 +++ g10/Makefile.am | 3 +- g10/keygen.c | 339 ++++++++++++++++++--------------------------- g10/main.h | 5 - g10/pubkey-enc.c | 29 ++-- g10/verify-stubs.c | 31 ----- 6 files changed, 167 insertions(+), 258 deletions(-) delete mode 100644 g10/verify-stubs.c diff --git a/g10/ChangeLog b/g10/ChangeLog index 4c28363a2..801146459 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,21 @@ +2011-01-25 Werner Koch + + * pubkey-enc.c (get_it): Fix assertion. + Use GPG_ERR_WRONG_SECKEY instead of log_fatal. Add safety checks + for NFRAME. + + * main.h (KEYGEN_FLAG_NO_PROTECTION, KEYGEN_FLAG_TRANSIENT_KEY): + Move back to .. + * keygen.c: .. here. + (pk_ecc_keypair_gen): Make static. + (common_key_gen): Fold back into .. + (common_gen): .. this. + (delme__pk_ecc_build_sexp): Remove unused function. + (pk_ecc_keypair_gen): Fold it into .. + (gen_ecc): .. this. + (ask_keysize): Use proper rounding for ECC. + * verify-stubs.c: Remove. + 2011-01-20 Werner Koch * keyserver.c: Rewrite most stuff for use with dirmngr. Get rid diff --git a/g10/Makefile.am b/g10/Makefile.am index 5d2470207..a28b2ab50 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -111,8 +111,7 @@ gpg2_SOURCES = gpg.c \ gpgv2_SOURCES = gpgv.c \ $(common_source) \ - verify.c \ - verify-stubs.c + verify.c #gpgd_SOURCES = gpgd.c \ # ks-proto.h \ 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,141 +1342,104 @@ 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) { - 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 +/* + * 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, + u32 timestamp, u32 expireval, int is_subkey, int keygen_flags, char **cache_nonce_addr) { - int rc; - PACKET *pkt; - PKT_public_key *pk; + int err; + unsigned int qbits; + char *keyparms; - rc = pk_ecc_keypair_gen( &pk, algo, keygen_flags, cache_nonce_addr, nbits ); - if( rc ) - return rc; + assert (algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH); - /* the rest is very similar to common_gen */ + 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. */ + } - pk->timestamp = timestamp; - if (expireval) - pk->expiredate = pk->timestamp + expireval; + if (nbits != 256 && nbits != 384 && nbits != 521) + { + log_info (_("keysize invalid; using %u bits\n"), 256); + /* FIXME: Where do we set it to 256? */ + } - //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' */ + /* 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 ); - 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 )); + 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_gen (keyparms, algo, + algo == PUBKEY_ALGO_ECDSA? "cq" : "cqp", + pub_root, timestamp, expireval, is_subkey, + keygen_flags, cache_nonce_addr); + xfree (keyparms); + } 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) diff --git a/g10/main.h b/g10/main.h index 1b6f30516..ea1ac2e1f 100644 --- a/g10/main.h +++ b/g10/main.h @@ -260,11 +260,6 @@ gpg_error_t generate_card_subkeypair (kbnode_t pub_keyblock, int save_unprotected_key_to_card (PKT_public_key *sk, int keyno); #endif -#define KEYGEN_FLAG_NO_PROTECTION 1 -#define KEYGEN_FLAG_TRANSIENT_KEY 2 -int pk_ecc_keypair_gen (PKT_public_key **pk_out, int algo, - int keygen_flags, char **cache_nonce_addr, - unsigned nbits); /*-- openfile.c --*/ int overwrite_filep( const char *fname ); diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index ddca41ec4..43f5419db 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -145,18 +145,17 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) gcry_sexp_t s_data; char *desc; char *keygrip; - byte fp[MAX_FINGERPRINT_LEN]; + byte fp[MAX_FINGERPRINT_LEN]; size_t fpn; - const int gcry_pkalgo = map_pk_openpgp_to_gcry( sk->pubkey_algo ); + const int pkalgo = map_pk_openpgp_to_gcry (sk->pubkey_algo); /* Get the keygrip. */ err = hexkeygrip_from_pk (sk, &keygrip); if (err) goto leave; - /* Convert the data to an S-expression. */ - if (gcry_pkalgo == GCRY_PK_ELG ||gcry_pkalgo == GCRY_PK_ELG_E) + if (pkalgo == GCRY_PK_ELG || pkalgo == GCRY_PK_ELG_E) { if (!enc->data[0] || !enc->data[1]) err = gpg_error (GPG_ERR_BAD_MPI); @@ -164,7 +163,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))", enc->data[0], enc->data[1]); } - else if (gcry_pkalgo == GCRY_PK_RSA || gcry_pkalgo == GCRY_PK_RSA_E) + else if (pkalgo == GCRY_PK_RSA || pkalgo == GCRY_PK_RSA_E) { if (!enc->data[0]) err = gpg_error (GPG_ERR_BAD_MPI); @@ -172,12 +171,12 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) err = gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", enc->data[0]); } - else if (gcry_pkalgo == GCRY_PK_ECDH ) + else if (pkalgo == GCRY_PK_ECDH) { if (!enc->data[0] || !enc->data[1]) err = gpg_error (GPG_ERR_BAD_MPI); else - err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(a%m)(b%m)))", + err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(a%m)(b%m)))", enc->data[0], enc->data[1]); } else @@ -186,8 +185,9 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) if (err) goto leave; - fingerprint_from_pk( sk, fp, &fpn ); - assert( fpn == 20 ); + /* fixme: only needed for ECDH. Don't compute always. */ + fingerprint_from_pk (sk, fp, &fpn); + assert (fpn == 20); /* Decrypt. */ desc = gpg_format_keydesc (sk, 0, 1); @@ -222,12 +222,12 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) { gcry_mpi_t shared_mpi; gcry_mpi_t decoded; - + /* At the beginning the frame are the bytes of shared point MPI. */ err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL); if (err) { - log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); + err = gpg_error (GPG_ERR_WRONG_SECKEY); goto leave; } @@ -247,13 +247,14 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) /* Allow double padding for the benefit of DEK size concealment. Higher than this is wasteful. */ - if (frame[nframe-1] > 8*2 || nframe <= 8) + if (!nframe || frame[nframe-1] > 8*2 || nframe <= 8 + || frame[nframe-1] > nframe) { err = gpg_error (GPG_ERR_WRONG_SECKEY); - goto leave; + goto leave; } nframe -= frame[nframe-1]; /* Remove padding. */ - assert (n); /* (used just below) */ + assert (!n); /* (used just below) */ } else { diff --git a/g10/verify-stubs.c b/g10/verify-stubs.c deleted file mode 100644 index c4c657b9f..000000000 --- a/g10/verify-stubs.c +++ /dev/null @@ -1,31 +0,0 @@ -/* To satisfy the linker for the gpgv target - * Copyright (C) 2010 Free Software Foundation, Inc. - * - * This file is part of GnuPG. - * - * GnuPG is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuPG is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - */ - -#include - -#include -#include "gpg.h" -#include "main.h" - -int -pk_ecc_keypair_gen (PKT_public_key **pk_out, int algo, int keygen_flags, - char **cache_nonce_addr, unsigned nbits) -{ - return GPG_ERR_NOT_IMPLEMENTED; -} From 302c5a826c0fd0b2aab85ad3c287b65429db2066 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 25 Jan 2011 17:48:51 +0100 Subject: [PATCH 15/26] More ECDH code cleanups --- g10/ChangeLog | 6 +++ g10/ecdh.c | 104 +++++++++++++++----------------------------------- g10/keygen.c | 61 ++++++++++++++++------------- g10/pkglue.h | 6 ++- 4 files changed, 74 insertions(+), 103 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 801146459..3ce4d1fac 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,5 +1,9 @@ 2011-01-25 Werner Koch + * ecdh.c (pk_ecdh_default_params_to_mpi): Remove. + (pk_ecdh_default_params): Rewrite. Factor KEK table out to .. + (kek_params_table): .. here. + * pubkey-enc.c (get_it): Fix assertion. Use GPG_ERR_WRONG_SECKEY instead of log_fatal. Add safety checks for NFRAME. @@ -14,6 +18,8 @@ (pk_ecc_keypair_gen): Fold it into .. (gen_ecc): .. this. (ask_keysize): Use proper rounding for ECC. + (pk_ecc_build_key_params): Remove NBITSSTR. + * verify-stubs.c: Remove. 2011-01-20 Werner Koch diff --git a/g10/ecdh.c b/g10/ecdh.c index cb251fef2..1fa36aa21 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -30,26 +30,15 @@ #include "main.h" #include "options.h" -gcry_mpi_t -pk_ecdh_default_params_to_mpi (int qbits) +/* A table with the default KEK parameters used by GnuPG. */ +static const struct { - gpg_error_t err; - gcry_mpi_t result; - /* Defaults are the strongest possible choices. Performance is not - an issue here, only interoperability. */ - byte kek_params[4] = { - 3 /*size of following field*/, - 1 /*fixed version for KDF+AESWRAP*/, - DIGEST_ALGO_SHA512 /* KEK MD */, - CIPHER_ALGO_AES256 /*KEK AESWRAP alg*/ - }; - int i; - - static const struct { - int qbits; - int openpgp_hash_id; - int openpgp_cipher_id; - } kek_params_table[] = { + unsigned int qbits; + int openpgp_hash_id; /* KEK digest algorithm. */ + int openpgp_cipher_id; /* KEK cipher algorithm. */ +} kek_params_table[] = + /* Note: Must be sorted by ascending values for QBITS. */ + { { 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES }, { 384, DIGEST_ALGO_SHA384, CIPHER_ALGO_AES256 }, @@ -57,77 +46,44 @@ pk_ecdh_default_params_to_mpi (int qbits) { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 } }; - for (i=0; i= qbits) - { - kek_params[2] = kek_params_table[i].openpgp_hash_id; - kek_params[3] = kek_params_table[i].openpgp_cipher_id; - break; - } - } - if (DBG_CIPHER) - log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params) ); - - err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, - kek_params, sizeof(kek_params), NULL); - if (err) - log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); - - return result; -} /* Returns allocated (binary) KEK parameters; the size is returned in - * sizeout. The caller must free the returned value with xfree. - * Returns NULL on error. - */ + sizeout. The caller must free the returned value. Returns NULL + and sets ERRNO on error. */ byte * -pk_ecdh_default_params (int qbits, size_t *sizeout) +pk_ecdh_default_params (unsigned int qbits, size_t *sizeout) { - /* Defaults are the strongest possible choices. Performance is not - an issue here, only interoperability. */ - byte kek_params[4] = { - 3 /*size of following field*/, - 1 /*fixed version for KDF+AESWRAP*/, - DIGEST_ALGO_SHA512 /* KEK MD */, - CIPHER_ALGO_AES256 /* KEK AESWRAP alg */ - }; + byte kek_params[4]; int i; - - static const struct { - int qbits; - int openpgp_hash_id; - int openpgp_cipher_id; - } kek_params_table[] = { - { 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES }, - { 384, DIGEST_ALGO_SHA384, CIPHER_ALGO_AES256 }, - /* Note: 528 is 521 rounded to the 8 bit boundary */ - { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 } - }; + byte *buffer; - byte *p; - - *sizeout = 0; + kek_params[0] = 3; /* Number of bytes to follow. */ + kek_params[1] = 1; /* Version for KDF+AESWRAP. */ - for (i=0; i= qbits) + if (kek_params_table[i].qbits >= qbits + || i+1 == DIM (kek_params_table)) { kek_params[2] = kek_params_table[i].openpgp_hash_id; kek_params[3] = kek_params_table[i].openpgp_cipher_id; break; } } - if (DBG_CIPHER ) - log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params)); - - p = xtrymalloc (sizeof(kek_params)); - if (!p) + assert (i < DIM (kek_params_table)); + if (DBG_CIPHER) + log_printhex ("ECDH KEK params are", kek_params, sizeof(kek_params) ); + + buffer = xtrymalloc (sizeof(kek_params)); + if (!buffer) return NULL; - memcpy (p, kek_params, sizeof(kek_params)); - *sizeout = sizeof(kek_params); - return p; + memcpy (buffer, kek_params, sizeof (kek_params)); + *sizeout = sizeof (kek_params); + return buffer; } 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) - { - n = strlen (keyparms); - keyparms = xtryrealloc (keyparms, n + kek_params_size + 4); - } - 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) { xfree (kek_params); return NULL; } - memcpy (keyparms+n, kek_params, kek_params_size); - xfree (kek_params); - memcpy (keyparms+n+kek_params_size, ")))", 4); + /* 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, ")))"); } - return keyparms; + xfree (kek_params); + return result; } diff --git a/g10/pkglue.h b/g10/pkglue.h index 0ceb43f55..b1cfbe507 100644 --- a/g10/pkglue.h +++ b/g10/pkglue.h @@ -20,6 +20,7 @@ #ifndef GNUPG_G10_PKGLUE_H #define GNUPG_G10_PKGLUE_H +/*-- pkglue.c --*/ gcry_mpi_t mpi_from_sexp (gcry_sexp_t sexp, const char * item); int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, @@ -29,12 +30,13 @@ int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *pkey); int pk_check_secret_key (int algo, gcry_mpi_t *skey); + +/*-- ecdh.c --*/ +byte *pk_ecdh_default_params (unsigned int qbits, size_t *sizeout); int pk_ecdh_encrypt (gcry_mpi_t *resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t * pkey); int pk_ecdh_decrypt (gcry_mpi_t *result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey); -gcry_mpi_t pk_ecdh_default_params_to_mpi (int qbits); -byte *pk_ecdh_default_params (int qbits, size_t *sizeout); #endif /*GNUPG_G10_PKGLUE_H*/ From d879c287ac1da7990c97b911018d63410c60433c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 25 Jan 2011 20:28:25 +0100 Subject: [PATCH 16/26] Started with some code cleanups in ECDH. The goal is to have the ECDH code more uniform with the other algorithms. Also make error messages and variable names more similar to other places. --- g10/ChangeLog | 3 + g10/ecdh.c | 212 +++++++++++++++++++++----------------------------- g10/misc.c | 2 +- g10/pkglue.c | 70 +++++++++++++---- g10/pkglue.h | 7 ++ 5 files changed, 158 insertions(+), 136 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 3ce4d1fac..9e1aa01da 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -3,6 +3,9 @@ * ecdh.c (pk_ecdh_default_params_to_mpi): Remove. (pk_ecdh_default_params): Rewrite. Factor KEK table out to .. (kek_params_table): .. here. + (pk_ecdh_generate_ephemeral_key): New. + (pk_ecdh_encrypt): Remove. + (pk_ecdh_encrypt_with_shared_point): Make public. * pubkey-enc.c (get_it): Fix assertion. Use GPG_ERR_WRONG_SECKEY instead of log_fatal. Add safety checks diff --git a/g10/ecdh.c b/g10/ecdh.c index 1fa36aa21..71c32fd5d 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -87,20 +87,26 @@ pk_ecdh_default_params (unsigned int qbits, size_t *sizeout) } -/* Encrypts/decrypts 'data' with a key derived from shared_mpi ECC - * point using FIPS SP 800-56A compliant method, which is key - * derivation + key wrapping. The direction is determined by the first - * parameter (is_encrypt=1 --> this is encryption). The result is - * returned in out as a size+value MPI. - * - * TODO: memory leaks (x_secret). +/* Encrypts/decrypts DATA using a key derived from the ECC shared + point SHARED_MPI using the FIPS SP 800-56A compliant method + key_derivation+key_wrapping. If IS_ENCRYPT is true the function + encrypts; if false, it decrypts. On success the result is stored + at R_RESULT; on failure NULL is stored at R_RESULT and an error + code returned. + + FIXME: explain PKEY and PK_FP. */ -static int + +/* + TODO: memory leaks (x_secret). +*/ +gpg_error_t pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t *pkey, - gcry_mpi_t *out) + gcry_mpi_t *r_result) { + gpg_error_t err; byte *secret_x; int secret_x_size; byte kdf_params[256]; @@ -108,47 +114,54 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, int nbits; int kdf_hash_algo; int kdf_encr_algo; - int rc; - *out = NULL; + *r_result = NULL; - nbits = pubkey_nbits( PUBKEY_ALGO_ECDH, pkey ); + nbits = pubkey_nbits (PUBKEY_ALGO_ECDH, pkey); + if (!nbits) + return gpg_error (GPG_ERR_TOO_SHORT); { size_t nbytes; + /* Extract x component of the shared point: this is the actual - shared secret */ + shared secret. */ nbytes = (mpi_get_nbits (pkey[1] /* public point */)+7)/8; - secret_x = xmalloc_secure( nbytes ); - rc = gcry_mpi_print (GCRYMPI_FMT_USG, secret_x, nbytes, - &nbytes, shared_mpi); - if (rc) + secret_x = xtrymalloc_secure (nbytes); + if (!secret_x) + return gpg_error_from_syserror (); + + err = gcry_mpi_print (GCRYMPI_FMT_USG, secret_x, nbytes, + &nbytes, shared_mpi); + if (err) { xfree (secret_x); - log_error ("ec ephemeral export of shared point failed: %s\n", - gpg_strerror (rc)); - return rc; + log_error ("ECDH ephemeral export of shared point failed: %s\n", + gpg_strerror (err)); + return err; } + + /* fixme: explain what we are doing. */ secret_x_size = (nbits+7)/8; assert (nbytes > secret_x_size); memmove (secret_x, secret_x+1, secret_x_size); memset (secret_x+secret_x_size, 0, nbytes-secret_x_size); if (DBG_CIPHER) - log_printhex ("ecdh shared secret X is:", secret_x, secret_x_size ); + log_printhex ("ECDH shared secret X is:", secret_x, secret_x_size ); } /*** We have now the shared secret bytes in secret_x. ***/ /* At this point we are done with PK encryption and the rest of the * function uses symmetric key encryption techniques to protect the - * input 'data'. The following two sections will simply replace + * input DATA. The following two sections will simply replace * current secret_x with a value derived from it. This will become * a KEK. */ { IOBUF obuf = iobuf_temp(); - rc = iobuf_write_size_body_mpi ( obuf, pkey[2] ); /* KEK params */ + err = iobuf_write_size_body_mpi ( obuf, pkey[2] ); /* KEK params */ kdf_params_size = iobuf_temp_to_buffer (obuf, kdf_params, sizeof(kdf_params)); @@ -185,11 +198,11 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, obuf = iobuf_temp(); /* variable-length field 1, curve name OID */ - rc = iobuf_write_size_body_mpi ( obuf, pkey[0] ); + err = iobuf_write_size_body_mpi ( obuf, pkey[0] ); /* fixed-length field 2 */ iobuf_put (obuf, PUBKEY_ALGO_ECDH); /* variable-length field 3, KDF params */ - rc = (rc ? rc : iobuf_write_size_body_mpi ( obuf, pkey[2] )); + err = (err ? err : iobuf_write_size_body_mpi ( obuf, pkey[2] )); /* fixed-length field 4 */ iobuf_write (obuf, "Anonymous Sender ", 20); /* fixed-length field 5, recipient fp */ @@ -198,8 +211,8 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, kdf_params_size = iobuf_temp_to_buffer (obuf, kdf_params, sizeof(kdf_params)); iobuf_close (obuf); - if (rc) - return rc; + if (err) + return err; if(DBG_CIPHER) log_printhex ("ecdh KDF message params are:", @@ -211,10 +224,10 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, gcry_md_hd_t h; int old_size; - rc = gcry_md_open (&h, kdf_hash_algo, 0); - if(rc) + err = gcry_md_open (&h, kdf_hash_algo, 0); + if(err) log_bug ("gcry_md_open failed for algo %d: %s", - kdf_hash_algo, gpg_strerror (gcry_error(rc))); + kdf_hash_algo, gpg_strerror (gcry_error(err))); gcry_md_write(h, "\x00\x00\x00\x01", 4); /* counter = 1 */ gcry_md_write(h, secret_x, secret_x_size); /* x of the point X */ gcry_md_write(h, kdf_params, kdf_params_size); /* KDF parameters */ @@ -248,22 +261,22 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, gcry_mpi_t result; - rc = gcry_cipher_open (&hd, kdf_encr_algo, GCRY_CIPHER_MODE_AESWRAP, 0); - if (rc) + err = gcry_cipher_open (&hd, kdf_encr_algo, GCRY_CIPHER_MODE_AESWRAP, 0); + if (err) { log_error ("ecdh failed to initialize AESWRAP: %s\n", - gpg_strerror (rc)); - return rc; + gpg_strerror (err)); + return err; } - rc = gcry_cipher_setkey (hd, secret_x, secret_x_size); + err = gcry_cipher_setkey (hd, secret_x, secret_x_size); xfree( secret_x ); - if (rc) + if (err) { gcry_cipher_close (hd); log_error ("ecdh failed in gcry_cipher_setkey: %s\n", - gpg_strerror (rc)); - return rc; + gpg_strerror (err)); + return err; } data_buf_size = (gcry_mpi_get_nbits(data)+7)/8; @@ -282,52 +295,52 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, /* Write data MPI into the end of data_buf. data_buf is size aeswrap data. */ - rc = gcry_mpi_print (GCRYMPI_FMT_USG, in, + err = gcry_mpi_print (GCRYMPI_FMT_USG, in, data_buf_size, &nbytes, data/*in*/); - if (rc) + if (err) { - log_error ("ecdh failed to export DEK: %s\n", gpg_strerror (rc)); + log_error ("ecdh failed to export DEK: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); xfree (data_buf); - return rc; + return err; } if (DBG_CIPHER) log_printhex ("ecdh encrypting :", in, data_buf_size ); - rc = gcry_cipher_encrypt (hd, data_buf+1, data_buf_size+8, + err = gcry_cipher_encrypt (hd, data_buf+1, data_buf_size+8, in, data_buf_size); memset (in, 0, data_buf_size); gcry_cipher_close (hd); - if (rc) + if (err) { log_error ("ecdh failed in gcry_cipher_encrypt: %s\n", - gpg_strerror (rc)); + gpg_strerror (err)); xfree (data_buf); - return rc; + return err; } data_buf[0] = data_buf_size+8; if (DBG_CIPHER) log_printhex ("ecdh encrypted to:", data_buf+1, data_buf[0] ); - rc = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, + err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, data_buf, 1+data_buf[0], NULL); /* (byte)size + aeswrap of DEK */ xfree( data_buf ); - if (rc) + if (err) { - log_error ("ecdh failed to create an MPI: %s\n", gpg_strerror (rc)); - return rc; + log_error ("ecdh failed to create an MPI: %s\n", gpg_strerror (err)); + return err; } - *out = result; + *r_result = result; } else { byte *in; - rc = gcry_mpi_print (GCRYMPI_FMT_USG, data_buf, data_buf_size, + err = gcry_mpi_print (GCRYMPI_FMT_USG, data_buf, data_buf_size, &nbytes, data/*in*/); if (nbytes != data_buf_size || data_buf[0] != data_buf_size-1) { @@ -341,15 +354,15 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, if (DBG_CIPHER) log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size); - rc = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1, + err = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1, data_buf_size); gcry_cipher_close (hd); - if (rc) + if (err) { log_error ("ecdh failed in gcry_cipher_decrypt: %s\n", - gpg_strerror (rc)); + gpg_strerror (err)); xfree (data_buf); - return rc; + return err; } data_buf_size -= 8; @@ -365,20 +378,20 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, /* return GPG_ERR_BAD_KEY; */ /* } */ - rc = gcry_mpi_scan ( &result, GCRYMPI_FMT_USG, in, data_buf_size, NULL); + err = gcry_mpi_scan ( &result, GCRYMPI_FMT_USG, in, data_buf_size, NULL); xfree (data_buf); - if (rc) + if (err) { log_error ("ecdh failed to create a plain text MPI: %s\n", - gpg_strerror (rc)); - return rc; + gpg_strerror (err)); + return err; } - *out = result; + *r_result = result; } } - return rc; + return err; } @@ -405,76 +418,31 @@ gen_k (unsigned nbits) return k; } -/* Perform ECDH encryption, which involves ECDH key generation. */ -int -pk_ecdh_encrypt (gcry_mpi_t *resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], - gcry_mpi_t data, gcry_mpi_t * pkey) -{ - gcry_sexp_t s_ciph, s_data, s_pkey; - int nbits; - int rc; +/* Generate an ephemeral key for the public ECDH key in PKEY. On + success the generated key is stored at R_K; on failure NULL is + stored at R_K and an error code returned. */ +gpg_error_t +pk_ecdh_generate_ephemeral_key (gcry_mpi_t *pkey, gcry_mpi_t *r_k) +{ + unsigned int nbits; gcry_mpi_t k; + *r_k = NULL; + nbits = pubkey_nbits (PUBKEY_ALGO_ECDH, pkey); - - /*** Generate an ephemeral key, actually, a scalar. ***/ - + if (!nbits) + return gpg_error (GPG_ERR_TOO_SHORT); k = gen_k (nbits); - if( k == NULL ) + if (!k) BUG (); - /*** Done with ephemeral key generation. - * Now use ephemeral secret to get the shared secret. ***/ - - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(ecdh(c%m)(q%m)(p%m)))", - pkey[0], pkey[1], pkey[2]); - if (rc) - BUG (); - - /* Put the data into a simple list. */ - /* Ephemeral scalar goes as data. */ - if (gcry_sexp_build (&s_data, NULL, "%m", k)) - BUG (); - - /* Pass it to libgcrypt. */ - rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); - gcry_sexp_release (s_data); - gcry_sexp_release (s_pkey); - if (rc) - return rc; - - /* Finally, perform encryption. */ - - { - /* ... and get the shared point/ */ - gcry_mpi_t shared; - - shared = mpi_from_sexp (s_ciph, "a"); - gcry_sexp_release (s_ciph); - /* Ephemeral public key. */ - resarr[0] = mpi_from_sexp (s_ciph, "b"); - - if (DBG_CIPHER) - { - unsigned char *buffer; - - if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, resarr[0])) - BUG (); - log_debug("ephemeral key MPI: %s\n", buffer); - gcry_free( buffer ); - } - - rc = pk_ecdh_encrypt_with_shared_point (1 /*=encrypton*/, shared, - pk_fp, data, pkey, resarr+1); - mpi_release (shared); - } - - return rc; + *r_k = k; + return 0; } + /* Perform ECDH decryption. */ int pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], diff --git a/g10/misc.c b/g10/misc.c index bdd797c16..fd00ec6d1 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -1423,7 +1423,7 @@ pubkey_nbits( int algo, gcry_mpi_t *key ) int rc, nbits; gcry_sexp_t sexp; -#warning Why this assert +#warning FIXME: We are mixing OpenPGP And CGrypt Ids assert( algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH ); if( algo == GCRY_PK_DSA ) { diff --git a/g10/pkglue.c b/g10/pkglue.c index f5c85976f..3aba4e4c1 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -28,6 +28,7 @@ #include "util.h" #include "pkglue.h" #include "main.h" +#include "options.h" /* FIXME: Better chnage the fucntion name because mpi_ is used by gcrypt macros. */ @@ -156,26 +157,39 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, rc = gcry_sexp_build (&s_pkey, NULL, "(public-key(elg(p%m)(g%m)(y%m)))", pkey[0], pkey[1], pkey[2]); + /* Put DATA into a simplified S-expression. */ + if (rc || gcry_sexp_build (&s_data, NULL, "%m", data)) + BUG (); + } else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_E) { rc = gcry_sexp_build (&s_pkey, NULL, "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]); + /* Put DATA into a simplified S-expression. */ + if (rc || gcry_sexp_build (&s_data, NULL, "%m", data)) + BUG (); } else if (algo == PUBKEY_ALGO_ECDH) { - return pk_ecdh_encrypt (resarr, pk_fp, data, pkey); + gcry_mpi_t k; + + rc = pk_ecdh_generate_ephemeral_key (pkey, &k); + if (rc) + return rc; + + /* Now use the ephemeral secret to compute the shared point. */ + rc = gcry_sexp_build (&s_pkey, NULL, + "(public-key(ecdh(c%m)(q%m)(p%m)))", + pkey[0], pkey[1], pkey[2]); + /* Put K into a simplified S-expression. */ + if (rc || gcry_sexp_build (&s_data, NULL, "%m", k)) + BUG (); } else - return GPG_ERR_PUBKEY_ALGO; + return gpg_error (GPG_ERR_PUBKEY_ALGO); - if (rc) - BUG (); - - /* Put the data into a simple list. */ - if (gcry_sexp_build (&s_data, NULL, "%m", data)) - BUG (); /* Pass it to libgcrypt. */ rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); @@ -184,12 +198,42 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, if (rc) ; - else - { /* Add better error handling or make gnupg use S-Exp directly. */ + else if (algo == PUBKEY_ALGO_ECDH) + { + gcry_mpi_t shared, public, result; + + /* Get the shared point and the ephemeral public key. */ + shared = mpi_from_sexp (s_ciph, "a"); + public = mpi_from_sexp (s_ciph, "b"); + gcry_sexp_release (s_ciph); + s_ciph = NULL; + if (DBG_CIPHER) + { + log_debug ("ECDH ephemeral key:"); + gcry_mpi_dump (public); + log_printf ("\n"); + } + + result = NULL; + rc = pk_ecdh_encrypt_with_shared_point (1 /*=encrypton*/, shared, + pk_fp, data, pkey, &result); + gcry_mpi_release (shared); + if (!rc) + { + resarr[0] = public; + resarr[1] = result; + } + else + { + gcry_mpi_release (public); + gcry_mpi_release (result); + } + } + else /* Elgamal or RSA case. */ + { /* Fixme: Add better error handling or make gnupg use + S-expressions directly. */ resarr[0] = mpi_from_sexp (s_ciph, "a"); - if (algo != GCRY_PK_RSA - && algo != GCRY_PK_RSA_E - && algo != PUBKEY_ALGO_ECDH) + if (algo != GCRY_PK_RSA && algo != GCRY_PK_RSA_E) resarr[1] = mpi_from_sexp (s_ciph, "b"); } diff --git a/g10/pkglue.h b/g10/pkglue.h index b1cfbe507..98d8c1440 100644 --- a/g10/pkglue.h +++ b/g10/pkglue.h @@ -33,6 +33,13 @@ int pk_check_secret_key (int algo, gcry_mpi_t *skey); /*-- ecdh.c --*/ byte *pk_ecdh_default_params (unsigned int qbits, size_t *sizeout); +gpg_error_t pk_ecdh_generate_ephemeral_key (gcry_mpi_t *pkey, gcry_mpi_t *r_k); +gpg_error_t pk_ecdh_encrypt_with_shared_point +/* */ (int is_encrypt, gcry_mpi_t shared_mpi, + const byte pk_fp[MAX_FINGERPRINT_LEN], + gcry_mpi_t data, gcry_mpi_t *pkey, + gcry_mpi_t *out); + int pk_ecdh_encrypt (gcry_mpi_t *resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t * pkey); int pk_ecdh_decrypt (gcry_mpi_t *result, const byte sk_fp[MAX_FINGERPRINT_LEN], From 358afc0dc8980d5ae0cb700efbb61499625a4625 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 26 Jan 2011 17:17:43 +0100 Subject: [PATCH 17/26] Function name cleanups Also nuked some trailing spaces. --- g10/ChangeLog | 12 ++++++ g10/build-packet.c | 105 ++++++++++++++++++++++++++++----------------- g10/ecdh.c | 6 +-- g10/main.h | 6 +-- g10/misc.c | 92 ++------------------------------------- g10/packet.h | 1 + g10/parse-packet.c | 61 +++++++++++++++++++++++--- 7 files changed, 142 insertions(+), 141 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 9e1aa01da..b27601563 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,15 @@ +2011-01-26 Werner Koch + + * misc.c (ecdsa_qbits_from_Q): Use unsigned int. + + * misc.c (iobuf_read_size_body): Move and rename to .. + * parse-packet.c (read_size_body): .. here. Make static. + * misc.c (iobuf_write_size_body_mpi): Move and rename to .. + * build-packet.c (write_size_body_mpi): .. here. + (iobuf_name_oid_write, ecdh_kek_params_write, ecdh_esk_write): + Remove macros. Replace users by direct calls to + write_size_body_mpi. + 2011-01-25 Werner Koch * ecdh.c (pk_ecdh_default_params_to_mpi): Remove. diff --git a/g10/build-packet.c b/g10/build-packet.c index d138e0614..e2bbdb511 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -178,17 +178,44 @@ mpi_write (iobuf_t out, gcry_mpi_t a) return rc; } -/* Write the name OID, encoded as an mpi, to OUT. The format of the - * content of the MPI is one byte LEN, following by LEN bytes that are - * DER representation of an ASN.1 OID. This is true for each of the 3 - * following functions. */ -#define iobuf_name_oid_write iobuf_write_size_body_mpi -/* Write the value of KEK fields for ECDH. */ -#define ecdh_kek_params_write iobuf_write_size_body_mpi +/* + * Write a special size+body mpi A, to OUT. The format of the content + * of the MPI is one byte LEN, following by LEN bytes. + */ +gpg_error_t +write_size_body_mpi (iobuf_t out, gcry_mpi_t a) +{ + gpg_error_t err; + byte buffer[256]; /* Fixed buffer for a public parameter, max possible */ + size_t nbytes = (mpi_get_nbits (a)+7)/8; -/* Write the value of encrypted filed for ECDH. */ -#define ecdh_esk_write iobuf_write_size_body_mpi + if (nbytes > sizeof(buffer)) + { + log_error("mpi with size+body is too large (%u bytes)\n", nbytes); + return gpg_error (GPG_ERR_TOO_LARGE); + } + + err = gcry_mpi_print (GCRYMPI_FMT_USG, buffer, sizeof(buffer), &nbytes, a); + if (err) + { + log_error ("failed to exported size+body mpi\n"); + return err; + } + if (nbytes < 2 || buffer[0] != nbytes-1) + { + if (nbytes > 2) + log_error ("internal size mismatch in mpi size+body: " + "%02x != %02x (other bytes: %02x %02x ... %02x %02x)\n", + buffer[0], nbytes-1, buffer[1], buffer[2], buffer[nbytes-2], + buffer[nbytes-1]); + else + log_error ("internal size mismatch in mpi size+body: " + "only %d bytes\n", nbytes); + return gpg_error (GPG_ERR_INV_DATA); + } + return iobuf_write (out, buffer, nbytes); +} /* Calculate the length of a packet described by PKT. */ @@ -228,11 +255,11 @@ calc_packet_length( PACKET *pkt ) static void write_fake_data (IOBUF out, gcry_mpi_t a) { - if (a) + if (a) { unsigned int n; void *p; - + p = gcry_mpi_get_opaque ( a, &n ); iobuf_write (out, p, (n+7)/8 ); } @@ -281,18 +308,18 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) ndays = 0; write_16(a, ndays); } - + iobuf_put (a, pk->pubkey_algo ); - + /* Get number of secret and public parameters. They are held in one array first the public ones, then the secret ones. */ nskey = pubkey_get_nskey (pk->pubkey_algo); npkey = pubkey_get_npkey (pk->pubkey_algo); - + /* If we don't have any public parameters - which is the case if we don't know the algorithm used - the parameters are stored as one blob in a faked (opaque) MPI. */ - if (!npkey) + if (!npkey) { write_fake_data (a, pk->pkey[0]); goto leave; @@ -305,7 +332,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) || pk->pubkey_algo == PUBKEY_ALGO_ECDH) { /* Write DER of OID with preceeding length byte. */ - err = iobuf_name_oid_write (a, pk->pkey[0]); + err = write_size_body_mpi (a, pk->pkey[0]); if (err) goto leave; /* Write point Q, the public key. */ @@ -316,7 +343,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) /* Write one more public field for ECDH. */ if (pk->pubkey_algo == PUBKEY_ALGO_ECDH) { - err = ecdh_kek_params_write(a,pk->pkey[2]); + err = write_size_body_mpi (a, pk->pkey[2]); if (err) goto leave; } @@ -328,14 +355,14 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) goto leave; } - + if (pk->seckey_info) { /* This is a secret key packet. */ struct seckey_info *ski = pk->seckey_info; /* Build the header for protected (encrypted) secret parameters. */ - if (ski->is_protected) + if (ski->is_protected) { if ( is_RSA (pk->pubkey_algo) && pk->version < 4 && !ski->s2k.mode ) { @@ -355,12 +382,12 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) viewed as a private/experimental extension (this is not specified in rfc2440 but the same scheme is used for all other algorithm identifiers). */ - iobuf_put (a, 101); + iobuf_put (a, 101); iobuf_put (a, ski->s2k.hash_algo); iobuf_write (a, "GNU", 3 ); iobuf_put (a, ski->s2k.mode - 1000); } - else + else { iobuf_put (a, ski->s2k.mode); iobuf_put (a, ski->s2k.hash_algo); @@ -370,7 +397,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) iobuf_write (a, ski->s2k.salt, 8); if (ski->s2k.mode == 3) - iobuf_put (a, ski->s2k.count); + iobuf_put (a, ski->s2k.count); /* For our special modes 1001, 1002 we do not need an IV. */ if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002) @@ -381,10 +408,10 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) iobuf_put (a, 0 ); if (ski->s2k.mode == 1001) - ; /* GnuPG extension - don't write a secret key at all. */ + ; /* GnuPG extension - don't write a secret key at all. */ else if (ski->s2k.mode == 1002) - { - /* GnuPG extension - divert to OpenPGP smartcard. */ + { + /* GnuPG extension - divert to OpenPGP smartcard. */ /* Length of the serial number or 0 for no serial number. */ iobuf_put (a, ski->ivlen ); /* The serial number gets stored in the IV field. */ @@ -395,19 +422,19 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) /* The secret key is protected - write it out as it is. */ byte *p; unsigned int ndatabits; - + assert (gcry_mpi_get_flag (pk->pkey[npkey], GCRYMPI_FLAG_OPAQUE)); p = gcry_mpi_get_opaque (pk->pkey[npkey], &ndatabits); iobuf_write (a, p, (ndatabits+7)/8 ); } - else if (ski->is_protected) + else if (ski->is_protected) { /* The secret key is protected the old v4 way. */ - for ( ; i < nskey; i++ ) + for ( ; i < nskey; i++ ) { byte *p; unsigned int ndatabits; - + assert (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE)); p = gcry_mpi_get_opaque (pk->pkey[i], &ndatabits); iobuf_write (a, p, (ndatabits+7)/8); @@ -476,9 +503,9 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) int rc = 0; int n, i; IOBUF a = iobuf_temp(); - + write_version( a, ctb ); - if ( enc->throw_keyid ) + if ( enc->throw_keyid ) { write_32(a, 0 ); /* Don't tell Eve who can decrypt the message. */ write_32(a, 0 ); @@ -500,7 +527,7 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) assert (n == 2); rc = mpi_write (a, enc->data[0]); if (!rc) - rc = ecdh_esk_write (a, enc->data[1]); + rc = write_size_body_mpi (a, enc->data[1]); } else { @@ -545,7 +572,7 @@ do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt ) for(i=0; i < pt->namelen; i++ ) iobuf_put(out, pt->name[i] ); rc = write_32(out, pt->timestamp ); - if (rc) + if (rc) return rc; n = 0; @@ -661,7 +688,7 @@ delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype ) } if( buflen < n ) break; - + type = *buffer & 0x7f; if( type == reqtype ) { buffer++; @@ -695,7 +722,7 @@ delete_sig_subpkt (subpktarea_t *area, sigsubpkttype_t reqtype ) * Note: All pointers into sig->[un]hashed (e.g. returned by * parse_sig_subpkt) are not valid after a call to this function. The * data to put into the subpaket should be in a buffer with a length - * of buflen. + * of buflen. */ void build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type, @@ -798,7 +825,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type, case SIGSUBPKT_SIGNATURE: hashed = 0; break; - default: + default: hashed = 1; break; } @@ -849,7 +876,7 @@ build_sig_subpkt (PKT_signature *sig, sigsubpkttype_t type, memcpy (p, buffer, buflen); } - if (hashed) + if (hashed) sig->hashed = newarea; else sig->unhashed = newarea; @@ -1135,7 +1162,7 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig ) if ( sig->version < 4 ) iobuf_put (a, 5 ); /* Constant */ iobuf_put (a, sig->sig_class ); - if ( sig->version < 4 ) + if ( sig->version < 4 ) { write_32(a, sig->timestamp ); write_32(a, sig->keyid[0] ); @@ -1143,7 +1170,7 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig ) } iobuf_put(a, sig->pubkey_algo ); iobuf_put(a, sig->digest_algo ); - if ( sig->version >= 4 ) + if ( sig->version >= 4 ) { size_t nn; /* Timestamp and keyid must have been packed into the subpackets diff --git a/g10/ecdh.c b/g10/ecdh.c index 71c32fd5d..95bd8668f 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -161,7 +161,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, */ { IOBUF obuf = iobuf_temp(); - err = iobuf_write_size_body_mpi ( obuf, pkey[2] ); /* KEK params */ + err = write_size_body_mpi (obuf, pkey[2]); /* KEK params */ kdf_params_size = iobuf_temp_to_buffer (obuf, kdf_params, sizeof(kdf_params)); @@ -198,11 +198,11 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, obuf = iobuf_temp(); /* variable-length field 1, curve name OID */ - err = iobuf_write_size_body_mpi ( obuf, pkey[0] ); + err = write_size_body_mpi (obuf, pkey[0]); /* fixed-length field 2 */ iobuf_put (obuf, PUBKEY_ALGO_ECDH); /* variable-length field 3, KDF params */ - err = (err ? err : iobuf_write_size_body_mpi ( obuf, pkey[2] )); + err = (err ? err : write_size_body_mpi ( obuf, pkey[2] )); /* fixed-length field 4 */ iobuf_write (obuf, "Anonymous Sender ", 20); /* fixed-length field 5, recipient fp */ diff --git a/g10/main.h b/g10/main.h index ea1ac2e1f..4cec61f9d 100644 --- a/g10/main.h +++ b/g10/main.h @@ -161,11 +161,7 @@ int pubkey_get_nsig( int algo ); int pubkey_get_nenc( int algo ); unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey ); int mpi_print (estream_t stream, gcry_mpi_t a, int mode); -int iobuf_write_size_body_mpi (iobuf_t out, gcry_mpi_t a); -int iobuf_read_size_body (iobuf_t inp, byte *body, int body_max_size, - int pktlen, gcry_mpi_t *out); - -int ecdsa_qbits_from_Q( int qbits ); +unsigned int ecdsa_qbits_from_Q (unsigned int qbits); /*-- status.c --*/ void set_status_fd ( int fd ); diff --git a/g10/misc.c b/g10/misc.c index fd00ec6d1..dc2f73be4 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -1459,7 +1459,6 @@ pubkey_nbits( int algo, gcry_mpi_t *key ) -/* FIXME: Use gcry_mpi_print directly. */ int mpi_print (estream_t fp, gcry_mpi_t a, int mode) { @@ -1487,98 +1486,15 @@ mpi_print (estream_t fp, gcry_mpi_t a, int mode) } -/* - * Write a special size+body mpi A, to OUT. The format of the content - * of the MPI is one byte LEN, following by LEN bytes. - */ -/* FIXME: Rename this function: it is not in iobuf.c */ -int -iobuf_write_size_body_mpi (iobuf_t out, gcry_mpi_t a) -{ - byte buffer[256]; /* Fixed buffer for a public parameter, max possible */ - size_t nbytes = (mpi_get_nbits (a)+7)/8; - int rc; - - if( nbytes > sizeof(buffer) ) { - log_error("mpi with size+body is too large (%u bytes)\n", nbytes); - return gpg_error (GPG_ERR_TOO_LARGE); - } - - rc = gcry_mpi_print (GCRYMPI_FMT_USG, buffer, sizeof(buffer), &nbytes, a); - if( rc ) { - log_error("Failed to exported size+body mpi\n"); - return rc; - } - if( nbytes < 2 || buffer[0] != nbytes-1 ) { - if( nbytes > 2 ) - log_error("Internal size mismatch in mpi size+body: %02x != %02x (other bytes: %02x %02x ... %02x %02x)\n", - buffer[0], nbytes-1, buffer[1], buffer[2], buffer[nbytes-2], buffer[nbytes-1]); - else - log_error("Internal size mismatch in mpi size+body: only %d bytes\n", nbytes ); - return gpg_error (GPG_ERR_INV_DATA); - } - return iobuf_write( out, buffer, nbytes ); -} - - -/* - * Read a special size+body from inp into body[body_max_size] and - * return it in a buffer and as MPI. On success the number of - * consumed bytes will body[0]+1. The format of the content of the - * returned MPI is one byte LEN, following by LEN bytes. Caller is - * expected to pre-allocate fixed-size 255 byte buffer (or smaller - * when appropriate). - */ -/* FIXME: Rename this function: it is not in iobuf.c */ -int -iobuf_read_size_body (iobuf_t inp, byte *body, int body_max_size, - int pktlen, gcry_mpi_t *out ) -{ - unsigned n; - int rc; - gcry_mpi_t result; - - *out = NULL; - - if( (n = iobuf_readbyte(inp)) == -1 ) - { - return G10ERR_INVALID_PACKET; - } - if ( n >= body_max_size || n < 2) - { - log_error("invalid size+body field\n"); - return G10ERR_INVALID_PACKET; - } - body[0] = n; - if ((n = iobuf_read(inp, body+1, n)) == -1) - { - log_error("invalid size+body field\n"); - return G10ERR_INVALID_PACKET; - } - if (n+1 > pktlen) - { - log_error("size+body field is larger than the packet\n"); - return G10ERR_INVALID_PACKET; - } - rc = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, body, n+1, NULL); - if (rc) - log_fatal ("mpi_scan failed: %s\n", gpg_strerror (rc)); - - *out = result; - - return rc; -} - - /* pkey[1] or skey[1] is Q for ECDSA, which is an uncompressed point, i.e. 04 */ -int -ecdsa_qbits_from_Q (int qbits ) +unsigned int +ecdsa_qbits_from_Q (unsigned int qbits) { if ((qbits%8) > 3) { - log_error(_("ECDSA public key is expected to be in SEC encoding " - "multiple of 8 bits\n")); + log_error (_("ECDSA public key is expected to be in SEC encoding " + "multiple of 8 bits\n")); return 0; } qbits -= qbits%8; diff --git a/g10/packet.h b/g10/packet.h index 541462af6..d06c4c7e7 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -444,6 +444,7 @@ PACKET *create_gpg_control ( ctrlpkttype_t type, /*-- build-packet.c --*/ int build_packet( iobuf_t inp, PACKET *pkt ); +gpg_error_t write_size_body_mpi (iobuf_t out, gcry_mpi_t a); u32 calc_packet_length( PACKET *pkt ); void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, const byte *buffer, size_t buflen ); diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 334a9a82b..a0844c7ac 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -741,6 +741,55 @@ read_rest (IOBUF inp, size_t pktlen, int partial) } +/* + * Read a special size+body from inp into body[body_max_size] and + * return it in a buffer and as MPI. On success the number of + * consumed bytes will body[0]+1. The format of the content of the + * returned MPI is one byte LEN, following by LEN bytes. Caller is + * expected to pre-allocate fixed-size 255 byte buffer (or smaller + * when appropriate). + */ +static int +read_size_body (iobuf_t inp, byte *body, int body_max_size, + int pktlen, gcry_mpi_t *out ) +{ + unsigned int n; + int rc; + gcry_mpi_t result; + + *out = NULL; + + if( (n = iobuf_readbyte(inp)) == -1 ) + { + return G10ERR_INVALID_PACKET; + } + if ( n >= body_max_size || n < 2) + { + log_error("invalid size+body field\n"); + return G10ERR_INVALID_PACKET; + } + body[0] = n; + if ((n = iobuf_read(inp, body+1, n)) == -1) + { + log_error("invalid size+body field\n"); + return G10ERR_INVALID_PACKET; + } + if (n+1 > pktlen) + { + log_error("size+body field is larger than the packet\n"); + return G10ERR_INVALID_PACKET; + } + rc = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, body, n+1, NULL); + if (rc) + log_fatal ("mpi_scan failed: %s\n", gpg_strerror (rc)); + + *out = result; + + return rc; +} + + +/* Parse a marker packet. */ static int parse_marker (IOBUF inp, int pkttype, unsigned long pktlen) { @@ -947,8 +996,8 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, n = pktlen; k->data[0] = mpi_read (inp, &n, 0); pktlen -= n; - rc = iobuf_read_size_body (inp, encr_buf, sizeof(encr_buf), - pktlen, k->data+1); + rc = read_size_body (inp, encr_buf, sizeof(encr_buf), + pktlen, k->data+1); if (rc) goto leave; @@ -1958,8 +2007,8 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, /* FIXME: The code in this function ignores the errors. */ byte name_oid[256]; - err = iobuf_read_size_body (inp, name_oid, sizeof(name_oid), - pktlen, pk->pkey+0); + err = read_size_body (inp, name_oid, sizeof(name_oid), + pktlen, pk->pkey+0); if (err) goto leave; n = name_oid[0]; @@ -1984,8 +2033,8 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, if (algorithm == PUBKEY_ALGO_ECDH) { /* (NAMEOID holds the KEK params.) */ - err = iobuf_read_size_body (inp, name_oid, sizeof(name_oid), - pktlen, pk->pkey+2); + err = read_size_body (inp, name_oid, sizeof(name_oid), + pktlen, pk->pkey+2); if (err) goto leave; n = name_oid[0]; From a6d1768e8e1dac81a20a7ccd830e87d2c9281682 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 26 Jan 2011 18:20:32 +0100 Subject: [PATCH 18/26] Update gitignore and add attributes to po/ --- .gitignore | 2 ++ po/.gitattributes | 7 +++++++ 2 files changed, 9 insertions(+) create mode 100644 po/.gitattributes diff --git a/.gitignore b/.gitignore index 699581b44..a36a733d3 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ doc/gnupg.info* doc/stamp-vti doc/version.texi po/gnupg2.pot +*.o +*.a diff --git a/po/.gitattributes b/po/.gitattributes new file mode 100644 index 000000000..17b178c0e --- /dev/null +++ b/po/.gitattributes @@ -0,0 +1,7 @@ +# You should add +#[filter "cleanpo"] +# clean = "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'" +# to your config file. + +/??.po filter=cleanpo +/??_??.po filter=cleanpo From fdfe7e77e6731744a48ce6640890d85e45eebc07 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 26 Jan 2011 18:23:46 +0100 Subject: [PATCH 19/26] Update gitignore to the one used in tye 2.0 branch. --- .gitignore | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a36a733d3..92c467445 100644 --- a/.gitignore +++ b/.gitignore @@ -4,11 +4,132 @@ autom4te.cache/ configure config.h.in config.h +config.log +config.status common/audit-events.h common/status-codes.h doc/gnupg.info* doc/stamp-vti doc/version.texi po/gnupg2.pot +po/POTFILES +stamp-h1 +Makefile +.deps/ +keyserver/gpg2keys_mailto +keyserver/gpg2keys_test +tools/gpg-zip + +# Files created by make when not using a VPATH build *.o -*.a +po/en@boldquot.insert-header +po/en@boldquot.po +po/en@quot.insert-header +po/en@quot.po +po/stamp-po +agent/gpg-agent +agent/gpg-preset-passphrase +agent/gpg-protect-tool +agent/t-protect +common/libcommon.a +common/libcommonpth.a +common/libgpgrl.a +common/libsimple-pwquery.a +common/t-b64 +common/t-convert +common/t-exechelp +common/t-gettime +common/t-helpfile +common/t-percent +common/t-session-env +common/t-sexputil +common/t-sysutils +doc/addgnupghome.8 +doc/applygnupgdefaults.8 +doc/faq.html +doc/faq.raw.xref +doc/gnupg-card-architecture.eps +doc/gnupg-card-architecture.pdf +doc/gnupg-card-architecture.png +doc/gnupg.7 +doc/gpg-agent.1 +doc/gpg-connect-agent.1 +doc/gpg-preset-passphrase.1 +doc/gpg-zip.1 +doc/gpg2.1 +doc/gpgconf.1 +doc/gpgparsemail.1 +doc/gpgsm-gencert.sh.1 +doc/gpgsm.1 +doc/gpgv2.1 +doc/scdaemon.1 +doc/symcryptrun.1 +doc/watchgnupg.1 +doc/yat2m +doc/yat2m-stamp +g10/gpg2 +g10/gpgv2 +g10/t-rmd160 +gl/alloca.h +gl/libgnu.a +jnlib/libjnlib.a +jnlib/t-stringhelp +kbx/kbxutil +kbx/libkeybox.a +keyserver/gpg2keys_curl +keyserver/gpg2keys_finger +keyserver/gpg2keys_hkp +keyserver/gpg2keys_kdns +keyserver/gpg2keys_ldap +scd/gnupg-pcsc-wrapper +scd/scdaemon +sm/gpgsm +tests/asschk +tests/gpg-agent.conf +tests/gpgsm.conf +tests/inittests.stamp +tests/openpgp/data-32000 +tests/openpgp/data-500 +tests/openpgp/data-80000 +tests/openpgp/data-9000 +tests/openpgp/gpg-agent.conf +tests/openpgp/gpg_dearmor +tests/openpgp/plain-1 +tests/openpgp/plain-2 +tests/openpgp/plain-3 +tests/openpgp/plain-large +tests/openpgp/prepared.stamp +tests/openpgp/pubring.gpg +tests/openpgp/pubring.pkr +tests/openpgp/secring.gpg +tests/openpgp/secring.skr +tests/pkits/ReadMe.txt +tests/pkits/certpairs/ +tests/pkits/certs/ +tests/pkits/crls/ +tests/pkits/gpg-agent.conf +tests/pkits/gpgsm.conf +tests/pkits/inittests.stamp +tests/pkits/pkcs12/ +tests/pkits/pkits.ldif +tests/pkits/pkits.schema +tests/pkits/policies.txt +tests/pkits/smime/ +tests/pkits/testdir.stamp +tests/pkits/trustlist.txt +tests/private-keys-v1.d/ +tests/pubring.kbx +tests/testdir.stamp +tests/trustlist.txt +tools/clean-sat +tools/gpg-check-pattern +tools/gpg-connect-agent +tools/gpgconf +tools/gpgkey2ssh +tools/gpgparsemail +tools/gpgsplit +tools/make-dns-cert +tools/mk-tdata +tools/symcryptrun +tools/watchgnupg +tools/gpgtar From a58a6b5b7874daa2a17e3dffe43062242032d665 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 26 Jan 2011 18:27:56 +0100 Subject: [PATCH 20/26] Update gitignore --- .gitignore | 9 + po/de.po | 2088 ---------------------------------------------------- 2 files changed, 9 insertions(+), 2088 deletions(-) diff --git a/.gitignore b/.gitignore index 92c467445..6eeeb5c13 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,8 @@ common/t-percent common/t-session-env common/t-sexputil common/t-sysutils +common/t-stringhelp +common/t-timestuff doc/addgnupghome.8 doc/applygnupgdefaults.8 doc/faq.html @@ -63,6 +65,8 @@ doc/gpgsm-gencert.sh.1 doc/gpgsm.1 doc/gpgv2.1 doc/scdaemon.1 +doc/dirmngr-client.1 +doc/dirmngr.8 doc/symcryptrun.1 doc/watchgnupg.1 doc/yat2m @@ -84,6 +88,10 @@ keyserver/gpg2keys_ldap scd/gnupg-pcsc-wrapper scd/scdaemon sm/gpgsm +dirmngr/dirmngr +dirmngr/dirmngr-client +dirmngr/dirmngr_ldap +dirmngr/no-libgcrypt.c tests/asschk tests/gpg-agent.conf tests/gpgsm.conf @@ -133,3 +141,4 @@ tools/mk-tdata tools/symcryptrun tools/watchgnupg tools/gpgtar +g13/g13 diff --git a/po/de.po b/po/de.po index 3f4a9781f..440c7089c 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,6 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.1.0\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"POT-Creation-Date: 2011-01-20 15:15+0100\n" "PO-Revision-Date: 2011-01-20 15:10+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: German \n" @@ -18,7 +17,6 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -#: agent/call-pinentry.c:244 #, c-format msgid "failed to acquire the pinentry lock: %s\n" msgstr "Die Sperre für das Pinentry kann nicht gesetzt werden: %s\n" @@ -28,21 +26,17 @@ msgstr "Die Sperre für das Pinentry kann nicht gesetzt werden: %s\n" #. should be used as an accelerator. Double the underscore for #. a literal one. The actual to be translated text starts after #. the second vertical bar. -#: agent/call-pinentry.c:407 msgid "|pinentry-label|_OK" msgstr "_OK" -#: agent/call-pinentry.c:408 msgid "|pinentry-label|_Cancel" msgstr "_Abbrechen" -#: agent/call-pinentry.c:409 msgid "|pinentry-label|PIN:" msgstr "PIN:" #. TRANSLATORS: This string is displayed by Pinentry as the label #. for the quality bar. -#: agent/call-pinentry.c:657 msgid "Quality:" msgstr "Qualität:" @@ -52,14 +46,12 @@ msgstr "Qualität:" #. tooltip is limited to about 900 characters. If you do not #. translate this entry, a default english text (see source) #. will be used. -#: agent/call-pinentry.c:679 msgid "pinentry.qualitybar.tooltip" msgstr "" "Die Qualität der Passphrase, die Sie oben eingegeben haben.\n" "Bitte fragen sie Ihren Systembeauftragten nach den\n" "Kriterien für die Messung der Qualität." -#: agent/call-pinentry.c:748 msgid "" "Please enter your PIN, so that the secret key can be unlocked for this " "session" @@ -67,7 +59,6 @@ msgstr "" "Bitte geben Sie Ihre PIN ein, so daß der geheime Schlüssel benutzt werden " "kann" -#: agent/call-pinentry.c:751 msgid "" "Please enter your passphrase, so that the secret key can be unlocked for " "this session" @@ -75,106 +66,74 @@ msgstr "" "Bitte geben Sie Ihre Passphrase ein, so daß der geheime Schlüssel benutzt " "werden kann." -#: agent/call-pinentry.c:808 #, c-format msgid "SETERROR %s (try %d of %d)" msgstr "SETERROR %s (Versuch %d von %d)" -#: agent/call-pinentry.c:838 agent/call-pinentry.c:850 msgid "PIN too long" msgstr "Die PIN ist zu lang" -#: agent/call-pinentry.c:839 msgid "Passphrase too long" msgstr "Das Mantra (Passphrase) ist zu lang!" -#: agent/call-pinentry.c:847 msgid "Invalid characters in PIN" msgstr "Ungültige Zeichen in der PIN!" -#: agent/call-pinentry.c:852 msgid "PIN too short" msgstr "Die PIN ist zu kurz!" -#: agent/call-pinentry.c:864 msgid "Bad PIN" msgstr "Falsche PIN!" -#: agent/call-pinentry.c:865 msgid "Bad Passphrase" msgstr "Falsche Passphrase!" -#: agent/call-pinentry.c:903 msgid "Passphrase" msgstr "Passphrase" -#: agent/command-ssh.c:528 #, c-format msgid "ssh keys greater than %d bits are not supported\n" msgstr "SSH Schlüssel von mehr als %d Bits werden nicht unterstützt\n" -#: agent/command-ssh.c:685 common/dotlock.c:326 g10/card-util.c:841 -#: g10/exec.c:481 g10/gpg.c:1129 g10/keygen.c:3202 g10/keyring.c:1213 -#: g10/keyring.c:1521 g10/openfile.c:290 g10/openfile.c:383 g10/sign.c:870 -#: g10/sign.c:1181 g10/tdbio.c:562 #, c-format msgid "can't create `%s': %s\n" msgstr "'%s' kann nicht erzeugt werden: %s\n" -#: agent/command-ssh.c:697 common/helpfile.c:47 g10/card-util.c:795 -#: g10/dearmor.c:60 g10/dearmor.c:107 g10/decrypt.c:67 g10/decrypt.c:129 -#: g10/decrypt.c:146 g10/encrypt.c:198 g10/encrypt.c:547 g10/gpg.c:1130 -#: g10/import.c:197 g10/keygen.c:2713 g10/keyring.c:1547 g10/openfile.c:197 -#: g10/openfile.c:211 g10/openfile.c:368 g10/plaintext.c:584 g10/sign.c:852 -#: g10/sign.c:1047 g10/sign.c:1165 g10/sign.c:1323 g10/tdbdump.c:142 -#: g10/tdbdump.c:150 g10/tdbio.c:566 g10/tdbio.c:647 g10/verify.c:98 -#: g10/verify.c:161 sm/gpgsm.c:2054 sm/gpgsm.c:2084 sm/gpgsm.c:2122 -#: sm/qualified.c:66 dirmngr/certcache.c:359 dirmngr/crlcache.c:2405 -#: dirmngr/dirmngr.c:1466 #, c-format msgid "can't open `%s': %s\n" msgstr "'%s' kann nicht geöffnet werden: %s\n" -#: agent/command-ssh.c:1651 agent/command-ssh.c:1669 #, c-format msgid "error getting serial number of card: %s\n" msgstr "Fehler beim Holen der Karten-Seriennummer: %s\n" -#: agent/command-ssh.c:1655 #, c-format msgid "detected card with S/N: %s\n" msgstr "Erkannte Karte hat die Seriennummer: %s\n" -#: agent/command-ssh.c:1660 #, c-format msgid "error getting default authentication keyID of card: %s\n" msgstr "Fehler beim Holen der Authentisierungsschlüssel-ID der Karte: %s\n" -#: agent/command-ssh.c:1680 #, c-format msgid "no suitable card key found: %s\n" msgstr "keine passender Kartenschlüssel gefunden: %s\n" -#: agent/command-ssh.c:1730 #, c-format msgid "shadowing the key failed: %s\n" msgstr "\"Shadowing\" des Schlüssels schlug fehl: %s\n" -#: agent/command-ssh.c:1745 #, c-format msgid "error writing key: %s\n" msgstr "Fehler beim Schreiben des Schlüssels: %s\n" -#: agent/command-ssh.c:2053 #, c-format msgid "Please enter the passphrase for the ssh key%0A %c" msgstr "Bitte geben Sie die Passphrase für den SSH-Schlüssel %0A %c ein." -#: agent/command-ssh.c:2381 agent/genkey.c:300 msgid "Please re-enter this passphrase" msgstr "Bitte geben Sie die Passphrase noch einmal ein:" -#: agent/command-ssh.c:2402 #, c-format msgid "" "Please enter a passphrase to protect the received secret key%%0A %s%%" @@ -183,92 +142,72 @@ msgstr "" "Bitte geben Sie eine Passphrase ein, um den empfangenen geheimen Schlüssel%%" "0A %s%%0A im Schlüsselspeicher des gpg-agenten zu schützen." -#: agent/command-ssh.c:2440 agent/genkey.c:334 tools/symcryptrun.c:439 msgid "does not match - try again" msgstr "Keine Übereinstimmung - bitte nochmal versuchen." -#: agent/command-ssh.c:2947 #, c-format msgid "failed to create stream from socket: %s\n" msgstr "Das Erzeugen eines Datenstroms aus dem Socket schlug fehl: %s\n" -#: agent/divert-scd.c:92 g10/call-agent.c:884 msgid "Please insert the card with serial number" msgstr "Die legen Sie die Karte mit der folgenden Seriennummer ein:" -#: agent/divert-scd.c:93 g10/call-agent.c:885 msgid "Please remove the current card and insert the one with serial number" msgstr "" "Bitte entfernen Sie die vorhanden Karte und legen Sie die mit der folgenden " "Seriennummer ein:" -#: agent/divert-scd.c:200 msgid "Admin PIN" msgstr "Admin-PIN" #. TRANSLATORS: A PUK is the Personal Unblocking Code #. used to unblock a PIN. -#: agent/divert-scd.c:205 msgid "PUK" msgstr "PUK" -#: agent/divert-scd.c:212 msgid "Reset Code" msgstr "Rückstellcode" -#: agent/divert-scd.c:238 #, c-format msgid "%s%%0A%%0AUse the reader's keypad for input." msgstr "%s%%0A%%0AZur Eingabe die Tastatur des Kartenlesers verwenden." -#: agent/divert-scd.c:287 msgid "Repeat this Reset Code" msgstr "Rückstellcode bitte wiederholen" -#: agent/divert-scd.c:289 msgid "Repeat this PUK" msgstr "PUK bitte wiederholen" -#: agent/divert-scd.c:290 msgid "Repeat this PIN" msgstr "PIN bitte wiederholen" -#: agent/divert-scd.c:295 msgid "Reset Code not correctly repeated; try again" msgstr "Rückstellcode wurde nicht richtig wiederholt; noch einmal versuchen" -#: agent/divert-scd.c:297 msgid "PUK not correctly repeated; try again" msgstr "PUK wurde nicht richtig wiederholt; noch einmal versuchen" -#: agent/divert-scd.c:298 msgid "PIN not correctly repeated; try again" msgstr "PIN wurde nicht richtig wiederholt; noch einmal versuchen" -#: agent/divert-scd.c:310 #, c-format msgid "Please enter the PIN%s%s%s to unlock the card" msgstr "Bitte geben Sie die PIN%s%s%s ein, um die Karte zu entsperren" -#: agent/genkey.c:108 sm/certreqgen-ui.c:384 #, c-format msgid "error creating temporary file: %s\n" msgstr "Fehler beim Erstellen einer temporären Datei: %s\n" -#: agent/genkey.c:115 #, c-format msgid "error writing to temporary file: %s\n" msgstr "Fehler beim Schreiben auf eine temporäre Datei: %s\n" -#: agent/genkey.c:156 agent/genkey.c:162 msgid "Enter new passphrase" msgstr "Neue Passphrase eingeben" -#: agent/genkey.c:170 msgid "Take this one anyway" msgstr "Diese trotzdem benutzen" -#: agent/genkey.c:196 #, c-format msgid "" "Warning: You have entered an insecure passphrase.%%0AA passphrase should be " @@ -283,7 +222,6 @@ msgstr[1] "" "WARNUNG: Sie haben eine offensichtlich unsichere%%0APassphrase eingegeben. " "Eine Passphrase sollte%%0Amindestens %u Zeichen lang sein." -#: agent/genkey.c:217 #, c-format msgid "" "Warning: You have entered an insecure passphrase.%%0AA passphrase should " @@ -299,7 +237,6 @@ msgstr[1] "" "WARNUNG: Sie haben eine offensichtlich unsichere%%0APassphrase eingegeben. " "Eine Passphrase sollte%%0Amindestens %u Sonderzeichen oder Ziffern enthalten." -#: agent/genkey.c:240 #, c-format msgid "" "Warning: You have entered an insecure passphrase.%%0AA passphrase may not be " @@ -309,7 +246,6 @@ msgstr "" "Eine Passphrase sollte kein%%0Abekanntes Wort sein oder nach bekannten " "Regeln aufgebaut sein." -#: agent/genkey.c:256 #, c-format msgid "" "You have not entered a passphrase!%0AAn empty passphrase is not allowed." @@ -317,7 +253,6 @@ msgstr "" "Sie haben keine Passphrase eingegeben!%0AEine leere Passphrase ist nicht " "erlaubt." -#: agent/genkey.c:258 #, c-format msgid "" "You have not entered a passphrase - this is in general a bad idea!%0APlease " @@ -327,21 +262,16 @@ msgstr "" "bestätigen Sie, daß sie auf jeden Schutz Ihres privaten Schlüssels\n" "verzichten." -#: agent/genkey.c:267 msgid "Yes, protection is not needed" msgstr "Ja, ein Schutz ist nicht notwendig" -#: agent/genkey.c:385 #, c-format msgid "Please enter the passphrase to%0Ato protect your new key" msgstr "Bitte geben Sie die Passphrase ein,%0Aum Ihren Schlüssel zu schützen." -#: agent/genkey.c:496 msgid "Please enter the new passphrase" msgstr "Bitte geben Sie die Passphrase ein:" -#: agent/gpg-agent.c:122 agent/preset-passphrase.c:71 scd/scdaemon.c:104 -#: tools/gpg-check-pattern.c:70 msgid "" "@Options:\n" " " @@ -349,118 +279,83 @@ msgstr "" "@Optionen:\n" " " -#: agent/gpg-agent.c:124 scd/scdaemon.c:106 dirmngr/dirmngr.c:134 msgid "run in server mode (foreground)" msgstr "Im Server Modus ausführen" -#: agent/gpg-agent.c:125 scd/scdaemon.c:109 dirmngr/dirmngr.c:135 msgid "run in daemon mode (background)" msgstr "Im Daemon Modus ausführen" -#: agent/gpg-agent.c:126 g10/gpg.c:494 g10/gpgv.c:71 kbx/kbxutil.c:88 -#: scd/scdaemon.c:110 sm/gpgsm.c:281 dirmngr/dirmngr-client.c:68 -#: dirmngr/dirmngr.c:149 dirmngr/dirmngr_ldap.c:127 -#: tools/gpg-connect-agent.c:71 tools/gpgconf.c:79 tools/symcryptrun.c:163 msgid "verbose" msgstr "Detaillierte Informationen" -#: agent/gpg-agent.c:127 g10/gpgv.c:72 kbx/kbxutil.c:89 scd/scdaemon.c:111 -#: sm/gpgsm.c:282 dirmngr/dirmngr-client.c:69 dirmngr/dirmngr.c:150 -#: dirmngr/dirmngr_ldap.c:128 msgid "be somewhat more quiet" msgstr "Reduzierte Informationen" -#: agent/gpg-agent.c:128 scd/scdaemon.c:112 dirmngr/dirmngr.c:151 msgid "sh-style command output" msgstr "Ausgabe für /bin/sh" -#: agent/gpg-agent.c:129 scd/scdaemon.c:113 dirmngr/dirmngr.c:152 msgid "csh-style command output" msgstr "Ausgabe für /bin/csh" -#: agent/gpg-agent.c:130 scd/scdaemon.c:114 sm/gpgsm.c:312 -#: dirmngr/dirmngr.c:153 tools/symcryptrun.c:166 msgid "|FILE|read options from FILE" msgstr "|DATEI|Konfigurationsoptionen aus DATEI lesen" -#: agent/gpg-agent.c:135 scd/scdaemon.c:124 dirmngr/dirmngr.c:156 msgid "do not detach from the console" msgstr "Im Vordergrund laufen lassen" -#: agent/gpg-agent.c:136 msgid "do not grab keyboard and mouse" msgstr "Tastatur und Maus nicht \"grabben\"" -#: agent/gpg-agent.c:137 tools/symcryptrun.c:165 msgid "use a log file for the server" msgstr "Logausgaben in eine Datei umlenken" -#: agent/gpg-agent.c:139 msgid "use a standard location for the socket" msgstr "Benutze einen Standardnamen für den Socket" -#: agent/gpg-agent.c:142 msgid "|PGM|use PGM as the PIN-Entry program" msgstr "|PGM|benutze PGM as PIN-Entry" -#: agent/gpg-agent.c:145 msgid "|PGM|use PGM as the SCdaemon program" msgstr "|PGM|benutze PGM als SCdaemon" -#: agent/gpg-agent.c:146 msgid "do not use the SCdaemon" msgstr "Den Scdaemon-basierten Kartenzugriff nicht nutzen" -#: agent/gpg-agent.c:158 msgid "ignore requests to change the TTY" msgstr "Ignoriere Anfragen, das TTY zu wechseln" -#: agent/gpg-agent.c:160 msgid "ignore requests to change the X display" msgstr "Ignoriere Anfragen, das X-Display zu wechseln" -#: agent/gpg-agent.c:163 msgid "|N|expire cached PINs after N seconds" msgstr "|N|lasse PINs im Cache nach N Sekunden verfallen" -#: agent/gpg-agent.c:176 msgid "do not use the PIN cache when signing" msgstr "benutze PINs im Cache nicht beim Signieren" -#: agent/gpg-agent.c:178 msgid "allow clients to mark keys as \"trusted\"" msgstr "erlaube Aufrufern Schlüssel als \"vertrauenswürdig\" zu markieren" -#: agent/gpg-agent.c:180 msgid "allow presetting passphrase" msgstr "erlaube ein \"preset\" von Passphrases" -#: agent/gpg-agent.c:181 msgid "enable ssh-agent emulation" msgstr "Die ssh-agent-Emulation anschalten" -#: agent/gpg-agent.c:183 msgid "|FILE|write environment settings also to FILE" msgstr "|DATEI|Schreibe die Umgebungsvariablen auf DATEI" #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug #. reporting address. This is so that we can change the #. reporting address without breaking the translations. -#: agent/gpg-agent.c:341 agent/preset-passphrase.c:93 agent/protect-tool.c:148 -#: g10/gpg.c:821 g10/gpgv.c:114 kbx/kbxutil.c:113 scd/scdaemon.c:247 -#: sm/gpgsm.c:529 dirmngr/dirmngr-client.c:147 dirmngr/dirmngr.c:302 -#: dirmngr/dirmngr_ldap.c:197 tools/gpg-connect-agent.c:188 -#: tools/gpgconf.c:101 tools/symcryptrun.c:203 tools/gpg-check-pattern.c:141 msgid "Please report bugs to <@EMAIL@>.\n" msgstr "" "Berichte über Programmfehler bitte in englisch an <@EMAIL@>.\n" "Sinn- oder Schreibfehler in den deutschen Texten bitte an .\n" -#: agent/gpg-agent.c:350 msgid "Usage: gpg-agent [options] (-h for help)" msgstr "Aufruf: gpg-agent [Optionen] (-h für Hilfe)" -#: agent/gpg-agent.c:352 msgid "" "Syntax: gpg-agent [options] [command [args]]\n" "Secret key management for GnuPG\n" @@ -468,156 +363,116 @@ msgstr "" "Syntax: gpg-agent [Optionen] [Befehl [Argumente]]\n" "Verwaltung von geheimen Schlüsseln für GnuPG\n" -#: agent/gpg-agent.c:398 g10/gpg.c:1014 scd/scdaemon.c:320 sm/gpgsm.c:679 -#: dirmngr/dirmngr.c:371 #, c-format msgid "invalid debug-level `%s' given\n" msgstr "ungültige Debugebene `%s' angegeben\n" -#: agent/gpg-agent.c:623 agent/protect-tool.c:561 kbx/kbxutil.c:428 -#: scd/scdaemon.c:427 sm/gpgsm.c:919 sm/gpgsm.c:922 dirmngr/dirmngr.c:629 -#: dirmngr/dirmngr.c:632 tools/symcryptrun.c:1001 -#: tools/gpg-check-pattern.c:177 #, c-format msgid "%s is too old (need %s, have %s)\n" msgstr "Die Bibliothek %s ist nicht aktuell (benötige %s, habe %s)\n" -#: agent/gpg-agent.c:737 g10/gpg.c:2122 scd/scdaemon.c:513 sm/gpgsm.c:1019 -#: dirmngr/dirmngr.c:751 #, c-format msgid "NOTE: no default option file `%s'\n" msgstr "Hinweis: Keine voreingestellte Optionendatei '%s' vorhanden\n" -#: agent/gpg-agent.c:748 agent/gpg-agent.c:1350 g10/gpg.c:2126 -#: scd/scdaemon.c:518 sm/gpgsm.c:1023 dirmngr/dirmngr.c:756 -#: dirmngr/dirmngr.c:1572 tools/symcryptrun.c:934 #, c-format msgid "option file `%s': %s\n" msgstr "Optionendatei '%s': %s\n" -#: agent/gpg-agent.c:756 g10/gpg.c:2133 scd/scdaemon.c:526 sm/gpgsm.c:1030 -#: dirmngr/dirmngr.c:764 #, c-format msgid "reading options from `%s'\n" msgstr "Optionen werden aus '%s' gelesen\n" -#: agent/gpg-agent.c:1125 g10/plaintext.c:160 g10/plaintext.c:169 -#: g10/plaintext.c:175 g10/plaintext.c:198 #, c-format msgid "error creating `%s': %s\n" msgstr "Fehler beim Erstellen von `%s': %s\n" -#: agent/gpg-agent.c:1470 agent/gpg-agent.c:1597 agent/gpg-agent.c:1636 -#: g10/exec.c:196 g10/openfile.c:444 scd/scdaemon.c:1037 #, c-format msgid "can't create directory `%s': %s\n" msgstr "Verzeichnis `%s' kann nicht erzeugt werden: %s\n" -#: agent/gpg-agent.c:1484 scd/scdaemon.c:1051 dirmngr/dirmngr.c:964 msgid "name of socket too long\n" msgstr "Der Name des Sockets ist zu lang\n" -#: agent/gpg-agent.c:1507 scd/scdaemon.c:1074 dirmngr/dirmngr.c:971 #, c-format msgid "can't create socket: %s\n" msgstr "Socket kann nicht erzeugt werden: %s\n" -#: agent/gpg-agent.c:1516 #, c-format msgid "socket name `%s' is too long\n" msgstr "Der Name des Sockets `%s' ist zu lang\n" -#: agent/gpg-agent.c:1544 msgid "a gpg-agent is already running - not starting a new one\n" msgstr "Ein gpg-agent läuft bereits - ein weiterer wird nicht gestartet\n" -#: agent/gpg-agent.c:1555 scd/scdaemon.c:1093 dirmngr/dirmngr.c:995 msgid "error getting nonce for the socket\n" msgstr "Fehler beim Ermitteln der \"Nonce\" dieses Sockets\n" -#: agent/gpg-agent.c:1560 scd/scdaemon.c:1096 dirmngr/dirmngr.c:998 #, c-format msgid "error binding socket to `%s': %s\n" msgstr "Der Socket kann nicht an `%s' gebunden werden: %s\n" -#: agent/gpg-agent.c:1572 scd/scdaemon.c:1105 dirmngr/dirmngr.c:1007 #, c-format msgid "listen() failed: %s\n" msgstr "Der listen()-Aufruf ist fehlgeschlagen: %s\n" -#: agent/gpg-agent.c:1578 scd/scdaemon.c:1112 dirmngr/dirmngr.c:1013 #, c-format msgid "listening on socket `%s'\n" msgstr "Es wird auf Socket `%s' gehört\n" -#: agent/gpg-agent.c:1600 agent/gpg-agent.c:1641 g10/openfile.c:447 #, c-format msgid "directory `%s' created\n" msgstr "Verzeichnis `%s' erzeugt\n" -#: agent/gpg-agent.c:1647 #, c-format msgid "stat() failed for `%s': %s\n" msgstr "stat()-Aufruf für `%s' fehlgeschlagen: %s\n" -#: agent/gpg-agent.c:1651 #, c-format msgid "can't use `%s' as home directory\n" msgstr "Die Datei `%s' kann nicht als Home-Verzeichnis benutzt werden\n" -#: agent/gpg-agent.c:1785 scd/scdaemon.c:1128 dirmngr/dirmngr.c:1689 #, c-format msgid "error reading nonce on fd %d: %s\n" msgstr "Fehler beim Lesen der \"Nonce\" von FD %d: %s\n" -#: agent/gpg-agent.c:1810 #, c-format msgid "handler 0x%lx for fd %d started\n" msgstr "Handhabungsroutine 0x%lx für fd %d gestartet\n" -#: agent/gpg-agent.c:1815 #, c-format msgid "handler 0x%lx for fd %d terminated\n" msgstr "Handhabungsroutine 0x%lx für den fd %d beendet\n" -#: agent/gpg-agent.c:1835 #, c-format msgid "ssh handler 0x%lx for fd %d started\n" msgstr "SSH-Handhabungsroutine 0x%lx für fd %d gestartet\n" -#: agent/gpg-agent.c:1840 #, c-format msgid "ssh handler 0x%lx for fd %d terminated\n" msgstr "SSH-Handhabungsroutine 0x%lx für fd %d beendet\n" -#: agent/gpg-agent.c:1985 scd/scdaemon.c:1265 #, c-format msgid "pth_select failed: %s - waiting 1s\n" msgstr "pth_select()-Aufruf fehlgeschlagen: %s - warte 1s\n" -#: agent/gpg-agent.c:2108 scd/scdaemon.c:1332 #, c-format msgid "%s %s stopped\n" msgstr "%s %s angehalten\n" -#: agent/gpg-agent.c:2244 msgid "no gpg-agent running in this session\n" msgstr "Der gpg-agent läuft nicht für diese Session\n" -#: agent/gpg-agent.c:2255 common/simple-pwquery.c:352 common/asshelp.c:497 msgid "malformed GPG_AGENT_INFO environment variable\n" msgstr "fehlerhaft aufgebaute GPG_AGENT_INFO - Umgebungsvariable\n" -#: agent/gpg-agent.c:2268 common/simple-pwquery.c:364 common/asshelp.c:509 #, c-format msgid "gpg-agent protocol version %d is not supported\n" msgstr "GPG-Agent-Protokoll-Version %d wird nicht unterstützt\n" -#: agent/preset-passphrase.c:97 msgid "Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n" msgstr "Aufruf: gpg-preset-passphrase [Optionen] KEYGRIP (-h für Hilfe)\n" -#: agent/preset-passphrase.c:100 msgid "" "Syntax: gpg-preset-passphrase [options] KEYGRIP\n" "Password cache maintenance\n" @@ -625,8 +480,6 @@ msgstr "" "Syntax: gpg-preset-passphrase [Optionen] KEYGRIP\n" "Kennwortpuffer-Pflege\n" -#: agent/protect-tool.c:105 g10/gpg.c:377 kbx/kbxutil.c:71 sm/gpgsm.c:187 -#: dirmngr/dirmngr.c:132 tools/gpgconf.c:59 msgid "" "@Commands:\n" " " @@ -634,9 +487,6 @@ msgstr "" "@Befehle:\n" " " -#: agent/protect-tool.c:114 g10/gpg.c:445 g10/gpgv.c:69 kbx/kbxutil.c:81 -#: sm/gpgsm.c:227 dirmngr/dirmngr.c:147 tools/gpg-connect-agent.c:69 -#: tools/gpgconf.c:76 tools/symcryptrun.c:156 msgid "" "@\n" "Options:\n" @@ -646,11 +496,9 @@ msgstr "" "Optionen:\n" " " -#: agent/protect-tool.c:151 msgid "Usage: gpg-protect-tool [options] (-h for help)\n" msgstr "Aufruf: gpg-protect-tool [Optionen] (-h für Hilfe)\n" -#: agent/protect-tool.c:153 msgid "" "Syntax: gpg-protect-tool [options] [args]\n" "Secret key maintenance tool\n" @@ -658,16 +506,13 @@ msgstr "" "Syntax: gpg-protect-tool [Optionen] [Argumente]\n" "Werkzeug zum Bearbeiten von geheimen Schlüsseln\n" -#: agent/protect-tool.c:682 msgid "Please enter the passphrase to unprotect the PKCS#12 object." msgstr "Bitte geben Sie die Passphrase zum Entsperren des PKCS#12 Objekts ein." -#: agent/protect-tool.c:687 msgid "Please enter the passphrase to protect the new PKCS#12 object." msgstr "" "Bitte geben Sie die Passphrase zum Schützen des neuen PKCS#12 Objekts ein." -#: agent/protect-tool.c:693 msgid "" "Please enter the passphrase to protect the imported object within the GnuPG " "system." @@ -675,7 +520,6 @@ msgstr "" "Bitte geben Sie die Passphrase ein, um das importierte Objekt im GnuPG " "System zu schützen." -#: agent/protect-tool.c:698 msgid "" "Please enter the passphrase or the PIN\n" "needed to complete this operation." @@ -683,58 +527,47 @@ msgstr "" "Die Eingabe der Passphrase bzw. der PIN\n" "wird benötigt, um diese Aktion auszuführen." -#: agent/protect-tool.c:703 tools/symcryptrun.c:440 msgid "Passphrase:" msgstr "Passphrase:" -#: agent/protect-tool.c:709 tools/symcryptrun.c:451 msgid "cancelled\n" msgstr "Vom Benutzer abgebrochen\n" -#: agent/protect-tool.c:711 tools/symcryptrun.c:447 #, c-format msgid "error while asking for the passphrase: %s\n" msgstr "Fehler bei der Abfrage der Passphrase: %s\n" -#: agent/trustlist.c:135 agent/trustlist.c:335 dirmngr/dirmngr.c:1374 #, c-format msgid "error opening `%s': %s\n" msgstr "Fehler beim Öffnen von `%s': %s\n" -#: agent/trustlist.c:151 common/helpfile.c:63 common/helpfile.c:79 #, c-format msgid "file `%s', line %d: %s\n" msgstr "Datei `%s', Zeile %d: %s\n" -#: agent/trustlist.c:173 agent/trustlist.c:181 #, c-format msgid "statement \"%s\" ignored in `%s', line %d\n" msgstr "" "Anweisung \"%s\" in `%s', Zeile %d\n" " ignoriert\n" -#: agent/trustlist.c:187 #, c-format msgid "system trustlist `%s' not available\n" msgstr "" "Systemliste der vertrauenswürdigen Zertifikate '%s' ist nicht vorhanden\n" -#: agent/trustlist.c:231 #, c-format msgid "bad fingerprint in `%s', line %d\n" msgstr "fehlerhafter Fingerabdruck in `%s', Zeile %d\n" -#: agent/trustlist.c:256 agent/trustlist.c:263 #, c-format msgid "invalid keyflag in `%s', line %d\n" msgstr "Ungültiges Schlüsselflag in `%s', Zeile %d\n" -#: agent/trustlist.c:297 common/helpfile.c:126 #, c-format msgid "error reading `%s', line %d: %s\n" msgstr "Fehler beim Lesen von `%s', Zeile %d: %s\n" -#: agent/trustlist.c:401 agent/trustlist.c:451 msgid "error reading list of trusted root certificates\n" msgstr "Fehler beim Lesen der Liste vertrauenswürdiger root-Zertifikate\n" @@ -746,7 +579,6 @@ msgstr "Fehler beim Lesen der Liste vertrauenswürdiger root-Zertifikate\n" #. plain % sign, you need to encode it as "%%25". The #. "%s" gets replaced by the name as stored in the #. certificate. -#: agent/trustlist.c:612 #, c-format msgid "" "Do you ultimately trust%%0A \"%s\"%%0Ato correctly certify user " @@ -755,11 +587,9 @@ msgstr "" "Wenn Sie vollständiges Vertrauen haben, daß%%0A \"%s\"%%" "0ABenutzerzertifikate verläßlich zertifiziert, so antworten Sie mit \"Ja\"." -#: agent/trustlist.c:621 common/audit.c:467 msgid "Yes" msgstr "Ja" -#: agent/trustlist.c:621 common/audit.c:469 msgid "No" msgstr "Nein" @@ -771,7 +601,6 @@ msgstr "Nein" #. "%%25". The second "%s" gets replaced by a hexdecimal #. fingerprint string whereas the first one receives the name #. as stored in the certificate. -#: agent/trustlist.c:655 #, c-format msgid "" "Please verify that the certificate identified as:%%0A \"%s\"%%0Ahas the " @@ -783,22 +612,18 @@ msgstr "" #. TRANSLATORS: "Correct" is the label of a button and intended #. to be hit if the fingerprint matches the one of the CA. The #. other button is "the default "Cancel" of the Pinentry. -#: agent/trustlist.c:669 msgid "Correct" msgstr "Korrekt" -#: agent/trustlist.c:669 msgid "Wrong" msgstr "Falsch" -#: agent/findkey.c:131 #, c-format msgid "Note: This passphrase has never been changed.%0APlease change it now." msgstr "" "Hinweis: Diese Passphrase wurde noch nie geändert/%0ABitte ändern Sie sie " "jetzt." -#: agent/findkey.c:147 #, c-format msgid "" "This passphrase has not been changed%%0Asince %.4s-%.2s-%.2s. Please change " @@ -807,631 +632,487 @@ msgstr "" "Diese Passphrase wurde seit dem %.4s-%.2s-%.2s nicht%%0A\n" "mehr geändert. Bitte ändern Sie sie jetzt." -#: agent/findkey.c:161 agent/findkey.c:168 msgid "Change passphrase" msgstr "Die Passphrase ändern" -#: agent/findkey.c:169 msgid "I'll change it later" msgstr "Ich werde sie später ändern" -#: agent/pksign.c:134 g10/seskey.c:226 sm/certcheck.c:85 msgid "DSA requires the hash length to be a multiple of 8 bits\n" msgstr "Für DSA muß die Hashlänge ein Vielfaches von 8 Bit sein\n" -#: agent/pksign.c:145 sm/certcheck.c:97 #, c-format msgid "%s key uses an unsafe (%u bit) hash\n" msgstr "%s-Schlüssel verwendet ein unsicheres (%u-Bit) Hashverfahren\n" -#: agent/pksign.c:154 #, c-format msgid "a %zu bit hash is not valid for a %u bit %s key\n" msgstr "" "Ein %zu-Bit Hashverfahren ist für einen %u-Bit %s Schlüssel nicht möglich\n" -#: agent/cvt-openpgp.c:216 msgid "secret key parts are not available\n" msgstr "Teile des geheimen Schlüssels sind nicht vorhanden\n" -#: agent/cvt-openpgp.c:225 #, c-format msgid "public key algorithm %d (%s) is not supported\n" msgstr "Public-Key-Verfahren %d (%s) wird nicht unterstützt\n" -#: agent/cvt-openpgp.c:285 #, c-format msgid "protection algorithm %d (%s) is not supported\n" msgstr "Schutzverfahren %d (%s) wird nicht unterstützt\n" -#: agent/cvt-openpgp.c:292 #, c-format msgid "protection hash algorithm %d (%s) is not supported\n" msgstr "Schutzverfahrenshash %d (%s) wird nicht unterstützt\n" -#: common/exechelp-posix.c:312 common/exechelp-w32.c:405 -#: common/exechelp-w32.c:429 dirmngr/ldap-wrapper.c:673 #, c-format msgid "error creating a pipe: %s\n" msgstr "Fehler beim Erzeugen einer \"Pipe\": %s\n" -#: common/exechelp-posix.c:322 common/exechelp-w32.c:415 -#: common/exechelp-w32.c:439 #, c-format msgid "error creating a stream for a pipe: %s\n" msgstr "Fehler beim Erzeugen eines \"streams\" zu einer \"pipe\": %s\n" -#: common/exechelp-posix.c:399 common/exechelp-posix.c:465 -#: common/exechelp-posix.c:579 dirmngr/dirmngr.c:1027 #, c-format msgid "error forking process: %s\n" msgstr "Fehler beim \"Forken\" des Prozess: %s\n" -#: common/exechelp-posix.c:508 common/exechelp-w32.c:670 -#: common/exechelp-w32ce.c:741 #, c-format msgid "waiting for process %d to terminate failed: %s\n" msgstr "Das Warten auf die Beendigung des Prozesses %d schlug fehl: %s\n" -#: common/exechelp-posix.c:517 #, c-format msgid "error running `%s': probably not installed\n" msgstr "Fehler bei Ausführung von `%s': wahrscheinlich nicht installiert\n" -#: common/exechelp-posix.c:523 common/exechelp-w32.c:684 -#: common/exechelp-w32ce.c:755 #, c-format msgid "error running `%s': exit status %d\n" msgstr "Fehler bei Ausführung von `%s': Endestatus %d\n" -#: common/exechelp-posix.c:531 #, c-format msgid "error running `%s': terminated\n" msgstr "Fehler bei Ausführung von `%s': beendet\n" -#: common/exechelp-w32.c:678 common/exechelp-w32ce.c:749 #, c-format msgid "error getting exit code of process %d: %s\n" msgstr "Fehler beim Holen des Exitwerte des Prozesses %d: %s\n" -#: common/http.c:1607 #, c-format msgid "error creating socket: %s\n" msgstr "Fehler beim Erstellen des Sockets: %s\n" -#: common/http.c:1651 msgid "host not found" msgstr "Host nicht gefunden" -#: common/simple-pwquery.c:338 msgid "gpg-agent is not available in this session\n" msgstr "GPG-Agent ist in dieser Sitzung nicht vorhanden\n" -#: common/simple-pwquery.c:395 #, c-format msgid "can't connect to `%s': %s\n" msgstr "Verbindung zu '%s' kann nicht aufgebaut werden: %s\n" -#: common/simple-pwquery.c:406 msgid "communication problem with gpg-agent\n" msgstr "Kommunikationsproblem mit GPG-Agent\n" -#: common/simple-pwquery.c:416 msgid "problem setting the gpg-agent options\n" msgstr "Beim Setzen der gpg-agent Optionen ist ein Problem aufgetreten\n" -#: common/simple-pwquery.c:579 common/simple-pwquery.c:675 msgid "canceled by user\n" msgstr "Vom Benutzer abgebrochen\n" -#: common/simple-pwquery.c:594 common/simple-pwquery.c:681 msgid "problem with the agent\n" msgstr "Problem mit dem Agenten\n" -#: common/sysutils.c:109 #, c-format msgid "can't disable core dumps: %s\n" msgstr "core-dump-Dateierzeugung kann nicht abgeschaltet werden: %s\n" -#: common/sysutils.c:193 #, c-format msgid "Warning: unsafe ownership on %s \"%s\"\n" msgstr "WARNUNG: Unsichere Besitzrechte für %s \"%s\"\n" -#: common/sysutils.c:225 #, c-format msgid "Warning: unsafe permissions on %s \"%s\"\n" msgstr "WARNUNG: Unsichere Zugriffsrechte für %s \"%s\"\n" #. TRANSLATORS: See doc/TRANSLATE about this string. -#: common/yesno.c:35 common/yesno.c:72 msgid "yes" msgstr "ja" -#: common/yesno.c:36 common/yesno.c:77 msgid "yY" msgstr "jJyY" #. TRANSLATORS: See doc/TRANSLATE about this string. -#: common/yesno.c:38 common/yesno.c:74 msgid "no" msgstr "nein" -#: common/yesno.c:39 common/yesno.c:78 msgid "nN" msgstr "nN" #. TRANSLATORS: See doc/TRANSLATE about this string. -#: common/yesno.c:76 msgid "quit" msgstr "quit" -#: common/yesno.c:79 msgid "qQ" msgstr "qQ" #. TRANSLATORS: See doc/TRANSLATE about this string. -#: common/yesno.c:113 msgid "okay|okay" msgstr "okay|okay" #. TRANSLATORS: See doc/TRANSLATE about this string. -#: common/yesno.c:115 msgid "cancel|cancel" msgstr "abbrechen|abbrechen" -#: common/yesno.c:116 msgid "oO" msgstr "oO" -#: common/yesno.c:117 msgid "cC" msgstr "cC" -#: common/miscellaneous.c:76 #, c-format msgid "out of core in secure memory while allocating %lu bytes" msgstr "" "Kein sicherer Speicher mehr vorhanden, als %lu Byte zugewiesen werden sollten" -#: common/miscellaneous.c:79 #, c-format msgid "out of core while allocating %lu bytes" msgstr "Kein Speicher mehr vorhanden, als %lu Byte zugewiesen werden sollten" -#: common/asshelp.c:378 #, c-format msgid "no running gpg-agent - starting `%s'\n" msgstr "Kein aktiver gpg-agent - `%s' wird gestartet\n" -#: common/asshelp.c:436 #, c-format msgid "waiting for the agent to come up ... (%ds)\n" msgstr "Warte bis der gpg-agent bereit ist ... (%ds)\n" -#: common/asshelp.c:445 common/asshelp.c:534 msgid "connection to agent established\n" msgstr "Verbindung zum gpg-agent aufgebaut\n" -#: common/asshelp.c:520 msgid "can't connect to the agent - trying fall back\n" msgstr "Verbindung zum gpg-agent nicht möglich - Ersatzmethode wird versucht\n" -#: common/asshelp.c:596 #, c-format msgid "no running Dirmngr - starting `%s'\n" msgstr "Kein aktiver Dirmngr - `%s' wird gestartet\n" -#: common/asshelp.c:630 #, c-format msgid "waiting for the dirmngr to come up ... (%ds)\n" msgstr "Warte bis der Dirmngr bereit ist ... (%ds)\n" -#: common/asshelp.c:639 common/asshelp.c:668 msgid "connection to the dirmngr established\n" msgstr "Verbindung zum Dirmngr aufgebaut\n" #. TRANSLATORS: Copy the prefix between the vertical bars #. verbatim. It will not be printed. -#: common/audit.c:474 msgid "|audit-log-result|Good" msgstr "|audit-log-result|Korrekt" -#: common/audit.c:477 msgid "|audit-log-result|Bad" msgstr "|audit-log-result|Falsch" -#: common/audit.c:479 msgid "|audit-log-result|Not supported" msgstr "|audit-log-result|Nicht unterstützt" -#: common/audit.c:481 msgid "|audit-log-result|No certificate" msgstr "|audit-log-result|Zertifikat fehlt" -#: common/audit.c:483 msgid "|audit-log-result|Not enabled" msgstr "|audit-log-result|Nicht eingeschaltet" -#: common/audit.c:485 msgid "|audit-log-result|Error" msgstr "|audit-log-result|Fehler" -#: common/audit.c:487 msgid "|audit-log-result|Not used" msgstr "|audit-log-result|Nicht benötigt" -#: common/audit.c:489 msgid "|audit-log-result|Okay" msgstr "|audit-log-result|Okay" -#: common/audit.c:491 msgid "|audit-log-result|Skipped" msgstr "|audit-log-result|Übergangen" -#: common/audit.c:493 msgid "|audit-log-result|Some" msgstr "|audit-log-result|Einige" -#: common/audit.c:726 msgid "Certificate chain available" msgstr "Zertifikatkette vorhanden" -#: common/audit.c:733 msgid "root certificate missing" msgstr "Das Wurzelzertifikat fehlt" -#: common/audit.c:759 msgid "Data encryption succeeded" msgstr "Verschlüsseln der Daten erfolgreich" -#: common/audit.c:764 common/audit.c:830 common/audit.c:906 common/audit.c:997 msgid "Data available" msgstr "Daten vorhanden" -#: common/audit.c:767 msgid "Session key created" msgstr "Sitzungsschlüssel erzeugt" -#: common/audit.c:772 common/audit.c:912 common/audit.c:919 #, c-format msgid "algorithm: %s" msgstr "Verfahren: %s" -#: common/audit.c:774 common/audit.c:776 common/audit.c:921 common/audit.c:923 #, c-format msgid "unsupported algorithm: %s" msgstr "Nicht unterstütztes Verfahren: %s" -#: common/audit.c:778 common/audit.c:925 msgid "seems to be not encrypted" msgstr "dies is wahrscheinlich nicht verschlüsselt" -#: common/audit.c:784 common/audit.c:933 msgid "Number of recipients" msgstr "Anzahl der Empfänger" -#: common/audit.c:792 common/audit.c:956 #, c-format msgid "Recipient %d" msgstr "Empfänger %d" -#: common/audit.c:825 msgid "Data signing succeeded" msgstr "Signieren der Daten erfolgreich" -#: common/audit.c:839 common/audit.c:1033 common/audit.c:1060 #, c-format msgid "data hash algorithm: %s" msgstr "Hashverfahren für Daten: %s" -#: common/audit.c:862 #, c-format msgid "Signer %d" msgstr "Unterzeichner %d" -#: common/audit.c:866 common/audit.c:1065 #, c-format msgid "attr hash algorithm: %s" msgstr "Hashverfahren für Attribute: %s" -#: common/audit.c:901 msgid "Data decryption succeeded" msgstr "Entschlüsselung der Daten erfolgreich" -#: common/audit.c:910 msgid "Encryption algorithm supported" msgstr "Verschlüsselungsverfahren %d%s wird nicht unterstützt" -#: common/audit.c:993 msgid "Data verification succeeded" msgstr "Prüfung der Signatur erfolgreich" -#: common/audit.c:1002 msgid "Signature available" msgstr "Signatur vorhanden" -#: common/audit.c:1024 msgid "Parsing data succeeded" msgstr "Syntaxanalyse der Daten erfolgreich" -#: common/audit.c:1036 #, c-format msgid "bad data hash algorithm: %s" msgstr "Ungültiges Hashverfahren für Daten: %s" -#: common/audit.c:1051 #, c-format msgid "Signature %d" msgstr "Signatur %d" -#: common/audit.c:1079 msgid "Certificate chain valid" msgstr "Zertifikatkette gültig" -#: common/audit.c:1090 msgid "Root certificate trustworthy" msgstr "Wurzelzertifikat vertrauenswürdig" -#: common/audit.c:1111 sm/certchain.c:935 msgid "no CRL found for certificate" msgstr "Keine CRL für das Zertifikat gefunden" -#: common/audit.c:1114 sm/certchain.c:945 msgid "the available CRL is too old" msgstr "Die vorhandene CRL ist zu alt" -#: common/audit.c:1119 msgid "CRL/OCSP check of certificates" msgstr "CRL/OCSP Prüfung der Zertifikate" -#: common/audit.c:1139 msgid "Included certificates" msgstr "Mitgesendete Zertifikate" -#: common/audit.c:1194 msgid "No audit log entries." msgstr "Keine Einträge in der Audit-Datei" -#: common/audit.c:1243 msgid "Unknown operation" msgstr "Unbekannte Operation" -#: common/audit.c:1261 msgid "Gpg-Agent usable" msgstr "Gpg-Agent benutzbar" -#: common/audit.c:1271 msgid "Dirmngr usable" msgstr "Dirmngr benutzbar" -#: common/audit.c:1307 #, c-format msgid "No help available for `%s'." msgstr "Keine Hilfe für '%s' vorhanden." -#: common/helpfile.c:80 msgid "ignoring garbage line" msgstr "Zeile mit nicht identifizierten Zeichen wird ignoriert" -#: common/gettime.c:520 msgid "[none]" msgstr "[keine]" -#: common/argparse.c:233 msgid "argument not expected" msgstr "Argument nicht erwartet" -#: common/argparse.c:235 msgid "read error" msgstr "Lesefehler" -#: common/argparse.c:237 msgid "keyword too long" msgstr "Schlüsselwort ist zu lang" -#: common/argparse.c:239 msgid "missing argument" msgstr "Fehlendes Argument" -#: common/argparse.c:241 msgid "invalid command" msgstr "Ungültiger Befehl" -#: common/argparse.c:243 msgid "invalid alias definition" msgstr "Ungültige Alias-Definition" -#: common/argparse.c:245 msgid "out of core" msgstr "Nicht genügend Speicher" -#: common/argparse.c:247 msgid "invalid option" msgstr "Ungültige Option" -#: common/argparse.c:255 #, c-format msgid "missing argument for option \"%.50s\"\n" msgstr "Fehlendes Argument für Option \"%.50s\"\n" -#: common/argparse.c:257 #, c-format msgid "option \"%.50s\" does not expect an argument\n" msgstr "Option \"%.50s\" erwartet kein Argument\n" -#: common/argparse.c:260 #, c-format msgid "invalid command \"%.50s\"\n" msgstr "Ungültiger Befehl \"%.50s\"\n" -#: common/argparse.c:262 #, c-format msgid "option \"%.50s\" is ambiguous\n" msgstr "Option \"%.50s\" ist mehrdeutig\n" -#: common/argparse.c:264 #, c-format msgid "command \"%.50s\" is ambiguous\n" msgstr "Befehl \"%.50s\" ist mehrdeutig\n" -#: common/argparse.c:266 dirmngr/dirmngr.c:1045 msgid "out of core\n" msgstr "Nicht genügend Speicher\n" -#: common/argparse.c:268 #, c-format msgid "invalid option \"%.50s\"\n" msgstr "Ungültige Option \"%.50s\"\n" -#: common/logging.c:860 #, c-format msgid "you found a bug ... (%s:%d)\n" msgstr "Sie haben einen Bug (Programmfehler) gefunden ... (%s:%d)\n" -#: common/utf8conv.c:89 #, c-format msgid "error loading `%s': %s\n" msgstr "Fehler beim Laden von `%s': %s\n" -#: common/utf8conv.c:91 g10/misc.c:539 g10/sig-check.c:107 #, c-format msgid "please see %s for more information\n" msgstr "Siehe %s für weitere Infos\n" -#: common/utf8conv.c:128 #, c-format msgid "conversion from `%s' to `%s' not available\n" msgstr "Umwandlung von `%s' in `%s' ist nicht verfügbar\n" -#: common/utf8conv.c:136 #, c-format msgid "iconv_open failed: %s\n" msgstr "iconv_open fehlgeschlagen: %s\n" -#: common/utf8conv.c:395 common/utf8conv.c:661 #, c-format msgid "conversion from `%s' to `%s' failed: %s\n" msgstr "Umwandlung von `%s' in `%s' schlug fehl: %s\n" -#: common/dotlock.c:237 #, c-format msgid "failed to create temporary file `%s': %s\n" msgstr "Die temporäre Datei `%s' kann nicht erstellt werden: %s\n" -#: common/dotlock.c:272 #, c-format msgid "error writing to `%s': %s\n" msgstr "Fehler beim Schreiben von %s: %s\n" -#: common/dotlock.c:472 #, c-format msgid "removing stale lockfile (created by %d)\n" msgstr "eine übriggebliebene Sperrdatei wird entfernt (erzeugt von %d)\n" -#: common/dotlock.c:478 msgid " - probably dead - removing lock" msgstr " - existiert wahrscheinlich nicht mehr - entferne Sperre" -#: common/dotlock.c:488 #, c-format msgid "waiting for lock (held by %d%s) %s...\n" msgstr "warte auf die Freigabe der Sperre (gehalten von %d%s) %s...\n" -#: common/dotlock.c:489 msgid "(deadlock?) " msgstr "(Deadlock?) " -#: common/dotlock.c:516 #, c-format msgid "lock `%s' not made: %s\n" msgstr "Dateisperre %s konnte nicht eingerichtet werden: %s\n" -#: common/dotlock.c:524 #, c-format msgid "waiting for lock %s...\n" msgstr "Warten auf die Freigabe der Dateisperre `%s' ...\n" -#: g10/armor.c:379 #, c-format msgid "armor: %s\n" msgstr "ASCII-Hülle: %s\n" -#: g10/armor.c:418 msgid "invalid armor header: " msgstr "Ungültige ASCII-Hülle" -#: g10/armor.c:429 msgid "armor header: " msgstr "ASCII-Hülle: " -#: g10/armor.c:442 msgid "invalid clearsig header\n" msgstr "Ungültige Klartextsignatur-Einleitung\n" -#: g10/armor.c:455 msgid "unknown armor header: " msgstr "Unbekannter Header in der ASCII-Hülle: " -#: g10/armor.c:508 msgid "nested clear text signatures\n" msgstr "verschachtelte Klartextsignatur\n" -#: g10/armor.c:643 msgid "unexpected armor: " msgstr "Unerwartete ASCII-Hülle: " -#: g10/armor.c:656 msgid "invalid dash escaped line: " msgstr "Ungültige mit Bindestrich \"escapte\" Zeile: " -#: g10/armor.c:811 g10/armor.c:1421 #, c-format msgid "invalid radix64 character %02X skipped\n" msgstr "Ungültiges \"radix64\" Zeichen %02x übersprungen\n" -#: g10/armor.c:854 msgid "premature eof (no CRC)\n" msgstr "vorzeitiges Dateiende (keine Prüfsumme)\n" -#: g10/armor.c:888 msgid "premature eof (in CRC)\n" msgstr "vorzeitiges Dateiende (innerhalb der Prüfsumme)\n" -#: g10/armor.c:896 msgid "malformed CRC\n" msgstr "Falsch aufgebaute Prüfsumme\n" -#: g10/armor.c:900 g10/armor.c:1458 #, c-format msgid "CRC error; %06lX - %06lX\n" msgstr "Prüfsummenfehler; %06lx - %06lx\n" -#: g10/armor.c:920 msgid "premature eof (in trailer)\n" msgstr "vorzeitiges Dateiende (im Nachsatz)\n" -#: g10/armor.c:924 msgid "error in trailer line\n" msgstr "Fehler in der Nachsatzzeile\n" -#: g10/armor.c:1235 msgid "no valid OpenPGP data found.\n" msgstr "Keine gültigen OpenPGP-Daten gefunden.\n" -#: g10/armor.c:1240 #, c-format msgid "invalid armor: line longer than %d characters\n" msgstr "ungültige ASCII-Hülle: Zeile ist länger als %d Zeichen\n" -#: g10/armor.c:1244 msgid "" "quoted printable character in armor - probably a buggy MTA has been used\n" msgstr "" "\"quoted printable\" Zeichen in der ASCII-Hülle gefunden - möglicherweise\n" " war ein fehlerhafter Email-Transporter(\"MTA\") die Ursache\n" -#: g10/build-packet.c:945 msgid "" "a notation name must have only printable characters or spaces, and end with " "an '='\n" @@ -1439,196 +1120,147 @@ msgstr "" "Ein \"notation\"-Name darf nur Buchstaben, Zahlen, Punkte oder Unterstriche " "enthalten und muß mit einem '=' enden\n" -#: g10/build-packet.c:957 msgid "a user notation name must contain the '@' character\n" msgstr "Ein \"notation\"-Wert darf das '@'-Zeichen nicht verwenden\n" -#: g10/build-packet.c:963 msgid "a notation name must not contain more than one '@' character\n" msgstr "Ein \"notation\"-Wert darf das '@'-Zeichen maximal einmal verwenden\n" -#: g10/build-packet.c:981 msgid "a notation value must not use any control characters\n" msgstr "Ein \"notation\"-Wert darf keine Kontrollzeichen verwenden\n" -#: g10/build-packet.c:1015 g10/build-packet.c:1024 msgid "WARNING: invalid notation data found\n" msgstr "WARNUNG: Ungültige \"Notation\"-Daten gefunden\n" -#: g10/build-packet.c:1046 g10/build-packet.c:1048 msgid "not human readable" msgstr "nicht als Klartext darstellbar" -#: g10/card-util.c:86 g10/card-util.c:376 #, c-format msgid "OpenPGP card not available: %s\n" msgstr "OpenPGP Karte ist nicht vorhanden: %s\n" -#: g10/card-util.c:91 #, c-format msgid "OpenPGP card no. %s detected\n" msgstr "OpenPGP Karte Nr. %s erkannt\n" -#: g10/card-util.c:99 g10/card-util.c:1792 g10/delkey.c:114 g10/keyedit.c:1479 -#: g10/keygen.c:2893 g10/revoke.c:216 g10/revoke.c:457 msgid "can't do this in batch mode\n" msgstr "Dies kann im Batchmodus nicht durchgeführt werden.\n" -#: g10/card-util.c:107 msgid "This command is only available for version 2 cards\n" msgstr "Dieser Befehl ist nur für Karten ab Version 2 möglich.\n" -#: g10/card-util.c:109 scd/app-openpgp.c:2020 msgid "Reset Code not or not anymore available\n" msgstr "Der Rückstellcode ist nicht vorhanden\n" -#: g10/card-util.c:142 g10/card-util.c:1469 g10/keyedit.c:419 -#: g10/keyedit.c:439 g10/keyedit.c:453 g10/keygen.c:1483 g10/keygen.c:1564 -#: sm/certreqgen-ui.c:165 sm/certreqgen-ui.c:249 sm/certreqgen-ui.c:283 msgid "Your selection? " msgstr "Ihre Auswahl? " -#: g10/card-util.c:273 g10/card-util.c:324 msgid "[not set]" msgstr "[nicht gesetzt]" -#: g10/card-util.c:516 msgid "male" msgstr "männlich" -#: g10/card-util.c:517 msgid "female" msgstr "weiblich" -#: g10/card-util.c:517 msgid "unspecified" msgstr "unbestimmt" -#: g10/card-util.c:544 msgid "not forced" msgstr "nicht zwingend" -#: g10/card-util.c:544 msgid "forced" msgstr "zwingend" -#: g10/card-util.c:639 msgid "Error: Only plain ASCII is currently allowed.\n" msgstr "Fehler: Nur reines ASCII ist derzeit erlaubt.\n" -#: g10/card-util.c:641 msgid "Error: The \"<\" character may not be used.\n" msgstr "Fehler: Das Zeichen \"<\" kann nicht benutzt werden.\n" -#: g10/card-util.c:643 msgid "Error: Double spaces are not allowed.\n" msgstr "Fehler: Doppelte Leerzeichen sind nicht erlaubt.\n" -#: g10/card-util.c:660 msgid "Cardholder's surname: " msgstr "Familienname des Kartenbesitzers:" -#: g10/card-util.c:662 msgid "Cardholder's given name: " msgstr "Vorname des Kartenbesitzers:" -#: g10/card-util.c:680 #, c-format msgid "Error: Combined name too long (limit is %d characters).\n" msgstr "" "Fehler: Der zusammengesetzte Name ist zu lang (Grenze beträgt %d Zeichen).\n" -#: g10/card-util.c:701 msgid "URL to retrieve public key: " msgstr "URL um den öffentlichen Schlüssel zu holen: " -#: g10/card-util.c:709 #, c-format msgid "Error: URL too long (limit is %d characters).\n" msgstr "Fehler: URL ist zu lang (Grenze beträgt %d Zeichen).\n" -#: g10/card-util.c:802 tools/no-libgcrypt.c:30 #, c-format msgid "error allocating enough memory: %s\n" msgstr "Fehler beim Zuteilen genügenden Speichers: %s\n" -#: g10/card-util.c:814 g10/import.c:317 dirmngr/crlcache.c:649 -#: dirmngr/crlcache.c:654 dirmngr/crlcache.c:908 dirmngr/crlcache.c:914 -#: dirmngr/dirmngr.c:1412 #, c-format msgid "error reading `%s': %s\n" msgstr "Fehler beim Lesen von `%s': %s\n" -#: g10/card-util.c:847 dirmngr/crlcache.c:919 #, c-format msgid "error writing `%s': %s\n" msgstr "Fehler beim Schreiben von %s: %s\n" -#: g10/card-util.c:874 msgid "Login data (account name): " msgstr "Logindaten (Kontenname): " -#: g10/card-util.c:884 #, c-format msgid "Error: Login data too long (limit is %d characters).\n" msgstr "Fehler: Logindaten sind zu lang (Grenze beträgt %d Zeichen).\n" -#: g10/card-util.c:920 msgid "Private DO data: " msgstr "Geheime DO-Daten: " -#: g10/card-util.c:930 #, c-format msgid "Error: Private DO too long (limit is %d characters).\n" msgstr "Fehler: Geheime DO-Daten sind zu lang (Grenze beträgt %d Zeichen).\n" -#: g10/card-util.c:1013 msgid "Language preferences: " msgstr "Spracheinstellungen" -#: g10/card-util.c:1021 msgid "Error: invalid length of preference string.\n" msgstr "Fehler: Ungültige Länge der Einstellungs-Zeichenfolge.\n" -#: g10/card-util.c:1030 msgid "Error: invalid characters in preference string.\n" msgstr "Fehler: Ungültige Zeichen in der Einstellungs-Zeichenfolge\n" -#: g10/card-util.c:1052 msgid "Sex ((M)ale, (F)emale or space): " msgstr "Geschlecht: (Männlich (M), Weiblich (F) oder Leerzeichen): " -#: g10/card-util.c:1066 msgid "Error: invalid response.\n" msgstr "Fehler: ungültige Antwort.\n" -#: g10/card-util.c:1088 msgid "CA fingerprint: " msgstr "CA-Fingerabdruck: " -#: g10/card-util.c:1111 msgid "Error: invalid formatted fingerprint.\n" msgstr "Fehler: ungültig geformter Fingerabdruck.\n" -#: g10/card-util.c:1161 #, c-format msgid "key operation not possible: %s\n" msgstr "Schlüsseloperation nicht möglich: %s\n" -#: g10/card-util.c:1162 msgid "not an OpenPGP card" msgstr "Keine gültige OpenPGP-Karte" -#: g10/card-util.c:1175 #, c-format msgid "error getting current key info: %s\n" msgstr "Fehler beim Holen der aktuellen Schlüsselinfo: %s\n" -#: g10/card-util.c:1262 msgid "Replace existing key? (y/N) " msgstr "Vorhandenen Schlüssel ersetzen? (j/N) " -#: g10/card-util.c:1278 msgid "" "NOTE: There is no guarantee that the card supports the requested size.\n" " If the key generation does not succeed, please check the\n" @@ -1640,59 +1272,47 @@ msgstr "" " fehlschlagen, so ziehen Sie bitte die Dokumentation Ihrer Karte\n" " zu Rate.\n" -#: g10/card-util.c:1303 #, c-format msgid "What keysize do you want for the Signature key? (%u) " msgstr "Welche Schlüssellänge wünschen Sie für den Signatur-Schlüssel? (%u) " -#: g10/card-util.c:1305 #, c-format msgid "What keysize do you want for the Encryption key? (%u) " msgstr "" "Welche Schlüssellänge wünschen Sie für den Verschlüsselungs-Schlüssel? (%u) " -#: g10/card-util.c:1306 #, c-format msgid "What keysize do you want for the Authentication key? (%u) " msgstr "" "Welche Schlüssellänge wünschen Sie für den Authentisierungs-Schlüssel? (%u) " -#: g10/card-util.c:1317 g10/keygen.c:1697 g10/keygen.c:1703 -#: sm/certreqgen-ui.c:194 #, c-format msgid "rounded up to %u bits\n" msgstr "aufgerundet auf %u Bit\n" -#: g10/card-util.c:1325 g10/keygen.c:1684 sm/certreqgen-ui.c:184 #, c-format msgid "%s keysizes must be in the range %u-%u\n" msgstr "%s-Schlüssellängen müssen im Bereich %u-%u sein\n" -#: g10/card-util.c:1330 #, c-format msgid "The card will now be re-configured to generate a key of %u bits\n" msgstr "" "Die Karte wird nun rekonfiguriert um einen Schlüssel von %u Bit zu erzeugen\n" -#: g10/card-util.c:1350 #, c-format msgid "error changing size of key %d to %u bits: %s\n" msgstr "Fehler bem Ändern der Länge des Schlüssels %d auf %u Bit: %s\n" -#: g10/card-util.c:1374 msgid "Make off-card backup of encryption key? (Y/n) " msgstr "" "Sicherung des Verschlüsselungsschlüssel außerhalb der Karte erstellen? (J/n) " -#: g10/card-util.c:1388 msgid "NOTE: keys are already stored on the card!\n" msgstr "ACHTUNG: Auf der Karte sind bereits Schlüssel gespeichert!\n" -#: g10/card-util.c:1391 msgid "Replace existing keys? (y/N) " msgstr "Vorhandene Schlüssel ersetzen? (j/N) " -#: g10/card-util.c:1403 #, c-format msgid "" "Please note that the factory settings of the PINs are\n" @@ -1703,214 +1323,164 @@ msgstr "" " PIN = `%s' Admin-PIN = `%s'\n" "Sie sollten sie mittels des Befehls --change-pin ändern\n" -#: g10/card-util.c:1460 msgid "Please select the type of key to generate:\n" msgstr "Bitte wählen Sie die Art des Schlüssel, der erzeugt werden soll:\n" -#: g10/card-util.c:1462 msgid " (1) Signature key\n" msgstr " (1) Signatur-Schlüssel\n" -#: g10/card-util.c:1463 msgid " (2) Encryption key\n" msgstr " (2) Verschlüsselungs-Schlüssel\n" -#: g10/card-util.c:1464 msgid " (3) Authentication key\n" msgstr " (3) Authentisierungs-Schlüssel\n" -#: g10/card-util.c:1481 g10/keyedit.c:947 g10/keygen.c:1487 g10/keygen.c:1515 -#: g10/keygen.c:1617 g10/revoke.c:655 msgid "Invalid selection.\n" msgstr "Ungültige Auswahl.\n" -#: g10/card-util.c:1701 g10/keyedit.c:1322 msgid "quit this menu" msgstr "Menü verlassen" -#: g10/card-util.c:1703 msgid "show admin commands" msgstr "Zeige Admin-Befehle" -#: g10/card-util.c:1704 g10/keyedit.c:1325 msgid "show this help" msgstr "Diese Hilfe zeigen" -#: g10/card-util.c:1706 msgid "list all available data" msgstr "Alle vorhandenen Daten auflisten" -#: g10/card-util.c:1709 msgid "change card holder's name" msgstr "Kartenbesitzernamen ändern" -#: g10/card-util.c:1710 msgid "change URL to retrieve key" msgstr "Schlüssel-holen-URL ändern" -#: g10/card-util.c:1711 msgid "fetch the key specified in the card URL" msgstr "Holen des Schlüssels mittels der URL auf der Karte" -#: g10/card-util.c:1712 msgid "change the login name" msgstr "Ändern der Logindaten" -#: g10/card-util.c:1713 msgid "change the language preferences" msgstr "Ändern der Spracheinstellungen" -#: g10/card-util.c:1714 msgid "change card holder's sex" msgstr "Ändern des Geschlechts des Kartenbesitzers" -#: g10/card-util.c:1715 msgid "change a CA fingerprint" msgstr "Ändern des CA-Fingerabdrucks" -#: g10/card-util.c:1716 msgid "toggle the signature force PIN flag" msgstr "Umschalten des \"Signature-force-PIN\"-Schalters" -#: g10/card-util.c:1717 msgid "generate new keys" msgstr "neue Schlüssel erzeugen" -#: g10/card-util.c:1718 msgid "menu to change or unblock the PIN" msgstr "Menü für Ändern oder Entsperren der PIN" -#: g10/card-util.c:1719 msgid "verify the PIN and list all data" msgstr "überprüfe die PIN und liste alle Daten auf" -#: g10/card-util.c:1720 msgid "unblock the PIN using a Reset Code" msgstr "die PIN mit dem Rückstellcode wieder freigeben" -#: g10/card-util.c:1842 msgid "gpg/card> " msgstr "gpg/card> " -#: g10/card-util.c:1883 msgid "Admin-only command\n" msgstr "nur-Admin Befehl\n" -#: g10/card-util.c:1914 msgid "Admin commands are allowed\n" msgstr "Admin-Befehle sind erlaubt\n" -#: g10/card-util.c:1916 msgid "Admin commands are not allowed\n" msgstr "Admin-Befehle sind nicht erlaubt\n" -#: g10/card-util.c:2007 g10/keyedit.c:2222 msgid "Invalid command (try \"help\")\n" msgstr "Ungültiger Befehl (versuchen Sie's mal mit \"help\")\n" -#: g10/decrypt.c:184 g10/encrypt.c:948 msgid "--output doesn't work for this command\n" msgstr "--output funktioniert nicht bei diesem Befehl\n" -#: g10/decrypt.c:240 g10/gpg.c:4050 g10/keyring.c:379 g10/keyring.c:690 #, c-format msgid "can't open `%s'\n" msgstr "'%s' kann nicht geöffnet werden\n" -#: g10/delkey.c:73 g10/export.c:691 g10/keyedit.c:3355 g10/keyserver.c:1134 -#: g10/revoke.c:227 #, c-format msgid "key \"%s\" not found: %s\n" msgstr "Schlüssel \"%s\" nicht gefunden: %s\n" -#: g10/delkey.c:81 g10/export.c:755 g10/getkey.c:2881 g10/keyserver.c:1148 -#: g10/revoke.c:233 g10/revoke.c:479 #, c-format msgid "error reading keyblock: %s\n" msgstr "Fehler beim Lesen des Schlüsselblocks: %s\n" -#: g10/delkey.c:115 g10/delkey.c:122 msgid "(unless you specify the key by fingerprint)\n" msgstr "(es sei denn, Sie geben den Schlüssel mittels Fingerprint an)\n" -#: g10/delkey.c:121 msgid "can't do this in batch mode without \"--yes\"\n" msgstr "dies kann im Batchmodus ohne \"--yes\" nicht durchgeführt werden\n" -#: g10/delkey.c:133 msgid "Delete this key from the keyring? (y/N) " msgstr "Diesen Schlüssel aus dem Schlüsselbund löschen? (j/N) " -#: g10/delkey.c:141 msgid "This is a secret key! - really delete? (y/N) " msgstr "Dies ist ein privater Schlüssel! - Wirklich löschen? (j/N) " -#: g10/delkey.c:151 #, c-format msgid "deleting keyblock failed: %s\n" msgstr "löschen des Schlüsselblocks fehlgeschlagen: %s\n" -#: g10/delkey.c:161 msgid "ownertrust information cleared\n" msgstr "Der \"Ownertrust\" wurde gelöscht\n" -#: g10/delkey.c:192 #, c-format msgid "there is a secret key for public key \"%s\"!\n" msgstr "" "Es gibt einen privaten Schlüssel zu diesem öffentlichen Schlüssel \"%s\"!\n" -#: g10/delkey.c:194 msgid "use option \"--delete-secret-keys\" to delete it first.\n" msgstr "" "Verwenden Sie zunächst den Befehl \"--delete-secret-key\", um ihn zu " "entfernen.\n" -#: g10/encrypt.c:232 g10/sign.c:1342 #, c-format msgid "error creating passphrase: %s\n" msgstr "Fehler beim Erzeugen der Passphrase: %s\n" -#: g10/encrypt.c:239 msgid "can't use a symmetric ESK packet due to the S2K mode\n" msgstr "" "Aufgrund des S2K-Modus kann ein symmetrisches ESK Paket nicht benutzt " "werden\n" -#: g10/encrypt.c:253 #, c-format msgid "using cipher %s\n" msgstr "benutze Cipher %s\n" -#: g10/encrypt.c:263 g10/encrypt.c:627 #, c-format msgid "`%s' already compressed\n" msgstr "`%s' ist bereits komprimiert\n" -#: g10/encrypt.c:320 g10/encrypt.c:662 g10/sign.c:627 #, c-format msgid "WARNING: `%s' is an empty file\n" msgstr "WARNUNG: '%s' ist eine leere Datei.\n" -#: g10/encrypt.c:519 msgid "you can only encrypt to RSA keys of 2048 bits or less in --pgp2 mode\n" msgstr "" "Im --pgp2-Modus kann nur für RSA-Schlüssel mit maximal 2048 Bit " "verschlüsselt werden\n" -#: g10/encrypt.c:553 #, c-format msgid "reading from `%s'\n" msgstr "Lesen von '%s'\n" -#: g10/encrypt.c:588 msgid "" "unable to use the IDEA cipher for all of the keys you are encrypting to.\n" msgstr "" "Die IDEA-Verschlüsselung kann nicht mit allen Zielschlüsseln verwendet " "werden.\n" -#: g10/encrypt.c:608 #, c-format msgid "" "WARNING: forcing symmetric cipher %s (%d) violates recipient preferences\n" @@ -1918,7 +1488,6 @@ msgstr "" "WARNUNG: Erzwungene Verwendung des symmetrischen Verschlüsselungsverfahren %" "s (%d) verletzt die Empfängervoreinstellungen\n" -#: g10/encrypt.c:709 g10/sign.c:1008 #, c-format msgid "" "WARNING: forcing compression algorithm %s (%d) violates recipient " @@ -1927,349 +1496,270 @@ msgstr "" "WARNUNG: Erzwungenes Kompressionsverfahren %s (%d) verletzt die " "Empfängervoreinstellungen.\n" -#: g10/encrypt.c:819 #, c-format msgid "forcing symmetric cipher %s (%d) violates recipient preferences\n" msgstr "" "Erzwungene Verwendung des symmetrischen Verschlüsselungsverfahren %s (%d) " "verletzt die Empfängervoreinstellungen\n" -#: g10/encrypt.c:890 g10/pkclist.c:916 g10/pkclist.c:965 #, c-format msgid "you may not use %s while in %s mode\n" msgstr "Die Benutzung von %s ist im %s-Modus nicht erlaubt.\n" -#: g10/encrypt.c:918 #, c-format msgid "%s/%s encrypted for: \"%s\"\n" msgstr "%s/%s verschlüsselt für: %s\n" -#: g10/decrypt-data.c:94 g10/mainproc.c:286 #, c-format msgid "%s encrypted data\n" msgstr "%s verschlüsselte Daten\n" -#: g10/decrypt-data.c:97 g10/mainproc.c:290 #, c-format msgid "encrypted with unknown algorithm %d\n" msgstr "Mit unbekanntem Verfahren verschlüsselt %d\n" -#: g10/decrypt-data.c:135 sm/decrypt.c:127 msgid "" "WARNING: message was encrypted with a weak key in the symmetric cipher.\n" msgstr "" "Warnung: Botschaft wurde mit einem unsicheren Schlüssel verschlüsselt.\n" -#: g10/decrypt-data.c:147 msgid "problem handling encrypted packet\n" msgstr "Problem beim Bearbeiten des verschlüsselten Pakets\n" -#: g10/exec.c:57 msgid "no remote program execution supported\n" msgstr "Ausführen von externen Programmen wird nicht unterstützt\n" -#: g10/exec.c:316 msgid "" "external program calls are disabled due to unsafe options file permissions\n" msgstr "" "Ausführen von externen Programmen ist ausgeschaltet, da die Dateirechte " "nicht sicher sind\n" -#: g10/exec.c:346 msgid "this platform requires temporary files when calling external programs\n" msgstr "" "Diese Plattform benötigt temporäre Dateien zur Ausführung von externen\n" "Programmen\n" -#: g10/exec.c:424 #, c-format msgid "unable to execute program `%s': %s\n" msgstr "Ausführen des Programms `%s' nicht möglich: %s\n" -#: g10/exec.c:427 #, c-format msgid "unable to execute shell `%s': %s\n" msgstr "Ausführen der Shell `%s' nicht möglich: %s\n" -#: g10/exec.c:518 #, c-format msgid "system error while calling external program: %s\n" msgstr "Fehler beim Aufruf eines externen Programms: %s\n" -#: g10/exec.c:529 g10/exec.c:596 msgid "unnatural exit of external program\n" msgstr "ungewöhnliches Ende eines externen Programms\n" -#: g10/exec.c:544 msgid "unable to execute external program\n" msgstr "Externes Programm konnte nicht aufgerufen werden\n" -#: g10/exec.c:561 #, c-format msgid "unable to read external program response: %s\n" msgstr "Die Ausgabe des externen Programms konnte nicht gelesen werden: %s\n" -#: g10/exec.c:607 g10/exec.c:614 #, c-format msgid "WARNING: unable to remove tempfile (%s) `%s': %s\n" msgstr "" "WARNUNG: die temporäre Datei (%s) `%s' konnte nicht entfernt werden: %s\n" -#: g10/exec.c:619 #, c-format msgid "WARNING: unable to remove temp directory `%s': %s\n" msgstr "WARNUNG: Temporäres Verzeichnis `%s' kann nicht entfernt werden: %s\n" -#: g10/export.c:63 msgid "export signatures that are marked as local-only" msgstr "Exportiere auch Signaturen die als nicht exportfähig markiert sind" -#: g10/export.c:65 msgid "export attribute user IDs (generally photo IDs)" msgstr "Exportiere Attribute von User-IDs (i.A. Foto-IDs)" -#: g10/export.c:67 msgid "export revocation keys marked as \"sensitive\"" msgstr "Exportiere Widerrufsschlüssel die als \"sensitiv\" markiert sind" -#: g10/export.c:69 msgid "remove unusable parts from key during export" msgstr "Unbrauchbare Teile des Schlüssel während des Exports entfernen" -#: g10/export.c:71 msgid "remove as much as possible from key during export" msgstr "Während des Exports soviel wie möglich vom Schlüssel entfernen" -#: g10/export.c:73 msgid "export keys in an S-expression based format" msgstr "Exportiere Schlüssel in einem auf S-Ausdrücken basierenden Format" -#: g10/export.c:706 msgid "exporting secret keys not allowed\n" msgstr "Exportieren geheimer Schlüssel ist nicht erlaubt\n" -#: g10/export.c:779 #, c-format msgid "key %s: PGP 2.x style key - skipped\n" msgstr "Schlüssel %s: PGP 2.x-artiger Schlüssel - übersprungen\n" -#: g10/export.c:963 #, c-format msgid "key %s: key material on-card - skipped\n" msgstr "Schlüssel %s: Schlüsselmaterial ist auf einer Karte - übersprungen\n" -#: g10/export.c:1062 msgid " - skipped" msgstr " - übersprungen" -#: g10/export.c:1133 msgid "WARNING: nothing exported\n" msgstr "WARNUNG: Nichts exportiert\n" -#: g10/getkey.c:161 msgid "too many entries in pk cache - disabled\n" msgstr "zu viele Einträge im pk-Cache - abgeschaltet\n" -#: g10/getkey.c:184 msgid "[User ID not found]" msgstr "[User-ID nicht gefunden]" -#: g10/getkey.c:872 #, c-format msgid "automatically retrieved `%s' via %s\n" msgstr "`%s' automatisch via %s geholt\n" -#: g10/getkey.c:877 #, c-format msgid "error retrieving `%s' via %s: %s\n" msgstr "Fehler beim automatischen holen von `%s' über `%s': %s\n" -#: g10/getkey.c:879 msgid "No fingerprint" msgstr "Kein Fingerabdruck vorhanden" -#: g10/getkey.c:1672 #, c-format msgid "Invalid key %s made valid by --allow-non-selfsigned-uid\n" msgstr "" "Ungültiger Schlüssel %s, gültig gemacht per --allow-non-selfsigned-uid\n" -#: g10/getkey.c:2429 #, c-format msgid "using subkey %s instead of primary key %s\n" msgstr "der Unterschlüssel %s wird anstelle des Hauptschlüssels %s verwendet\n" -#: g10/getkey.c:3023 #, c-format msgid "no secret subkey for public subkey %s - ignoring\n" msgstr "" "Kein privater Unterschlüssel zum öffentlichen Unterschlüssel %s - ignoriert\n" -#: g10/gpg.c:379 sm/gpgsm.c:189 msgid "make a signature" msgstr "Eine Signatur erzeugen" -#: g10/gpg.c:380 sm/gpgsm.c:190 msgid "make a clear text signature" msgstr "Eine Klartextsignatur erzeugen" -#: g10/gpg.c:381 sm/gpgsm.c:191 msgid "make a detached signature" msgstr "Eine abgetrennte Signatur erzeugen" -#: g10/gpg.c:382 sm/gpgsm.c:192 msgid "encrypt data" msgstr "Daten verschlüsseln" -#: g10/gpg.c:384 sm/gpgsm.c:193 msgid "encryption only with symmetric cipher" msgstr "Daten symmetrisch verschlüsseln" -#: g10/gpg.c:386 sm/gpgsm.c:194 msgid "decrypt data (default)" msgstr "Daten entschlüsseln (Voreinstellung)" -#: g10/gpg.c:388 sm/gpgsm.c:195 msgid "verify a signature" msgstr "Signatur prüfen" -#: g10/gpg.c:390 sm/gpgsm.c:196 msgid "list keys" msgstr "Liste der Schlüssel" -#: g10/gpg.c:392 msgid "list keys and signatures" msgstr "Liste der Schlüssel und ihrer Signaturen" -#: g10/gpg.c:393 msgid "list and check key signatures" msgstr "Signaturen der Schlüssel auflisten und prüfen" -#: g10/gpg.c:394 sm/gpgsm.c:201 msgid "list keys and fingerprints" msgstr "Liste der Schlüssel und ihrer \"Fingerabdrücke\"" -#: g10/gpg.c:395 sm/gpgsm.c:199 msgid "list secret keys" msgstr "Liste der geheimen Schlüssel" -#: g10/gpg.c:396 sm/gpgsm.c:202 msgid "generate a new key pair" msgstr "Ein neues Schlüsselpaar erzeugen" -#: g10/gpg.c:397 msgid "generate a revocation certificate" msgstr "Ein Schlüsselwiderruf-Zertifikat erzeugen" -#: g10/gpg.c:399 sm/gpgsm.c:204 msgid "remove keys from the public keyring" msgstr "Schlüssel aus dem öff. Schlüsselbund entfernen" -#: g10/gpg.c:401 msgid "remove keys from the secret keyring" msgstr "Schlüssel aus dem geh. Schlüsselbund entfernen" -#: g10/gpg.c:402 msgid "sign a key" msgstr "Schlüssel signieren" -#: g10/gpg.c:403 msgid "sign a key locally" msgstr "Schlüssel nur für diesen Rechner signieren" -#: g10/gpg.c:404 msgid "sign or edit a key" msgstr "Signieren oder bearbeiten eines Schlüssels" -#: g10/gpg.c:406 sm/gpgsm.c:216 msgid "change a passphrase" msgstr "Die Passphrase ändern" -#: g10/gpg.c:408 msgid "export keys" msgstr "Schlüssel exportieren" -#: g10/gpg.c:409 sm/gpgsm.c:205 msgid "export keys to a key server" msgstr "Schlüssel zu einem Schlü.server exportieren" -#: g10/gpg.c:410 sm/gpgsm.c:206 msgid "import keys from a key server" msgstr "Schlüssel von einem Schlü.server importieren" -#: g10/gpg.c:412 msgid "search for keys on a key server" msgstr "Schlüssel auf einem Schlü.server suchen" -#: g10/gpg.c:414 msgid "update all keys from a keyserver" msgstr "alle Schlüssel per Schlü.server aktualisieren" -#: g10/gpg.c:419 msgid "import/merge keys" msgstr "Schlüssel importieren/kombinieren" -#: g10/gpg.c:422 msgid "print the card status" msgstr "den Karten-Status ausgeben" -#: g10/gpg.c:423 msgid "change data on a card" msgstr "Daten auf einer Karte ändern" -#: g10/gpg.c:424 msgid "change a card's PIN" msgstr "PIN einer Karte ändern" -#: g10/gpg.c:433 msgid "update the trust database" msgstr "Ändern der \"Trust\"-Datenbank" -#: g10/gpg.c:440 msgid "print message digests" msgstr "Hashwerte für die Dateien ausgeben" -#: g10/gpg.c:443 sm/gpgsm.c:211 msgid "run in server mode" msgstr "Im Server Modus ausführen" -#: g10/gpg.c:447 sm/gpgsm.c:229 msgid "create ascii armored output" msgstr "Ausgabe mit ASCII-Hülle versehen" -#: g10/gpg.c:450 sm/gpgsm.c:242 msgid "|USER-ID|encrypt for USER-ID" msgstr "|USER-ID|Verschlüsseln für USER-ID" -#: g10/gpg.c:463 sm/gpgsm.c:278 msgid "|USER-ID|use USER-ID to sign or decrypt" msgstr "|USER-ID|Mit USER-ID signieren bzw. entschlüsseln" -#: g10/gpg.c:468 msgid "|N|set compress level to N (0 disables)" msgstr "|N|Kompressionsstufe auf N setzen (0=keine)" -#: g10/gpg.c:474 msgid "use canonical text mode" msgstr "Textmodus benutzen" -#: g10/gpg.c:491 sm/gpgsm.c:280 msgid "|FILE|write output to FILE" msgstr "|DATEI|Ausgabe auf DATEI schreiben" -#: g10/gpg.c:507 kbx/kbxutil.c:90 sm/gpgsm.c:292 tools/gpgconf.c:81 msgid "do not make any changes" msgstr "Keine wirklichen Änderungen durchführen" -#: g10/gpg.c:508 msgid "prompt before overwriting" msgstr "vor Überschreiben nachfragen" -#: g10/gpg.c:560 msgid "use strict OpenPGP behavior" msgstr "OpenPGP-Verhalten strikt beachten" -#: g10/gpg.c:590 sm/gpgsm.c:336 msgid "" "@\n" "(See the man page for a complete listing of all commands and options)\n" @@ -2278,7 +1768,6 @@ msgstr "" "(Auf der \"man\"-Seite ist eine vollständige Liste aller Befehle und " "Optionen)\n" -#: g10/gpg.c:593 sm/gpgsm.c:339 msgid "" "@\n" "Examples:\n" @@ -2298,11 +1787,9 @@ msgstr "" " --list-keys [Namen] Schlüssel anzeigen\n" " --fingerprint [Namen] \"Fingerabdrücke\" anzeigen\n" -#: g10/gpg.c:843 msgid "Usage: gpg [options] [files] (-h for help)" msgstr "Aufruf: gpg [Optionen] [Dateien] (-h für Hilfe)" -#: g10/gpg.c:846 msgid "" "Syntax: gpg [options] [files]\n" "sign, check, encrypt or decrypt\n" @@ -2312,7 +1799,6 @@ msgstr "" "Signieren, prüfen, verschlüsseln, entschlüsseln.\n" "Die voreingestellte Operation ist abhängig von den Eingabedaten\n" -#: g10/gpg.c:857 sm/gpgsm.c:553 msgid "" "\n" "Supported algorithms:\n" @@ -2320,73 +1806,58 @@ msgstr "" "\n" "Unterstützte Verfahren:\n" -#: g10/gpg.c:860 msgid "Pubkey: " msgstr "Öff. Schlüssel: " -#: g10/gpg.c:867 g10/keyedit.c:2325 msgid "Cipher: " msgstr "Verschlü.: " -#: g10/gpg.c:874 msgid "Hash: " msgstr "Hash: " -#: g10/gpg.c:881 g10/keyedit.c:2374 msgid "Compression: " msgstr "Komprimierung: " -#: g10/gpg.c:951 msgid "usage: gpg [options] " msgstr "Aufruf: gpg [Optionen] " -#: g10/gpg.c:1165 sm/gpgsm.c:726 msgid "conflicting commands\n" msgstr "Widersprüchliche Befehle\n" -#: g10/gpg.c:1183 #, c-format msgid "no = sign found in group definition `%s'\n" msgstr "Kein '='-Zeichen in der Gruppendefinition gefunden `%s'\n" -#: g10/gpg.c:1380 #, c-format msgid "WARNING: unsafe ownership on homedir `%s'\n" msgstr "WARNUNG: Unsicheres Besitzverhältnis des Home-Verzeichnis `%s'\n" -#: g10/gpg.c:1383 #, c-format msgid "WARNING: unsafe ownership on configuration file `%s'\n" msgstr "WARNUNG: Unsicheres Besitzverhältnis der Konfigurationsdatei `%s'\n" -#: g10/gpg.c:1386 #, c-format msgid "WARNING: unsafe ownership on extension `%s'\n" msgstr "WARNUNG: Unsicheres Besitzverhältnis auf die Erweiterung `%s'\n" -#: g10/gpg.c:1392 #, c-format msgid "WARNING: unsafe permissions on homedir `%s'\n" msgstr "WARNUNG: Unsichere Zugriffsrechte des Home-Verzeichnis `%s'\n" -#: g10/gpg.c:1395 #, c-format msgid "WARNING: unsafe permissions on configuration file `%s'\n" msgstr "WARNUNG: Unsichere Zugriffsrechte der Konfigurationsdatei `%s'\n" -#: g10/gpg.c:1398 #, c-format msgid "WARNING: unsafe permissions on extension `%s'\n" msgstr "WARNUNG: Unsichere Zugriffsrechte auf die Erweiterung `%s'\n" -#: g10/gpg.c:1404 #, c-format msgid "WARNING: unsafe enclosing directory ownership on homedir `%s'\n" msgstr "" "WARNUNG: Unsicheres Besitzverhältnis des umgebenden Verzeichnisses für Home-" "Verzeichnis `%s'\n" -#: g10/gpg.c:1407 #, c-format msgid "" "WARNING: unsafe enclosing directory ownership on configuration file `%s'\n" @@ -2394,20 +1865,17 @@ msgstr "" "WARNUNG: Unsicheres Besitzverhältnis des umgebenden Verzeichnisses der " "Konfigurationsdatei `%s'\n" -#: g10/gpg.c:1410 #, c-format msgid "WARNING: unsafe enclosing directory ownership on extension `%s'\n" msgstr "" "WARNUNG: Unsicheres Besitzverhältnis des umgebenden Verzeichnisses `%s'\n" -#: g10/gpg.c:1416 #, c-format msgid "WARNING: unsafe enclosing directory permissions on homedir `%s'\n" msgstr "" "WARNUNG: Unsichere Zugriffsrechte des umgebenden Verzeichnisses des Home-" "Verzeichnisses `%s'\n" -#: g10/gpg.c:1419 #, c-format msgid "" "WARNING: unsafe enclosing directory permissions on configuration file `%s'\n" @@ -2415,501 +1883,390 @@ msgstr "" "WARNUNG: Unsichere Zugriffsrechte des umgebenden Verzeichnisses der " "Konfigurationsdatei `%s'\n" -#: g10/gpg.c:1422 #, c-format msgid "WARNING: unsafe enclosing directory permissions on extension `%s'\n" msgstr "" "WARNUNG: Unsichere Zugriffsrechte des umgebenden Verzeichnisses auf " "Erweiterung `%s'\n" -#: g10/gpg.c:1605 #, c-format msgid "unknown configuration item `%s'\n" msgstr "Unbekanntes Konfigurationselement `%s'\n" -#: g10/gpg.c:1711 msgid "display photo IDs during key listings" msgstr "Anzeigen der Foto-ID in den Schlüssellisten" -#: g10/gpg.c:1713 msgid "show policy URLs during signature listings" msgstr "Zeige Richtlinien-URL während des listens der Signaturen" -#: g10/gpg.c:1715 msgid "show all notations during signature listings" msgstr "Alle Notationen mit den Signaturen anlisten" -#: g10/gpg.c:1717 msgid "show IETF standard notations during signature listings" msgstr "Zeige IETF-Standard" -#: g10/gpg.c:1721 msgid "show user-supplied notations during signature listings" msgstr "Zeige Benutzer-Notationen während des listens der Signaturen" -#: g10/gpg.c:1723 msgid "show preferred keyserver URLs during signature listings" msgstr "Der bevorzugten Schlüsselserver mit den Signaturen anlisten" -#: g10/gpg.c:1725 msgid "show user ID validity during key listings" msgstr "Zeige Gültigkeit der User-ID in den Schlüssellisten" -#: g10/gpg.c:1727 msgid "show revoked and expired user IDs in key listings" msgstr "Zeige widerrufene und verfallene User-ID in den Schlüssellisten" -#: g10/gpg.c:1729 msgid "show revoked and expired subkeys in key listings" msgstr "Zeige widerrufene und verfallene Unterschlüssel in den Schlüssellisten" -#: g10/gpg.c:1731 msgid "show the keyring name in key listings" msgstr "Anzeigen des Schlüsselbundes, in dem ein Schlüssel drin ist" -#: g10/gpg.c:1733 msgid "show expiration dates during signature listings" msgstr "Das Ablaufdatum mit den Signaturen anlisten" -#: g10/gpg.c:1867 #, c-format msgid "NOTE: old default options file `%s' ignored\n" msgstr "Hinweis: Alte voreingestellte Optionendatei '%s' wurde ignoriert\n" -#: g10/gpg.c:1958 #, c-format msgid "libgcrypt is too old (need %s, have %s)\n" msgstr "" "Die Bibliothek \"libgcrypt\" ist zu alt (benötigt wird %s, vorhanden ist %" "s)\n" -#: g10/gpg.c:2360 g10/gpg.c:3066 g10/gpg.c:3078 #, c-format msgid "NOTE: %s is not for normal use!\n" msgstr "Hinweis: %s ist nicht für den üblichen Gebrauch gedacht!\n" -#: g10/gpg.c:2549 g10/gpg.c:2561 #, c-format msgid "`%s' is not a valid signature expiration\n" msgstr "`%s' ist kein gültiges Signaturablaufdatum\n" -#: g10/gpg.c:2643 #, c-format msgid "`%s' is not a valid character set\n" msgstr "`%s' ist kein gültiger Zeichensatz\n" -#: g10/gpg.c:2666 g10/gpg.c:2861 g10/keyedit.c:3951 msgid "could not parse keyserver URL\n" msgstr "Schlüsselserver-URL konnte nicht analysiert werden\n" -#: g10/gpg.c:2678 #, c-format msgid "%s:%d: invalid keyserver options\n" msgstr "%s:%d: ungültige Schlüsselserver-Option\n" -#: g10/gpg.c:2681 msgid "invalid keyserver options\n" msgstr "Ungültige Schlüsselserver-Option\n" -#: g10/gpg.c:2688 #, c-format msgid "%s:%d: invalid import options\n" msgstr "%s:%d: ungültige Import-Option\n" -#: g10/gpg.c:2691 msgid "invalid import options\n" msgstr "Ungültige Import-Option\n" -#: g10/gpg.c:2698 #, c-format msgid "%s:%d: invalid export options\n" msgstr "%s:%d: ungültige Export-Option.\n" -#: g10/gpg.c:2701 msgid "invalid export options\n" msgstr "Ungültige Export-Option\n" -#: g10/gpg.c:2708 #, c-format msgid "%s:%d: invalid list options\n" msgstr "%s:%d: ungültige Listen-Option.\n" -#: g10/gpg.c:2711 msgid "invalid list options\n" msgstr "Ungültige Listen-Option\n" -#: g10/gpg.c:2719 msgid "display photo IDs during signature verification" msgstr "Foto-ID während der Signaturprüfung anzeigen" -#: g10/gpg.c:2721 msgid "show policy URLs during signature verification" msgstr "Richtlinien-URLs während der Signaturprüfung anzeigen" -#: g10/gpg.c:2723 msgid "show all notations during signature verification" msgstr "Alle Notationen während der Signaturprüfung anzeigen" -#: g10/gpg.c:2725 msgid "show IETF standard notations during signature verification" msgstr "Standard-Notationen während der Signaturprüfung anzeigen" -#: g10/gpg.c:2729 msgid "show user-supplied notations during signature verification" msgstr "Benutzer-Notationen während der Signaturprüfung anzeigen" -#: g10/gpg.c:2731 msgid "show preferred keyserver URLs during signature verification" msgstr "" "Die URL für den bevorzugten Schlüsselserver während der Signaturprüfung " "anzeigen" -#: g10/gpg.c:2733 msgid "show user ID validity during signature verification" msgstr "Die Gültigkeit der User-ID während der Signaturprüfung anzeigen" -#: g10/gpg.c:2735 msgid "show revoked and expired user IDs in signature verification" msgstr "Zeige widerrufene und verfallene User-IDs während der Signaturprüfung" -#: g10/gpg.c:2737 msgid "show only the primary user ID in signature verification" msgstr "Zeige nur die Haupt-User-ID während der Signaturprüfung" -#: g10/gpg.c:2739 msgid "validate signatures with PKA data" msgstr "Prüfe Signaturgültigkeit mittels PKA-Daten" -#: g10/gpg.c:2741 msgid "elevate the trust of signatures with valid PKA data" msgstr "Werte das Vertrauen zu Signaturen durch gültige PKA-Daten auf" -#: g10/gpg.c:2748 #, c-format msgid "%s:%d: invalid verify options\n" msgstr "%s:%d: ungültige Überprüfungs-Option.\n" -#: g10/gpg.c:2751 msgid "invalid verify options\n" msgstr "Ungültige Überprüfungs-Option\n" -#: g10/gpg.c:2758 #, c-format msgid "unable to set exec-path to %s\n" msgstr "Der Ausführungspfad konnte nicht auf %s gesetzt werden.\n" -#: g10/gpg.c:2944 #, c-format msgid "%s:%d: invalid auto-key-locate list\n" msgstr "%s:%d: ungültige \"auto-key-locate\"-Liste\n" -#: g10/gpg.c:2947 msgid "invalid auto-key-locate list\n" msgstr "ungültige \"auto-key-locate\"-Liste\n" -#: g10/gpg.c:3055 sm/gpgsm.c:1452 msgid "WARNING: program may create a core file!\n" msgstr "WARNUNG: Programm könnte eine core-dump-Datei schreiben!\n" -#: g10/gpg.c:3059 #, c-format msgid "WARNING: %s overrides %s\n" msgstr "WARNUNG: %s ersetzt %s\n" -#: g10/gpg.c:3068 #, c-format msgid "%s not allowed with %s!\n" msgstr "%s kann nicht zusammen mit %s verwendet werden!\n" -#: g10/gpg.c:3071 #, c-format msgid "%s makes no sense with %s!\n" msgstr "%s zusammen mit %s ist nicht sinnvoll!\n" -#: g10/gpg.c:3086 sm/gpgsm.c:1469 dirmngr/dirmngr.c:873 msgid "WARNING: running with faked system time: " msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: " -#: g10/gpg.c:3097 #, c-format msgid "will not run with insecure memory due to %s\n" msgstr "Startet nicht mit unsicherem Speicher, wegen Option %s\n" -#: g10/gpg.c:3111 msgid "you can only make detached or clear signatures while in --pgp2 mode\n" msgstr "" "Im --pgp2-Modus können Sie nur abgetrennte oder Klartextsignaturen machen\n" -#: g10/gpg.c:3117 msgid "you can't sign and encrypt at the same time while in --pgp2 mode\n" msgstr "" "Im --pgp2-Modus können Sie nicht gleichzeitig signieren und verschlüsseln\n" -#: g10/gpg.c:3123 msgid "you must use files (and not a pipe) when working with --pgp2 enabled.\n" msgstr "" "Im --pgp2-Modus müssen Sie Dateien benutzen und können keine Pipes " "verwenden.\n" -#: g10/gpg.c:3136 msgid "encrypting a message in --pgp2 mode requires the IDEA cipher\n" msgstr "" "Verschlüsseln einer Botschaft benötigt im --pgp2-Modus die IDEA-" "Verschlüsselung\n" -#: g10/gpg.c:3203 g10/gpg.c:3227 sm/gpgsm.c:1524 msgid "selected cipher algorithm is invalid\n" msgstr "Das ausgewählte Verschlüsselungsverfahren ist ungültig\n" -#: g10/gpg.c:3209 g10/gpg.c:3233 sm/gpgsm.c:1530 sm/gpgsm.c:1536 msgid "selected digest algorithm is invalid\n" msgstr "Das ausgewählte Hashverfahren ist ungültig\n" -#: g10/gpg.c:3215 msgid "selected compression algorithm is invalid\n" msgstr "Das ausgewählte Komprimierungsverfahren ist ungültig\n" -#: g10/gpg.c:3221 msgid "selected certification digest algorithm is invalid\n" msgstr "Das ausgewählte Hashverfahren ist ungültig\n" -#: g10/gpg.c:3236 msgid "completes-needed must be greater than 0\n" msgstr "completes-needed müssen größer als 0 sein\n" -#: g10/gpg.c:3238 msgid "marginals-needed must be greater than 1\n" msgstr "marginals-needed müssen größer als 1 sein\n" -#: g10/gpg.c:3240 msgid "max-cert-depth must be in the range from 1 to 255\n" msgstr "max-cert-depth muß im Bereich 1 bis 255 liegen\n" -#: g10/gpg.c:3242 msgid "invalid default-cert-level; must be 0, 1, 2, or 3\n" msgstr "ungültiger \"default-cert-level\"; Wert muß 0, 1, 2 oder 3 sein\n" -#: g10/gpg.c:3244 msgid "invalid min-cert-level; must be 1, 2, or 3\n" msgstr "ungültiger \"min-cert-level\"; Wert muß 0, 1, 2 oder 3 sein\n" -#: g10/gpg.c:3247 msgid "NOTE: simple S2K mode (0) is strongly discouraged\n" msgstr "Hinweis: Vom \"simple S2K\"-Modus (0) ist strikt abzuraten\n" -#: g10/gpg.c:3251 msgid "invalid S2K mode; must be 0, 1 or 3\n" msgstr "ungültiger \"simple S2K\"-Modus; Wert muß 0, 1 oder 3 sein\n" -#: g10/gpg.c:3258 msgid "invalid default preferences\n" msgstr "ungültige Standard-Voreinstellungen\n" -#: g10/gpg.c:3262 msgid "invalid personal cipher preferences\n" msgstr "ungültige private Verschlüsselungsvoreinstellungen\n" -#: g10/gpg.c:3266 msgid "invalid personal digest preferences\n" msgstr "ungültige private Hashvoreinstellungen\n" -#: g10/gpg.c:3270 msgid "invalid personal compress preferences\n" msgstr "ungültige private Komprimierungsvoreinstellungen\n" -#: g10/gpg.c:3303 #, c-format msgid "%s does not yet work with %s\n" msgstr "%s arbeitet noch nicht mit %s zusammen\n" -#: g10/gpg.c:3350 #, c-format msgid "you may not use cipher algorithm `%s' while in %s mode\n" msgstr "" "Die Benutzung des Verschlüsselungsverfahren %s ist im %s-Modus nicht " "erlaubt.\n" -#: g10/gpg.c:3355 #, c-format msgid "you may not use digest algorithm `%s' while in %s mode\n" msgstr "Die Benutzung der Hashmethode %s ist im %s-Modus nicht erlaubt.\n" -#: g10/gpg.c:3360 #, c-format msgid "you may not use compression algorithm `%s' while in %s mode\n" msgstr "" "Die Benutzung des Komprimierverfahren %s ist im %s-Modus nicht erlaubt.\n" -#: g10/gpg.c:3439 #, c-format msgid "failed to initialize the TrustDB: %s\n" msgstr "Die Trust-DB kann nicht initialisiert werden: %s\n" -#: g10/gpg.c:3450 msgid "WARNING: recipients (-r) given without using public key encryption\n" msgstr "" "WARNUNG: Empfänger (-r) angegeben ohne Verwendung von Public-Key-Verfahren\n" -#: g10/gpg.c:3465 msgid "--store [filename]" msgstr "--store [Dateiname]" -#: g10/gpg.c:3472 msgid "--symmetric [filename]" msgstr "--symmetric [Dateiname]" -#: g10/gpg.c:3474 #, c-format msgid "symmetric encryption of `%s' failed: %s\n" msgstr "Symmetrische Entschlüsselung von `%s' fehlgeschlagen: %s\n" -#: g10/gpg.c:3484 msgid "--encrypt [filename]" msgstr "--encrypt [Dateiname]" -#: g10/gpg.c:3497 msgid "--symmetric --encrypt [filename]" msgstr "--symmetric --encrypt [Dateiname]" -#: g10/gpg.c:3499 msgid "you cannot use --symmetric --encrypt with --s2k-mode 0\n" msgstr "" "--symmetric --encrypt kann nicht zusammen mit --s2k-mode 0 verwendet werden\n" -#: g10/gpg.c:3502 #, c-format msgid "you cannot use --symmetric --encrypt while in %s mode\n" msgstr "Im %s-Modus kann --symmetric --encrypt nicht verwendet werden.\n" -#: g10/gpg.c:3520 msgid "--sign [filename]" msgstr "--sign [Dateiname]" -#: g10/gpg.c:3533 msgid "--sign --encrypt [filename]" msgstr "--sign --encrypt [Dateiname]" -#: g10/gpg.c:3548 msgid "--symmetric --sign --encrypt [filename]" msgstr "--symmetric --sign --encrypt [Dateiname]" -#: g10/gpg.c:3550 msgid "you cannot use --symmetric --sign --encrypt with --s2k-mode 0\n" msgstr "" "--symmetric --sign --encrypt kann nicht zusammen mit --s2k-mode 0 verwendet " "werden\n" -#: g10/gpg.c:3553 #, c-format msgid "you cannot use --symmetric --sign --encrypt while in %s mode\n" msgstr "" "Im %s-Modus kann --symmetric --sign --encrypt nicht verwendet werden.\n" -#: g10/gpg.c:3574 msgid "--sign --symmetric [filename]" msgstr "--sign --symmetric [Dateiname]" -#: g10/gpg.c:3583 msgid "--clearsign [filename]" msgstr "--clearsign [Dateiname]" -#: g10/gpg.c:3608 msgid "--decrypt [filename]" msgstr "--decrypt [Dateiname]" -#: g10/gpg.c:3616 msgid "--sign-key user-id" msgstr "--sign-key User-ID" -#: g10/gpg.c:3620 msgid "--lsign-key user-id" msgstr "--lsign-key User-ID" -#: g10/gpg.c:3641 msgid "--edit-key user-id [commands]" msgstr "--edit-key User-ID [Befehle]" -#: g10/gpg.c:3657 msgid "--passwd " msgstr "--passwd User-ID" -#: g10/gpg.c:3744 g10/keyserver.c:1634 #, c-format msgid "keyserver send failed: %s\n" msgstr "Senden an Schlüsselserver fehlgeschlagen: %s\n" -#: g10/gpg.c:3746 #, c-format msgid "keyserver receive failed: %s\n" msgstr "Empfangen vom Schlüsselserver fehlgeschlagen: %s\n" -#: g10/gpg.c:3748 #, c-format msgid "key export failed: %s\n" msgstr "Schlüsselexport fehlgeschlagen: %s\n" -#: g10/gpg.c:3759 #, c-format msgid "keyserver search failed: %s\n" msgstr "Suche auf dem Schlüsselserver fehlgeschlagen: %s\n" -#: g10/gpg.c:3769 #, c-format msgid "keyserver refresh failed: %s\n" msgstr "Refresh vom Schlüsselserver fehlgeschlagen: %s\n" -#: g10/gpg.c:3820 #, c-format msgid "dearmoring failed: %s\n" msgstr "Entfernen der ASCII-Hülle ist fehlgeschlagen: %s\n" -#: g10/gpg.c:3828 #, c-format msgid "enarmoring failed: %s\n" msgstr "Anbringen der ASCII-Hülle ist fehlgeschlagen: %s\n" -#: g10/gpg.c:3919 #, c-format msgid "invalid hash algorithm `%s'\n" msgstr "Ungültiges Hashverfahren '%s'\n" -#: g10/gpg.c:4034 msgid "[filename]" msgstr "[Dateiname]" -#: g10/gpg.c:4040 msgid "Go ahead and type your message ...\n" msgstr "Auf geht's - Botschaft eintippen ...\n" -#: g10/gpg.c:4357 msgid "the given certification policy URL is invalid\n" msgstr "Die angegebene Zertifikat-Richtlinien-URL ist ungültig\n" -#: g10/gpg.c:4359 msgid "the given signature policy URL is invalid\n" msgstr "Die angegebene Signatur-Richtlinien-URL ist ungültig\n" -#: g10/gpg.c:4392 msgid "the given preferred keyserver URL is invalid\n" msgstr "Die angegebene URL des bevorzugten Schlüsselserver ist ungültig\n" -#: g10/gpgv.c:74 msgid "|FILE|take the keys from the keyring FILE" msgstr "|DATEI|Schlüssel aus der Schlüsselbund DATEI nehmen" -#: g10/gpgv.c:76 msgid "make timestamp conflicts only a warning" msgstr "differierende Zeitangaben sind kein Fehler" -#: g10/gpgv.c:78 sm/gpgsm.c:326 msgid "|FD|write status info to this FD" msgstr "|FD|Statusinfo auf FD (Dateihandle) ausgeben" -#: g10/gpgv.c:117 msgid "Usage: gpgv [options] [files] (-h for help)" msgstr "Aufruf: gpgv [Optionen] [Dateien] (-h für Hilfe)" -#: g10/gpgv.c:119 msgid "" "Syntax: gpgv [options] [files]\n" "Check signatures against known trusted keys\n" @@ -2917,125 +2274,99 @@ msgstr "" "Aufruf: gpgv [Optionen] [Dateien] (-h Hilfe)\n" "Prüfe Signaturen gegen eine Liste bekannter Schlüssel\n" -#: g10/helptext.c:72 msgid "No help available" msgstr "Keine Hilfe vorhanden." -#: g10/helptext.c:82 #, c-format msgid "No help available for `%s'" msgstr "Keine Hilfe für '%s' vorhanden." -#: g10/import.c:98 msgid "import signatures that are marked as local-only" msgstr "Importiere Signaturen, die als nicht exportfähig markiert sind" -#: g10/import.c:100 msgid "repair damage from the pks keyserver during import" msgstr "Beseitige Beschädigung durch den Schlüsselserver während des Imports" -#: g10/import.c:102 msgid "do not update the trustdb after import" msgstr "ändern Sie die \"Trust\"-Datenbank nach dem Import nicht" -#: g10/import.c:104 msgid "only accept updates to existing keys" msgstr "Nur Änderungen bereits existierender Schlüssel vornehmen" -#: g10/import.c:106 msgid "remove unusable parts from key after import" msgstr "entferne nach dem Import unbrauchbare Teile des Schlüssels" -#: g10/import.c:108 msgid "remove as much as possible from key after import" msgstr "nach dem Import soviel wie möglich aus dem Schlüssel entfernen" -#: g10/import.c:303 #, c-format msgid "skipping block of type %d\n" msgstr "überspringe den Block vom Typ %d\n" -#: g10/import.c:312 #, c-format msgid "%lu keys processed so far\n" msgstr "%lu Schlüssel bislang bearbeitet\n" -#: g10/import.c:329 #, c-format msgid "Total number processed: %lu\n" msgstr "Anzahl insgesamt bearbeiteter Schlüssel: %lu\n" -#: g10/import.c:331 #, c-format msgid " skipped new keys: %lu\n" msgstr " ignorierte neue Schlüssel: %lu\n" -#: g10/import.c:334 #, c-format msgid " w/o user IDs: %lu\n" msgstr " ohne User-ID: %lu\n" -#: g10/import.c:336 sm/import.c:130 #, c-format msgid " imported: %lu" msgstr " importiert: %lu" -#: g10/import.c:342 sm/import.c:134 #, c-format msgid " unchanged: %lu\n" msgstr " unverändert: %lu\n" -#: g10/import.c:344 #, c-format msgid " new user IDs: %lu\n" msgstr " neue User-IDs: %lu\n" -#: g10/import.c:346 #, c-format msgid " new subkeys: %lu\n" msgstr " neue Unterschlüssel: %lu\n" -#: g10/import.c:348 #, c-format msgid " new signatures: %lu\n" msgstr " neue Signaturen: %lu\n" -#: g10/import.c:350 #, c-format msgid " new key revocations: %lu\n" msgstr " neue Schlüsselwiderrufe: %lu\n" -#: g10/import.c:352 sm/import.c:136 #, c-format msgid " secret keys read: %lu\n" msgstr " gelesene geheime Schlüssel: %lu\n" -#: g10/import.c:354 sm/import.c:138 #, c-format msgid " secret keys imported: %lu\n" msgstr " geheime Schlüssel importiert: %lu\n" -#: g10/import.c:356 sm/import.c:140 #, c-format msgid " secret keys unchanged: %lu\n" msgstr " unveränderte geh. Schl.: %lu\n" -#: g10/import.c:358 sm/import.c:142 #, c-format msgid " not imported: %lu\n" msgstr " nicht importiert: %lu\n" -#: g10/import.c:360 #, c-format msgid " signatures cleaned: %lu\n" msgstr " Signaturen bereinigt: %lu\n" -#: g10/import.c:362 #, c-format msgid " user IDs cleaned: %lu\n" msgstr " User-IDs bereinigt: %lu\n" -#: g10/import.c:640 #, c-format msgid "" "WARNING: key %s contains preferences for unavailable\n" @@ -3044,397 +2375,318 @@ msgstr "" "WARNUNG: Schlüssel %s hat Einstellungen zu nicht verfügbaren\n" "Verfahren für folgende User-ID:\n" -#: g10/import.c:681 #, c-format msgid " \"%s\": preference for cipher algorithm %s\n" msgstr " \"%s\": Einstellungen des Verschlüsselungsverfahren %s\n" -#: g10/import.c:696 #, c-format msgid " \"%s\": preference for digest algorithm %s\n" msgstr " \"%s\": Einstellungen der Hashmethode %s\n" -#: g10/import.c:708 #, c-format msgid " \"%s\": preference for compression algorithm %s\n" msgstr " \"%s\": Einstellungen der Komprimierungsverfahren %s\n" -#: g10/import.c:721 msgid "it is strongly suggested that you update your preferences and\n" msgstr "es ist extrem empfehlenswert Ihre Einstellungen zu ändern und\n" -#: g10/import.c:723 msgid "re-distribute this key to avoid potential algorithm mismatch problems\n" msgstr "" "diesen Schlüssel wieder zu verteilen, um mögliche Probleme durch unpassende " "Verfahrenskombinationen zu vermeiden\n" -#: g10/import.c:747 #, c-format msgid "you can update your preferences with: gpg --edit-key %s updpref save\n" msgstr "" "Sie können Ihren Einstellungen mittels \"gpg --edit-key %s updpref save\" " "ändern\n" -#: g10/import.c:801 g10/import.c:1429 #, c-format msgid "key %s: no user ID\n" msgstr "Schlüssel %s: Keine User-ID\n" -#: g10/import.c:830 #, c-format msgid "key %s: PKS subkey corruption repaired\n" msgstr "Schlüssel %s: PKS Unterschlüsseldefekt repariert\n" -#: g10/import.c:845 #, c-format msgid "key %s: accepted non self-signed user ID \"%s\"\n" msgstr "Schlüssel %s: Nicht eigenbeglaubigte User-ID `%s' übernommen\n" -#: g10/import.c:851 #, c-format msgid "key %s: no valid user IDs\n" msgstr "Schlüssel %s: Keine gültigen User-IDs\n" -#: g10/import.c:853 msgid "this may be caused by a missing self-signature\n" msgstr "dies könnte durch fehlende Eigenbeglaubigung verursacht worden sein\n" -#: g10/import.c:863 g10/import.c:1549 #, c-format msgid "key %s: public key not found: %s\n" msgstr "Schlüssel %s: Öffentlicher Schlüssel nicht gefunden: %s\n" -#: g10/import.c:869 #, c-format msgid "key %s: new key - skipped\n" msgstr "Schlüssel %s: neuer Schlüssel - übersprungen\n" -#: g10/import.c:878 #, c-format msgid "no writable keyring found: %s\n" msgstr "kein schreibbarer Schlüsselbund gefunden: %s\n" -#: g10/import.c:883 g10/openfile.c:202 g10/openfile.c:293 g10/sign.c:874 -#: g10/sign.c:1185 #, c-format msgid "writing to `%s'\n" msgstr "Schreiben nach '%s'\n" -#: g10/import.c:887 g10/import.c:987 g10/import.c:1610 #, c-format msgid "error writing keyring `%s': %s\n" msgstr "Fehler beim Schreiben des Schlüsselbundes `%s': %s\n" -#: g10/import.c:906 #, c-format msgid "key %s: public key \"%s\" imported\n" msgstr "Schlüssel %s: Öffentlicher Schlüssel \"%s\" importiert\n" -#: g10/import.c:930 #, c-format msgid "key %s: doesn't match our copy\n" msgstr "Schlüssel %s: Stimmt nicht mit unserer Kopie überein\n" -#: g10/import.c:947 g10/import.c:1567 #, c-format msgid "key %s: can't locate original keyblock: %s\n" msgstr "Schlüssel %s: der originale Schlüsselblock wurde nicht gefunden: %s\n" -#: g10/import.c:955 g10/import.c:1574 #, c-format msgid "key %s: can't read original keyblock: %s\n" msgstr "Schlüssel %s: Lesefehler im originalen Schlüsselblock: %s\n" -#: g10/import.c:997 #, c-format msgid "key %s: \"%s\" 1 new user ID\n" msgstr "Schlüssel %s: \"%s\" 1 neue User-ID\n" -#: g10/import.c:1000 #, c-format msgid "key %s: \"%s\" %d new user IDs\n" msgstr "Schlüssel %s: \"%s\" %d neue User-IDs\n" -#: g10/import.c:1003 #, c-format msgid "key %s: \"%s\" 1 new signature\n" msgstr "Schlüssel %s: \"%s\" 1 neue Signatur\n" -#: g10/import.c:1006 #, c-format msgid "key %s: \"%s\" %d new signatures\n" msgstr "Schlüssel %s: \"%s\" %d neue Signaturen\n" -#: g10/import.c:1009 #, c-format msgid "key %s: \"%s\" 1 new subkey\n" msgstr "Schlüssel %s: \"%s\" 1 neuer Unterschlüssel\n" -#: g10/import.c:1012 #, c-format msgid "key %s: \"%s\" %d new subkeys\n" msgstr "Schlüssel %s: \"%s\" %d neue Unterschlüssel\n" -#: g10/import.c:1015 #, c-format msgid "key %s: \"%s\" %d signature cleaned\n" msgstr "Schlüssel %s: \"%s\" %d Signaturen bereinigt\n" -#: g10/import.c:1018 #, c-format msgid "key %s: \"%s\" %d signatures cleaned\n" msgstr "Schlüssel %s: \"%s\" %d Signaturen bereinigt\n" -#: g10/import.c:1021 #, c-format msgid "key %s: \"%s\" %d user ID cleaned\n" msgstr "Schlüssel %s: \"%s\" %d User-ID bereinigt\n" -#: g10/import.c:1024 #, c-format msgid "key %s: \"%s\" %d user IDs cleaned\n" msgstr "Schlüssel %s: \"%s\" %d User-IDs bereinigt\n" -#: g10/import.c:1047 #, c-format msgid "key %s: \"%s\" not changed\n" msgstr "Schlüssel %s: \"%s\" nicht geändert\n" -#: g10/import.c:1301 g10/import.c:1494 #, c-format msgid "key %s: secret key imported\n" msgstr "Schlüssel %s: geheimer Schlüssel importiert\n" -#: g10/import.c:1308 #, c-format msgid "key %s: secret key already exists\n" msgstr "Schlüssel %s: geheimer Schlüssel bereits vorhanden\n" -#: g10/import.c:1315 #, c-format msgid "key %s: error sending to agent: %s\n" msgstr "Schlüssel %s: Fehler beim Senden zum gpg-agent: %s\n" -#: g10/import.c:1445 #, c-format msgid "key %s: secret key with invalid cipher %d - skipped\n" msgstr "" "Schlüssel %s: geheimer Schlüssel mit ungültiger Verschlüsselung %d - " "übersprungen\n" -#: g10/import.c:1456 msgid "importing secret keys not allowed\n" msgstr "Importieren geheimer Schlüssel ist nicht erlaubt\n" -#: g10/import.c:1507 #, c-format msgid "key %s: secret key part already available\n" msgstr "Schlüssel %s: Die geheimen Teile sind bereits vorhanden\n" -#: g10/import.c:1542 #, c-format msgid "key %s: no public key - can't apply revocation certificate\n" msgstr "" "Schlüssel %s: Kein öffentlicher Schlüssel - der Schlüsselwiderruf kann nicht " "angebracht werden\n" -#: g10/import.c:1585 #, c-format msgid "key %s: invalid revocation certificate: %s - rejected\n" msgstr "Schlüssel %s: Ungültiges Widerrufzertifikat: %s - zurückgewiesen\n" -#: g10/import.c:1617 #, c-format msgid "key %s: \"%s\" revocation certificate imported\n" msgstr "Schlüssel %s: \"%s\" Widerrufzertifikat importiert\n" -#: g10/import.c:1693 #, c-format msgid "key %s: no user ID for signature\n" msgstr "Schlüssel %s: Keine User-ID für Signatur\n" -#: g10/import.c:1710 #, c-format msgid "key %s: unsupported public key algorithm on user ID \"%s\"\n" msgstr "" "Schlüssel %s: Nicht unterstütztes Public-Key-Verfahren für User-ID \"%s\"\n" -#: g10/import.c:1712 #, c-format msgid "key %s: invalid self-signature on user ID \"%s\"\n" msgstr "Schlüssel %s: Ungültige Eigenbeglaubigung für User-ID \"%s\"\n" -#: g10/import.c:1729 g10/import.c:1755 g10/import.c:1806 #, c-format msgid "key %s: unsupported public key algorithm\n" msgstr "Schlüssel %s: Nicht unterstütztes Public-Key-Verfahren\n" -#: g10/import.c:1730 #, c-format msgid "key %s: invalid direct key signature\n" msgstr "Schlüssel %s: Ungültige \"direct-key\"-Signatur\n" -#: g10/import.c:1744 #, c-format msgid "key %s: no subkey for key binding\n" msgstr "Schlüssel %s: Kein Unterschlüssel für die Unterschlüsselanbindung\n" -#: g10/import.c:1757 #, c-format msgid "key %s: invalid subkey binding\n" msgstr "Schlüssel %s: Ungültige Unterschlüssel-Anbindung\n" -#: g10/import.c:1773 #, c-format msgid "key %s: removed multiple subkey binding\n" msgstr "Schlüssel %s: Mehrfache Unterschlüssel-Anbindung entfernt\n" -#: g10/import.c:1795 #, c-format msgid "key %s: no subkey for key revocation\n" msgstr "Schlüssel %s: Kein Unterschlüssel für Schlüsselwiderruf\n" -#: g10/import.c:1808 #, c-format msgid "key %s: invalid subkey revocation\n" msgstr "Schlüssel %s: Ungültiger Unterschlüsselwiderruf\n" -#: g10/import.c:1823 #, c-format msgid "key %s: removed multiple subkey revocation\n" msgstr "Schlüssel %s: Mehrfacher Unterschlüsselwiderruf entfernt\n" -#: g10/import.c:1865 #, c-format msgid "key %s: skipped user ID \"%s\"\n" msgstr "Schlüssel %s: User-ID übersprungen \"%s\"\n" -#: g10/import.c:1886 #, c-format msgid "key %s: skipped subkey\n" msgstr "Schlüssel %s: Unterschlüssel übersprungen\n" -#: g10/import.c:1913 #, c-format msgid "key %s: non exportable signature (class 0x%02X) - skipped\n" msgstr "" "Schlüssel %s: Nicht exportfähige Signatur (Klasse %02x) - übersprungen\n" -#: g10/import.c:1923 #, c-format msgid "key %s: revocation certificate at wrong place - skipped\n" msgstr "Schlüssel %s: Widerrufzertifikat an falschem Platz - übersprungen\n" -#: g10/import.c:1940 #, c-format msgid "key %s: invalid revocation certificate: %s - skipped\n" msgstr "Schlüssel %s: Ungültiges Widerrufzertifikat: %s - übersprungen\n" -#: g10/import.c:1954 #, c-format msgid "key %s: subkey signature in wrong place - skipped\n" msgstr "" "Schlüssel %s: Unterschlüssel-Widerrufzertifikat an falschem Platz - " "übersprungen\n" -#: g10/import.c:1962 #, c-format msgid "key %s: unexpected signature class (0x%02X) - skipped\n" msgstr "Schlüssel %s: unerwartete Signaturklasse (0x%02x) - übersprungen\n" -#: g10/import.c:2091 #, c-format msgid "key %s: duplicated user ID detected - merged\n" msgstr "Schlüssel %s: Doppelte User-ID entdeckt - zusammengeführt\n" -#: g10/import.c:2153 #, c-format msgid "WARNING: key %s may be revoked: fetching revocation key %s\n" msgstr "WARNUNG: Schlüssel %s ist u.U. widerrufen: hole Widerrufschlüssel %s\n" -#: g10/import.c:2168 #, c-format msgid "WARNING: key %s may be revoked: revocation key %s not present.\n" msgstr "" "WARNUNG: Schlüssel %s ist u.U. widerrufen: Widerrufschlüssel %s ist nicht " "vorhanden\n" -#: g10/import.c:2227 #, c-format msgid "key %s: \"%s\" revocation certificate added\n" msgstr "Schlüssel %s: \"%s\" Widerrufzertifikat hinzugefügt\n" -#: g10/import.c:2261 #, c-format msgid "key %s: direct key signature added\n" msgstr "Schlüssel %s: \"direct-key\"-Signaturen hinzugefügt\n" -#: g10/keydb.c:181 #, c-format msgid "error creating keyring `%s': %s\n" msgstr "Fehler beim Erzeugen des Schlüsselbundes `%s': %s\n" -#: g10/keydb.c:187 #, c-format msgid "keyring `%s' created\n" msgstr "Schlüsselbund `%s' erstellt\n" -#: g10/keydb.c:326 #, c-format msgid "keyblock resource `%s': %s\n" msgstr "Schlüsselblockhilfsmittel`%s': %s\n" -#: g10/keydb.c:700 #, c-format msgid "failed to rebuild keyring cache: %s\n" msgstr "Schlüsselbund-Cache konnte nicht neu erzeugt werden: %s\n" -#: g10/keyedit.c:247 msgid "[revocation]" msgstr "[Widerruf]" -#: g10/keyedit.c:247 msgid "[self-signature]" msgstr "[Eigenbeglaubigung]" -#: g10/keyedit.c:335 g10/keylist.c:402 msgid "1 bad signature\n" msgstr "1 falsche Beglaubigung\n" -#: g10/keyedit.c:337 g10/keylist.c:404 #, c-format msgid "%d bad signatures\n" msgstr "%d falsche Beglaubigungen\n" -#: g10/keyedit.c:339 g10/keylist.c:406 msgid "1 signature not checked due to a missing key\n" msgstr "1 Beglaubigung wegen fehlendem Schlüssel nicht geprüft\n" -#: g10/keyedit.c:341 g10/keylist.c:408 #, c-format msgid "%d signatures not checked due to missing keys\n" msgstr "%d Beglaubigungen wegen fehlenden Schlüsseln nicht geprüft\n" -#: g10/keyedit.c:343 g10/keylist.c:411 msgid "1 signature not checked due to an error\n" msgstr "1 Beglaubigung aufgrund von Fehler nicht geprüft\n" -#: g10/keyedit.c:345 g10/keylist.c:413 #, c-format msgid "%d signatures not checked due to errors\n" msgstr "%d Beglaubigungen aufgrund von Fehlern nicht geprüft\n" -#: g10/keyedit.c:347 msgid "1 user ID without valid self-signature detected\n" msgstr "Eine User-ID ohne gültige Eigenbeglaubigung entdeckt\n" -#: g10/keyedit.c:349 #, c-format msgid "%d user IDs without valid self-signatures detected\n" msgstr "%d User-IDs ohne gültige Eigenbeglaubigung entdeckt\n" -#: g10/keyedit.c:409 g10/pkclist.c:273 msgid "" "Please decide how far you trust this user to correctly verify other users' " "keys\n" @@ -3447,17 +2699,14 @@ msgstr "" "unterschiedlichen Quellen ...)?\n" "\n" -#: g10/keyedit.c:413 g10/pkclist.c:285 #, c-format msgid " %d = I trust marginally\n" msgstr " %d = Ich vertraue ihm marginal\n" -#: g10/keyedit.c:414 g10/pkclist.c:287 #, c-format msgid " %d = I trust fully\n" msgstr " %d = Ich vertraue ihm vollständig\n" -#: g10/keyedit.c:432 msgid "" "Please enter the depth of this trust signature.\n" "A depth greater than 1 allows the key you are signing to make\n" @@ -3467,47 +2716,36 @@ msgstr "" "Eine Tiefe größer 1 erlaubt dem zu signierenden Schlüssel\n" "Trust-Signatures für Sie zu machen.\n" -#: g10/keyedit.c:448 msgid "Please enter a domain to restrict this signature, or enter for none.\n" msgstr "" "Geben Sie bitte eine Domain ein, um die Signatur einzuschränken\n" "oder nur die Eingabetaste für keine Domain\n" -#: g10/keyedit.c:594 #, c-format msgid "User ID \"%s\" is revoked." msgstr "User-ID \"%s\" ist widerrufen." -#: g10/keyedit.c:603 g10/keyedit.c:631 g10/keyedit.c:658 g10/keyedit.c:831 -#: g10/keyedit.c:896 g10/keyedit.c:1691 msgid "Are you sure you still want to sign it? (y/N) " msgstr "Wollen Sie ihn immer noch beglaubigen? (j/N) " -#: g10/keyedit.c:617 g10/keyedit.c:645 g10/keyedit.c:672 g10/keyedit.c:837 -#: g10/keyedit.c:1696 msgid " Unable to sign.\n" msgstr " Beglaubigen ist nicht möglich.\n" -#: g10/keyedit.c:622 #, c-format msgid "User ID \"%s\" is expired." msgstr "User-ID \"%s\" ist abgelaufen." -#: g10/keyedit.c:650 #, c-format msgid "User ID \"%s\" is not self-signed." msgstr "User-ID \"%s\" ist nicht eigenbeglaubigt." -#: g10/keyedit.c:678 #, c-format msgid "User ID \"%s\" is signable. " msgstr "User-ID \"%s\" ist signierbar." -#: g10/keyedit.c:680 msgid "Sign it? (y/N) " msgstr "Wirklich signieren? (j/N) " -#: g10/keyedit.c:705 #, c-format msgid "" "The self-signature on \"%s\"\n" @@ -3516,11 +2754,9 @@ msgstr "" "Die Eigenbeglaubigung von \"%s\"\n" "ist eine PGP 2.x artige Signatur.\n" -#: g10/keyedit.c:714 msgid "Do you want to promote it to an OpenPGP self-signature? (y/N) " msgstr "Soll sie zu einer OpenPGP Eigenbeglaubigung geändert werden? (j/N) " -#: g10/keyedit.c:728 #, c-format msgid "" "Your current signature on \"%s\"\n" @@ -3529,13 +2765,11 @@ msgstr "" "Ihre derzeitige Beglaubigung von \"%s\"\n" "ist abgelaufen.\n" -#: g10/keyedit.c:733 msgid "Do you want to issue a new signature to replace the expired one? (y/N) " msgstr "" "Soll eine neue Beglaubigung als Ersatz für die abgelaufene erstellt werden? " "(J/n) " -#: g10/keyedit.c:754 #, c-format msgid "" "Your current signature on \"%s\"\n" @@ -3544,55 +2778,44 @@ msgstr "" "Die derzeitige Beglaubigung von \"%s\"\n" "ist nur für diesen Rechner gültig.\n" -#: g10/keyedit.c:759 msgid "Do you want to promote it to a full exportable signature? (y/N) " msgstr "" "Soll sie zu einer voll exportierbaren Beglaubigung erhoben werden? (j/N) " -#: g10/keyedit.c:779 #, c-format msgid "\"%s\" was already locally signed by key %s\n" msgstr "\"%s\" wurde bereits durch Schlüssel %s lokal beglaubigt\n" -#: g10/keyedit.c:782 #, c-format msgid "\"%s\" was already signed by key %s\n" msgstr "\"%s\" wurde bereits durch Schlüssel %s beglaubigt\n" -#: g10/keyedit.c:787 msgid "Do you want to sign it again anyway? (y/N) " msgstr "Wollen Sie ihn immer noch wieder beglaubigen? (j/N) " -#: g10/keyedit.c:809 #, c-format msgid "Nothing to sign with key %s\n" msgstr "Nichts zu beglaubigen für Schlüssel %s\n" -#: g10/keyedit.c:825 msgid "This key has expired!" msgstr "Dieser Schlüssel ist verfallen!" -#: g10/keyedit.c:843 #, c-format msgid "This key is due to expire on %s.\n" msgstr "Dieser Schlüssel wird %s verfallen.\n" -#: g10/keyedit.c:849 msgid "Do you want your signature to expire at the same time? (Y/n) " msgstr "Soll Ihre Beglaubigung zur selben Zeit verfallen? (J/n) " -#: g10/keyedit.c:889 msgid "" "You may not make an OpenPGP signature on a PGP 2.x key while in --pgp2 " "mode.\n" msgstr "" "Im --pgp2-Modus kann nur mit PGP-2.x-artigen Schlüsseln signiert werden\n" -#: g10/keyedit.c:891 msgid "This would make the key unusable in PGP 2.x.\n" msgstr "Dies würde den Schlüssel für PGP 2.x unbrauchbar machen\n" -#: g10/keyedit.c:916 msgid "" "How carefully have you verified the key you are about to sign actually " "belongs\n" @@ -3602,32 +2825,26 @@ msgstr "" "wollen, wirklich der o.g. Person gehört?\n" "Wenn Sie darauf keine Antwort wissen, geben Sie \"0\" ein.\n" -#: g10/keyedit.c:921 #, c-format msgid " (0) I will not answer.%s\n" msgstr " (0) Ich antworte nicht.%s\n" -#: g10/keyedit.c:923 #, c-format msgid " (1) I have not checked at all.%s\n" msgstr " (1) Ich habe es überhaupt nicht überprüft.%s\n" -#: g10/keyedit.c:925 #, c-format msgid " (2) I have done casual checking.%s\n" msgstr " (2) Ich habe es flüchtig überprüft.%s\n" -#: g10/keyedit.c:927 #, c-format msgid " (3) I have done very careful checking.%s\n" msgstr " (3) Ich habe es sehr sorgfältig überprüft.%s\n" # translated by wk -#: g10/keyedit.c:934 msgid "Your selection? (enter `?' for more information): " msgstr "Ihre Auswahl? ('?' für weitere Informationen): " -#: g10/keyedit.c:958 #, c-format msgid "" "Are you sure that you want to sign this key with your\n" @@ -3636,235 +2853,179 @@ msgstr "" "Sind Sie wirklich sicher, daß Sie vorstehenden Schlüssel mit Ihrem\n" "Schlüssel \"%s\" (%s) beglaubigen wollen\n" -#: g10/keyedit.c:965 msgid "This will be a self-signature.\n" msgstr "Dies wird eine Eigenbeglaubigung sein.\n" -#: g10/keyedit.c:970 msgid "WARNING: the signature will not be marked as non-exportable.\n" msgstr "" "WARNUNG: Die Signatur wird nicht als nicht-exportierbar markiert werden.\n" -#: g10/keyedit.c:977 msgid "WARNING: the signature will not be marked as non-revocable.\n" msgstr "WARNUNG: Die Signatur wird nicht als unwiderrufbar markiert werden.\n" -#: g10/keyedit.c:987 msgid "The signature will be marked as non-exportable.\n" msgstr "Die Signatur wird als nicht-exportfähig markiert werden.\n" -#: g10/keyedit.c:994 msgid "The signature will be marked as non-revocable.\n" msgstr "Die Signatur wird als unwiderrufbar markiert werden.\n" -#: g10/keyedit.c:1001 msgid "I have not checked this key at all.\n" msgstr "Ich habe diesen Schlüssel überhaupt nicht überprüft.\n" -#: g10/keyedit.c:1006 msgid "I have checked this key casually.\n" msgstr "Ich habe diesen Schlüssel flüchtig überprüft.\n" -#: g10/keyedit.c:1011 msgid "I have checked this key very carefully.\n" msgstr "Ich habe diesen Schlüssel sehr sorgfältig überprüft.\n" -#: g10/keyedit.c:1021 msgid "Really sign? (y/N) " msgstr "Wirklich signieren? (j/N) " -#: g10/keyedit.c:1071 g10/keyedit.c:4735 g10/keyedit.c:4826 g10/keyedit.c:4888 -#: g10/keyedit.c:4949 g10/sign.c:334 #, c-format msgid "signing failed: %s\n" msgstr "Beglaubigung fehlgeschlagen: %s\n" -#: g10/keyedit.c:1158 msgid "Key has only stub or on-card key items - no passphrase to change.\n" msgstr "" "Der Schlüssel enthält nur \"stub\"- oder \"on-card\"-Schlüsselelemente- " "keine Passphrase ist zu ändern.\n" -#: g10/keyedit.c:1187 #, c-format msgid "key %s: error changing passphrase: %s\n" msgstr "Schlüssel %s: Fehler beim Ändern der Passphrase: %s\n" -#: g10/keyedit.c:1234 msgid "moving a key signature to the correct place\n" msgstr "schiebe eine Beglaubigung an die richtige Stelle\n" -#: g10/keyedit.c:1324 msgid "save and quit" msgstr "speichern und Menü verlassen" -#: g10/keyedit.c:1327 msgid "show key fingerprint" msgstr "Fingerabdruck des Schlüssels anzeigen" -#: g10/keyedit.c:1328 msgid "list key and user IDs" msgstr "Schlüssel und User-IDs auflisten" -#: g10/keyedit.c:1330 msgid "select user ID N" msgstr "User-ID N auswählen" -#: g10/keyedit.c:1331 msgid "select subkey N" msgstr "Unterschlüssel N auswählen" -#: g10/keyedit.c:1332 msgid "check signatures" msgstr "Signaturen prüfen" -#: g10/keyedit.c:1337 msgid "sign selected user IDs [* see below for related commands]" msgstr "die ausgewählten User-IDs beglaubigen [* für verwandte Befehle s.u.]" -#: g10/keyedit.c:1342 msgid "sign selected user IDs locally" msgstr "Die ausgewählte User-ID nur für diesen Rechner beglaubigen" -#: g10/keyedit.c:1343 msgid "sign selected user IDs with a trust signature" msgstr "Die ausgewählte User-ID mit einer \"Trust\"-Signatur beglaubigen" -#: g10/keyedit.c:1345 msgid "sign selected user IDs with a non-revocable signature" msgstr "die ausgewählten User-IDs unwiderrufbar beglaubigen" -#: g10/keyedit.c:1347 msgid "add a user ID" msgstr "Eine User-ID hinzufügen" -#: g10/keyedit.c:1349 msgid "add a photo ID" msgstr "Eine Foto-ID hinzufügen" -#: g10/keyedit.c:1350 msgid "delete selected user IDs" msgstr "ausgewählte User-IDs entfernen" -#: g10/keyedit.c:1353 msgid "add a subkey" msgstr "einen Unterschlüssel hinzufügen" -#: g10/keyedit.c:1356 msgid "add a key to a smartcard" msgstr "der Smartcard einen Schlüssel hinzufügen" -#: g10/keyedit.c:1358 msgid "move a key to a smartcard" msgstr "einen Schlüssel auf die Smartcard schieben" -#: g10/keyedit.c:1360 msgid "move a backup key to a smartcard" msgstr "eine Sicherungskopie des Schlüssels auf die Smartcard schieben" -#: g10/keyedit.c:1363 msgid "delete selected subkeys" msgstr "ausgewählte Unterschlüssel entfernen" -#: g10/keyedit.c:1365 msgid "add a revocation key" msgstr "Einen Widerrufschlüssel hinzufügen" -#: g10/keyedit.c:1367 msgid "delete signatures from the selected user IDs" msgstr "Beglaubigungen der ausgewählten User-IDs entfernen" -#: g10/keyedit.c:1369 msgid "change the expiration date for the key or selected subkeys" msgstr "" "das Verfallsdatum des Schlüssel oder ausgewählter Unterschlüssels ändern" -#: g10/keyedit.c:1371 msgid "flag the selected user ID as primary" msgstr "User-ID als Haupt-User-ID kennzeichnen" -#: g10/keyedit.c:1373 msgid "toggle between the secret and public key listings" msgstr "Umschalten zwischen dem Auflisten geheimer und öffentlicher Schlüssel" -#: g10/keyedit.c:1375 msgid "list preferences (expert)" msgstr "Liste der Voreinstellungen (für Experten)" -#: g10/keyedit.c:1376 msgid "list preferences (verbose)" msgstr "Liste der Voreinstellungen (ausführlich)" -#: g10/keyedit.c:1378 msgid "set preference list for the selected user IDs" msgstr "ändern der Voreinstellungsliste der ausgewählten User-IDs" -#: g10/keyedit.c:1381 msgid "set the preferred keyserver URL for the selected user IDs" msgstr "" "Setze die URL des bevorzugten Schlüsselservers für die ausgewählten User-IDs" -#: g10/keyedit.c:1383 msgid "set a notation for the selected user IDs" msgstr "Eine Notation für die ausgewählten User-IDs setzen" -#: g10/keyedit.c:1385 msgid "change the passphrase" msgstr "Die Passphrase ändern" -#: g10/keyedit.c:1387 msgid "change the ownertrust" msgstr "Den \"Owner trust\" ändern" -#: g10/keyedit.c:1389 msgid "revoke signatures on the selected user IDs" msgstr "Beglaubigungen der ausgewählten User-IDs widerrufen" -#: g10/keyedit.c:1391 msgid "revoke selected user IDs" msgstr "Ausgewählte User-ID widerrufen" -#: g10/keyedit.c:1394 msgid "revoke key or selected subkeys" msgstr "Schlüssel oder ausgewählten Unterschlüssel widerrufen" -#: g10/keyedit.c:1395 msgid "enable key" msgstr "Schlüssel anschalten" -#: g10/keyedit.c:1396 msgid "disable key" msgstr "Schlüssel abschalten" -#: g10/keyedit.c:1397 msgid "show selected photo IDs" msgstr "ausgewählte Foto-IDs anzeigen" -#: g10/keyedit.c:1399 msgid "compact unusable user IDs and remove unusable signatures from key" msgstr "" "unbrauchbare User-IDs verkleinern und unbrauchbare Signaturen aus dem " "Schlüssel entfernen" -#: g10/keyedit.c:1401 msgid "compact unusable user IDs and remove all signatures from key" msgstr "" "unbrauchbare User-IDs verkleinern und alle Signaturen aus dem Schlüssel " "entfernen" -#: g10/keyedit.c:1515 msgid "Secret key is available.\n" msgstr "Geheimer Schlüssel ist vorhanden.\n" -#: g10/keyedit.c:1608 msgid "Need the secret key to do this.\n" msgstr "Hierzu wird der geheime Schlüssel benötigt.\n" -#: g10/keyedit.c:1615 msgid "Please use the command \"toggle\" first.\n" msgstr "Bitte verwenden sie zunächst den Befehl \"toggle\"\n" -#: g10/keyedit.c:1636 msgid "" "* The `sign' command may be prefixed with an `l' for local signatures " "(lsign),\n" @@ -3877,222 +3038,172 @@ msgstr "" "Signaturen\n" " (\"nrsign\"), oder jede Kombination davon (\"ltsign\", \"tnrsign\", etc.).\n" -#: g10/keyedit.c:1684 msgid "Key is revoked." msgstr "Schlüssel wurde widerrufen." -#: g10/keyedit.c:1703 msgid "Really sign all user IDs? (y/N) " msgstr "Wirklich alle User-IDs beglaubigen? (j/N) " -#: g10/keyedit.c:1710 msgid "Hint: Select the user IDs to sign\n" msgstr "Tip: Wählen Sie die User-IDs, die beglaubigt werden sollen\n" -#: g10/keyedit.c:1720 #, c-format msgid "Unknown signature type `%s'\n" msgstr "Unbekannter Signaturtyp `%s'\n" -#: g10/keyedit.c:1745 #, c-format msgid "This command is not allowed while in %s mode.\n" msgstr "Dieser Befehl ist im %s-Modus nicht erlaubt.\n" -#: g10/keyedit.c:1766 g10/keyedit.c:1786 g10/keyedit.c:1983 msgid "You must select at least one user ID.\n" msgstr "Zumindestens eine User-ID muß ausgewählt werden.\n" -#: g10/keyedit.c:1768 msgid "You can't delete the last user ID!\n" msgstr "Die letzte User-ID kann nicht gelöscht werden!\n" -#: g10/keyedit.c:1771 msgid "Really remove all selected user IDs? (y/N) " msgstr "Möchten Sie alle ausgewählten User-IDs wirklich entfernen? (j/N) " -#: g10/keyedit.c:1772 msgid "Really remove this user ID? (y/N) " msgstr "Diese User-ID wirklich entfernen? (j/N) " #. TRANSLATORS: Please take care: This is about #. moving the key and not about removing it. -#: g10/keyedit.c:1825 msgid "Really move the primary key? (y/N) " msgstr "Den Hauptschlüssel wirklich verschieben? (j/N) " -#: g10/keyedit.c:1837 msgid "You must select exactly one key.\n" msgstr "Sie müssen genau einen Schlüssel auswählen.\n" -#: g10/keyedit.c:1868 msgid "Command expects a filename argument\n" msgstr "Befehl benötigt einen Dateinamen als Argument\n" -#: g10/keyedit.c:1882 #, c-format msgid "Can't open `%s': %s\n" msgstr "'%s' kann nicht geöffnet werden: %s\n" -#: g10/keyedit.c:1898 #, c-format msgid "Error reading backup key from `%s': %s\n" msgstr "Fehler beim Lesen der Sicherungskopie des Schlüssels von `%s': %s\n" -#: g10/keyedit.c:1947 msgid "You must select at least one key.\n" msgstr "Zumindestens ein Schlüssel muß ausgewählt werden.\n" -#: g10/keyedit.c:1950 msgid "Do you really want to delete the selected keys? (y/N) " msgstr "Möchten Sie die ausgewählten Schlüssel wirklich entfernen? (j/N) " -#: g10/keyedit.c:1952 msgid "Do you really want to delete this key? (y/N) " msgstr "Möchten Sie diesen Schlüssel wirklich entfernen? (j/N) " -#: g10/keyedit.c:1986 msgid "Really revoke all selected user IDs? (y/N) " msgstr "Möchten Sie wirklich alle ausgewählten User-IDs widerrufen? (j/N) " -#: g10/keyedit.c:1987 msgid "Really revoke this user ID? (y/N) " msgstr "Diese User-ID wirklich widerrufen? (j/N) " -#: g10/keyedit.c:2005 msgid "Do you really want to revoke the entire key? (y/N) " msgstr "Möchten Sie diesen Schlüssel wirklich vollständig widerrufen? (j/N) " -#: g10/keyedit.c:2016 msgid "Do you really want to revoke the selected subkeys? (y/N) " msgstr "" "Möchten Sie die ausgewählten Unterschlüssel wirklich widerrufen? (j/N) " -#: g10/keyedit.c:2018 msgid "Do you really want to revoke this subkey? (y/N) " msgstr "Möchten Sie diesen Schlüssel wirklich widerrufen? (j/N) " -#: g10/keyedit.c:2065 msgid "Owner trust may not be set while using a user provided trust database\n" msgstr "" "\"Owner trust\" kann nicht gesetzt werden, wenn eine anwendereigene 'Trust'-" "Datenbank benutzt wird\n" -#: g10/keyedit.c:2109 msgid "Set preference list to:\n" msgstr "Setze die Liste der Voreinstellungen auf:\n" -#: g10/keyedit.c:2116 msgid "Really update the preferences for the selected user IDs? (y/N) " msgstr "" "Möchten Sie die Voreinstellungen der ausgewählten User-IDs wirklich ändern? " "(j/N) " -#: g10/keyedit.c:2118 msgid "Really update the preferences? (y/N) " msgstr "Die Voreinstellungen wirklich ändern? (j/N) " -#: g10/keyedit.c:2190 msgid "Save changes? (y/N) " msgstr "Änderungen speichern? (j/N) " -#: g10/keyedit.c:2194 msgid "Quit without saving? (y/N) " msgstr "Beenden ohne zu speichern? (j/N) " -#: g10/keyedit.c:2205 #, c-format msgid "update failed: %s\n" msgstr "Änderung fehlgeschlagen: %s\n" -#: g10/keyedit.c:2210 msgid "Key not changed so no update needed.\n" msgstr "Schlüssel ist nicht geändert worden, also ist kein Speichern nötig.\n" -#: g10/keyedit.c:2350 msgid "Digest: " msgstr "Digest: " -#: g10/keyedit.c:2407 msgid "Features: " msgstr "Eigenschaften: " -#: g10/keyedit.c:2418 msgid "Keyserver no-modify" msgstr "Keyserver no-modify" -#: g10/keyedit.c:2433 g10/keylist.c:320 msgid "Preferred keyserver: " msgstr "Bevorzugter Schlüsselserver:" -#: g10/keyedit.c:2441 g10/keyedit.c:2442 msgid "Notations: " msgstr "\"Notationen\": " -#: g10/keyedit.c:2666 msgid "There are no preferences on a PGP 2.x-style user ID.\n" msgstr "PGP 2.x-artige Schlüssel haben keine Voreinstellungen.\n" -#: g10/keyedit.c:2729 #, c-format msgid "The following key was revoked on %s by %s key %s\n" msgstr "Der folgende Schlüssel wurde am %s von %s Schlüssel %s widerrufen\n" -#: g10/keyedit.c:2752 #, c-format msgid "This key may be revoked by %s key %s" msgstr "" "Dieser Schlüssel könnte durch %s mit Schlüssel %s widerrufen worden sein" -#: g10/keyedit.c:2758 msgid "(sensitive)" msgstr "(empfindlich)" -#: g10/keyedit.c:2775 g10/keyedit.c:2888 g10/keyserver.c:557 #, c-format msgid "created: %s" msgstr "erzeugt: %s" -#: g10/keyedit.c:2778 g10/keylist.c:810 g10/keylist.c:933 g10/mainproc.c:1008 #, c-format msgid "revoked: %s" msgstr "widerrufen: %s" -#: g10/keyedit.c:2780 g10/keylist.c:816 g10/keylist.c:939 #, c-format msgid "expired: %s" msgstr "verfallen: %s" -#: g10/keyedit.c:2782 g10/keyedit.c:2890 g10/keylist.c:822 g10/keylist.c:945 -#: g10/keyserver.c:563 g10/mainproc.c:1014 #, c-format msgid "expires: %s" msgstr "verfällt: %s" -#: g10/keyedit.c:2784 #, c-format msgid "usage: %s" msgstr "Aufruf: %s" -#: g10/keyedit.c:2792 msgid "card-no: " msgstr "Kartennummer:" -#: g10/keyedit.c:2828 #, c-format msgid "trust: %s" msgstr "Vertrauen: %s" -#: g10/keyedit.c:2832 #, c-format msgid "validity: %s" msgstr "Gültigkeit: %s" -#: g10/keyedit.c:2839 msgid "This key has been disabled" msgstr "Hinweis: Dieser Schlüssel ist abgeschaltet" -#: g10/keyedit.c:2856 msgid "" "Please note that the shown key validity is not necessarily correct\n" "unless you restart the program.\n" @@ -4100,19 +3211,13 @@ msgstr "" "Bitte beachten Sie, daß ohne einen Programmneustart die angezeigte\n" "Schlüsselgültigkeit nicht notwendigerweise korrekt ist.\n" -#: g10/keyedit.c:2907 g10/keyedit.c:3219 g10/keyserver.c:567 -#: g10/mainproc.c:1874 g10/trustdb.c:1202 g10/trustdb.c:1731 -#: dirmngr/ocsp.c:699 msgid "revoked" msgstr "widerrufen" -#: g10/keyedit.c:2909 g10/keyedit.c:3221 g10/keyserver.c:571 -#: g10/mainproc.c:1876 g10/trustdb.c:549 g10/trustdb.c:1733 msgid "expired" msgstr "verfallen" # translated by wk -#: g10/keyedit.c:2974 msgid "" "WARNING: no user ID has been marked as primary. This command may\n" " cause a different user ID to become the assumed primary.\n" @@ -4120,7 +3225,6 @@ msgstr "" "WARNUNG: Keine User-ID ist als primär markiert. Dieser Befehl kann\n" "dazu führen, daß eine andere User-ID als primär angesehen wird.\n" -#: g10/keyedit.c:3027 msgid "" "WARNING: This is a PGP2-style key. Adding a photo ID may cause some " "versions\n" @@ -4130,74 +3234,58 @@ msgstr "" "könnte\n" " bei einigen PGP-Versionen zur Zurückweisung des Schlüssels führen.\n" -#: g10/keyedit.c:3032 g10/keyedit.c:3316 msgid "Are you sure you still want to add it? (y/N) " msgstr "Wollen Sie ihn immer noch hinzufügen? (j/N) " -#: g10/keyedit.c:3038 msgid "You may not add a photo ID to a PGP2-style key.\n" msgstr "Sie können einem PGP2-artigen Schlüssel keine Foto-ID hinzufügen.\n" -#: g10/keyedit.c:3147 msgid "Delete this good signature? (y/N/q)" msgstr "Diese korrekte Beglaubigung entfernen? (j/N/q)" -#: g10/keyedit.c:3157 msgid "Delete this invalid signature? (y/N/q)" msgstr "Diese ungültige Beglaubigung entfernen= (j/N/q)" -#: g10/keyedit.c:3161 msgid "Delete this unknown signature? (y/N/q)" msgstr "Diese unbekannte Beglaubigung entfernen? (j/N/q)" -#: g10/keyedit.c:3168 msgid "Really delete this self-signature? (y/N)" msgstr "Eigenbeglaubigung wirklich entfernen? (j/N)" -#: g10/keyedit.c:3184 #, c-format msgid "Deleted %d signature.\n" msgstr "%d Beglaubigungen entfernt.\n" -#: g10/keyedit.c:3185 #, c-format msgid "Deleted %d signatures.\n" msgstr "%d Beglaubigungen entfernt.\n" -#: g10/keyedit.c:3188 msgid "Nothing deleted.\n" msgstr "Nichts entfernt.\n" -#: g10/keyedit.c:3223 g10/trustdb.c:1735 msgid "invalid" msgstr "ungültig" -#: g10/keyedit.c:3225 #, c-format msgid "User ID \"%s\" compacted: %s\n" msgstr "User-ID \"%s\" bereits verkleinert: %s\n" -#: g10/keyedit.c:3232 #, c-format msgid "User ID \"%s\": %d signature removed\n" msgstr "User-ID \"%s\": %d Signatur entfernt\n" -#: g10/keyedit.c:3233 #, c-format msgid "User ID \"%s\": %d signatures removed\n" msgstr "User-ID \"%s\": %d Signaturen entfernt\n" -#: g10/keyedit.c:3241 #, c-format msgid "User ID \"%s\": already minimized\n" msgstr "User-ID \"%s\": bereits minimiert\n" -#: g10/keyedit.c:3242 #, c-format msgid "User ID \"%s\": already clean\n" msgstr "User-ID \"%s\": bereits sauber\n" -#: g10/keyedit.c:3311 msgid "" "WARNING: This is a PGP 2.x-style key. Adding a designated revoker may " "cause\n" @@ -4207,264 +3295,206 @@ msgstr "" " Widerrufers könnte bei einigen PGP-Versionen zur Zurückweisung\n" " des Schlüssels führen.\n" -#: g10/keyedit.c:3322 msgid "You may not add a designated revoker to a PGP 2.x-style key.\n" msgstr "" "Sie können einem PGP2-artigen Schlüssel keine vorgesehenen Widerrufer " "hinzufügen.\n" -#: g10/keyedit.c:3341 msgid "Enter the user ID of the designated revoker: " msgstr "Geben sie die User-ID des designierten Widerrufers ein: " -#: g10/keyedit.c:3366 msgid "cannot appoint a PGP 2.x style key as a designated revoker\n" msgstr "" "Ein PGP 2.x-artiger Schlüssel kann nicht als vorgesehener Widerrufer " "eingetragen werden\n" -#: g10/keyedit.c:3381 msgid "you cannot appoint a key as its own designated revoker\n" msgstr "Ein Schlüssel kann nicht sein eigener vorgesehener Widerrufer werden\n" -#: g10/keyedit.c:3403 msgid "this key has already been designated as a revoker\n" msgstr "Dieser Schlüssel wurde bereits als ein Widerrufer vorgesehen\n" -#: g10/keyedit.c:3422 msgid "WARNING: appointing a key as a designated revoker cannot be undone!\n" msgstr "" "WARNUNG: Einen Schlüssel als vorgesehenen Widerrufer zu deklarieren, kann " "nicht rückgangig gemacht werden!\n" -#: g10/keyedit.c:3428 msgid "" "Are you sure you want to appoint this key as a designated revoker? (y/N) " msgstr "" "Möchten Sie diesen Schlüssel wirklich als vorgesehenen Widerrufer festlegen? " "(j/N): " -#: g10/keyedit.c:3479 msgid "Please select at most one subkey.\n" msgstr "Bitte wählen Sie höchstens einen Unterschlüssel aus.\n" -#: g10/keyedit.c:3483 msgid "Changing expiration time for a subkey.\n" msgstr "Ändern des Verfallsdatums des Unterschlüssels.\n" -#: g10/keyedit.c:3486 msgid "Changing expiration time for the primary key.\n" msgstr "Ändern des Verfallsdatums des Hauptschlüssels.\n" -#: g10/keyedit.c:3533 msgid "You can't change the expiration date of a v3 key\n" msgstr "Sie können das Verfallsdatum eines v3-Schlüssels nicht ändern\n" -#: g10/keyedit.c:3600 #, c-format msgid "signing subkey %s is already cross-certified\n" msgstr "Signaturunterschlüssel %s ist bereits rücksigniert\n" -#: g10/keyedit.c:3606 #, c-format msgid "subkey %s does not sign and so does not need to be cross-certified\n" msgstr "" "Unterschlüssel %s ist des Signieren nicht mächtig und braucht deshalb keine " "Rücksignatur\n" -#: g10/keyedit.c:3721 msgid "Please select exactly one user ID.\n" msgstr "Bitte genau eine User-ID auswählen.\n" -#: g10/keyedit.c:3762 g10/keyedit.c:3876 g10/keyedit.c:3989 g10/keyedit.c:4126 #, c-format msgid "skipping v3 self-signature on user ID \"%s\"\n" msgstr "Überspringen der v3 Eigenbeglaubigung von User-ID \"%s\"\n" -#: g10/keyedit.c:3933 msgid "Enter your preferred keyserver URL: " msgstr "Geben Sie die URL Ihres bevorzugten Schlüsselservers ein: " -#: g10/keyedit.c:4012 msgid "Are you sure you want to replace it? (y/N) " msgstr "Wollen Sie ihn wirklich ersetzen? (j/N) " -#: g10/keyedit.c:4013 msgid "Are you sure you want to delete it? (y/N) " msgstr "Wollen Sie ihn wirklich löschen? (j/N) " -#: g10/keyedit.c:4072 msgid "Enter the notation: " msgstr "Geben Sie die \"Notation\" ein: " -#: g10/keyedit.c:4219 msgid "Proceed? (y/N) " msgstr "Fortfahren (j/N)? " -#: g10/keyedit.c:4289 #, c-format msgid "No user ID with index %d\n" msgstr "Keine User-ID mit Index %d\n" -#: g10/keyedit.c:4351 #, c-format msgid "No user ID with hash %s\n" msgstr "Keine User-ID mit Hash %s\n" -#: g10/keyedit.c:4387 #, c-format msgid "No subkey with index %d\n" msgstr "Kein Unterschlüssel mit Index %d\n" -#: g10/keyedit.c:4528 #, c-format msgid "user ID: \"%s\"\n" msgstr "User-ID: \"%s\"\n" -#: g10/keyedit.c:4531 g10/keyedit.c:4633 g10/keyedit.c:4681 #, c-format msgid "signed by your key %s on %s%s%s\n" msgstr " beglaubigt durch Ihren Schlüssel %s am %s%s%s\n" -#: g10/keyedit.c:4533 g10/keyedit.c:4635 g10/keyedit.c:4683 msgid " (non-exportable)" msgstr " (nicht-exportierbar)" -#: g10/keyedit.c:4537 #, c-format msgid "This signature expired on %s.\n" msgstr "Diese Signatur ist seit %s verfallen.\n" -#: g10/keyedit.c:4542 msgid "Are you sure you still want to revoke it? (y/N) " msgstr "Wollen Sie ihn immer noch widerrufen? (j/N) " -#: g10/keyedit.c:4547 msgid "Create a revocation certificate for this signature? (y/N) " msgstr "Ein Widerrufszertifikat für diese Signatur erzeugen (j/N)" -#: g10/keyedit.c:4601 msgid "Not signed by you.\n" msgstr "Nicht von Ihnen signiert.\n" -#: g10/keyedit.c:4607 #, c-format msgid "You have signed these user IDs on key %s:\n" msgstr "Sie haben folgende User-IDs des Schlüssels %s beglaubigt:\n" -#: g10/keyedit.c:4636 msgid " (non-revocable)" msgstr " (unwiderrufbar)" -#: g10/keyedit.c:4643 #, c-format msgid "revoked by your key %s on %s\n" msgstr "widerrufen durch Ihren Schlüssel %s um %s\n" -#: g10/keyedit.c:4668 msgid "You are about to revoke these signatures:\n" msgstr "Es werden nun folgende Beglaubigungen entfernt:\n" -#: g10/keyedit.c:4691 msgid "Really create the revocation certificates? (y/N) " msgstr "Wirklich ein Signatur-Widerrufszertifikat erzeugen? (j/N) " -#: g10/keyedit.c:4724 msgid "no secret key\n" msgstr "Kein geheimer Schlüssel\n" -#: g10/keyedit.c:4792 #, c-format msgid "user ID \"%s\" is already revoked\n" msgstr "User-ID \"%s\" ist bereits widerrufen\n" -#: g10/keyedit.c:4809 #, c-format msgid "WARNING: a user ID signature is dated %d seconds in the future\n" msgstr "" "WARNUNG: Eine User-ID-Signatur datiert mit %d Sekunden aus der Zukunft\n" -#: g10/keyedit.c:4874 #, c-format msgid "Key %s is already revoked.\n" msgstr "Schlüssel %s ist bereits widerrufen\n" -#: g10/keyedit.c:4935 #, c-format msgid "Subkey %s is already revoked.\n" msgstr "Unterschlüssel %s ist bereits widerrufen\n" -#: g10/keyedit.c:5029 #, c-format msgid "Displaying %s photo ID of size %ld for key %s (uid %d)\n" msgstr "Anzeigen einer %s Foto-ID (Größe %ld) für Schlüssel %s (User-ID %d)\n" -#: g10/keygen.c:273 #, c-format msgid "preference `%s' duplicated\n" msgstr "Voreinstellung `%s' ist doppelt\n" -#: g10/keygen.c:280 msgid "too many cipher preferences\n" msgstr "zu viele Verschlüsselungeinstellungen\n" -#: g10/keygen.c:282 msgid "too many digest preferences\n" msgstr "zu viele Hashvoreinstellungen\n" -#: g10/keygen.c:284 msgid "too many compression preferences\n" msgstr "zu viele Komprimierungsvoreinstellungen\n" -#: g10/keygen.c:442 #, c-format msgid "invalid item `%s' in preference string\n" msgstr "Ungültiges Feld `%s' in der Voreinstellungszeichenkette\n" -#: g10/keygen.c:929 msgid "writing direct signature\n" msgstr "Die \"Direct Key Signature\" wird geschrieben\n" -#: g10/keygen.c:975 msgid "writing self signature\n" msgstr "Die Eigenbeglaubigung wird geschrieben\n" -#: g10/keygen.c:1031 msgid "writing key binding signature\n" msgstr "Schreiben der \"key-binding\" Signatur\n" -#: g10/keygen.c:1210 g10/keygen.c:1260 g10/keygen.c:1265 g10/keygen.c:1350 -#: g10/keygen.c:3075 #, c-format msgid "keysize invalid; using %u bits\n" msgstr "Ungültige Schlüssellänge; %u Bit werden verwendet\n" -#: g10/keygen.c:1216 g10/keygen.c:1271 g10/keygen.c:1279 g10/keygen.c:1356 -#: g10/keygen.c:3081 #, c-format msgid "keysize rounded up to %u bits\n" msgstr "Schlüssellänge auf %u Bit aufgerundet\n" -#: g10/keygen.c:1305 msgid "" "WARNING: some OpenPGP programs can't handle a DSA key with this digest size\n" msgstr "" "WARNUNG: Einige OpenPGP-Programme können einen DSA-Schlüssel dieser " "Digestlänge nicht verwenden\n" -#: g10/keygen.c:1411 msgid "Sign" msgstr "Signieren" -#: g10/keygen.c:1414 msgid "Certify" msgstr "Zertif." -#: g10/keygen.c:1417 msgid "Encrypt" msgstr "Verschl." -#: g10/keygen.c:1420 msgid "Authenticate" msgstr "Authentisierung" @@ -4478,104 +3508,83 @@ msgstr "Authentisierung" #. a = Toggle authentication capability #. q = Finish #. -#: g10/keygen.c:1438 msgid "SsEeAaQq" msgstr "UuVvAaQq" -#: g10/keygen.c:1461 #, c-format msgid "Possible actions for a %s key: " msgstr "Mögliche Vorgänge eines %s-Schlüssels: " -#: g10/keygen.c:1465 msgid "Current allowed actions: " msgstr "Derzeit erlaubte Vorgänge: " -#: g10/keygen.c:1470 #, c-format msgid " (%c) Toggle the sign capability\n" msgstr " (%c) Umschalten der Signaturfähigkeit\n" -#: g10/keygen.c:1473 #, c-format msgid " (%c) Toggle the encrypt capability\n" msgstr " (%c) Umschalten der Verschlüsselungsfähigkeit\n" -#: g10/keygen.c:1476 #, c-format msgid " (%c) Toggle the authenticate capability\n" msgstr " (%c) Umschalten der Authentisierungsfähigkeit\n" -#: g10/keygen.c:1479 #, c-format msgid " (%c) Finished\n" msgstr " (%c) Beenden\n" -#: g10/keygen.c:1539 sm/certreqgen-ui.c:157 msgid "Please select what kind of key you want:\n" msgstr "Bitte wählen Sie, welche Art von Schlüssel Sie möchten:\n" -#: g10/keygen.c:1542 #, c-format msgid " (%d) RSA and RSA (default)\n" msgstr " (%d) RSA und RSA (voreingestellt)\n" -#: g10/keygen.c:1544 #, c-format msgid " (%d) DSA and Elgamal\n" msgstr " (%d) DSA und Elgamal\n" -#: g10/keygen.c:1546 #, c-format msgid " (%d) DSA (sign only)\n" msgstr " (%d) DSA (nur signieren/beglaubigen)\n" -#: g10/keygen.c:1547 #, c-format msgid " (%d) RSA (sign only)\n" msgstr " (%d) RSA (nur signieren/beglaubigen)\n" -#: g10/keygen.c:1551 #, c-format msgid " (%d) Elgamal (encrypt only)\n" msgstr " (%d) Elgamal (nur verschlüsseln)\n" -#: g10/keygen.c:1552 #, c-format msgid " (%d) RSA (encrypt only)\n" msgstr " (%d) RSA (nur verschlüsseln)\n" -#: g10/keygen.c:1556 #, c-format msgid " (%d) DSA (set your own capabilities)\n" msgstr " (%d) DSA (Leistungsfähigkeit selber einstellbar)\n" -#: g10/keygen.c:1557 #, c-format msgid " (%d) RSA (set your own capabilities)\n" msgstr " (%d) RSA (Leistungsfähigkeit selber einstellbar)\n" -#: g10/keygen.c:1665 #, c-format msgid "%s keys may be between %u and %u bits long.\n" msgstr "%s-Schlüssel können zwischen %u und %u Bit lang sein.\n" -#: g10/keygen.c:1673 #, c-format msgid "What keysize do you want for the subkey? (%u) " msgstr "Welche Schlüssellänge wünschen Sie für den Unterschlüssel? (%u) " -#: g10/keygen.c:1676 sm/certreqgen-ui.c:179 #, c-format msgid "What keysize do you want? (%u) " msgstr "Welche Schlüssellänge wünschen Sie? (%u) " -#: g10/keygen.c:1690 sm/certreqgen-ui.c:189 #, c-format msgid "Requested keysize is %u bits\n" msgstr "Die verlangte Schlüssellänge beträgt %u Bit\n" -#: g10/keygen.c:1778 msgid "" "Please specify how long the key should be valid.\n" " 0 = key does not expire\n" @@ -4591,7 +3600,6 @@ msgstr "" " m = Schlüssel verfällt nach n Monaten\n" " y = Schlüssel verfällt nach n Jahren\n" -#: g10/keygen.c:1789 msgid "" "Please specify how long the signature should be valid.\n" " 0 = signature does not expire\n" @@ -4607,38 +3615,30 @@ msgstr "" " m = Schlüssel verfällt nach n Monaten\n" " y = Schlüssel verfällt nach n Jahren\n" -#: g10/keygen.c:1812 msgid "Key is valid for? (0) " msgstr "Wie lange bleibt der Schlüssel gültig? (0) " -#: g10/keygen.c:1817 #, c-format msgid "Signature is valid for? (%s) " msgstr "Wie lange bleibt die Beglaubigung gültig? (%s) " -#: g10/keygen.c:1835 g10/keygen.c:1860 msgid "invalid value\n" msgstr "Ungültiger Wert.\n" -#: g10/keygen.c:1842 msgid "Key does not expire at all\n" msgstr "Schlüssel verfällt nie\n" -#: g10/keygen.c:1843 msgid "Signature does not expire at all\n" msgstr "Signature verfällt nie\n" -#: g10/keygen.c:1848 #, c-format msgid "Key expires at %s\n" msgstr "Key verfällt am %s\n" -#: g10/keygen.c:1849 #, c-format msgid "Signature expires at %s\n" msgstr "Signatur verfällt am %s\n" -#: g10/keygen.c:1853 msgid "" "Your system can't display dates beyond 2038.\n" "However, it will be correctly handled up to 2106.\n" @@ -4646,11 +3646,9 @@ msgstr "" "Ihr Rechner kann Daten jenseits des Jahres 2038 nicht anzeigen.\n" "Trotzdem werden Daten bis 2106 korrekt verarbeitet.\n" -#: g10/keygen.c:1866 msgid "Is this correct? (y/N) " msgstr "Ist dies richtig? (j/N) " -#: g10/keygen.c:1916 msgid "" "\n" "GnuPG needs to construct a user ID to identify your key.\n" @@ -4664,7 +3662,6 @@ msgstr "" #. but you should keep your existing translation. In case #. the new string is not translated this old string will #. be used. -#: g10/keygen.c:1931 msgid "" "\n" "You need a user ID to identify your key; the software constructs the user " @@ -4680,44 +3677,34 @@ msgstr "" " \"Heinrich Heine (Der Dichter) \"\n" "\n" -#: g10/keygen.c:1950 msgid "Real name: " msgstr "Ihr Name (\"Vorname Nachname\"): " -#: g10/keygen.c:1958 msgid "Invalid character in name\n" msgstr "Ungültiges Zeichen im Namen\n" -#: g10/keygen.c:1960 msgid "Name may not start with a digit\n" msgstr "Der Name darf nicht mit einer Ziffer beginnen.\n" -#: g10/keygen.c:1962 msgid "Name must be at least 5 characters long\n" msgstr "Der Name muß min. 5 Zeichen lang sein.\n" -#: g10/keygen.c:1970 msgid "Email address: " msgstr "Email-Adresse: " -#: g10/keygen.c:1976 msgid "Not a valid email address\n" msgstr "Diese Email-Adresse ist ungültig\n" -#: g10/keygen.c:1984 msgid "Comment: " msgstr "Kommentar: " -#: g10/keygen.c:1990 msgid "Invalid character in comment\n" msgstr "Ungültiges Zeichen im Kommentar.\n" -#: g10/keygen.c:2012 #, c-format msgid "You are using the `%s' character set.\n" msgstr "Sie benutzen den Zeichensatz `%s'\n" -#: g10/keygen.c:2018 #, c-format msgid "" "You selected this USER-ID:\n" @@ -4728,11 +3715,9 @@ msgstr "" " \"%s\"\n" "\n" -#: g10/keygen.c:2023 msgid "Please don't put the email address into the real name or the comment\n" msgstr "Bitte keine Emailadressen als Namen oder Kommentar verwenden\n" -#: g10/keygen.c:2038 msgid "Such a user ID already exists on this key!\n" msgstr "Solch eine User-ID ist bereits für den Schlüssel vorhanden!\n" @@ -4747,23 +3732,18 @@ msgstr "Solch eine User-ID ist bereits für den Schlüssel vorhanden!\n" #. o = Okay (ready, continue) #. q = Quit #. -#: g10/keygen.c:2054 msgid "NnCcEeOoQq" msgstr "NnKkEeFfAa" -#: g10/keygen.c:2064 msgid "Change (N)ame, (C)omment, (E)mail or (Q)uit? " msgstr "Ändern: (N)ame, (K)ommentar, (E)-Mail oder (A)bbrechen? " -#: g10/keygen.c:2065 msgid "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? " msgstr "Ändern: (N)ame, (K)ommentar, (E)-Mail oder (F)ertig/(A)bbrechen? " -#: g10/keygen.c:2084 msgid "Please correct the error first\n" msgstr "Bitte beseitigen Sie zuerst den Fehler\n" -#: g10/keygen.c:2126 msgid "" "You need a Passphrase to protect your secret key.\n" "\n" @@ -4771,7 +3751,6 @@ msgstr "" "Sie benötigen eine Passphrase, um den geheimen Schlüssel zu schützen.\n" "\n" -#: g10/keygen.c:2129 msgid "" "Please enter a passphrase to protect the off-card backup of the new " "encryption key." @@ -4779,16 +3758,13 @@ msgstr "" "Bitte geben Sie die Passphrase ein, um die Sicherheitskopie des neuen " "Verschlüsselungsschlüssel der Karte zu schützen." -#: g10/keygen.c:2144 msgid "passphrase not correctly repeated; try again" msgstr "Passphrase wurde nicht richtig wiederholt; noch einmal versuchen" -#: g10/keygen.c:2145 #, c-format msgid "%s.\n" msgstr "%s.\n" -#: g10/keygen.c:2151 msgid "" "You don't want a passphrase - this is probably a *bad* idea!\n" "I will do it anyway. You can change your passphrase at any time,\n" @@ -4801,7 +3777,6 @@ msgstr "" "aufrufen.\n" "\n" -#: g10/keygen.c:2177 msgid "" "We need to generate a lot of random bytes. It is a good idea to perform\n" "some other action (type on the keyboard, move the mouse, utilize the\n" @@ -4812,30 +3787,24 @@ msgstr "" "unterstützen, indem Sie z.B. in einem anderen Fenster/Konsole irgendetwas\n" "tippen, die Maus verwenden oder irgendwelche anderen Programme benutzen.\n" -#: g10/keygen.c:3034 msgid "Key generation canceled.\n" msgstr "Schlüsselerzeugung abgebrochen.\n" -#: g10/keygen.c:3214 g10/keygen.c:3350 #, c-format msgid "writing public key to `%s'\n" msgstr "schreiben des öffentlichen Schlüssels nach '%s'\n" -#: g10/keygen.c:3345 #, c-format msgid "no writable public keyring found: %s\n" msgstr "kein schreibbarer öffentlicher Schlüsselbund gefunden: %s\n" -#: g10/keygen.c:3358 #, c-format msgid "error writing public keyring `%s': %s\n" msgstr "Fehler beim Schreiben des öff. Schlüsselbundes `%s': %s\n" -#: g10/keygen.c:3385 msgid "public and secret key created and signed.\n" msgstr "Öffentlichen und geheimen Schlüssel erzeugt und signiert.\n" -#: g10/keygen.c:3396 msgid "" "Note that this key cannot be used for encryption. You may want to use\n" "the command \"--edit-key\" to generate a subkey for this purpose.\n" @@ -4844,12 +3813,10 @@ msgstr "" "werden kann. Sie können aber mit dem Befehl \"--edit-key\" einen\n" "Unterschlüssel für diesem Zweck erzeugen.\n" -#: g10/keygen.c:3409 g10/keygen.c:3519 g10/keygen.c:3616 #, c-format msgid "Key generation failed: %s\n" msgstr "Schlüsselerzeugung fehlgeschlagen: %s\n" -#: g10/keygen.c:3458 g10/keygen.c:3564 g10/sign.c:259 #, c-format msgid "" "key has been created %lu second in future (time warp or clock problem)\n" @@ -4857,7 +3824,6 @@ msgstr "" "Der Schlüssel wurde %lu Sekunde in der Zukunft erzeugt (Zeitreise oder Uhren " "stimmen nicht überein)\n" -#: g10/keygen.c:3460 g10/keygen.c:3566 g10/sign.c:261 #, c-format msgid "" "key has been created %lu seconds in future (time warp or clock problem)\n" @@ -4865,614 +3831,484 @@ msgstr "" "Der Schlüssel wurde %lu Sekunden in der Zukunft erzeugt (Zeitreise oder " "Uhren stimmen nicht überein)\n" -#: g10/keygen.c:3471 g10/keygen.c:3577 msgid "NOTE: creating subkeys for v3 keys is not OpenPGP compliant\n" msgstr "HINWEIS: Unterschlüssel für v3-Schlüssel sind nicht OpenPGP-konform\n" -#: g10/keygen.c:3482 msgid "Secret parts of primary key are not available.\n" msgstr "Geheime Teile des Hauptschlüssels sind nicht vorhanden.\n" -#: g10/keygen.c:3486 msgid "Secret parts of primary key are stored on-card.\n" msgstr "Geheime Teile des Hauptschlüssels sind auf der Karte gespeichert.\n" -#: g10/keygen.c:3493 g10/keygen.c:3592 msgid "Really create? (y/N) " msgstr "Wirklich erzeugen? (j/N) " -#: g10/keygen.c:3763 #, c-format msgid "storing key onto card failed: %s\n" msgstr "Speicher des Schlüssels auf der Karte schlug fehl: %s\n" -#: g10/keygen.c:3812 #, c-format msgid "can't create backup file `%s': %s\n" msgstr "Sicherungsdatei '%s' kann nicht erzeugt werden: %s\n" -#: g10/keygen.c:3838 #, c-format msgid "NOTE: backup of card key saved to `%s'\n" msgstr "Hinweis: Sicherung des Kartenschlüssels wurde auf `%s' gespeichert\n" -#: g10/keyid.c:500 g10/keyid.c:513 g10/keyid.c:526 msgid "never " msgstr "niemals " -#: g10/keylist.c:274 msgid "Critical signature policy: " msgstr "Entscheidende Beglaubigungsrichtlinie: " -#: g10/keylist.c:276 msgid "Signature policy: " msgstr "Beglaubigungsrichtlinie: " -#: g10/keylist.c:318 msgid "Critical preferred keyserver: " msgstr "Entscheidender bevorzugter Schlüsselserver" -#: g10/keylist.c:371 msgid "Critical signature notation: " msgstr "Entscheidender Beglaubigungs-\"Notation\": " -#: g10/keylist.c:373 msgid "Signature notation: " msgstr "Beglaubigungs-\"Notation\": " -#: g10/keylist.c:493 msgid "Keyring" msgstr "Schlüsselbund" -#: g10/keylist.c:1527 msgid "Primary key fingerprint:" msgstr "Haupt-Fingerabdruck =" -#: g10/keylist.c:1529 msgid " Subkey fingerprint:" msgstr "Unter-Fingerabdruck =" #. TRANSLATORS: this should fit into 24 bytes to that the #. * fingerprint data is properly aligned with the user ID -#: g10/keylist.c:1537 msgid " Primary key fingerprint:" msgstr " Haupt-Fingerabdruck =" -#: g10/keylist.c:1539 msgid " Subkey fingerprint:" msgstr " Unter-Fingerabdruck =" -#: g10/keylist.c:1544 g10/keylist.c:1549 msgid " Key fingerprint =" msgstr " Schl.-Fingerabdruck =" -#: g10/keylist.c:1587 msgid " Card serial no. =" msgstr " Kartenseriennr. =" -#: g10/keyring.c:1258 #, c-format msgid "renaming `%s' to `%s' failed: %s\n" msgstr "umbenennen von `%s' nach `%s' schlug fehl: %s\n" -#: g10/keyring.c:1382 #, c-format msgid "caching keyring `%s'\n" msgstr "Puffern des Schlüsselbundes `%s'\n" -#: g10/keyring.c:1441 #, c-format msgid "%lu keys cached so far (%lu signatures)\n" msgstr "%lu Schlüssel bislang gepuffert (%lu Beglaubigungen)\n" -#: g10/keyring.c:1453 #, c-format msgid "%lu keys cached (%lu signatures)\n" msgstr "%lu Schlüssel gepuffert (%lu Beglaubigungen)\n" -#: g10/keyring.c:1525 #, c-format msgid "%s: keyring created\n" msgstr "%s: Schlüsselbund erstellt\n" -#: g10/keyserver.c:97 msgid "include revoked keys in search results" msgstr "Widerrufene Schlüssel in den Suchergebnissen aufführen" -#: g10/keyserver.c:98 msgid "include subkeys when searching by key ID" msgstr "Unterschlüssel in der Suche über Schlüssel-IDs aufführen" -#: g10/keyserver.c:100 msgid "use temporary files to pass data to keyserver helpers" msgstr "" "verwende temporäre Dateien, um Daten an die Schlüsselserverhilfsprogramme zu " "geben" -#: g10/keyserver.c:102 msgid "do not delete temporary files after using them" msgstr "Temporäre Dateien nach Nutzung nicht löschen" -#: g10/keyserver.c:106 msgid "automatically retrieve keys when verifying signatures" msgstr "Schlüssel für die Signaturprüfung automatisch holen" -#: g10/keyserver.c:108 msgid "honor the preferred keyserver URL set on the key" msgstr "" "Die im Schlüssel enthaltene bevorzugte URL für Schlüsselserver beachten" -#: g10/keyserver.c:110 msgid "honor the PKA record set on a key when retrieving keys" msgstr "Die im Schlüssel enthaltenen PKA-Daten beim Schlüsselholen beachten" -#: g10/keyserver.c:178 #, c-format msgid "WARNING: keyserver option `%s' is not used on this platform\n" msgstr "" "WARNUNG: Schlüsselserver-Option `%s' wird auf dieser Plattform nicht " "verwendet\n" -#: g10/keyserver.c:569 msgid "disabled" msgstr "abgeschaltet" -#: g10/keyserver.c:773 msgid "Enter number(s), N)ext, or Q)uit > " msgstr "Eingabe von Nummern, Nächste (N) oder Abbrechen (Q) > " -#: g10/keyserver.c:867 #, c-format msgid "invalid keyserver protocol (us %d!=handler %d)\n" msgstr "Ungültiges Schlüsselserverprotokoll (wir %d!=Handhabungsroutine %d)\n" -#: g10/keyserver.c:1008 g10/keyserver.c:1043 #, c-format msgid "\"%s\" not a key ID: skipping\n" msgstr "\"%s\" ist keine Schlüssel-ID: überspringe\n" -#: g10/keyserver.c:1303 #, c-format msgid "WARNING: unable to refresh key %s via %s: %s\n" msgstr "WARNUNG: Schlüssel %s kann per %s nicht aktualisiert werden: %s\n" -#: g10/keyserver.c:1325 #, c-format msgid "refreshing 1 key from %s\n" msgstr "ein Schlüssel wird per %s aktualisiert\n" -#: g10/keyserver.c:1327 #, c-format msgid "refreshing %d keys from %s\n" msgstr "%d Schlüssel werden per %s aktualisiert\n" -#: g10/keyserver.c:1363 g10/keyserver.c:1415 g10/keyserver.c:1604 -#: g10/keyserver.c:1754 msgid "no keyserver known (use option --keyserver)\n" msgstr "Kein Schlüsselserver bekannt (Option --keyserver verwenden)\n" -#: g10/keyserver.c:1408 #, c-format msgid "key \"%s\" not found on keyserver\n" msgstr "Schlüssel \"%s\" wurde auf dem Schlüsselserver nicht gefunden\n" -#: g10/keyserver.c:1411 msgid "key not found on keyserver\n" msgstr "Schlüssel wurde auf dem Schlüsselserver nicht gefunden\n" -#: g10/keyserver.c:1548 #, c-format msgid "requesting key %s from %s server %s\n" msgstr "fordere Schlüssel %s von %s-Server %s an\n" -#: g10/keyserver.c:1552 #, c-format msgid "requesting key %s from %s\n" msgstr "fordere Schlüssel %s von %s an\n" -#: g10/keyserver.c:1618 g10/skclist.c:191 g10/skclist.c:219 #, c-format msgid "skipped \"%s\": %s\n" msgstr "übersprungen \"%s\": %s\n" -#: g10/keyserver.c:1622 #, c-format msgid "sending key %s to %s server %s\n" msgstr "sende Schlüssel %s auf den %s-Server %s\n" -#: g10/keyserver.c:1626 #, c-format msgid "sending key %s to %s\n" msgstr "sende Schlüssel %s auf %s\n" -#: g10/keyserver.c:1673 #, c-format msgid "WARNING: unable to fetch URI %s: %s\n" msgstr "WARNUNG: die URI %s kann nicht geholt werden: %s\n" -#: g10/keyserver.c:1679 #, c-format msgid "WARNING: unable to parse URI %s\n" msgstr "WARNUNG: die URI %s kann nicht analysiert werden\n" -#: g10/mainproc.c:231 #, c-format msgid "weird size for an encrypted session key (%d)\n" msgstr "Seltsame Länge für einen verschlüsselten Sitzungsschlüssel (%d)\n" -#: g10/mainproc.c:284 #, c-format msgid "%s encrypted session key\n" msgstr "%s verschlüsselter Sitzungsschlüssel\n" -#: g10/mainproc.c:294 #, c-format msgid "passphrase generated with unknown digest algorithm %d\n" msgstr "Passphrase wurde mit unbekanntem Hashverfahren %d erstellt\n" -#: g10/mainproc.c:360 #, c-format msgid "public key is %s\n" msgstr "Öffentlicher Schlüssel ist %s\n" -#: g10/mainproc.c:429 msgid "public key encrypted data: good DEK\n" msgstr "Mit öffentlichem Schlüssel verschlüsselte Daten: Korrekte DEK\n" -#: g10/mainproc.c:462 #, c-format msgid "encrypted with %u-bit %s key, ID %s, created %s\n" msgstr "verschlüsselt mit %u-Bit %s Schlüssel, ID %s, erzeugt %s\n" -#: g10/mainproc.c:466 g10/pkclist.c:228 #, c-format msgid " \"%s\"\n" msgstr " \"%s\"\n" # Scripte scannen lt. dl1bke auf "ID (0-9A-F)+" deswegen muß "ID" rein :-( # [kw] -#: g10/mainproc.c:470 #, c-format msgid "encrypted with %s key, ID %s\n" msgstr "verschlüsselt mit %s Schlüssel, ID %s\n" -#: g10/mainproc.c:485 #, c-format msgid "public key decryption failed: %s\n" msgstr "Entschlüsselung mit Public-Key-Verfahren fehlgeschlagen: %s\n" -#: g10/mainproc.c:501 #, c-format msgid "encrypted with %lu passphrases\n" msgstr "Verschlüsselt mit %lu Passphrases\n" -#: g10/mainproc.c:503 msgid "encrypted with 1 passphrase\n" msgstr "Verschlüsselt mit einer Passphrase\n" -#: g10/mainproc.c:535 g10/mainproc.c:557 #, c-format msgid "assuming %s encrypted data\n" msgstr "vermutlich %s-verschlüsselte Daten\n" -#: g10/mainproc.c:543 #, c-format msgid "IDEA cipher unavailable, optimistically attempting to use %s instead\n" msgstr "IDEA-Verschlüsselung nicht verfügbar; versucht wird stattdessen %s\n" -#: g10/mainproc.c:576 msgid "decryption okay\n" msgstr "Entschlüsselung erfolgreich\n" -#: g10/mainproc.c:580 msgid "WARNING: message was not integrity protected\n" msgstr "" "WARNUNG: Botschaft wurde nicht integritätsgeschützt (integrity protected)\n" -#: g10/mainproc.c:594 msgid "WARNING: encrypted message has been manipulated!\n" msgstr "Warnung: Verschlüsselte Botschaft ist manipuliert worden!\n" -#: g10/mainproc.c:602 #, c-format msgid "cleared passphrase cached with ID: %s\n" msgstr "Passphrase aus dem Cache gelöscht. Cache ID: %s\n" -#: g10/mainproc.c:608 #, c-format msgid "decryption failed: %s\n" msgstr "Entschlüsselung fehlgeschlagen: %s\n" -#: g10/mainproc.c:629 msgid "NOTE: sender requested \"for-your-eyes-only\"\n" msgstr "" "Hinweis: Der Absender verlangte Vertraulichkeit(\"for-your-eyes-only\")\n" -#: g10/mainproc.c:631 #, c-format msgid "original file name='%.*s'\n" msgstr "Ursprünglicher Dateiname='%.*s'\n" -#: g10/mainproc.c:719 msgid "WARNING: multiple plaintexts seen\n" msgstr "WARNUNG: Mehr als ein Klartext erkannt\n" -#: g10/mainproc.c:861 msgid "standalone revocation - use \"gpg --import\" to apply\n" msgstr "" "Einzelner Widerruf - verwenden Sie \"gpg --import\", um ihn anzuwenden\n" -#: g10/mainproc.c:1219 g10/mainproc.c:1263 msgid "no signature found\n" msgstr "Keine Signatur gefunden\n" -#: g10/mainproc.c:1502 msgid "signature verification suppressed\n" msgstr "Signaturüberprüfung unterdrückt\n" -#: g10/mainproc.c:1611 msgid "can't handle this ambiguous signature data\n" msgstr "diese mehrdeutige Signaturdaten können nicht bearbeitet werden\n" -#: g10/mainproc.c:1622 #, c-format msgid "Signature made %s\n" msgstr "Signatur vom %s\n" -#: g10/mainproc.c:1623 #, c-format msgid " using %s key %s\n" msgstr " mittels %s-Schlüssel %s\n" # Scripte scannen lt. dl1bke auf "ID (0-9A-F)+" deswegen muß "ID" rein :-( -#: g10/mainproc.c:1627 #, c-format msgid "Signature made %s using %s key ID %s\n" msgstr "Signatur vom %s mittels %s-Schlüssel ID %s\n" -#: g10/mainproc.c:1647 msgid "Key available at: " msgstr "Schlüssel erhältlich bei: " -#: g10/mainproc.c:1780 g10/mainproc.c:1828 #, c-format msgid "BAD signature from \"%s\"" msgstr "FALSCHE Signatur von \"%s\"" -#: g10/mainproc.c:1782 g10/mainproc.c:1830 #, c-format msgid "Expired signature from \"%s\"" msgstr "Verfallene Signatur von \"%s\"" -#: g10/mainproc.c:1784 g10/mainproc.c:1832 #, c-format msgid "Good signature from \"%s\"" msgstr "Korrekte Signatur von \"%s\"" -#: g10/mainproc.c:1834 msgid "[uncertain]" msgstr "[ungewiß] " -#: g10/mainproc.c:1867 #, c-format msgid " aka \"%s\"" msgstr " alias \"%s\"" -#: g10/mainproc.c:1965 #, c-format msgid "Signature expired %s\n" msgstr "Diese Signatur ist seit %s verfallen.\n" -#: g10/mainproc.c:1970 #, c-format msgid "Signature expires %s\n" msgstr "Diese Signatur verfällt am %s.\n" -#: g10/mainproc.c:1973 #, c-format msgid "%s signature, digest algorithm %s\n" msgstr "%s Signatur, Hashmethode \"%s\"\n" -#: g10/mainproc.c:1974 msgid "binary" msgstr "Binäre" -#: g10/mainproc.c:1975 msgid "textmode" msgstr "Textmodus" -#: g10/mainproc.c:1975 g10/trustdb.c:548 dirmngr/ocsp.c:700 msgid "unknown" msgstr "unbekannt" -#: g10/mainproc.c:1995 #, c-format msgid "Can't check signature: %s\n" msgstr "Signatur kann nicht geprüft werden: %s\n" -#: g10/mainproc.c:2079 g10/mainproc.c:2095 g10/mainproc.c:2191 msgid "not a detached signature\n" msgstr "keine abgetrennte Signatur\n" -#: g10/mainproc.c:2122 msgid "" "WARNING: multiple signatures detected. Only the first will be checked.\n" msgstr "" "WARNUNG: Mehrfache Signaturen erkannt. Es wird nur die erste geprüft.\n" -#: g10/mainproc.c:2130 #, c-format msgid "standalone signature of class 0x%02x\n" msgstr "Einzelne Signatur der Klasse 0x%02x\n" -#: g10/mainproc.c:2195 msgid "old style (PGP 2.x) signature\n" msgstr "Signatur nach alter (PGP 2.x) Art\n" -#: g10/mainproc.c:2205 msgid "invalid root packet detected in proc_tree()\n" msgstr "ungültiges root-Paket in proc_tree() entdeckt\n" -#: g10/misc.c:109 g10/misc.c:139 g10/misc.c:215 #, c-format msgid "fstat of `%s' failed in %s: %s\n" msgstr "fstat von `%s' schlug fehl in %s: %s\n" -#: g10/misc.c:178 #, c-format msgid "fstat(%d) failed in %s: %s\n" msgstr "fstat(%d) schlug fehl in %s: %s\n" -#: g10/misc.c:296 #, c-format msgid "WARNING: using experimental public key algorithm %s\n" msgstr "WARNUNG: Verwendung des experimentellen Public-Key-Verfahrens %s\n" -#: g10/misc.c:302 msgid "WARNING: Elgamal sign+encrypt keys are deprecated\n" msgstr "" "WARNUNG: Die Verwendung von Elgamal sign+encrypt Schlüsseln ist nicht " "ratsam\n" -#: g10/misc.c:315 #, c-format msgid "WARNING: using experimental cipher algorithm %s\n" msgstr "WARNING: Verwendung des experimentellen Verschlüsselungsverfahren %s\n" -#: g10/misc.c:330 #, c-format msgid "WARNING: using experimental digest algorithm %s\n" msgstr "WARNUNG: Verwendung des experimentellen Hashverfahrens %s\n" -#: g10/misc.c:335 #, c-format msgid "WARNING: digest algorithm %s is deprecated\n" msgstr "WARNUNG: Die Verwendung des Hashverfahrens %s ist nicht ratsam\n" -#: g10/misc.c:538 msgid "the IDEA cipher plugin is not present\n" msgstr "das IDEA-Verschlüsselungs-Plugin ist nicht vorhanden\n" -#: g10/misc.c:798 #, c-format msgid "%s:%d: deprecated option \"%s\"\n" msgstr "%s:%d: mißbilligte Option \"%s\".\n" -#: g10/misc.c:802 #, c-format msgid "WARNING: \"%s\" is a deprecated option\n" msgstr "WARNUNG: \"%s\" ist eine mißbilligte Option.\n" -#: g10/misc.c:804 #, c-format msgid "please use \"%s%s\" instead\n" msgstr "Bitte benutzen Sie stattdessen \"%s%s\".\n" -#: g10/misc.c:811 #, c-format msgid "WARNING: \"%s\" is a deprecated command - do not use it\n" msgstr "" "WARNUNG: \"%s\" ist ein nicht ratsamer Befehl - verwenden Sie ihn nicht.\n" -#: g10/misc.c:821 #, c-format msgid "%s:%u: obsolete option \"%s\" - it has no effect\n" msgstr "%s:%u: Die Option \"%s\" is veraltet - sie hat keine Wirkung\n" -#: g10/misc.c:824 #, c-format msgid "WARNING: \"%s\" is an obsolete option - it has no effect\n" msgstr "WARNUNG: \"%s\" ist eine veraltete Option - sie hat keine Wirkung.\n" -#: g10/misc.c:885 msgid "Uncompressed" msgstr "nicht komprimiert" #. TRANSLATORS: See doc/TRANSLATE about this string. -#: g10/misc.c:910 msgid "uncompressed|none" msgstr "unkomprimiert|kein|keine" -#: g10/misc.c:1040 #, c-format msgid "this message may not be usable by %s\n" msgstr "Diese Botschaft könnte für %s unbrauchbar sein\n" -#: g10/misc.c:1215 #, c-format msgid "ambiguous option `%s'\n" msgstr "Mehrdeutige Option '%s'\n" -#: g10/misc.c:1240 #, c-format msgid "unknown option `%s'\n" msgstr "Unbekannte Option '%s'\n" -#: g10/openfile.c:85 #, c-format msgid "File `%s' exists. " msgstr "Datei '%s' existiert bereits. " -#: g10/openfile.c:89 msgid "Overwrite? (y/N) " msgstr "Überschreiben (j/N)? " -#: g10/openfile.c:122 #, c-format msgid "%s: unknown suffix\n" msgstr "%s: unbekannte Dateinamenerweiterung\n" -#: g10/openfile.c:146 msgid "Enter new filename" msgstr "Neuen Dateinamen eingeben" -#: g10/openfile.c:214 msgid "writing to stdout\n" msgstr "Schreiben auf die Standardausgabe\n" -#: g10/openfile.c:331 #, c-format msgid "assuming signed data in `%s'\n" msgstr "die unterzeichneten Daten sind wohl in '%s'\n" -#: g10/openfile.c:410 #, c-format msgid "new configuration file `%s' created\n" msgstr "Neue Konfigurationsdatei `%s' erstellt\n" -#: g10/openfile.c:412 #, c-format msgid "WARNING: options in `%s' are not yet active during this run\n" msgstr "" "WARNUNG: Optionen in `%s' sind während dieses Laufes noch nicht wirksam\n" -#: g10/parse-packet.c:201 #, c-format msgid "can't handle public key algorithm %d\n" msgstr "dieses Public-Key Verfahren %d kann nicht benutzt werden\n" -#: g10/parse-packet.c:864 msgid "WARNING: potentially insecure symmetrically encrypted session key\n" msgstr "" "WARNUNG: Möglicherweise unsicherer symmetrisch verschlüsselter " "Sitzungsschlüssel\n" -#: g10/parse-packet.c:1358 #, c-format msgid "subpacket of type %d has critical bit set\n" msgstr "Im Unterpaket des Typs %d ist das \"critical bit\" gesetzt\n" -#: g10/passphrase.c:75 g10/passphrase.c:408 g10/passphrase.c:471 #, c-format msgid "problem with the agent: %s\n" msgstr "Problem mit dem Agenten: %s\n" -#: g10/passphrase.c:333 g10/passphrase.c:603 g10/passphrase.c:702 #, c-format msgid " (main key ID %s)" msgstr " (Hauptschlüssel-ID %s)" -#: g10/passphrase.c:347 #, c-format msgid "" "Please enter the passphrase to unlock the secret key for the OpenPGP " @@ -5486,15 +4322,12 @@ msgstr "" "Benutzer: \"%.*s\"\n" "%u-bit %s Schlüssel, ID %s, erzeugt %s%s\n" -#: g10/passphrase.c:373 msgid "Enter passphrase\n" msgstr "Geben Sie die Passphrase ein\n" -#: g10/passphrase.c:402 msgid "cancelled by user\n" msgstr "Abbruch durch Benutzer\n" -#: g10/passphrase.c:582 #, c-format msgid "" "You need a passphrase to unlock the secret key for\n" @@ -5503,17 +4336,14 @@ msgstr "" "Sie benötigen eine Passphrase, um den geheimen Schlüssel zu entsperren.\n" "Benutzer: \"%s\"\n" -#: g10/passphrase.c:590 #, c-format msgid "%u-bit %s key, ID %s, created %s" msgstr "%u-Bit %s Schlüssel, ID %s, erzeugt %s" -#: g10/passphrase.c:599 #, c-format msgid " (subkey on main key ID %s)" msgstr " (Unterschlüssel aus Hauptschlüssel-ID %s)" -#: g10/passphrase.c:709 msgid "" "Please enter the passphrase to unlock the secret key for the OpenPGP " "certificate:" @@ -5521,7 +4351,6 @@ msgstr "" "Sie benötigen eine Passphrase, um den geheimen OpenPGP Schlüssel zu " "entsperren:" -#: g10/passphrase.c:713 msgid "" "Please enter the passphrase to import the secret key for the OpenPGP " "certificate:" @@ -5529,7 +4358,6 @@ msgstr "" "Sie benötigen eine Passphrase, um den geheimen OpenPGP Schlüssel zu " "importieren:" -#: g10/passphrase.c:721 #, c-format msgid "" "%s\n" @@ -5543,7 +4371,6 @@ msgstr "" "erzeugt %s%s.\n" # translated by wk -#: g10/photoid.c:74 msgid "" "\n" "Pick an image to use for your photo ID. The image must be a JPEG file.\n" @@ -5558,156 +4385,123 @@ msgstr "" "wir Ihr Schlüssel leider auch sehr groß werden. Ein Bild der Größe\n" "240x288 Pixel ist eine gute Wahl.\n" -#: g10/photoid.c:96 msgid "Enter JPEG filename for photo ID: " msgstr "Dateiname mit JPEG für die Foto-ID eingeben: " -#: g10/photoid.c:117 #, c-format msgid "unable to open JPEG file `%s': %s\n" msgstr "JPEG-Datei `%s' kann nicht geöffnet werden: %s\n" -#: g10/photoid.c:128 #, c-format msgid "This JPEG is really large (%d bytes) !\n" msgstr "Diese JPEG-Datei ist echt groß (%d Byte)!\n" -#: g10/photoid.c:130 msgid "Are you sure you want to use it? (y/N) " msgstr "Wollen Sie es wirklich benutzen? (j/N) " -#: g10/photoid.c:147 #, c-format msgid "`%s' is not a JPEG file\n" msgstr "`%s' ist keine JPEG-Datei\n" -#: g10/photoid.c:166 msgid "Is this photo correct (y/N/q)? " msgstr "Ist dieses Bild richtig? (j/N) " -#: g10/photoid.c:370 msgid "unable to display photo ID!\n" msgstr "Die Foto-ID kann nicht angezeigt werden!\n" -#: g10/pkclist.c:72 g10/revoke.c:593 msgid "No reason specified" msgstr "Kein Grund angegeben" -#: g10/pkclist.c:74 g10/revoke.c:595 msgid "Key is superseded" msgstr "Schlüssel ist überholt" -#: g10/pkclist.c:76 g10/revoke.c:594 msgid "Key has been compromised" msgstr "Hinweis: Dieser Schlüssel ist nicht mehr sicher" -#: g10/pkclist.c:78 g10/revoke.c:596 msgid "Key is no longer used" msgstr "Schlüssel wird nicht mehr benutzt" -#: g10/pkclist.c:80 g10/revoke.c:597 msgid "User ID is no longer valid" msgstr "User-ID ist nicht mehr gültig" -#: g10/pkclist.c:84 msgid "reason for revocation: " msgstr "Grund für Widerruf: " -#: g10/pkclist.c:100 msgid "revocation comment: " msgstr "Widerruf-Bemerkung: " -#: g10/pkclist.c:215 msgid "iImMqQsS" msgstr "iImMqQsS" -#: g10/pkclist.c:223 msgid "No trust value assigned to:\n" msgstr "Es ist kein \"trust value\" zugewiesen für:\n" -#: g10/pkclist.c:256 #, c-format msgid " aka \"%s\"\n" msgstr " \"%s\"\n" -#: g10/pkclist.c:266 msgid "" "How much do you trust that this key actually belongs to the named user?\n" msgstr "" "Wie sicher sind Sie, daß dieser Schlüssel wirklich dem angegebenen Besitzer " "gehört?\n" -#: g10/pkclist.c:281 #, c-format msgid " %d = I don't know or won't say\n" msgstr " %d = Weiß nicht so recht\n" -#: g10/pkclist.c:283 #, c-format msgid " %d = I do NOT trust\n" msgstr " %d = Nein, ihm traue ich NICHT\n" -#: g10/pkclist.c:289 #, c-format msgid " %d = I trust ultimately\n" msgstr " %d = Ich vertraue ihm absolut\n" -#: g10/pkclist.c:295 msgid " m = back to the main menu\n" msgstr " m = Zurück zum Menü\n" -#: g10/pkclist.c:298 msgid " s = skip this key\n" msgstr " s = diesen Schlüssel überspringen\n" -#: g10/pkclist.c:299 msgid " q = quit\n" msgstr " q = verlassen\n" -#: g10/pkclist.c:303 #, c-format msgid "" "The minimum trust level for this key is: %s\n" "\n" msgstr "Die minimale Trust-Ebene für diesen Schlüssel beträgt: %s\n" -#: g10/pkclist.c:309 g10/revoke.c:622 msgid "Your decision? " msgstr "Ihre Auswahl? " -#: g10/pkclist.c:330 msgid "Do you really want to set this key to ultimate trust? (y/N) " msgstr "Wollen Sie diesem Schlüssel wirklich uneingeschränkt vertrauen? (j/N) " -#: g10/pkclist.c:344 msgid "Certificates leading to an ultimately trusted key:\n" msgstr "Zertifikate führen zu einem letztlich vertrauenswürdigen Schlüssel:\n" -#: g10/pkclist.c:429 #, c-format msgid "%s: There is no assurance this key belongs to the named user\n" msgstr "" "%s: Es gibt keine Garantie, daß dieser Schlüssel wirklich dem angegebenen " "Besitzer gehört.\n" -#: g10/pkclist.c:434 #, c-format msgid "%s: There is limited assurance this key belongs to the named user\n" msgstr "" "%s: Es gibt nur eine beschränkte Garantie, daß dieser Schlüssel wirklich dem " "angegebenen Besitzer gehört.\n" -#: g10/pkclist.c:440 msgid "This key probably belongs to the named user\n" msgstr "Dieser Schlüssel gehört wahrscheinlich dem angegebenen Besitzer\n" -#: g10/pkclist.c:445 msgid "This key belongs to us\n" msgstr "" "Dieser Schlüssel gehört uns (da wir nämlich den geheimen Schlüssel dazu " "haben)\n" -#: g10/pkclist.c:471 msgid "" "It is NOT certain that the key belongs to the person named\n" "in the user ID. If you *really* know what you are doing,\n" @@ -5717,121 +4511,96 @@ msgstr "" "Genannten gehört. Wenn Sie *wirklich* wissen, was Sie tun,\n" "können Sie die nächste Frage mit ja beantworten\n" -#: g10/pkclist.c:490 msgid "Use this key anyway? (y/N) " msgstr "Diesen Schlüssel trotzdem benutzen? (j/N) " -#: g10/pkclist.c:524 msgid "WARNING: Using untrusted key!\n" msgstr "WARNUNG: Ein Schlüssel ohne gesichertes Vertrauen wird benutzt!\n" -#: g10/pkclist.c:531 msgid "WARNING: this key might be revoked (revocation key not present)\n" msgstr "" "WARNUNG: Dieser Schlüssel ist u.U. widerrufen: Widerrufschlüssel ist nicht " "vorhanden\n" -#: g10/pkclist.c:540 msgid "WARNING: This key has been revoked by its designated revoker!\n" msgstr "" "WARNUNG: Dieser Schlüssel wurde vom vorgesehen Widerrufer widerrufen!\n" -#: g10/pkclist.c:543 msgid "WARNING: This key has been revoked by its owner!\n" msgstr "WARNUNG: Dieser Schlüssel wurde von seinem Besitzer widerrufen!\n" -#: g10/pkclist.c:544 msgid " This could mean that the signature is forged.\n" msgstr " Das könnte bedeuten, daß die Signatur gefälscht ist.\n" -#: g10/pkclist.c:550 msgid "WARNING: This subkey has been revoked by its owner!\n" msgstr "WARNUNG: Dieser Unterschlüssel wurde von seinem Besitzer widerrufen!\n" -#: g10/pkclist.c:555 msgid "Note: This key has been disabled.\n" msgstr "Hinweis: Dieser Schlüssel wurde abgeschaltet.\n" -#: g10/pkclist.c:575 #, c-format msgid "Note: Verified signer's address is `%s'\n" msgstr "Hinweis: Überprüfte Adresse des Unterzeichners ist `%s'\n" -#: g10/pkclist.c:582 #, c-format msgid "Note: Signer's address `%s' does not match DNS entry\n" msgstr "" "Hinweise: Adresse des Unterzeichners `%s' passt nicht zum DNS-Eintrag\n" -#: g10/pkclist.c:594 msgid "trustlevel adjusted to FULL due to valid PKA info\n" msgstr "\"Trust\"-Ebene auf VOLLSTÄNDIG geändert (wg. gültiger PKA-Info)\n" -#: g10/pkclist.c:602 msgid "trustlevel adjusted to NEVER due to bad PKA info\n" msgstr "\"Trust\"-Ebene auf NIEMALS geändert (wg. falscher PKA-Info)\n" -#: g10/pkclist.c:613 msgid "Note: This key has expired!\n" msgstr "Hinweis: Dieser Schlüssel ist verfallen!\n" -#: g10/pkclist.c:624 msgid "WARNING: This key is not certified with a trusted signature!\n" msgstr "WARNUNG: Dieser Schlüssel trägt keine vertrauenswürdige Signatur!\n" -#: g10/pkclist.c:626 msgid "" " There is no indication that the signature belongs to the owner.\n" msgstr "" " Es gibt keinen Hinweis, daß die Signatur wirklich dem vorgeblichen " "Besitzer gehört.\n" -#: g10/pkclist.c:634 msgid "WARNING: We do NOT trust this key!\n" msgstr "WARNUNG: Wir haben KEIN Vertrauen zu diesem Schlüssel!\n" -#: g10/pkclist.c:635 msgid " The signature is probably a FORGERY.\n" msgstr " Die Signatur ist wahrscheinlich eine FÄLSCHUNG.\n" -#: g10/pkclist.c:643 msgid "" "WARNING: This key is not certified with sufficiently trusted signatures!\n" msgstr "" "WARNUNG: Dieser Schlüssel ist nicht durch hinreichend vertrauenswürdige " "Signaturen zertifiziert!\n" -#: g10/pkclist.c:645 msgid " It is not certain that the signature belongs to the owner.\n" msgstr "" " Es ist nicht sicher, daß die Signatur wirklich dem vorgeblichen " "Besitzer gehört.\n" -#: g10/pkclist.c:800 g10/pkclist.c:811 g10/pkclist.c:937 g10/pkclist.c:978 #, c-format msgid "%s: skipped: %s\n" msgstr "%s: übersprungen: %s\n" -#: g10/pkclist.c:822 #, c-format msgid "%s: skipped: public key is disabled\n" msgstr "%s: übersprungen: öffentlicher Schlüssel ist abgeschaltet\n" -#: g10/pkclist.c:840 g10/pkclist.c:948 #, c-format msgid "%s: skipped: public key already present\n" msgstr "%s: übersprungen: öffentlicher Schlüssel bereits vorhanden\n" -#: g10/pkclist.c:998 msgid "You did not specify a user ID. (you may use \"-r\")\n" msgstr "" "Sie haben keine User-ID angegeben (Sie können die Option \"-r\" verwenden).\n" -#: g10/pkclist.c:1022 msgid "Current recipients:\n" msgstr "Derzeitige Empfänger:\n" -#: g10/pkclist.c:1048 msgid "" "\n" "Enter the user ID. End with an empty line: " @@ -5839,160 +4608,125 @@ msgstr "" "\n" "Geben Sie die User-ID ein. Beenden mit einer leeren Zeile: " -#: g10/pkclist.c:1073 msgid "No such user ID.\n" msgstr "Keine solche User-ID vorhanden.\n" -#: g10/pkclist.c:1082 g10/pkclist.c:1156 msgid "skipped: public key already set as default recipient\n" msgstr "" "übersprungen: öffentlicher Schlüssel bereits als Standardempfänger gesetzt\n" -#: g10/pkclist.c:1103 msgid "Public key is disabled.\n" msgstr "Öffentlicher Schlüssel ist abgeschaltet.\n" -#: g10/pkclist.c:1112 msgid "skipped: public key already set\n" msgstr "übersprungen: öffentlicher Schlüssel bereits gesetzt\n" -#: g10/pkclist.c:1147 #, c-format msgid "unknown default recipient \"%s\"\n" msgstr "Unbekannter voreingestellter Empfänger \"%s\"\n" -#: g10/pkclist.c:1193 msgid "no valid addressees\n" msgstr "Keine gültigen Adressaten\n" -#: g10/pkclist.c:1531 #, c-format msgid "Note: key %s has no %s feature\n" msgstr "Hinweis: Schlüssel %s besitzt nicht die %s Eigenschaft\n" -#: g10/pkclist.c:1556 #, c-format msgid "Note: key %s has no preference for %s\n" msgstr "Hinweis: Schlüssel %s hat keine Einstellung für %s\n" -#: g10/plaintext.c:109 msgid "data not saved; use option \"--output\" to save it\n" msgstr "" "Daten wurden nicht gespeichert; verwenden Sie dafür die Option \"--output\"\n" -#: g10/plaintext.c:550 msgid "Detached signature.\n" msgstr "Abgetrennte Beglaubigungen.\n" -#: g10/plaintext.c:558 msgid "Please enter name of data file: " msgstr "Bitte geben Sie den Namen der Datendatei ein: " -#: g10/plaintext.c:595 msgid "reading stdin ...\n" msgstr "lese stdin ...\n" -#: g10/plaintext.c:635 msgid "no signed data\n" msgstr "keine signierten Daten\n" -#: g10/plaintext.c:653 #, c-format msgid "can't open signed data `%s'\n" msgstr "kann signierte Datei '%s' nicht öffnen.\n" -#: g10/plaintext.c:688 #, c-format msgid "can't open signed data fd=%d: %s\n" msgstr "kann signierte Daten auf fd=%d nicht öffnen: %s\n" -#: g10/pubkey-enc.c:114 #, c-format msgid "anonymous recipient; trying secret key %s ...\n" msgstr "Ungenannter Empfänger; Versuch mit geheimen Schlüssel %s ...\n" -#: g10/pubkey-enc.c:120 msgid "okay, we are the anonymous recipient.\n" msgstr "Alles klar, wir sind der ungenannte Empfänger.\n" -#: g10/pubkey-enc.c:214 msgid "old encoding of the DEK is not supported\n" msgstr "alte Kodierung des DEK wird nicht unterstützt\n" -#: g10/pubkey-enc.c:243 #, c-format msgid "cipher algorithm %d%s is unknown or disabled\n" msgstr "Verschlüsselungsverfahren %d%s ist unbekannt oder abgeschaltet\n" -#: g10/pubkey-enc.c:286 #, c-format msgid "WARNING: cipher algorithm %s not found in recipient preferences\n" msgstr "" "WARNUNG: Das Verschlüsselungsverfahren %s wurde nicht in den " "Empfängereinstellungen gefunden\n" -#: g10/pubkey-enc.c:311 #, c-format msgid "NOTE: secret key %s expired at %s\n" msgstr "Hinweis: geheimer Schlüssel %s verfällt am %s\n" -#: g10/pubkey-enc.c:318 msgid "NOTE: key has been revoked" msgstr "Hinweis: Schlüssel wurde widerrufen" -#: g10/revoke.c:102 g10/revoke.c:116 g10/revoke.c:128 g10/revoke.c:174 -#: g10/revoke.c:186 g10/revoke.c:557 #, c-format msgid "build_packet failed: %s\n" msgstr "\"build_packet\" fehlgeschlagen: %s\n" -#: g10/revoke.c:145 #, c-format msgid "key %s has no user IDs\n" msgstr "Schlüssel %s hat keine User-IDs\n" -#: g10/revoke.c:308 msgid "To be revoked by:\n" msgstr "Schlüssel soll widerrufen werden von:\n" -#: g10/revoke.c:312 msgid "(This is a sensitive revocation key)\n" msgstr "(Dies ist ein \"sensitiver\" Widerrufsschlüssel)\n" -#: g10/revoke.c:316 msgid "Create a designated revocation certificate for this key? (y/N) " msgstr "" "Ein vorgesehenes Widerrufszertifikat für diesen Schlüssel erzeugen? (j/N) " -#: g10/revoke.c:329 g10/revoke.c:521 msgid "ASCII armored output forced.\n" msgstr "Ausgabe mit ASCII Hülle erzwungen\n" -#: g10/revoke.c:345 g10/revoke.c:536 #, c-format msgid "make_keysig_packet failed: %s\n" msgstr "\"make_keysig_packet\" fehlgeschlagen: %s\n" -#: g10/revoke.c:408 msgid "Revocation certificate created.\n" msgstr "Widerrufzertifikat erzeugt.\n" -#: g10/revoke.c:414 #, c-format msgid "no revocation keys found for \"%s\"\n" msgstr "keine Widerrufsschlüssel für \"%s\" gefunden\n" -#: g10/revoke.c:471 g10/revoke.c:492 #, c-format msgid "secret key \"%s\" not found: %s\n" msgstr "Geheimer Schlüssel \"%s\" nicht gefunden: %s\n" -#: g10/revoke.c:502 msgid "Create a revocation certificate for this key? (y/N) " msgstr "Ein Widerrufszertifikat für diesen Schlüssel erzeugen? (j/N) " # translated by wk -#: g10/revoke.c:564 msgid "" "Revocation certificate created.\n" "\n" @@ -6012,83 +4746,66 @@ msgstr "" "Drucksystem kann unter Umständen eine Kopie anderen Nutzern zugänglich\n" "machen.\n" -#: g10/revoke.c:605 msgid "Please select the reason for the revocation:\n" msgstr "Grund für den Widerruf:\n" -#: g10/revoke.c:615 msgid "Cancel" msgstr "Abbruch" -#: g10/revoke.c:617 #, c-format msgid "(Probably you want to select %d here)\n" msgstr "(Wahrscheinlich möchten Sie hier %d auswählen)\n" -#: g10/revoke.c:658 msgid "Enter an optional description; end it with an empty line:\n" msgstr "" "Geben Sie eine optionale Beschreibung ein. Beenden mit einer leeren Zeile:\n" -#: g10/revoke.c:686 #, c-format msgid "Reason for revocation: %s\n" msgstr "Grund für Widerruf: %s\n" -#: g10/revoke.c:688 msgid "(No description given)\n" msgstr "(Keine Beschreibung angegeben)\n" -#: g10/revoke.c:693 msgid "Is this okay? (y/N) " msgstr "Ist das OK? (j/N) " -#: g10/seskey.c:61 sm/encrypt.c:123 msgid "weak key created - retrying\n" msgstr "Unsicherer Schlüssel erzeugt - neuer Versuch\n" -#: g10/seskey.c:65 #, c-format msgid "cannot avoid weak key for symmetric cipher; tried %d times!\n" msgstr "" "Trotz %d-fachen Versuches konnte die Erzeugung eines unsicheren Schlüssels " "für sym. Verschlüsselung nicht vermieden werden!\n" -#: g10/seskey.c:239 #, c-format msgid "DSA key %s uses an unsafe (%zu bit) hash\n" msgstr "DSA-Schlüssel %s verwendet einen unsicheren (%zu Bit-) Hash\n" -#: g10/seskey.c:250 #, c-format msgid "DSA key %s requires a %zu bit or larger hash\n" msgstr "DSA-Schlüssel %s benötigt einen mindestens %zu Bit langen Hash\n" -#: g10/sig-check.c:80 msgid "WARNING: signature digest conflict in message\n" msgstr "WARNUNG: Widersprechende Hashverfahren in der signierten Nachricht\n" -#: g10/sig-check.c:105 #, c-format msgid "WARNING: signing subkey %s is not cross-certified\n" msgstr "WARNUNG: Signaturunterschlüssel %s hat keine Rücksignatur\n" -#: g10/sig-check.c:117 #, c-format msgid "WARNING: signing subkey %s has an invalid cross-certification\n" msgstr "WARNUNG: Signaturunterschlüssel %s hat eine ungültige Rücksignatur\n" -#: g10/sig-check.c:211 #, c-format msgid "public key %s is %lu second newer than the signature\n" msgstr "Öffentlicher Schlüssel %s ist %lu Sekunden jünger als die Signatur\n" -#: g10/sig-check.c:212 #, c-format msgid "public key %s is %lu seconds newer than the signature\n" msgstr "Öffentlicher Schlüssel %s ist %lu Sekunden jünger als die Signatur\n" -#: g10/sig-check.c:223 #, c-format msgid "" "key %s was created %lu second in the future (time warp or clock problem)\n" @@ -6096,7 +4813,6 @@ msgstr "" "Schlüssel %s wurde %lu Sekunden in der Zukunft erzeugt (Zeitreise oder " "Uhrenproblem)\n" -#: g10/sig-check.c:225 #, c-format msgid "" "key %s was created %lu seconds in the future (time warp or clock problem)\n" @@ -6104,45 +4820,38 @@ msgstr "" "Schlüssel %s wurde %lu Sekunden in der Zukunft erzeugt (Zeitreise oder " "Uhrenproblem)\n" -#: g10/sig-check.c:239 #, c-format msgid "NOTE: signature key %s expired %s\n" msgstr "Hinweis: Signaturschlüssel %s ist am %s verfallen\n" -#: g10/sig-check.c:252 #, c-format msgid "NOTE: signature key %s has been revoked\n" msgstr "Hinweis: Signaturschlüssel %s wurde widerrufen\n" -#: g10/sig-check.c:328 #, c-format msgid "assuming bad signature from key %s due to an unknown critical bit\n" msgstr "" "Vermutlich eine FALSCHE Signatur von Schlüssel %s, wegen unbekanntem " "\"critical bit\"\n" -#: g10/sig-check.c:593 #, c-format msgid "key %s: no subkey for subkey revocation signature\n" msgstr "" "Schlüssel %s: Kein Unterschlüssel für die Unterschlüsselwiderruf-" "Beglaubigung\n" -#: g10/sig-check.c:620 #, c-format msgid "key %s: no subkey for subkey binding signature\n" msgstr "" "Schlüssel %s: Kein Unterschlüssel für die Unterschlüsselanbindungs-" "Beglaubigung\n" -#: g10/sign.c:89 #, c-format msgid "WARNING: unable to %%-expand notation (too large). Using unexpanded.\n" msgstr "" "WARNUNG: \"Notation\" kann nicht %%-erweitert werden (zu groß). Verwende " "\"unerweiterte\".\n" -#: g10/sign.c:115 #, c-format msgid "" "WARNING: unable to %%-expand policy URL (too large). Using unexpanded.\n" @@ -6150,7 +4859,6 @@ msgstr "" "WARNUNG: Richtlinien-URL kann nicht %%-erweitert werden (zu groß). Verwende " "\"unerweiterte\".\n" -#: g10/sign.c:138 #, c-format msgid "" "WARNING: unable to %%-expand preferred keyserver URL (too large). Using " @@ -6159,23 +4867,19 @@ msgstr "" "WARNUNG: URL für bevorzugten Schlüsselserver kann nicht %%-erweitert werden " "(zu groß). Verwende \"unerweiterte\".\n" -#: g10/sign.c:328 #, c-format msgid "checking created signature failed: %s\n" msgstr "Prüfung der erstellten Signatur ist fehlgeschlagen: %s\n" -#: g10/sign.c:340 #, c-format msgid "%s/%s signature from: \"%s\"\n" msgstr "%s/%s Signatur von: \"%s\"\n" -#: g10/sign.c:829 msgid "you can only detach-sign with PGP 2.x style keys while in --pgp2 mode\n" msgstr "" "Im --pgp2-Modus kann nur mit PGP-2.x-artigen Schlüsseln eine abgetrennte " "Signatur erzeugt werden\n" -#: g10/sign.c:907 #, c-format msgid "" "WARNING: forcing digest algorithm %s (%d) violates recipient preferences\n" @@ -6183,48 +4887,39 @@ msgstr "" "WARNUNG: Erzwingen des Hashverfahrens %s (%d) verstößt gegen die " "Empfängervoreinstellungen\n" -#: g10/sign.c:1033 msgid "signing:" msgstr "signiere:" -#: g10/sign.c:1150 msgid "you can only clearsign with PGP 2.x style keys while in --pgp2 mode\n" msgstr "" "Im --pgp2-Modus können Sie Klartextsignaturen nur mit PGP-2.x-artigen " "Schlüssel machen\n" -#: g10/sign.c:1336 #, c-format msgid "%s encryption will be used\n" msgstr "%s Verschlüsselung wird verwendet\n" -#: g10/skclist.c:150 g10/skclist.c:231 msgid "key is not flagged as insecure - can't use it with the faked RNG!\n" msgstr "" "Schlüssel ist nicht als unsicher gekennzeichnet - er ist nur mit einem\n" "echten Zufallsgenerator verwendbar\n" -#: g10/skclist.c:182 #, c-format msgid "skipped \"%s\": duplicated\n" msgstr "übersprungen \"%s\": doppelt\n" -#: g10/skclist.c:201 msgid "skipped: secret key already present\n" msgstr "übersprungen: geheimer Schlüssel bereits vorhanden\n" -#: g10/skclist.c:220 msgid "this is a PGP generated Elgamal key which is not secure for signatures!" msgstr "" "Dies ist ein durch PGP erzeugter Elgamal-Schlüssel. Das ist für Signaturen " "NICHT sicher genug!" -#: g10/tdbdump.c:58 g10/trustdb.c:362 #, c-format msgid "trust record %lu, type %d: write failed: %s\n" msgstr "Vertrauenssatz %lu, Typ %d: Schreiben fehlgeschlagen: %s\n" -#: g10/tdbdump.c:106 #, c-format msgid "" "# List of assigned trustvalues, created %s\n" @@ -6233,345 +4928,272 @@ msgstr "" "# Liste der zugewiesenen Trustwerte, erzeugt am %s\n" "# (\"gpg --import-ownertrust\" um sie zu restaurieren)\n" -#: g10/tdbdump.c:161 g10/tdbdump.c:169 g10/tdbdump.c:174 g10/tdbdump.c:179 #, c-format msgid "error in `%s': %s\n" msgstr "Fehler in `%s': %s\n" -#: g10/tdbdump.c:161 msgid "line too long" msgstr "Zeile ist zu lang" -#: g10/tdbdump.c:169 msgid "colon missing" msgstr "Doppelpunkt fehlt" -#: g10/tdbdump.c:175 msgid "invalid fingerprint" msgstr "ungültiger Fingerabdruck" -#: g10/tdbdump.c:180 msgid "ownertrust value missing" msgstr "\"Owner trust\"-Wert fehlt" -#: g10/tdbdump.c:216 #, c-format msgid "error finding trust record in `%s': %s\n" msgstr "Fehler beim Suchen des \"Trust records\" in `%s': %s\n" -#: g10/tdbdump.c:220 #, c-format msgid "read error in `%s': %s\n" msgstr "Lesefehler in `%s': %s\n" -#: g10/tdbdump.c:229 g10/trustdb.c:377 #, c-format msgid "trustdb: sync failed: %s\n" msgstr "\"Trust-DB\": sync fehlgeschlagen: %s\n" -#: g10/tdbio.c:135 g10/tdbio.c:1482 #, c-format msgid "trustdb rec %lu: lseek failed: %s\n" msgstr "trustdb Satz %lu: lseek fehlgeschlagen: %s\n" -#: g10/tdbio.c:142 g10/tdbio.c:1489 #, c-format msgid "trustdb rec %lu: write failed (n=%d): %s\n" msgstr "trustdb Satz %lu: write fehlgeschlagen (n=%d): %s\n" -#: g10/tdbio.c:252 msgid "trustdb transaction too large\n" msgstr "trustdb Transaktion zu groß\n" -#: g10/tdbio.c:512 #, c-format msgid "can't access `%s': %s\n" msgstr "kann aus `%s' nicht zugreifen: %s\n" -#: g10/tdbio.c:539 #, c-format msgid "%s: directory does not exist!\n" msgstr "%s: Verzeichnis existiert nicht!\n" -#: g10/tdbio.c:549 g10/tdbio.c:572 g10/tdbio.c:613 sm/keydb.c:221 #, c-format msgid "can't create lock for `%s'\n" msgstr "Datei `%s' konnte nicht gesperrt werden\n" -#: g10/tdbio.c:551 g10/tdbio.c:616 #, c-format msgid "can't lock `%s'\n" msgstr "'%s' kann nicht gesperrt werden\n" -#: g10/tdbio.c:577 #, c-format msgid "%s: failed to create version record: %s" msgstr "%s: Fehler beim Erzeugen des Versionsatzes: %s" -#: g10/tdbio.c:581 #, c-format msgid "%s: invalid trustdb created\n" msgstr "%s: ungültige trust-db erzeugt\n" -#: g10/tdbio.c:584 #, c-format msgid "%s: trustdb created\n" msgstr "%s: trust-db erzeugt\n" -#: g10/tdbio.c:644 msgid "NOTE: trustdb not writable\n" msgstr "Notiz: Die \"trustdb\" ist nicht schreibbar\n" -#: g10/tdbio.c:653 #, c-format msgid "%s: invalid trustdb\n" msgstr "%s: ungültige 'Trust'-Datenbank\n" -#: g10/tdbio.c:685 #, c-format msgid "%s: failed to create hashtable: %s\n" msgstr "%s: hashtable kann nicht erzeugt werden: %s\n" -#: g10/tdbio.c:693 #, c-format msgid "%s: error updating version record: %s\n" msgstr "%s: Fehler beim Ändern des Versionsatzes: %s\n" -#: g10/tdbio.c:710 g10/tdbio.c:730 g10/tdbio.c:746 g10/tdbio.c:760 -#: g10/tdbio.c:790 g10/tdbio.c:1414 g10/tdbio.c:1441 #, c-format msgid "%s: error reading version record: %s\n" msgstr "%s: Fehler beim Lesen des Versionsatzes: %s\n" -#: g10/tdbio.c:769 #, c-format msgid "%s: error writing version record: %s\n" msgstr "%s: Fehler beim Schreiben des Versionsatzes: %s\n" -#: g10/tdbio.c:1209 #, c-format msgid "trustdb: lseek failed: %s\n" msgstr "trustdb: lseek fehlgeschlagen: %s\n" -#: g10/tdbio.c:1218 #, c-format msgid "trustdb: read failed (n=%d): %s\n" msgstr "trustdb: read failed (n=%d): %s\n" -#: g10/tdbio.c:1239 #, c-format msgid "%s: not a trustdb file\n" msgstr "%s: keine trustdb Datei\n" -#: g10/tdbio.c:1257 #, c-format msgid "%s: version record with recnum %lu\n" msgstr "%s: version record with recnum %lu\n" -#: g10/tdbio.c:1262 #, c-format msgid "%s: invalid file version %d\n" msgstr "%s: invalid file version %d\n" -#: g10/tdbio.c:1447 #, c-format msgid "%s: error reading free record: %s\n" msgstr "%s: Fehler beim Lesen eines freien Satzes: %s\n" -#: g10/tdbio.c:1455 #, c-format msgid "%s: error writing dir record: %s\n" msgstr "%s: Fehler beim Schreiben eines Verzeichnis-Satzes: %s\n" -#: g10/tdbio.c:1465 #, c-format msgid "%s: failed to zero a record: %s\n" msgstr "%s: konnte einen Satz nicht Nullen: %s\n" -#: g10/tdbio.c:1495 #, c-format msgid "%s: failed to append a record: %s\n" msgstr "%s: konnte Satz nicht anhängen: %s\n" -#: g10/tdbio.c:1538 msgid "Error: The trustdb is corrupted.\n" msgstr "Fehler: Die Vertrauensdatenbank ist fehlerhaft\n" -#: g10/textfilter.c:147 #, c-format msgid "can't handle text lines longer than %d characters\n" msgstr "Textzeilen länger als %d Zeichen können nicht benutzt werden\n" -#: g10/textfilter.c:247 #, c-format msgid "input line longer than %d characters\n" msgstr "Eingabezeile ist länger als %d Zeichen\n" -#: g10/trustdb.c:223 #, c-format msgid "`%s' is not a valid long keyID\n" msgstr "'%s' ist keine gültige lange Schlüssel-ID\n" -#: g10/trustdb.c:254 #, c-format msgid "key %s: accepted as trusted key\n" msgstr "Schlüssel %s: Als vertrauenswürdiger Schlüssel akzeptiert\n" -#: g10/trustdb.c:292 #, c-format msgid "key %s occurs more than once in the trustdb\n" msgstr "Schlüssel %s tritt mehr als einmal in der \"trustdb\" auf\n" -#: g10/trustdb.c:307 #, c-format msgid "key %s: no public key for trusted key - skipped\n" msgstr "" "Schlüssel %s: kein öffentlicher Schlüssel für den vertrauenswürdigen " "Schlüssel - übersprungen\n" -#: g10/trustdb.c:317 #, c-format msgid "key %s marked as ultimately trusted\n" msgstr "Schlüssel %s ist als uneingeschränkt vertrauenswürdig gekennzeichnet\n" -#: g10/trustdb.c:341 #, c-format msgid "trust record %lu, req type %d: read failed: %s\n" msgstr "trust record %lu, req type %d: read failed: %s\n" -#: g10/trustdb.c:347 #, c-format msgid "trust record %lu is not of requested type %d\n" msgstr "Vertrauenssatz %lu ist nicht von der angeforderten Art %d\n" -#: g10/trustdb.c:420 msgid "You may try to re-create the trustdb using the commands:\n" msgstr "" "Sie können versuchen die Vertrauensdatenbank durch folgende Befehle\n" "wiederherzustellen:\n" -#: g10/trustdb.c:429 msgid "If that does not work, please consult the manual\n" msgstr "Falls dies nicht funktioniert, sehen Sie bitte im Handbuch nach\n" -#: g10/trustdb.c:464 #, c-format msgid "unable to use unknown trust model (%d) - assuming %s trust model\n" msgstr "" "kann unbekanntes Vertrauensmodell nicht verwenden (%d) - verwende " "Vertrauensmodell %s\n" -#: g10/trustdb.c:470 #, c-format msgid "using %s trust model\n" msgstr "verwende Vertrauensmodell %s\n" -#: g10/trustdb.c:522 msgid "10 translator see trustdb.c:uid_trust_string_fixed" msgstr "10" -#: g10/trustdb.c:524 msgid "[ revoked]" msgstr "[widerrufen]" -#: g10/trustdb.c:526 g10/trustdb.c:531 msgid "[ expired]" msgstr "[verfall.]" -#: g10/trustdb.c:530 msgid "[ unknown]" msgstr "[ unbek.]" -#: g10/trustdb.c:532 msgid "[ undef ]" msgstr "[ undef.]" -#: g10/trustdb.c:533 msgid "[marginal]" msgstr "[marginal]" -#: g10/trustdb.c:534 msgid "[ full ]" msgstr "[ vollst.]" -#: g10/trustdb.c:535 msgid "[ultimate]" msgstr "[ uneing.]" -#: g10/trustdb.c:550 msgid "undefined" msgstr "unbestimmt" -#: g10/trustdb.c:551 msgid "never" msgstr "niemals" -#: g10/trustdb.c:552 msgid "marginal" msgstr "marginal" -#: g10/trustdb.c:553 msgid "full" msgstr "vollständig" -#: g10/trustdb.c:554 msgid "ultimate" msgstr "uneingeschränkt" -#: g10/trustdb.c:594 msgid "no need for a trustdb check\n" msgstr "\"Trust-DB\"-Überprüfung nicht nötig\n" -#: g10/trustdb.c:600 g10/trustdb.c:2486 #, c-format msgid "next trustdb check due at %s\n" msgstr "nächste \"Trust-DB\"-Pflichtüberprüfung am %s\n" -#: g10/trustdb.c:609 #, c-format msgid "no need for a trustdb check with `%s' trust model\n" msgstr "\"Trust-DB\"-Überprüfung ist beim `%s'-Vertrauensmodell nicht nötig\n" -#: g10/trustdb.c:624 #, c-format msgid "no need for a trustdb update with `%s' trust model\n" msgstr "\"Trust-DB\"-Änderung ist beim `%s'-Vertrauensmodell nicht nötig\n" -#: g10/trustdb.c:856 g10/trustdb.c:1308 #, c-format msgid "public key %s not found: %s\n" msgstr "Öffentlicher Schlüssel %s nicht gefunden: %s\n" -#: g10/trustdb.c:1050 msgid "please do a --check-trustdb\n" msgstr "Bitte ein --check-trustdb durchführen\n" -#: g10/trustdb.c:1054 msgid "checking the trustdb\n" msgstr "\"Trust-DB\" wird überprüft\n" # translated by wk -#: g10/trustdb.c:2229 #, c-format msgid "%d keys processed (%d validity counts cleared)\n" msgstr "%d Schlüssel verarbeitet (%d Validity Zähler gelöscht)\n" -#: g10/trustdb.c:2294 msgid "no ultimately trusted keys found\n" msgstr "keine uneingeschränkt vertrauenswürdigen Schlüssel gefunden\n" -#: g10/trustdb.c:2308 #, c-format msgid "public key of ultimately trusted key %s not found\n" msgstr "" "öff. Schlüssel des uneingeschränkt vertrautem Schlüssel %s nicht gefunden\n" -#: g10/trustdb.c:2331 #, c-format msgid "%d marginal(s) needed, %d complete(s) needed, %s trust model\n" msgstr "%d marginal-needed, %d complete-needed, %s Vertrauensmodell\n" -#: g10/trustdb.c:2417 #, c-format msgid "" "depth: %d valid: %3d signed: %3d trust: %d-, %dq, %dn, %dm, %df, %du\n" @@ -6579,14 +5201,12 @@ msgstr "" "Tiefe: %d gültig: %3d signiert: %3d Vertrauen: %d-, %dq, %dn, %dm, %df, %" "du\n" -#: g10/trustdb.c:2492 #, c-format msgid "unable to update trustdb version record: write failed: %s\n" msgstr "" "\"Trust-DB\"-Versions-Satz kann nicht geändert werden: Schreiben " "fehlgeschlagen: %s\n" -#: g10/verify.c:117 msgid "" "the signature could not be verified.\n" "Please remember that the signature file (.sig or .asc)\n" @@ -6596,29 +5216,23 @@ msgstr "" "Denken Sie daran, daß die Datei mit der Signatur (.sig oder .asc)\n" "als erste in der Kommandozeile stehen sollte.\n" -#: g10/verify.c:204 #, c-format msgid "input line %u too long or missing LF\n" msgstr "Eingabezeile %u ist zu lang oder es fehlt ein LF\n" -#: g10/verify.c:253 #, c-format msgid "can't open fd %d: %s\n" msgstr "fd=%d kann nicht geöffnet werden: %s\n" -#: kbx/kbxutil.c:92 msgid "set debugging flags" msgstr "Debug Flags setzen" -#: kbx/kbxutil.c:93 msgid "enable full debugging" msgstr "Alle Debug Flags setzen" -#: kbx/kbxutil.c:117 msgid "Usage: kbxutil [options] [files] (-h for help)" msgstr "Aufruf: kbxutil [Optionen] [Dateien] (-h für Hilfe)" -#: kbx/kbxutil.c:120 msgid "" "Syntax: kbxutil [options] [files]\n" "list, export, import Keybox data\n" @@ -6626,59 +5240,46 @@ msgstr "" "Syntax: kbxutil [Optionen] [Dateien]\n" "Anlisten exportieren und Importieren von KeyBox Dateien\n" -#: scd/app-nks.c:713 scd/app-openpgp.c:2638 #, c-format msgid "RSA modulus missing or not of size %d bits\n" msgstr "Der RSA Modulus fehlt oder ist nicht %d Bits lang\n" -#: scd/app-nks.c:721 scd/app-openpgp.c:2650 #, c-format msgid "RSA public exponent missing or larger than %d bits\n" msgstr "Der öffentliche Exponent fehlt oder ist zu groß (mehr als %d Bit)\n" -#: scd/app-nks.c:801 scd/app-openpgp.c:1540 scd/app-openpgp.c:1559 -#: scd/app-openpgp.c:1720 scd/app-openpgp.c:1737 scd/app-openpgp.c:1985 -#: scd/app-openpgp.c:2030 scd/app-dinsig.c:303 #, c-format msgid "PIN callback returned error: %s\n" msgstr "PIN-Callback meldete Fehler: %s\n" -#: scd/app-nks.c:834 msgid "the NullPIN has not yet been changed\n" msgstr "Die Nullpin wurde noch nicht geändert\n" -#: scd/app-nks.c:1092 msgid "|N|Please enter a new PIN for the standard keys." msgstr "|N|Bitte eine neue PIN für den Standard-Schlüssel eingeben." -#: scd/app-nks.c:1093 msgid "||Please enter the PIN for the standard keys." msgstr "||Bitte die PIN für den Standard-Schlüssel eingeben." -#: scd/app-nks.c:1099 msgid "|NP|Please enter a new PIN Unblocking Code (PUK) for the standard keys." msgstr "" "|NP|Bitte geben Sie einen neuen PIN Entsperrcode (PUK) für den Standard-" "Schlüssel ein." -#: scd/app-nks.c:1101 msgid "|P|Please enter the PIN Unblocking Code (PUK) for the standard keys." msgstr "" "|P|Bitte geben Sie den PIN Entsperrcode (PUK) für den Standard-Schlüssel ein." -#: scd/app-nks.c:1109 msgid "|N|Please enter a new PIN for the key to create qualified signatures." msgstr "" "|N|Bitte geben Sie eine neue PIN für den Schlüssel zur Erstellung " "qualifizierter Signaturen ein." -#: scd/app-nks.c:1111 msgid "||Please enter the PIN for the key to create qualified signatures." msgstr "" "||Bitte geben Sie die PIN für den Schlüssel zur Erstellung qualifizierter " "Signaturen ein." -#: scd/app-nks.c:1119 msgid "" "|NP|Please enter a new PIN Unblocking Code (PUK) for the key to create " "qualified signatures." @@ -6686,7 +5287,6 @@ msgstr "" "|NP|Bitte geben Sie einen neuen PIN Entsperrcode (PUK) für den Schlüssel zur " "Erstellung qualifizierter Signaturen ein." -#: scd/app-nks.c:1121 msgid "" "|P|Please enter the PIN Unblocking Code (PUK) for the key to create " "qualified signatures." @@ -6694,256 +5294,199 @@ msgstr "" "|N|Bitte geben Sie den PIN Entsperrcode (PUK) für den Schlüssel zur " "Erstellung qualifizierter Signaturen ein." -#: scd/app-nks.c:1222 scd/app-openpgp.c:2063 scd/app-dinsig.c:532 #, c-format msgid "error getting new PIN: %s\n" msgstr "Fehler beim Abfragen einer neuen PIN: %s\n" -#: scd/app-openpgp.c:695 #, c-format msgid "failed to store the fingerprint: %s\n" msgstr "Der Fingerabdruck kann nicht gespeichert werden: %s\n" -#: scd/app-openpgp.c:708 #, c-format msgid "failed to store the creation date: %s\n" msgstr "Das Erzeugungsdatum konnte nicht gespeichert werden: %s\n" -#: scd/app-openpgp.c:1147 #, c-format msgid "reading public key failed: %s\n" msgstr "Lesen des öffentlichen Schlüssels fehlgeschlagen: %s\n" -#: scd/app-openpgp.c:1155 scd/app-openpgp.c:2873 msgid "response does not contain the public key data\n" msgstr "Die Antwort enthält keine öffentliche Schlüssel-Daten\n" -#: scd/app-openpgp.c:1163 scd/app-openpgp.c:2881 msgid "response does not contain the RSA modulus\n" msgstr "Die Antwort enthält das RSA-Modulus nicht\n" -#: scd/app-openpgp.c:1172 scd/app-openpgp.c:2891 msgid "response does not contain the RSA public exponent\n" msgstr "Antwort enthält den öffentlichen RSA-Exponenten nicht\n" -#: scd/app-openpgp.c:1492 #, c-format msgid "using default PIN as %s\n" msgstr "Die Standard PIN wird für %s benutzt\n" -#: scd/app-openpgp.c:1499 #, c-format msgid "failed to use default PIN as %s: %s - disabling further default use\n" msgstr "" "Die Standard PIN für %s konnte nicht benutzt werden: %s - Die Standard PIN " "wird nicht weiter benutzt\n" -#: scd/app-openpgp.c:1514 #, c-format msgid "||Please enter the PIN%%0A[sigs done: %lu]" msgstr "||Bitte die PIN eingeben%%0A[Sigs erzeugt: %lu]" -#: scd/app-openpgp.c:1525 scd/app-openpgp.c:1979 msgid "||Please enter the PIN" msgstr "||Bitte die PIN eingeben" -#: scd/app-openpgp.c:1566 scd/app-openpgp.c:1744 scd/app-openpgp.c:1992 #, c-format msgid "PIN for CHV%d is too short; minimum length is %d\n" msgstr "PIN für CHV%d ist zu kurz; die Mindestlänge beträgt %d\n" -#: scd/app-openpgp.c:1579 scd/app-openpgp.c:1618 scd/app-openpgp.c:1756 -#: scd/app-openpgp.c:3191 #, c-format msgid "verify CHV%d failed: %s\n" msgstr "Prüfung des CHV%d fehlgeschlagen: %s\n" -#: scd/app-openpgp.c:1647 scd/app-openpgp.c:2011 scd/app-openpgp.c:3487 msgid "error retrieving CHV status from card\n" msgstr "Fehler beim Holen des CHV-Status' von der Karte\n" -#: scd/app-openpgp.c:1653 scd/app-openpgp.c:3496 msgid "card is permanently locked!\n" msgstr "Karte ist dauerhaft gesperrt!\n" -#: scd/app-openpgp.c:1660 #, c-format msgid "%d Admin PIN attempts remaining before card is permanently locked\n" msgstr "Noch %d Admin-PIN-Versuche, bis die Karte dauerhaft gesperrt ist\n" #. TRANSLATORS: Do not translate the "|A|" prefix but keep it at #. the start of the string. Use %%0A to force a linefeed. -#: scd/app-openpgp.c:1667 #, c-format msgid "|A|Please enter the Admin PIN%%0A[remaining attempts: %d]" msgstr "|A|Bitte die Admin-PIN eingeben.%%0A[Verbliebene Versuche: %d]" -#: scd/app-openpgp.c:1671 msgid "|A|Please enter the Admin PIN" msgstr "|A|Bitte die Admin-PIN eingeben." -#: scd/app-openpgp.c:1692 msgid "access to admin commands is not configured\n" msgstr "Zugriff auf Admin-Befehle ist nicht eingerichtet\n" -#: scd/app-openpgp.c:2026 msgid "||Please enter the Reset Code for the card" msgstr "Bitte geben Sie den Rückstellcode für diese Karte ein" -#: scd/app-openpgp.c:2036 scd/app-openpgp.c:2088 #, c-format msgid "Reset Code is too short; minimum length is %d\n" msgstr "Der Rückstellcode ist zu kurz; die Mindestlänge beträgt %d\n" -#: scd/app-openpgp.c:2058 msgid "|RN|New Reset Code" msgstr "|RN|Neuer Rückstellcode" -#: scd/app-openpgp.c:2059 msgid "|AN|New Admin PIN" msgstr "|AN|Neue Admin-PIN" -#: scd/app-openpgp.c:2059 msgid "|N|New PIN" msgstr "|N|Neue PIN" -#: scd/app-openpgp.c:2169 scd/app-openpgp.c:2959 msgid "error reading application data\n" msgstr "Fehler beim Lesen der Anwendungsdaten\n" -#: scd/app-openpgp.c:2175 scd/app-openpgp.c:2966 msgid "error reading fingerprint DO\n" msgstr "Fehler beim Lesen des Fingerabdrucks DO\n" -#: scd/app-openpgp.c:2185 msgid "key already exists\n" msgstr "Schlüssel existiert bereits\n" -#: scd/app-openpgp.c:2189 msgid "existing key will be replaced\n" msgstr "Existierender Schlüssel wird ersetzt werden\n" -#: scd/app-openpgp.c:2191 msgid "generating new key\n" msgstr "neue Schlüssel werden erzeugt\n" -#: scd/app-openpgp.c:2193 msgid "writing new key\n" msgstr "der neue Schlüssel wird geschrieben\n" -#: scd/app-openpgp.c:2618 msgid "creation timestamp missing\n" msgstr "Erzeugungsdatum fehlt\n" -#: scd/app-openpgp.c:2660 scd/app-openpgp.c:2668 #, c-format msgid "RSA prime %s missing or not of size %d bits\n" msgstr "Die RSA Primzahl %s fehlt oder ist nicht %d Bits lang\n" -#: scd/app-openpgp.c:2764 #, c-format msgid "failed to store the key: %s\n" msgstr "Speichern des Schlüssels fehlgeschlagen: %s\n" -#: scd/app-openpgp.c:2850 msgid "please wait while key is being generated ...\n" msgstr "Bitte warten, der Schlüssel wird erzeugt ...\n" -#: scd/app-openpgp.c:2863 msgid "generating key failed\n" msgstr "Schlüsselerzeugung fehlgeschlagen\n" -#: scd/app-openpgp.c:2866 #, c-format msgid "key generation completed (%d seconds)\n" msgstr "Schlüsselerzeugung abgeschlossen (%d Sekunden)\n" -#: scd/app-openpgp.c:2924 msgid "invalid structure of OpenPGP card (DO 0x93)\n" msgstr "Ungültige Struktur der OpenPGP-Karte (DO 0x93)\n" -#: scd/app-openpgp.c:2974 msgid "fingerprint on card does not match requested one\n" msgstr "Der Fingerabdruck auf der Karte entspricht nicht dem angeforderten.\n" -#: scd/app-openpgp.c:3090 #, c-format msgid "card does not support digest algorithm %s\n" msgstr "Die Hashmethode %s wird von der Karte nicht unterstützt\n" -#: scd/app-openpgp.c:3166 #, c-format msgid "signatures created so far: %lu\n" msgstr "Anzahl bereits erzeugter Signaturen: %lu\n" -#: scd/app-openpgp.c:3501 msgid "" "verification of Admin PIN is currently prohibited through this command\n" msgstr "" "Die Überprüfung der Admin PIN ist momentan durch einen Befehl verboten " "worden\n" -#: scd/app-openpgp.c:3726 scd/app-openpgp.c:3737 #, c-format msgid "can't access %s - invalid OpenPGP card?\n" msgstr "Kann auf %s nicht zugreifen - ungültige OpenPGP-Karte?\n" -#: scd/app-dinsig.c:299 msgid "||Please enter your PIN at the reader's keypad" msgstr "||Bitte die PIN auf der Tastatur des Kartenlesers eingeben" #. TRANSLATORS: Do not translate the "|*|" prefixes but #. keep it at the start of the string. We need this elsewhere #. to get some infos on the string. -#: scd/app-dinsig.c:529 msgid "|N|Initial New PIN" msgstr "|N|Erstmalige neue PIN" -#: scd/scdaemon.c:108 msgid "run in multi server mode (foreground)" msgstr "Im Multiserver Modus ausführen" -#: scd/scdaemon.c:118 sm/gpgsm.c:316 dirmngr/dirmngr.c:155 msgid "|LEVEL|set the debugging level to LEVEL" msgstr "|NAME|Die Debugstufe auf NAME setzen" -#: scd/scdaemon.c:125 tools/gpgconf-comp.c:632 msgid "|FILE|write a log to FILE" msgstr "|DATEI|Schreibe Logs auf DATEI" -#: scd/scdaemon.c:127 msgid "|N|connect to reader at port N" msgstr "|N|Verbinde mit dem Leser auf Port N" -#: scd/scdaemon.c:129 msgid "|NAME|use NAME as ct-API driver" msgstr "|NAME|Benutze NAME als CT-API Treiber" -#: scd/scdaemon.c:131 msgid "|NAME|use NAME as PC/SC driver" msgstr "|NAME|Benutze NAME als PC/SC Treiber" -#: scd/scdaemon.c:134 msgid "do not use the internal CCID driver" msgstr "Den internen CCID Treiber nicht benutzen" -#: scd/scdaemon.c:140 msgid "|N|disconnect the card after N seconds of inactivity" msgstr "|N|Schalte die Karte nach N Sekunden Inaktivität ab" -#: scd/scdaemon.c:142 msgid "do not use a reader's keypad" msgstr "Die Tastatur des Kartenlesers nicht benutzen" -#: scd/scdaemon.c:145 msgid "deny the use of admin card commands" msgstr "Verweigere die Benutzung von \"Admin\"-Befehlen" -#: scd/scdaemon.c:260 msgid "Usage: scdaemon [options] (-h for help)" msgstr "Aufruf: scdaemon [Optionen] (-h für Hilfe)" -#: scd/scdaemon.c:262 msgid "" "Syntax: scdaemon [options] [command [args]]\n" "Smartcard daemon for GnuPG\n" @@ -6951,304 +5494,236 @@ msgstr "" "Syntax: scdaemon [Optionen] [Befehl [Argumente]]\n" "Smartcard Daemon für GnuPG\n" -#: scd/scdaemon.c:769 msgid "please use the option `--daemon' to run the program in the background\n" msgstr "" "Bitte die Option `--daemon' nutzen, um das Programm im Hintergund " "auszuführen\n" -#: scd/scdaemon.c:1137 dirmngr/dirmngr.c:1718 #, c-format msgid "handler for fd %d started\n" msgstr "Handhabungsroutine für fd %d gestartet\n" -#: scd/scdaemon.c:1149 dirmngr/dirmngr.c:1723 #, c-format msgid "handler for fd %d terminated\n" msgstr "Handhabungsroutine für den fd %d beendet\n" -#: sm/base64.c:327 #, c-format msgid "invalid radix64 character %02x skipped\n" msgstr "Ungültiges Basis-64 Zeichen %02X wurde übersprungen\n" -#: sm/call-agent.c:145 #, c-format msgid "failed to proxy %s inquiry to client\n" msgstr "Die %s \"inquiry\" konnte nicht an den Client weitergeleitet werden\n" -#: sm/certchain.c:196 #, c-format msgid "validation model requested by certificate: %s" msgstr "Durch Zertifikat angefordertes Gültigkeitsmodell: %s" -#: sm/certchain.c:197 sm/certchain.c:1828 msgid "chain" msgstr "Kette" -#: sm/certchain.c:198 sm/certchain.c:1828 msgid "shell" msgstr "Schale" -#: sm/certchain.c:258 dirmngr/validate.c:107 #, c-format msgid "critical certificate extension %s is not supported" msgstr "Die kritische Zertifikaterweiterung %s wird nicht unterstützt" -#: sm/certchain.c:297 dirmngr/validate.c:205 msgid "issuer certificate is not marked as a CA" msgstr "Das Herausgeberzertifikat ist nicht für eine CA gekennzeichnet" -#: sm/certchain.c:335 msgid "critical marked policy without configured policies" msgstr "entscheidende Richtlinie ohne konfigurierte Richtlinien" -#: sm/certchain.c:345 #, c-format msgid "failed to open `%s': %s\n" msgstr "Datei `%s' kann nicht geöffnet werden: %s\n" -#: sm/certchain.c:353 sm/certchain.c:382 dirmngr/validate.c:167 msgid "note: non-critical certificate policy not allowed" msgstr "Notiz: Die unkritische Zertifikatsrichtlinie ist nicht erlaubt" -#: sm/certchain.c:357 sm/certchain.c:386 dirmngr/validate.c:172 msgid "certificate policy not allowed" msgstr "Die Zertifikatsrichtlinie ist nicht erlaubt" -#: sm/certchain.c:498 msgid "looking up issuer at external location\n" msgstr "Der Herausgeber wird von einer externen Stelle gesucht\n" -#: sm/certchain.c:517 #, c-format msgid "number of issuers matching: %d\n" msgstr "Anzahl der übereinstimmenden Herausgeber: %d\n" -#: sm/certchain.c:561 msgid "looking up issuer from the Dirmngr cache\n" msgstr "Der Herausgeber wird im Cache des Dirmngr gesucht\n" -#: sm/certchain.c:585 #, c-format msgid "number of matching certificates: %d\n" msgstr "Anzahl der übereinstimmenden Zertifikate: %d\n" -#: sm/certchain.c:587 #, c-format msgid "dirmngr cache-only key lookup failed: %s\n" msgstr "Schlüsselsuche im Cache des Dirmngr schlug fehl: %s\n" -#: sm/certchain.c:759 sm/certchain.c:1252 sm/certchain.c:1856 sm/decrypt.c:262 -#: sm/encrypt.c:339 sm/sign.c:337 sm/verify.c:114 msgid "failed to allocated keyDB handle\n" msgstr "Ein keyDB Handle konnte nicht bereitgestellt werden\n" -#: sm/certchain.c:925 msgid "certificate has been revoked" msgstr "Das Zertifikat wurde widerrufen" -#: sm/certchain.c:940 msgid "the status of the certificate is unknown" msgstr "Der Status des Zertifikats ist nicht bekannt" -#: sm/certchain.c:947 msgid "please make sure that the \"dirmngr\" is properly installed\n" msgstr "" "Bitte vergewissern Sie sich, daß der \"dirmngr\" richtig installiert ist\n" -#: sm/certchain.c:953 #, c-format msgid "checking the CRL failed: %s" msgstr "Die CRL konnte nicht geprüft werden: %s" -#: sm/certchain.c:982 sm/certchain.c:1050 dirmngr/validate.c:473 #, c-format msgid "certificate with invalid validity: %s" msgstr "Zertifikat mit unzulässiger Gültigkeit: %s" -#: sm/certchain.c:997 sm/certchain.c:1082 dirmngr/validate.c:491 msgid "certificate not yet valid" msgstr "Das Zertifikat ist noch nicht gültig" -#: sm/certchain.c:998 sm/certchain.c:1083 msgid "root certificate not yet valid" msgstr "Das Wurzelzertifikat ist noch nicht gültig" -#: sm/certchain.c:999 sm/certchain.c:1084 msgid "intermediate certificate not yet valid" msgstr "Das Zwischenzertifikat ist noch nicht gültig" -#: sm/certchain.c:1012 dirmngr/validate.c:502 msgid "certificate has expired" msgstr "Das Zertifikat ist abgelaufen" -#: sm/certchain.c:1013 msgid "root certificate has expired" msgstr "Das Wurzelzertifikat ist abgelaufen" -#: sm/certchain.c:1014 msgid "intermediate certificate has expired" msgstr "Das Zwischenzertifikat ist abgelaufen" -#: sm/certchain.c:1056 #, c-format msgid "required certificate attributes missing: %s%s%s" msgstr "Notwendige Zertifikatattribute fehlen: %s%s%s" -#: sm/certchain.c:1065 msgid "certificate with invalid validity" msgstr "Zertifikat mit unzulässiger Gültigkeit" -#: sm/certchain.c:1102 msgid "signature not created during lifetime of certificate" msgstr "Die Signatur wurde nicht in der Gültigkeitszeit des Zertifikat erzeugt" -#: sm/certchain.c:1104 msgid "certificate not created during lifetime of issuer" msgstr "" "Das Zertifikat wurde nicht während der Gültigkeitszeit des Herausgebers " "erzeugt" -#: sm/certchain.c:1105 msgid "intermediate certificate not created during lifetime of issuer" msgstr "" "Das Zwischenzertifikat wurde nicht während der Gültigkeitszeit des " "Herausgebers erzeugt" -#: sm/certchain.c:1109 msgid " ( signature created at " msgstr " ( Signatur erzeugt am " -#: sm/certchain.c:1110 msgid " (certificate created at " msgstr " ( Zertifikat erzeugt am " -#: sm/certchain.c:1113 msgid " (certificate valid from " msgstr " ( Zertifikat gültig von " -#: sm/certchain.c:1114 msgid " ( issuer valid from " msgstr " ( Herausgeber gültig von " -#: sm/certchain.c:1144 dirmngr/validate.c:552 #, c-format msgid "fingerprint=%s\n" msgstr "Fingerprint=%s\n" -#: sm/certchain.c:1153 msgid "root certificate has now been marked as trusted\n" msgstr "Das Wurzelzertifikat wurde nun als vertrauenswürdig markiert\n" -#: sm/certchain.c:1166 msgid "interactive marking as trusted not enabled in gpg-agent\n" msgstr "" "Interaktives vertrauenswürdig-Markieren ist in gpg-agent ausgeschaltet\n" -#: sm/certchain.c:1172 msgid "interactive marking as trusted disabled for this session\n" msgstr "" "Interaktives vertrauenswürdig-Markieren ist in dieser Sitzung ausgeschaltet\n" -#: sm/certchain.c:1229 msgid "WARNING: creation time of signature not known - assuming current time" msgstr "" "WARNUNG: Der Erzeugungszeitpunkt der Signatur ist nicht bekannt - Nehme die " "aktuelle Zeit an" -#: sm/certchain.c:1293 msgid "no issuer found in certificate" msgstr "Im Zertifikat ist kein Herausgeber enthalten" -#: sm/certchain.c:1366 msgid "self-signed certificate has a BAD signature" msgstr "Das eigenbeglaubigte Zertifikat hat eine FALSCHE Signatur" -#: sm/certchain.c:1435 dirmngr/validate.c:550 msgid "root certificate is not marked trusted" msgstr "Das Wurzelzertifikat ist nicht als vertrauenswürdig markiert" -#: sm/certchain.c:1448 #, c-format msgid "checking the trust list failed: %s\n" msgstr "Fehler beim Prüfen der vertrauenswürdigen Zertifikate: %s\n" -#: sm/certchain.c:1477 sm/import.c:176 dirmngr/validate.c:605 msgid "certificate chain too long\n" msgstr "Der Zertifikatkette ist zu lang\n" -#: sm/certchain.c:1489 dirmngr/validate.c:617 msgid "issuer certificate not found" msgstr "Herausgeberzertifikat nicht gefunden" -#: sm/certchain.c:1522 dirmngr/validate.c:643 msgid "certificate has a BAD signature" msgstr "Das Zertifikat hat eine FALSCHE Signatur" -#: sm/certchain.c:1553 dirmngr/validate.c:667 msgid "found another possible matching CA certificate - trying again" msgstr "" "Eine anderes möglicherweise passendes CA-Zertifikat gefunden - versuche " "nochmal" -#: sm/certchain.c:1604 dirmngr/validate.c:692 #, c-format msgid "certificate chain longer than allowed by CA (%d)" msgstr "Die Zertifikatkette ist länger als von der CA erlaubt (%d)" -#: sm/certchain.c:1644 sm/certchain.c:1927 dirmngr/validate.c:722 msgid "certificate is good\n" msgstr "Das Zertifikat ist korrekt\n" -#: sm/certchain.c:1645 msgid "intermediate certificate is good\n" msgstr "Das Zwischenzertifikat ist korrekt\n" -#: sm/certchain.c:1646 msgid "root certificate is good\n" msgstr "Das Wurzelzertifikat ist korrekt\n" -#: sm/certchain.c:1817 msgid "switching to chain model" msgstr "Umgeschaltet auf das Kettenmodell" -#: sm/certchain.c:1826 #, c-format msgid "validation model used: %s" msgstr "Benutztes Gültigkeitsmodell: %s" -#: sm/certcheck.c:107 #, c-format msgid "a %u bit hash is not valid for a %u bit %s key\n" msgstr "" "Ein %u-Bit Hashverfahren ist für einen %u-Bit %s Schlüssel nicht möglich\n" -#: sm/certcheck.c:244 sm/verify.c:202 msgid "(this is the MD2 algorithm)\n" msgstr "(Dies ist der MD2 Algorithmus)\n" -#: sm/certdump.c:60 sm/certdump.c:143 dirmngr/ocsp.c:701 msgid "none" msgstr "keine" -#: sm/certdump.c:564 sm/certdump.c:609 sm/certdump.c:674 sm/certdump.c:732 msgid "[Error - invalid encoding]" msgstr "[Fehler - Ungültige Kodierung]" -#: sm/certdump.c:572 sm/certdump.c:617 msgid "[Error - out of core]" msgstr "[Fehler - Nicht genügend Speicher]" -#: sm/certdump.c:654 sm/certdump.c:710 msgid "[Error - No name]" msgstr "[Fehler - Kein Name]" -#: sm/certdump.c:679 sm/certdump.c:738 msgid "[Error - invalid DN]" msgstr "[Fehler - Ungültiger DN]" -#: sm/certdump.c:948 #, c-format msgid "" "Please enter the passphrase to unlock the secret key for the X.509 " @@ -7264,88 +5739,70 @@ msgstr "" "gültig von %s bis %s\n" "zu entsperren.\n" -#: sm/certlist.c:122 dirmngr/validate.c:1079 msgid "no key usage specified - assuming all usages\n" msgstr "" "Schlüsselverwendungszweck nicht vorhanden - für alle Zwecke akzeptiert\n" -#: sm/certlist.c:132 sm/keylist.c:272 dirmngr/validate.c:1089 #, c-format msgid "error getting key usage information: %s\n" msgstr "Fehler beim Holen der Schlüsselbenutzungsinformationen: %s\n" -#: sm/certlist.c:142 dirmngr/validate.c:1099 msgid "certificate should have not been used for certification\n" msgstr "Das Zertifikat hätte nicht zum Zertifizieren benutzt werden sollen\n" -#: sm/certlist.c:154 dirmngr/validate.c:1111 msgid "certificate should have not been used for OCSP response signing\n" msgstr "" "Das Zertifikat hätte nicht zum Signieren von OCSP Antworten benutzt werden " "sollen\n" -#: sm/certlist.c:165 dirmngr/validate.c:1131 msgid "certificate should have not been used for encryption\n" msgstr "Das Zertifikat hätte nicht zum Verschlüsseln benutzt werden sollen\n" -#: sm/certlist.c:166 dirmngr/validate.c:1133 msgid "certificate should have not been used for signing\n" msgstr "Das Zertifikat hätte nicht zum Signieren benutzt werden sollen\n" -#: sm/certlist.c:167 dirmngr/validate.c:1134 msgid "certificate is not usable for encryption\n" msgstr "Das Zertifikat kann nicht zum Verschlüsseln benutzt werden\n" -#: sm/certlist.c:168 dirmngr/validate.c:1135 msgid "certificate is not usable for signing\n" msgstr "Das Zertifikat kann nicht zum Signieren benutzt werden\n" -#: sm/certreqgen.c:475 #, c-format msgid "line %d: invalid algorithm\n" msgstr "Zeile %d: Ungültiges Verfahren\n" -#: sm/certreqgen.c:489 #, c-format msgid "line %d: invalid key length %u (valid are %d to %d)\n" msgstr "Zeile %d: Ungültige Schlüssellänge %u (gültig Werte: %d bis %d)\n" -#: sm/certreqgen.c:507 #, c-format msgid "line %d: no subject name given\n" msgstr "Zeile %d: Kein Subjekt-Name angegeben\n" -#: sm/certreqgen.c:516 #, c-format msgid "line %d: invalid subject name label `%.*s'\n" msgstr "Zeile %d: ungültiger Subjekt-Name-Label `%.*s'\n" -#: sm/certreqgen.c:519 #, c-format msgid "line %d: invalid subject name `%s' at pos %d\n" msgstr "Zeile %d: ungültige Betreffbezeichnung `%s' in Spalte %d\n" -#: sm/certreqgen.c:536 #, c-format msgid "line %d: not a valid email address\n" msgstr "Zeile %d: Keine gültige E-Mailadresse\n" -#: sm/certreqgen.c:548 #, c-format msgid "line %d: error reading key `%s' from card: %s\n" msgstr "Zeile %d: Fehler beim Lesen des Schlüssels `%s' von der Karte: %s\n" -#: sm/certreqgen.c:560 #, c-format msgid "line %d: error getting key by keygrip `%s': %s\n" msgstr "Zeile %d: Fehler beim Holen des Schlüssels per \"Keygrip\" `%s': %s\n" -#: sm/certreqgen.c:576 #, c-format msgid "line %d: key generation failed: %s <%s>\n" msgstr "Zeile %d: Schlüsselerzeugung schlug fehl: %s <%s>\n" -#: sm/certreqgen.c:808 msgid "" "To complete this certificate request please enter the passphrase for the key " "you just created once more.\n" @@ -7353,76 +5810,60 @@ msgstr "" "Um die Zertifikatsanforderung fertigzustellen, geben Sie nun bitte\n" "noch einmal die Passphrase des soeben erzeugten Schlüssels ein.\n" -#: sm/certreqgen-ui.c:158 #, c-format msgid " (%d) RSA\n" msgstr " (%d) RSA\n" -#: sm/certreqgen-ui.c:159 #, c-format msgid " (%d) Existing key\n" msgstr " (%d) Vorhandener Schlüssel\n" -#: sm/certreqgen-ui.c:160 #, c-format msgid " (%d) Existing key from card\n" msgstr " (%d) Vorhandener Schlüssel auf der Karte\n" -#: sm/certreqgen-ui.c:202 msgid "Enter the keygrip: " msgstr "Geben Sie den \"Keygrip\" ein: " -#: sm/certreqgen-ui.c:210 msgid "Not a valid keygrip (expecting 40 hex digits)\n" msgstr "Kein gültiger \"Keygrip\" (40 Hex-Ziffern werden erwartet)\n" -#: sm/certreqgen-ui.c:212 msgid "No key with this keygrip\n" msgstr "Kein Schlüssel mit diesem \"Keygrip\"\n" -#: sm/certreqgen-ui.c:230 sm/certreqgen-ui.c:239 #, c-format msgid "error reading the card: %s\n" msgstr "Fehler beim Lesen von der Karte: %s\n" -#: sm/certreqgen-ui.c:233 #, c-format msgid "Serial number of the card: %s\n" msgstr "Karten-Seriennummer: %s\n" -#: sm/certreqgen-ui.c:245 msgid "Available keys:\n" msgstr "Vorhandene Schlüssel:\n" -#: sm/certreqgen-ui.c:276 #, c-format msgid "Possible actions for a %s key:\n" msgstr "Mögliche Vorgänge eines %s-Schlüssels:\n" -#: sm/certreqgen-ui.c:277 #, c-format msgid " (%d) sign, encrypt\n" msgstr " (%d) signieren, verschlüsseln\n" -#: sm/certreqgen-ui.c:278 #, c-format msgid " (%d) sign\n" msgstr " (%d) signieren\n" -#: sm/certreqgen-ui.c:279 #, c-format msgid " (%d) encrypt\n" msgstr " (%d) verschlüsseln\n" -#: sm/certreqgen-ui.c:303 msgid "Enter the X.509 subject name: " msgstr "Bitte geben sie den Namen des X.509 Subjekts ein: " -#: sm/certreqgen-ui.c:307 msgid "No subject name given\n" msgstr "Kein Subjekt-Name angegeben\n" -#: sm/certreqgen-ui.c:311 #, c-format msgid "Invalid subject name label `%.*s'\n" msgstr "Ungültiger Subjekt-Name-Label `%.*s'\n" @@ -7432,206 +5873,157 @@ msgstr "Ungültiger Subjekt-Name-Label `%.*s'\n" #. adjust it do the length of your translation. The #. second string is merely passed to atoi so you can #. drop everything after the number. -#: sm/certreqgen-ui.c:320 #, c-format msgid "Invalid subject name `%s'\n" msgstr "Ungültiger Subjekt-Name `%s'\n" -#: sm/certreqgen-ui.c:322 msgid "22 translator: see certreg-ui.c:gpgsm_gencertreq_tty" msgstr "25" -#: sm/certreqgen-ui.c:334 msgid "Enter email addresses" msgstr "Email-Adresse eingeben" -#: sm/certreqgen-ui.c:335 msgid " (end with an empty line):\n" msgstr " (Beenden mit einer leeren Zeile):\n" -#: sm/certreqgen-ui.c:339 msgid "Enter DNS names" msgstr "DNS Namen eingeben" -#: sm/certreqgen-ui.c:340 sm/certreqgen-ui.c:345 msgid " (optional; end with an empty line):\n" msgstr " (Optional. Beenden mit einer leeren Zeile):\n" -#: sm/certreqgen-ui.c:344 msgid "Enter URIs" msgstr "Bitte geben Sie die URIs ein" -#: sm/certreqgen-ui.c:371 msgid "Parameters to be used for the certificate request:\n" msgstr "Parameter die für die Zertifikatsanforderung benutzt werden sollen:\n" -#: sm/certreqgen-ui.c:389 msgid "Now creating certificate request. This may take a while ...\n" msgstr "" "Die Zertifikatsanforderung wird erzeugt. Dies kann einen Moment dauern ...\n" -#: sm/certreqgen-ui.c:398 msgid "Ready. You should now send this request to your CA.\n" msgstr "Fertig. Sie sollten nun diese Anforderung an die CA senden.\n" -#: sm/certreqgen-ui.c:403 msgid "resource problem: out of core\n" msgstr "Resourcenproblem: Nicht genügend Hauptspeicher\n" -#: sm/decrypt.c:330 msgid "(this is the RC2 algorithm)\n" msgstr "(Dies ist der RC-2 Algorithmus)\n" -#: sm/decrypt.c:332 msgid "(this does not seem to be an encrypted message)\n" msgstr "(dies ist wahrscheinlich keine verschlüsselte Nachricht)\n" -#: sm/delete.c:51 sm/delete.c:112 #, c-format msgid "certificate `%s' not found: %s\n" msgstr "Zertifikat `%s' nicht gefunden: %s\n" -#: sm/delete.c:122 sm/keydb.c:1121 sm/keydb.c:1223 #, c-format msgid "error locking keybox: %s\n" msgstr "Fehler beim Sperren der Keybox: %s\n" -#: sm/delete.c:143 #, c-format msgid "duplicated certificate `%s' deleted\n" msgstr "Doppeltes Zertifikat `%s' gelöscht\n" -#: sm/delete.c:145 #, c-format msgid "certificate `%s' deleted\n" msgstr "Zertifikat `%s' gelöscht\n" -#: sm/delete.c:175 #, c-format msgid "deleting certificate \"%s\" failed: %s\n" msgstr "Fehler beim Löschen des Zertifikats \"%s\": %s\n" -#: sm/encrypt.c:325 msgid "no valid recipients given\n" msgstr "Keine gültigen Empfänger angegeben\n" -#: sm/gpgsm.c:198 msgid "list external keys" msgstr "Externe Schlüssel anzeigen" -#: sm/gpgsm.c:200 msgid "list certificate chain" msgstr "Schlüssel mit Zertifikatekette anzeigen" -#: sm/gpgsm.c:207 msgid "import certificates" msgstr "Zertifikate importieren" -#: sm/gpgsm.c:208 msgid "export certificates" msgstr "Zertifikate exportieren" -#: sm/gpgsm.c:210 msgid "register a smartcard" msgstr "Smartcard registrieren" -#: sm/gpgsm.c:213 msgid "pass a command to the dirmngr" msgstr "Das Kommando an den Dirmngr durchreichen" -#: sm/gpgsm.c:215 msgid "invoke gpg-protect-tool" msgstr "Rufe das gpg-protect-tool auf" -#: sm/gpgsm.c:231 msgid "create base-64 encoded output" msgstr "Ausgabe im Basis-64 Format erzeugen" -#: sm/gpgsm.c:236 msgid "assume input is in PEM format" msgstr "Eingabedaten sind im PEM Format" -#: sm/gpgsm.c:238 msgid "assume input is in base-64 format" msgstr "Eingabedaten sind im Basis-64 Format" -#: sm/gpgsm.c:240 msgid "assume input is in binary format" msgstr "Eingabedaten sind im Binärformat" -#: sm/gpgsm.c:247 msgid "never consult a CRL" msgstr "Niemals eine CRL konsultieren" -#: sm/gpgsm.c:257 msgid "check validity using OCSP" msgstr "Die Gültigkeit mittels OCSP prüfen" -#: sm/gpgsm.c:262 msgid "|N|number of certificates to include" msgstr "|N|Sende N Zertifikate mit" -#: sm/gpgsm.c:265 msgid "|FILE|take policy information from FILE" msgstr "|DATEI|Richtlinieninformationen DATEI entnehmen" -#: sm/gpgsm.c:268 msgid "do not check certificate policies" msgstr "Zertifikatsrichtlinien nicht überprüfen" -#: sm/gpgsm.c:272 msgid "fetch missing issuer certificates" msgstr "Fehlende Zertifikate automatisch holen" -#: sm/gpgsm.c:283 msgid "don't use the terminal at all" msgstr "das Terminal gar nicht benutzen" -#: sm/gpgsm.c:285 msgid "|FILE|write a server mode log to FILE" msgstr "|DATEI|Schreibe im Servermodus Logs auf DATEI" -#: sm/gpgsm.c:290 msgid "|FILE|write an audit log to FILE" msgstr "|DATEI|Schreibe ein Audit-Log auf DATEI" -#: sm/gpgsm.c:293 msgid "batch mode: never ask" msgstr "Stapelmodus: Keine Abfragen" -#: sm/gpgsm.c:294 msgid "assume yes on most questions" msgstr "\"Ja\" als Standardantwort annehmen" -#: sm/gpgsm.c:295 msgid "assume no on most questions" msgstr "\"Nein\" als Standardantwort annehmen" -#: sm/gpgsm.c:298 msgid "|FILE|add keyring to the list of keyrings" msgstr "|DATEI|DATEI als öffentlichen Schlüsselbund mitbenutzen" -#: sm/gpgsm.c:301 msgid "|USER-ID|use USER-ID as default secret key" msgstr "|USER-ID|USER-ID als voreingestellten Schlüssel benutzen" -#: sm/gpgsm.c:311 tools/gpgconf-comp.c:770 msgid "|SPEC|use this keyserver to lookup keys" msgstr "|SPEC|Schlüssel bei diesem Server nachschlagen" -#: sm/gpgsm.c:329 msgid "|NAME|use cipher algorithm NAME" msgstr "|NAME|Verschlüsselungsverfahren NAME benutzen" -#: sm/gpgsm.c:331 msgid "|NAME|use message digest algorithm NAME" msgstr "|NAME|Hashverfahren NAME benutzen" -#: sm/gpgsm.c:532 msgid "Usage: gpgsm [options] [files] (-h for help)" msgstr "Aufruf: gpgsm [Optionen] [Dateien] (-h für Hilfe)" -#: sm/gpgsm.c:535 msgid "" "Syntax: gpgsm [options] [files]\n" "sign, check, encrypt or decrypt using the S/MIME protocol\n" @@ -7640,149 +6032,118 @@ msgstr "" "Syntax: gpgsm [Optionen] [Dateien]\n" "Signieren, prüfen, ver- und entschlüsseln mittels S/MIME Protokoll\n" -#: sm/gpgsm.c:627 msgid "usage: gpgsm [options] " msgstr "Aufruf: gpgsm [Optionen] " -#: sm/gpgsm.c:749 #, c-format msgid "NOTE: won't be able to encrypt to `%s': %s\n" msgstr "Hinweis: Verschlüsselung für `%s' wird nicht möglich sein: %s\n" -#: sm/gpgsm.c:760 #, c-format msgid "unknown validation model `%s'\n" msgstr "Unbekanntes Gültigkeitsmodell '%s'\n" -#: sm/gpgsm.c:811 dirmngr/ldapserver.c:86 #, c-format msgid "%s:%u: no hostname given\n" msgstr "%s:%u: Kein Server-Name angegeben\n" -#: sm/gpgsm.c:830 dirmngr/ldapserver.c:105 #, c-format msgid "%s:%u: password given without user\n" msgstr "%s:%u: Passwort ohne Benutzer\n" -#: sm/gpgsm.c:851 dirmngr/ldapserver.c:126 #, c-format msgid "%s:%u: skipping this line\n" msgstr "%s:%u: Zeile wird übersprungen\n" -#: sm/gpgsm.c:1389 msgid "could not parse keyserver\n" msgstr "Schlüsselserver-URL konnte nicht analysiert werden\n" -#: sm/gpgsm.c:1569 #, c-format msgid "importing common certificates `%s'\n" msgstr "Importiere allgemeine Zertifikate: %s\n" -#: sm/gpgsm.c:1610 #, c-format msgid "can't sign using `%s': %s\n" msgstr "Signieren mit `%s' nicht möglich: %s\n" -#: sm/gpgsm.c:1941 msgid "invalid command (there is no implicit command)\n" msgstr "Ungültiger Befehl (Es gibt keinen implizierten Befehl)\n" -#: sm/import.c:127 #, c-format msgid "total number processed: %lu\n" msgstr "gesamte verarbeitete Anzahl: %lu\n" -#: sm/import.c:246 msgid "error storing certificate\n" msgstr "Fehler beim Speichern des Zertifikats\n" -#: sm/import.c:254 msgid "basic certificate checks failed - not imported\n" msgstr "Grundlegende Zertifikatprüfungen fehlgeschlagen - nicht importiert\n" -#: sm/import.c:410 sm/keydb.c:1043 sm/keydb.c:1111 msgid "failed to allocate keyDB handle\n" msgstr "Kann keinen KeyDB Handler bereitstellen\n" -#: sm/import.c:467 sm/keydb.c:1141 sm/keydb.c:1235 #, c-format msgid "error getting stored flags: %s\n" msgstr "Fehler beim Holen der gespeicherten Flags: %s\n" -#: sm/import.c:526 sm/import.c:558 #, c-format msgid "error importing certificate: %s\n" msgstr "Fehler beim Importieren des Zertifikats: %s\n" -#: sm/import.c:746 tools/gpg-connect-agent.c:1404 #, c-format msgid "error reading input: %s\n" msgstr "Fehler beim Lesen der Eingabe: %s\n" -#: sm/keydb.c:188 #, c-format msgid "error creating keybox `%s': %s\n" msgstr "Die \"Keybox\" `%s' konnte nicht erstellt werden: %s\n" -#: sm/keydb.c:191 msgid "you may want to start the gpg-agent first\n" msgstr "Sie sollten zuerst den gpg-agent starten\n" -#: sm/keydb.c:196 #, c-format msgid "keybox `%s' created\n" msgstr "Die \"Keybox\" `%s' wurde erstellt\n" -#: sm/keydb.c:1036 sm/keydb.c:1104 msgid "failed to get the fingerprint\n" msgstr "Kann den Fingerprint nicht ermitteln\n" -#: sm/keydb.c:1064 #, c-format msgid "problem looking for existing certificate: %s\n" msgstr "Problem bei der Suche nach vorhandenem Zertifikat: %s\n" -#: sm/keydb.c:1072 #, c-format msgid "error finding writable keyDB: %s\n" msgstr "Fehler bei der Suche nach einer schreibbaren KeyDB: %s\n" -#: sm/keydb.c:1080 #, c-format msgid "error storing certificate: %s\n" msgstr "Fehler beim Speichern des Zertifikats: %s\n" -#: sm/keydb.c:1132 #, c-format msgid "problem re-searching certificate: %s\n" msgstr "Problem bei Wiederfinden des Zertifikats: %s\n" -#: sm/keydb.c:1153 sm/keydb.c:1246 #, c-format msgid "error storing flags: %s\n" msgstr "Fehler beim Speichern der Flags: %s\n" -#: sm/keylist.c:642 msgid "Error - " msgstr "Fehler - " -#: sm/misc.c:55 msgid "GPG_TTY has not been set - using maybe bogus default\n" msgstr "" "GPG_TTY wurde nicht gesetzt - ein (möglicherweise falscher) Standardwert " "wird deshalb verwendet\n" -#: sm/qualified.c:105 #, c-format msgid "invalid formatted fingerprint in `%s', line %d\n" msgstr "Der Fingerabdruck in `%s', Zeile %d is fehlerhaft formatiert\n" -#: sm/qualified.c:123 #, c-format msgid "invalid country code in `%s', line %d\n" msgstr "Ungültiger Landescode in `%s', Zeile %d\n" -#: sm/qualified.c:206 #, c-format msgid "" "You are about to create a signature using your certificate:\n" @@ -7799,7 +6160,6 @@ msgstr "" "\n" "%s%sSind Sie wirklich sicher, daß Sie dies möchten?" -#: sm/qualified.c:215 sm/verify.c:617 msgid "" "Note, that this software is not officially approved to create or verify such " "signatures.\n" @@ -7807,7 +6167,6 @@ msgstr "" "Bitte beachten Sie, daß diese Software nicht offiziell zur Erzeugung\n" "oder Prüfung von qualifizierten Signaturen zugelassen ist.\n" -#: sm/qualified.c:282 #, c-format msgid "" "You are about to create a signature using your certificate:\n" @@ -7819,394 +6178,316 @@ msgstr "" "zu erzeugen. Bitte beachten Sie, daß dies KEINE qualifizierte\n" "Signatur erzeugen wird." -#: sm/sign.c:451 #, c-format msgid "hash algorithm %d (%s) for signer %d not supported; using %s\n" msgstr "" "Hashverfahren %d (%s) wird für Unterzeichner %d nicht unterstützt; %s wird " "benutzt\n" -#: sm/sign.c:465 #, c-format msgid "hash algorithm used for signer %d: %s (%s)\n" msgstr "Benutztes Hashverfahren für Unterzeichner %d: %s (%s)\n" -#: sm/sign.c:517 #, c-format msgid "checking for qualified certificate failed: %s\n" msgstr "Prüfung auf ein qualifiziertes Zertifikats fehlgeschlagen: %s\n" -#: sm/verify.c:450 msgid "Signature made " msgstr "Signatur erzeugt am " -#: sm/verify.c:454 msgid "[date not given]" msgstr "[Datum nicht vorhanden]" -#: sm/verify.c:455 #, c-format msgid " using certificate ID 0x%08lX\n" msgstr " mittels Zertifikat ID 0x%08lX\n" -#: sm/verify.c:474 msgid "" "invalid signature: message digest attribute does not match computed one\n" msgstr "" "Ungültige Signatur: Nachricht entspricht nicht dem Prüfwert in der " "Nachricht.\n" -#: sm/verify.c:595 msgid "Good signature from" msgstr "Korrekte Signatur von" -#: sm/verify.c:596 msgid " aka" msgstr " alias" -#: sm/verify.c:614 msgid "This is a qualified signature\n" msgstr "Dies ist eine qualifizierte Signatur.\n" -#: dirmngr/certcache.c:103 #, c-format msgid "can't initialize certificate cache lock: %s\n" msgstr "" "Sperre für den Zertifikatzwischenspeicher kann nicht initialisiert werden: %" "s\n" -#: dirmngr/certcache.c:111 #, c-format msgid "can't acquire read lock on the certificate cache: %s\n" msgstr "" "Lesesperre für den Zertifikatzwischenspeicher kann nicht gesetzt werden: %s\n" -#: dirmngr/certcache.c:119 #, c-format msgid "can't acquire write lock on the certificate cache: %s\n" msgstr "" "Schreibsperre für den Zertifikatzwischenspeicher kann nicht gesetzt werden: %" "s\n" -#: dirmngr/certcache.c:127 #, c-format msgid "can't release lock on the certificate cache: %s\n" msgstr "" "Sperre für den Zertifikatzwischenspeicher kann nicht freigegeben werden: %s\n" -#: dirmngr/certcache.c:255 #, c-format msgid "dropping %u certificates from the cache\n" msgstr "%u Zertifikate werden aus dem Zertifikatzwischenspeicher entfernt\n" -#: dirmngr/certcache.c:340 #, c-format msgid "can't access directory `%s': %s\n" msgstr "Fehler beim Zugriff auf das Verzeichnis `%s': %s\n" -#: dirmngr/certcache.c:378 #, c-format msgid "can't parse certificate `%s': %s\n" msgstr "Zertifikat `%s' kann nicht zerlegt werden: %s\n" -#: dirmngr/certcache.c:386 #, c-format msgid "certificate `%s' already cached\n" msgstr "Zertifikat `%s' ist bereits im Zwischenspeicher\n" -#: dirmngr/certcache.c:390 #, c-format msgid "trusted certificate `%s' loaded\n" msgstr "Vertrauenswürdiges Zertifikat `%s' wurde geladen\n" -#: dirmngr/certcache.c:392 #, c-format msgid "certificate `%s' loaded\n" msgstr "Zertifikat `%s' wurde geladen\n" -#: dirmngr/certcache.c:396 #, c-format msgid " SHA1 fingerprint = %s\n" msgstr " SHA1 Fingerabdruck=%s\n" -#: dirmngr/certcache.c:399 msgid " issuer =" msgstr " Issuer =" -#: dirmngr/certcache.c:400 msgid " subject =" msgstr " Subjekt =" -#: dirmngr/certcache.c:404 #, c-format msgid "error loading certificate `%s': %s\n" msgstr "Fehler beim Laden des Zertifikats `%s': %s\n" -#: dirmngr/certcache.c:480 #, c-format msgid "permanently loaded certificates: %u\n" msgstr " dauerhaft geladene Zertifikate: %u\n" -#: dirmngr/certcache.c:482 #, c-format msgid " runtime cached certificates: %u\n" msgstr "zur Laufzeit zwischengespeicherte Zertifikate: %u\n" -#: dirmngr/certcache.c:497 dirmngr/dirmngr-client.c:368 msgid "certificate already cached\n" msgstr "Zertifikat ist bereits im Zwischenspeicher\n" -#: dirmngr/certcache.c:499 msgid "certificate cached\n" msgstr "Zertifikat wurde zwischengespeichert\n" -#: dirmngr/certcache.c:501 dirmngr/certcache.c:521 -#: dirmngr/dirmngr-client.c:372 #, c-format msgid "error caching certificate: %s\n" msgstr "Fehler beim Zwischenspeichern des Zertifikats: %s\n" -#: dirmngr/certcache.c:584 #, c-format msgid "invalid SHA1 fingerprint string `%s'\n" msgstr "ungültiger SHA1 Fingerabdruck `%s'\n" -#: dirmngr/certcache.c:1028 dirmngr/certcache.c:1037 #, c-format msgid "error fetching certificate by S/N: %s\n" msgstr "Fehler beim Holen des Zertifikats mittels Seriennummer: %s\n" -#: dirmngr/certcache.c:1191 dirmngr/certcache.c:1200 #, c-format msgid "error fetching certificate by subject: %s\n" msgstr "Fehler beim Holen des Zertifikats mittels Subject: %s\n" -#: dirmngr/certcache.c:1304 dirmngr/validate.c:459 msgid "no issuer found in certificate\n" msgstr "Im Zertifikat ist kein Herausgeber enthalten\n" -#: dirmngr/certcache.c:1314 #, c-format msgid "error getting authorityKeyIdentifier: %s\n" msgstr "Fehler beim Holen des \"authorityKeyIdentifier\": %s\n" -#: dirmngr/crlcache.c:214 #, c-format msgid "creating directory `%s'\n" msgstr "Das Verzeichnis `%s' wird erzeugt\n" -#: dirmngr/crlcache.c:218 #, c-format msgid "error creating directory `%s': %s\n" msgstr "Fehler beim Erzeugen des Verzeichnis '%s': %s\n" -#: dirmngr/crlcache.c:246 #, c-format msgid "ignoring database dir `%s'\n" msgstr "Das DB-Verzeichnis `%s' wird ignoriert\n" -#: dirmngr/crlcache.c:255 #, c-format msgid "error reading directory `%s': %s\n" msgstr "Fehler beim Lesen des Verzeichnis `%s': %s\n" -#: dirmngr/crlcache.c:276 #, c-format msgid "removing cache file `%s'\n" msgstr "Die Zwischenspeicherdatei `%s' wird entfernt\n" -#: dirmngr/crlcache.c:285 #, c-format msgid "not removing file `%s'\n" msgstr "Die Datei `%s' wird nicht gelöscht\n" -#: dirmngr/crlcache.c:374 dirmngr/crlcache.c:1112 dirmngr/crlcache.c:2197 #, c-format msgid "error closing cache file: %s\n" msgstr "Fehler beim Schließen der Zwischenspeicherdatei: %s\n" -#: dirmngr/crlcache.c:412 dirmngr/crlcache.c:788 #, c-format msgid "failed to open cache dir file `%s': %s\n" msgstr "" "Die Zwischenspeicherverzeichnisdatei `%s' konnte nicht geöffnet werden: %s\n" -#: dirmngr/crlcache.c:422 #, c-format msgid "error creating new cache dir file `%s': %s\n" msgstr "" "Fehler beim Erzeugen der neuen Zwischenspeicherverzeichnisdatei `%s': %s\n" -#: dirmngr/crlcache.c:429 #, c-format msgid "error writing new cache dir file `%s': %s\n" msgstr "" "Fehler beim Schreiben der neuen Zwischenspeicherverzeichnisdatei `%s': %s\n" -#: dirmngr/crlcache.c:436 #, c-format msgid "error closing new cache dir file `%s': %s\n" msgstr "" "Fehler beim Schließen der neuen Zwischenspeicherverzeichnisdatei `%s': %s\n" -#: dirmngr/crlcache.c:441 #, c-format msgid "new cache dir file `%s' created\n" msgstr "Neue Zwischenspeicherverzeichnisdatei `%s' wurde erzeugt\n" -#: dirmngr/crlcache.c:446 #, c-format msgid "failed to re-open cache dir file `%s': %s\n" msgstr "" "Fehler beim Wiederöffnen der Zwischenspeicherverzeichnisdatei `%s': %s\n" -#: dirmngr/crlcache.c:474 #, c-format msgid "first record of `%s' is not the version\n" msgstr "Der erste Datensatz von `%s' enthält nicht die Version\n" -#: dirmngr/crlcache.c:487 msgid "old version of cache directory - cleaning up\n" msgstr "Alte Version des Zwischenspeicherverzeichnisses - räume auf\n" -#: dirmngr/crlcache.c:503 msgid "old version of cache directory - giving up\n" msgstr "Alte Version des Zwischenspeicherverzeichnisses - gebe auf\n" -#: dirmngr/crlcache.c:608 #, c-format msgid "extra field detected in crl record of `%s' line %u\n" msgstr "Weiteres Feld im CRL Datensatz von `%s', Zeile %u festgestellt\n" -#: dirmngr/crlcache.c:616 #, c-format msgid "invalid line detected in `%s' line %u\n" msgstr "Ungültige Zeile in `%s', Zeile %u\n" -#: dirmngr/crlcache.c:625 #, c-format msgid "duplicate entry detected in `%s' line %u\n" msgstr "Doppelter Eintrag in `%s', Zeile %u festgestellt\n" -#: dirmngr/crlcache.c:640 #, c-format msgid "unsupported record type in `%s' line %u skipped\n" msgstr "Nicht unterstützter Datensatztyp in `%s', Zeile %u übergangen\n" -#: dirmngr/crlcache.c:666 #, c-format msgid "invalid issuer hash in `%s' line %u\n" msgstr "Ungültiger Issuer Hashwert in `%s', Zeile %u\n" -#: dirmngr/crlcache.c:672 #, c-format msgid "no issuer DN in `%s' line %u\n" msgstr "Kein Issuer DN in `%s', Zeile %u\n" -#: dirmngr/crlcache.c:679 #, c-format msgid "invalid timestamp in `%s' line %u\n" msgstr "Ungültiger Zeitstempel in `%s', Zeile %u\n" -#: dirmngr/crlcache.c:685 #, c-format msgid "WARNING: invalid cache file hash in `%s' line %u\n" msgstr "WARNUNG: Ungültiger Zwischenspeicherdatei Hashwert in `%s', Zeile %u\n" -#: dirmngr/crlcache.c:691 msgid "detected errors in cache dir file\n" msgstr "Id der Zwischenspeicherverzeichnisdatei wurden Fehler erkannt\n" -#: dirmngr/crlcache.c:692 msgid "please check the reason and manually delete that file\n" msgstr "" "Bitte ermitteln sie die Ursache und löschen sie die Datei dann manuell\n" -#: dirmngr/crlcache.c:820 dirmngr/crlcache.c:834 #, c-format msgid "failed to create temporary cache dir file `%s': %s\n" msgstr "" "Die temporäre Zwischenspeicherverzeichnisdatei `%s' konnte nicht erzeugt " "werden: %s\n" -#: dirmngr/crlcache.c:930 #, c-format msgid "error closing `%s': %s\n" msgstr "Fehler beim Schließen von `%s': %s\n" -#: dirmngr/crlcache.c:942 #, c-format msgid "error renaming `%s' to `%s': %s\n" msgstr "Fehler beim Umbenennen von `%s` nach `%s': %s\n" -#: dirmngr/crlcache.c:996 #, c-format msgid "can't hash `%s': %s\n" msgstr "Hashwert von `%s' kann nicht gebildet werden: %s\n" -#: dirmngr/crlcache.c:1004 #, c-format msgid "error setting up MD5 hash context: %s\n" msgstr "Fehler beim Vorbereiten des MD5 Hashkontext: %s\n" -#: dirmngr/crlcache.c:1020 #, c-format msgid "error hashing `%s': %s\n" msgstr "Fehler beim Hashen von `%s': %s\n" -#: dirmngr/crlcache.c:1048 #, c-format msgid "invalid formatted checksum for `%s'\n" msgstr "Ungültig formatierte Prüfsumme für `%s'\n" -#: dirmngr/crlcache.c:1101 msgid "too many open cache files; can't open anymore\n" msgstr "" "Zu viele geöffnete Zwischenspeicherdateien; weitere kann nicht geöffnet " "werden\n" -#: dirmngr/crlcache.c:1119 #, c-format msgid "opening cache file `%s'\n" msgstr "Die Zwischenspeicherdatei `%s' wird geöffnet\n" -#: dirmngr/crlcache.c:1138 #, c-format msgid "error opening cache file `%s': %s\n" msgstr "Fehler beim Öffnen der Zwischenspeicherdatei `%s': %s\n" -#: dirmngr/crlcache.c:1147 #, c-format msgid "error initializing cache file `%s' for reading: %s\n" msgstr "" "Fehler beim Initialisieren der Zwischenspeicherdatei `%s' zum Lesen: %s\n" -#: dirmngr/crlcache.c:1168 msgid "calling unlock_db_file on a closed file\n" msgstr "unlock_db_file wird für eine geschlossene Datei aufgerufen\n" -#: dirmngr/crlcache.c:1170 msgid "calling unlock_db_file on an unlocked file\n" msgstr "unlock_db_file wird für eine nicht gesperrte Datei aufgerufen\n" -#: dirmngr/crlcache.c:1224 #, c-format msgid "failed to create a new cache object: %s\n" msgstr "Ein neues Zwischenspeicherobjekt konnte nicht erzeugt werden: %s\n" -#: dirmngr/crlcache.c:1279 #, c-format msgid "no CRL available for issuer id %s\n" msgstr "Es ist keine CRL für den Issuer mit der ID %s vorhanden\n" -#: dirmngr/crlcache.c:1286 #, c-format msgid "cached CRL for issuer id %s too old; update required\n" msgstr "" "Die zwischengespeicherte CRL für den Issuer mit der ID %s ist zu alt; ein " "Update wird benötigt\n" -#: dirmngr/crlcache.c:1300 #, c-format msgid "" "force-crl-refresh active and %d minutes passed for issuer id %s; update " @@ -8215,199 +6496,161 @@ msgstr "" "\"force-crl-refresh\" ist aktiviert und %d Minuten für den Issuer mit Id %s " "sind vorbei; Update wird benötigt\n" -#: dirmngr/crlcache.c:1308 #, c-format msgid "force-crl-refresh active for issuer id %s; update required\n" msgstr "" "\"force-crl-refresh\" ist für den Issuer mit der Id %s aktiviert; Update " "wird benötigt\n" -#: dirmngr/crlcache.c:1317 #, c-format msgid "available CRL for issuer ID %s can't be used\n" msgstr "" "Die vorhandene CRL für den Issuer mit der ID %s kann nicht benutzt werden\n" -#: dirmngr/crlcache.c:1328 #, c-format msgid "cached CRL for issuer id %s tampered; we need to update\n" msgstr "" "Die zwischengespeicherte CRL für den Issuer mit der ID %s wurde verändert; " "eine Update wird benötigt\n" -#: dirmngr/crlcache.c:1340 msgid "WARNING: invalid cache record length for S/N " msgstr "WARNUNG: Ungültige Länge des Zwischenspeicherdateisatzes für S/N " -#: dirmngr/crlcache.c:1349 #, c-format msgid "problem reading cache record for S/N %s: %s\n" msgstr "Problem beim Lesen des Zwischenspeicherdatensatzes für S/N %s: %s\n" -#: dirmngr/crlcache.c:1352 #, c-format msgid "S/N %s is not valid; reason=%02X date=%.15s\n" msgstr "S/N %s ist nicht gültig; Grund=%02X Datum=%.15s\n" -#: dirmngr/crlcache.c:1363 #, c-format msgid "S/N %s is valid, it is not listed in the CRL\n" msgstr "S/N %s ist gültig; sie ist nicht in der CRL enthalten\n" -#: dirmngr/crlcache.c:1371 #, c-format msgid "error getting data from cache file: %s\n" msgstr "Fehler beim Holen der Daten aus der Zwischenspeicherdatei: %s\n" -#: dirmngr/crlcache.c:1533 dirmngr/validate.c:882 #, c-format msgid "unknown hash algorithm `%s'\n" msgstr "Ungültige Hashmethode `%s'\n" -#: dirmngr/crlcache.c:1540 #, c-format msgid "gcry_md_open for algorithm %d failed: %s\n" msgstr "gcry_md_open für Methode %d fehlgeschlagen: %s\n" -#: dirmngr/crlcache.c:1577 dirmngr/crlcache.c:1596 msgid "got an invalid S-expression from libksba\n" msgstr "Ungültige S-Expression von Libksba erhalten\n" -#: dirmngr/crlcache.c:1584 dirmngr/crlcache.c:1603 dirmngr/misc.c:168 #, c-format msgid "converting S-expression failed: %s\n" msgstr "Konvertierung der S-Expression fehlgeschlagen: %s\n" -#: dirmngr/crlcache.c:1618 dirmngr/ocsp.c:417 #, c-format msgid "creating S-expression failed: %s\n" msgstr "Erzeugen der S-Expression fehlgeschlagen: %s\n" -#: dirmngr/crlcache.c:1690 #, c-format msgid "ksba_crl_parse failed: %s\n" msgstr "ksba_crl_parse fehlgeschlagen: %s\n" -#: dirmngr/crlcache.c:1704 #, c-format msgid "error getting update times of CRL: %s\n" msgstr "Die \"Update Times\" konnte nicht aus der CRL bestimmt werden: %s\n" -#: dirmngr/crlcache.c:1711 #, c-format msgid "update times of this CRL: this=%s next=%s\n" msgstr "Die \"Update Times\" dieser CRL sind: this=%s next=%s\n" -#: dirmngr/crlcache.c:1715 msgid "nextUpdate not given; assuming a validity period of one day\n" msgstr "\"nextUpdate\" fehlt; wir nehmen eine Gültigkeit von einem Tag an\n" -#: dirmngr/crlcache.c:1735 #, c-format msgid "error getting CRL item: %s\n" msgstr "Fehler beim Holen eines CRL Items: %s\n" -#: dirmngr/crlcache.c:1750 #, c-format msgid "error inserting item into temporary cache file: %s\n" msgstr "" "Fehler beim Einfügen eines Items in die temporäre Zwischenspeicherdatei: %s\n" -#: dirmngr/crlcache.c:1777 #, c-format msgid "no CRL issuer found in CRL: %s\n" msgstr "In der CRL wurde kein CRL Herausgeber gefunden: %s\n" -#: dirmngr/crlcache.c:1792 msgid "locating CRL issuer certificate by authorityKeyIdentifier\n" msgstr "" "CRL Herausgeberzertifikat wird über \"authorityKeyIdentifier\" geholt\n" -#: dirmngr/crlcache.c:1837 #, c-format msgid "CRL signature verification failed: %s\n" msgstr "Signaturprüfung der CRL ist fehlgeschlagen: %s\n" -#: dirmngr/crlcache.c:1848 #, c-format msgid "error checking validity of CRL issuer certificate: %s\n" msgstr "Fehler beim Püfen des CRL Herausgeberzertifikats: %s\n" -#: dirmngr/crlcache.c:1991 #, c-format msgid "ksba_crl_new failed: %s\n" msgstr "ksba_crl_new fehlgeschlagen: %s\n" -#: dirmngr/crlcache.c:1998 #, c-format msgid "ksba_crl_set_reader failed: %s\n" msgstr "ksba_crl_set_reader fehlgeschlagen: %s\n" -#: dirmngr/crlcache.c:2032 #, c-format msgid "removed stale temporary cache file `%s'\n" msgstr "Die alte temporäre Zwischenspeicherdatei `%s' wurde entfernt\n" -#: dirmngr/crlcache.c:2036 #, c-format msgid "problem removing stale temporary cache file `%s': %s\n" msgstr "" "Problem beim Löschen der alten temporären Zwischenspeicherdatei `%s': %s\n" -#: dirmngr/crlcache.c:2046 #, c-format msgid "error creating temporary cache file `%s': %s\n" msgstr "Fehler beim Erzeugen der temporären Zwischenspeicherdatei `%s': %s\n" -#: dirmngr/crlcache.c:2056 #, c-format msgid "crl_parse_insert failed: %s\n" msgstr "crl_parse_insert fehlgeschlagen: %s\n" -#: dirmngr/crlcache.c:2066 #, c-format msgid "error finishing temporary cache file `%s': %s\n" msgstr "" "Fehler beim Fertigstellen der temporären Zwischenspeicherdatei `%s': %s\n" -#: dirmngr/crlcache.c:2073 #, c-format msgid "error closing temporary cache file `%s': %s\n" msgstr "Fehler beim Schließen der temporären Zwischenspeicherdatei `%s': %s\n" -#: dirmngr/crlcache.c:2098 #, c-format msgid "WARNING: new CRL still too old; it expired on %s - loading anyway\n" msgstr "" "WARNUNG: Neue CRL ist immer noch zu alt; sie verfiel am %s - wird trotzdem " "geladen\n" -#: dirmngr/crlcache.c:2102 #, c-format msgid "new CRL still too old; it expired on %s\n" msgstr "Neue CRL ist immer noch zu alt; sie verviel am %s\n" -#: dirmngr/crlcache.c:2118 #, c-format msgid "unknown critical CRL extension %s\n" msgstr "Unbekannte kritische CRL Erweiterung %s\n" -#: dirmngr/crlcache.c:2128 #, c-format msgid "error reading CRL extensions: %s\n" msgstr "Fehler beim Lesen einer CRL Erweiterung: %s\n" -#: dirmngr/crlcache.c:2179 #, c-format msgid "creating cache file `%s'\n" msgstr "Zwischenspeicherdatei `%s' wird erzeugt\n" -#: dirmngr/crlcache.c:2211 #, c-format msgid "problem renaming `%s' to `%s': %s\n" msgstr "Problem beim Umbenennen von `%s' nach `%s': %s\n" -#: dirmngr/crlcache.c:2225 msgid "" "updating the DIR file failed - cache entry will get lost with the next " "program start\n" @@ -8415,167 +6658,130 @@ msgstr "" "Update der Zwischenspeicherverzeichnisdatei fehlgeschlagen - " "Zwischenspeichereintrag wird mit dem nächste Programmstart verloren gehen\n" -#: dirmngr/crlcache.c:2262 #, c-format msgid "Begin CRL dump (retrieved via %s)\n" msgstr "Anfang CRL Ausgabe (geholt via %s)\n" -#: dirmngr/crlcache.c:2285 msgid "" " ERROR: The CRL will not be used because it was still too old after an " "update!\n" msgstr "" " FEHLER: Die CRL wird nicht benutzt, da sie trotz eines Updates zu alt war!\n" -#: dirmngr/crlcache.c:2288 msgid "" " ERROR: The CRL will not be used due to an unknown critical extension!\n" msgstr "" " FEHLER: Die CRL wird nicht benutzt, da sie eine unbekannte kritische CRL " "Erweiterung trägt!\n" -#: dirmngr/crlcache.c:2291 msgid " ERROR: The CRL will not be used\n" msgstr " FEHLER: Die CRL wird nicht benutzt\n" -#: dirmngr/crlcache.c:2298 msgid " ERROR: This cached CRL may has been tampered with!\n" msgstr "" " FEHLER: Diese zwischengespeicherte CRL ist möglicherweise abgeändert " "worden!\n" -#: dirmngr/crlcache.c:2316 msgid " WARNING: invalid cache record length\n" msgstr " WARNUNG: Ungültige Länge eines Zwischenspeicherdatensatzes\n" -#: dirmngr/crlcache.c:2323 #, c-format msgid "problem reading cache record: %s\n" msgstr "Problem beim Lesen eines Zwischenspeicherdatensatzes: %s\n" -#: dirmngr/crlcache.c:2334 #, c-format msgid "problem reading cache key: %s\n" msgstr "Problem beim Lesen eines Zwischenspeicherschlüssels: %s\n" -#: dirmngr/crlcache.c:2365 #, c-format msgid "error reading cache entry from db: %s\n" msgstr "Fehler beim Lesen eine Zwischenspeichereintrags aus der DB: %s\n" -#: dirmngr/crlcache.c:2368 msgid "End CRL dump\n" msgstr "Ende CRL Ausgabe\n" -#: dirmngr/crlcache.c:2489 #, c-format msgid "crl_fetch via DP failed: %s\n" msgstr "crl_fetch über den DP fehlgeschlagen: %s\n" -#: dirmngr/crlcache.c:2500 #, c-format msgid "crl_cache_insert via DP failed: %s\n" msgstr "crl_cache_insert über den DP fehlgeschlagen: %s\n" -#: dirmngr/crlcache.c:2560 #, c-format msgid "crl_cache_insert via issuer failed: %s\n" msgstr "crl_cache_insert über den Issuer fehlgeschlagen: %s\n" -#: dirmngr/crlfetch.c:74 msgid "reader to file mapping table full - waiting\n" msgstr "\"reader to file\" Zuordnungstabelle ist voll - warte\n" -#: dirmngr/crlfetch.c:179 msgid "using \"http\" instead of \"https\"\n" msgstr "Es wird \"HTTP\" anstatt \"HTTPS\" verwendet\n" -#: dirmngr/crlfetch.c:190 dirmngr/crlfetch.c:285 dirmngr/crlfetch.c:305 -#: dirmngr/crlfetch.c:323 #, c-format msgid "CRL access not possible due to disabled %s\n" msgstr "CRL Zugriff nicht möglich da %s abgeschaltet ist\n" -#: dirmngr/crlfetch.c:219 dirmngr/ldap-wrapper-ce.c:394 -#: dirmngr/ldap-wrapper.c:711 dirmngr/misc.c:524 #, c-format msgid "error initializing reader object: %s\n" msgstr "Fehler beim Initialisieren des \"reader\" Objekts: %s\n" -#: dirmngr/crlfetch.c:245 dirmngr/ocsp.c:210 #, c-format msgid "URL `%s' redirected to `%s' (%u)\n" msgstr "URL `%s' nach `%s' umgeleitet (%u)\n" -#: dirmngr/crlfetch.c:264 dirmngr/ocsp.c:227 msgid "too many redirections\n" msgstr "zu viele verschachtelte Umleitungen\n" -#: dirmngr/crlfetch.c:270 #, c-format msgid "error retrieving `%s': %s\n" msgstr "Fehler beim Holen von `%s': %s\n" -#: dirmngr/crlfetch.c:275 #, c-format msgid "error retrieving `%s': http status %u\n" msgstr "Fehler beim Holen von `%s': HTTP Status %u\n" -#: dirmngr/crlfetch.c:337 #, c-format msgid "certificate search not possible due to disabled %s\n" msgstr "Zertifikatsuche ist nicht möglich da %s abgeschaltet ist\n" -#: dirmngr/dirmngr-client.c:70 msgid "use OCSP instead of CRLs" msgstr "OCSP anstatt CRL benutzen" -#: dirmngr/dirmngr-client.c:71 msgid "check whether a dirmngr is running" msgstr "Teste ob der dirmngr noch läuft" -#: dirmngr/dirmngr-client.c:72 msgid "add a certificate to the cache" msgstr "Ein Zertifikat dem Zwischenspeicher zufügen" -#: dirmngr/dirmngr-client.c:73 msgid "validate a certificate" msgstr "Zertifikat prüfen" -#: dirmngr/dirmngr-client.c:74 msgid "lookup a certificate" msgstr "Zertifikat auffinden" -#: dirmngr/dirmngr-client.c:75 msgid "lookup only locally stored certificates" msgstr "Nur lokal gespeicherte Zertifikate auffinden" -#: dirmngr/dirmngr-client.c:76 msgid "expect an URL for --lookup" msgstr "Eine URL wird für --lookup erwartet" -#: dirmngr/dirmngr-client.c:77 msgid "load a CRL into the dirmngr" msgstr "CRL in den Dirmngr laden" -#: dirmngr/dirmngr-client.c:78 msgid "special mode for use by Squid" msgstr "Sondermodus für Squid" -#: dirmngr/dirmngr-client.c:79 msgid "certificates are expected in PEM format" msgstr "Zertifikate werden im PEM Format erwartet" -#: dirmngr/dirmngr-client.c:81 msgid "force the use of the default OCSP responder" msgstr "Die Nutzung des voreingestellten OCSP Responder erzwingen" -#: dirmngr/dirmngr-client.c:151 msgid "Usage: dirmngr-client [options] [certfile|pattern] (-h for help)\n" msgstr "" "Gebrauch: dirmngr-client [Optionen] [Zertdatei|Muster] (-h für Hilfe)\n" -#: dirmngr/dirmngr-client.c:155 msgid "" "Syntax: dirmngr-client [options] [certfile|pattern]\n" "Test an X.509 certificate against a CRL or do an OCSP check\n" @@ -8588,205 +6794,157 @@ msgstr "" "The Prozess gibt 0 zurück wenn das Zertifikat gültig ist, 1 wenn es nicht\n" "gültig ist und weitere Werte bei anderen Fehlern.\n" -#: dirmngr/dirmngr-client.c:268 dirmngr/dirmngr-client.c:997 #, c-format msgid "error reading certificate from stdin: %s\n" msgstr "Fehler beim Lesen des Zertifikats von der Standardeingabe: %s\n" -#: dirmngr/dirmngr-client.c:275 #, c-format msgid "error reading certificate from `%s': %s\n" msgstr "Fehler beim Lesen des Zertifikats von `%s': %s\n" -#: dirmngr/dirmngr-client.c:289 msgid "certificate too large to make any sense\n" msgstr "Zertifikat ist zu groß um Sinnvoll zu sein\n" -#: dirmngr/dirmngr-client.c:315 #, c-format msgid "lookup failed: %s\n" msgstr "Aufsuchen fehlgeschlagen: %s\n" -#: dirmngr/dirmngr-client.c:330 #, c-format msgid "loading CRL `%s' failed: %s\n" msgstr "Laden der CRL von `%s' fehlgeschlagen: %s\n" -#: dirmngr/dirmngr-client.c:358 msgid "a dirmngr daemon is up and running\n" msgstr "Ein dirmngr ist vorhanden und aktiv\n" -#: dirmngr/dirmngr-client.c:380 #, c-format msgid "validation of certificate failed: %s\n" msgstr "Prüfung des Zertifikats fehlgeschlagen: %s\n" -#: dirmngr/dirmngr-client.c:387 dirmngr/dirmngr-client.c:1008 msgid "certificate is valid\n" msgstr "Zertifikat ist gültig\n" -#: dirmngr/dirmngr-client.c:393 dirmngr/dirmngr-client.c:1016 msgid "certificate has been revoked\n" msgstr "Zertifikat wurde widerrufen\n" -#: dirmngr/dirmngr-client.c:398 dirmngr/dirmngr-client.c:1018 #, c-format msgid "certificate check failed: %s\n" msgstr "Zertifikatprüfung fehlgeschlagen: %s\n" -#: dirmngr/dirmngr-client.c:411 #, c-format msgid "got status: `%s'\n" msgstr "Erhielt Status: `%s'\n" -#: dirmngr/dirmngr-client.c:426 #, c-format msgid "error writing base64 encoding: %s\n" msgstr "Fehler beim Schreiben der Base-64 Darstellung: %s\n" -#: dirmngr/dirmngr-client.c:453 dirmngr/server.c:1804 #, c-format msgid "failed to allocate assuan context: %s\n" msgstr "Fehler beim Bereitstellen eines Assuan Kontext: %s\n" -#: dirmngr/dirmngr-client.c:467 msgid "apparently no running dirmngr\n" msgstr "Offensichtlich ist kein Dirmngr vorhanden\n" -#: dirmngr/dirmngr-client.c:472 msgid "no running dirmngr - starting one\n" msgstr "Dirmngr läuft nicht - ein neuer wird gestartet\n" -#: dirmngr/dirmngr-client.c:505 msgid "malformed DIRMNGR_INFO environment variable\n" msgstr "Fehlerhafte DIRMNGR_INFO Variable\n" -#: dirmngr/dirmngr-client.c:520 #, c-format msgid "dirmngr protocol version %d is not supported\n" msgstr "Dirmngr Protocol Version %d wird nicht unterstützt\n" -#: dirmngr/dirmngr-client.c:536 msgid "can't connect to the dirmngr - trying fall back\n" msgstr "Verbindung zum Dirmngr nicht möglich - Rückfallmethode wird versucht\n" -#: dirmngr/dirmngr-client.c:545 #, c-format msgid "can't connect to the dirmngr: %s\n" msgstr "Verbindung zum Dirmngr nicht möglich: %s\n" -#: dirmngr/dirmngr-client.c:794 #, c-format msgid "unsupported inquiry `%s'\n" msgstr "Nicht unterstützte INQUIRY `%s'\n" -#: dirmngr/dirmngr-client.c:896 msgid "absolute file name expected\n" msgstr "Absoluter Dateiname erwartet\n" -#: dirmngr/dirmngr-client.c:941 #, c-format msgid "looking up `%s'\n" msgstr "Auffinden von `%s'\n" -#: dirmngr/dirmngr.c:137 msgid "run as windows service (background)" msgstr "Als Windows-Service ausführen (Hintergrund)" -#: dirmngr/dirmngr.c:139 msgid "list the contents of the CRL cache" msgstr "Den Inhalt des CRL Zwischenspeichers anzeigen" -#: dirmngr/dirmngr.c:140 msgid "|FILE|load CRL from FILE into cache" msgstr "|DATEI|Lade die CRL aus der DATEI in den Zwischenspeicher" -#: dirmngr/dirmngr.c:141 msgid "|URL|fetch a CRL from URL" msgstr "|URL|Hole eine CRL von dieser URL" -#: dirmngr/dirmngr.c:142 msgid "shutdown the dirmngr" msgstr "Den Dirmngr herunterfahren" -#: dirmngr/dirmngr.c:143 msgid "flush the cache" msgstr "Den Zwischenspeicher löschen" -#: dirmngr/dirmngr.c:158 tools/gpgconf-comp.c:509 tools/gpgconf-comp.c:698 -#: tools/gpgconf-comp.c:784 tools/gpgconf-comp.c:870 msgid "|FILE|write server mode logs to FILE" msgstr "|DATEI|Schreibe im Servermodus Logs auf DATEI" -#: dirmngr/dirmngr.c:159 msgid "run without asking a user" msgstr "Ausführung ohne Benutzernachfrage" -#: dirmngr/dirmngr.c:160 msgid "force loading of outdated CRLs" msgstr "Laden von abgelaufenen CRLs erzwingen" -#: dirmngr/dirmngr.c:161 msgid "allow sending OCSP requests" msgstr "OCSP Anfragen erlauben" -#: dirmngr/dirmngr.c:162 msgid "inhibit the use of HTTP" msgstr "Sperre die Benutzung von HTTP" -#: dirmngr/dirmngr.c:163 msgid "inhibit the use of LDAP" msgstr "Sperre die Benutzung von LDAP" -#: dirmngr/dirmngr.c:165 msgid "ignore HTTP CRL distribution points" msgstr "Übergehe HTTP CRL Distribution Points" -#: dirmngr/dirmngr.c:167 msgid "ignore LDAP CRL distribution points" msgstr "Übergehe LDAP CRL Distribution Points" -#: dirmngr/dirmngr.c:169 msgid "ignore certificate contained OCSP service URLs" msgstr "Übergehe im Zertifikat enthaltene OCSP Service URLs" -#: dirmngr/dirmngr.c:172 msgid "|URL|redirect all HTTP requests to URL" msgstr "|URL|Leite alle HTTP Anfragen über URL" -#: dirmngr/dirmngr.c:174 msgid "|HOST|use HOST for LDAP queries" msgstr "|HOST|Benutze HOST für LDAP Anfragen" -#: dirmngr/dirmngr.c:176 msgid "do not use fallback hosts with --ldap-proxy" msgstr "Keine Benutzung der Rückgriffshosts mit --ldap-proxy" -#: dirmngr/dirmngr.c:179 msgid "|FILE|read LDAP server list from FILE" msgstr "|DATEI|Lese die LDAP Serverliste aus DATEI" -#: dirmngr/dirmngr.c:181 msgid "add new servers discovered in CRL distribution points to serverlist" msgstr "Füge neue Server aus den CRL Distribution Points der Serverliste hinzu" -#: dirmngr/dirmngr.c:184 dirmngr/dirmngr_ldap.c:129 msgid "|N|set LDAP timeout to N seconds" msgstr "|N|Setze das LDAP Timeout auf N Sekunden" -#: dirmngr/dirmngr.c:187 msgid "|URL|use OCSP responder at URL" msgstr "|URL|Benutze den OCSP Responder mit dieser URL" -#: dirmngr/dirmngr.c:189 msgid "|FPR|OCSP response signed by FPR" msgstr "|FPR|OCSP Antwort ist durch FPR signiert" -#: dirmngr/dirmngr.c:195 msgid "|N|do not return more than N items in one query" msgstr "|N|Nicht mehr als N Angaben in einer Anfrage zurückgeben" -#: dirmngr/dirmngr.c:210 msgid "" "@\n" "(See the \"info\" manual for a complete listing of all commands and " @@ -8796,11 +6954,9 @@ msgstr "" "(Im \"info\"-Handbuch findet sich eine vollständige Liste aller Kommandos " "und Optionen)\n" -#: dirmngr/dirmngr.c:305 msgid "Usage: dirmngr [options] (-h for help)" msgstr "Gebrauch: dirmnr [Optionen] [Kommando [Argumente]]" -#: dirmngr/dirmngr.c:307 msgid "" "Syntax: dirmngr [options] [command [args]]\n" "LDAP and OCSP access for GnuPG\n" @@ -8808,136 +6964,106 @@ msgstr "" "Syntax: dirmngr [Optionen] [Kommando [Argumente]]\n" "LDAP und OCSP Zugriff für GnuPG\n" -#: dirmngr/dirmngr.c:372 #, c-format msgid "valid debug levels are: %s\n" msgstr "Gültige Debugebenen sind: %s\n" -#: dirmngr/dirmngr.c:395 msgid "usage: dirmngr [options] " msgstr "Gebrauch: dirmngr [Optionen] " -#: dirmngr/dirmngr.c:958 msgid "colons are not allowed in the socket name\n" msgstr "Doppelpunkte sind im Namen des Sockets nicht erlaubt\n" -#: dirmngr/dirmngr.c:1164 dirmngr/server.c:1185 #, c-format msgid "fetching CRL from `%s' failed: %s\n" msgstr "Holen der CRL von `%s' fehlgeschlagen: %s\n" -#: dirmngr/dirmngr.c:1170 dirmngr/server.c:1191 #, c-format msgid "processing CRL from `%s' failed: %s\n" msgstr "Verarbeitung der CRL von `%s' fehlgeschlagen: %s\n" -#: dirmngr/dirmngr.c:1389 #, c-format msgid "%s:%u: line too long - skipped\n" msgstr "%s:%u: Zeile ist zu lang - übergangen\n" -#: dirmngr/dirmngr.c:1444 dirmngr/dirmngr.c:1528 #, c-format msgid "%s:%u: invalid fingerprint detected\n" msgstr "%s:%u: ungültiger Fingerabdruck erkannt\n" -#: dirmngr/dirmngr.c:1480 dirmngr/dirmngr.c:1506 #, c-format msgid "%s:%u: read error: %s\n" msgstr "%s:%u: Lesefehler: %s\n" -#: dirmngr/dirmngr.c:1535 #, c-format msgid "%s:%u: garbage at end of line ignored\n" msgstr "%s:%u: Müll am Ende der Zeile wird ignoriert\n" -#: dirmngr/dirmngr.c:1601 msgid "SIGHUP received - re-reading configuration and flushing caches\n" msgstr "" "SIGHUP empfangen - lese die Konfiguration erneut und lösche die " "Zwischenspeicher\n" -#: dirmngr/dirmngr.c:1628 msgid "SIGUSR2 received - no action defined\n" msgstr "SIGUSR2 empfangen - keine Aktion definiert\n" -#: dirmngr/dirmngr.c:1633 dirmngr/dirmngr.c:1670 msgid "SIGTERM received - shutting down ...\n" msgstr "SIGTERM empfangen - wird heruntergefahren ...\n" -#: dirmngr/dirmngr.c:1635 #, c-format msgid "SIGTERM received - still %d active connections\n" msgstr "SIGTERM empfangen - immer noch %d Verbindungen aktiv\n" -#: dirmngr/dirmngr.c:1640 dirmngr/dirmngr.c:1673 msgid "shutdown forced\n" msgstr "Herunterfahren wurde erzwungen\n" -#: dirmngr/dirmngr.c:1648 msgid "SIGINT received - immediate shutdown\n" msgstr "SIGINT empfangen - wird sofort heruntergefahren\n" -#: dirmngr/dirmngr.c:1655 #, c-format msgid "signal %d received - no action defined\n" msgstr "Signal %d empfangen - keine Aktion definiert\n" -#: dirmngr/dirmngr.c:1807 #, c-format msgid "accept failed: %s - waiting 1s\n" msgstr "accept() fehlgeschlagen: %s - warte 1s\n" -#: dirmngr/dirmngr.c:1837 #, c-format msgid "error spawning connection handler: %s\n" msgstr "Fehler beim Starten des Verbindungshandler: %s\n" -#: dirmngr/dirmngr_ldap.c:130 msgid "return all values in a record oriented format" msgstr "Alle Werte in einem Record Format zurückgeben" -#: dirmngr/dirmngr_ldap.c:133 msgid "|NAME|ignore host part and connect through NAME" msgstr "|NAME|Host Teil ignorieren und über NAME verbinden" -#: dirmngr/dirmngr_ldap.c:134 msgid "|NAME|connect to host NAME" msgstr "|NAME|Verbinde mit dem Host NAME" -#: dirmngr/dirmngr_ldap.c:135 msgid "|N|connect to port N" msgstr "|N|Verbinde mit dem Port N" -#: dirmngr/dirmngr_ldap.c:136 msgid "|NAME|use user NAME for authentication" msgstr "|NAME|Benutze NAME zur Authentifizierung" -#: dirmngr/dirmngr_ldap.c:137 msgid "|PASS|use password PASS for authentication" msgstr "Benutze Passwort PASS zur Authentifizierung" -#: dirmngr/dirmngr_ldap.c:139 msgid "take password from $DIRMNGR_LDAP_PASS" msgstr "Nimm das Passwort von $DIRMNGR_LDAP_PASS" -#: dirmngr/dirmngr_ldap.c:140 msgid "|STRING|query DN STRING" msgstr "|STRING|Frage den DN STRING ab" -#: dirmngr/dirmngr_ldap.c:141 msgid "|STRING|use STRING as filter expression" msgstr "|STRING|Benutze STRING als Filterausdruck" -#: dirmngr/dirmngr_ldap.c:142 msgid "|STRING|return the attribute STRING" msgstr "|STRING|Gib das Attribut STRING zurück" -#: dirmngr/dirmngr_ldap.c:201 msgid "Usage: dirmngr_ldap [options] [URL] (-h for help)\n" msgstr "Gebrauch: dirmngr_ldap [Optionen] [URL] (-h für Hilfe)\n" -#: dirmngr/dirmngr_ldap.c:204 msgid "" "Syntax: dirmngr_ldap [options] [URL]\n" "Internal LDAP helper for Dirmngr.\n" @@ -8947,528 +7073,413 @@ msgstr "" "Internes LDAP-Hilfsprogramm für Dirmngr.\n" "Interface und Optionen können sich mit jedem Release ändern.\n" -#: dirmngr/dirmngr_ldap.c:327 #, c-format msgid "invalid port number %d\n" msgstr "Ungültige Portnummer %d\n" -#: dirmngr/dirmngr_ldap.c:403 #, c-format msgid "scanning result for attribute `%s'\n" msgstr "Absuchen des Ergebnisses nach Attribut `%s'\n" -#: dirmngr/dirmngr_ldap.c:410 dirmngr/dirmngr_ldap.c:493 -#: dirmngr/dirmngr_ldap.c:517 dirmngr/dirmngr_ldap.c:529 -#: dirmngr/dirmngr_ldap.c:654 #, c-format msgid "error writing to stdout: %s\n" msgstr "Fehler beim Schreiben auf Standardausgabe: %s\n" -#: dirmngr/dirmngr_ldap.c:427 #, c-format msgid " available attribute `%s'\n" msgstr " verfügbare Attribute `%s'\n" -#: dirmngr/dirmngr_ldap.c:465 #, c-format msgid "attribute `%s' not found\n" msgstr "Attribut `%s' nicht gefunden\n" -#: dirmngr/dirmngr_ldap.c:472 #, c-format msgid "found attribute `%s'\n" msgstr "Attribut `%s' gefunden\n" -#: dirmngr/dirmngr_ldap.c:581 #, c-format msgid "processing url `%s'\n" msgstr "Verarbeiten der URL `%s'\n" -#: dirmngr/dirmngr_ldap.c:583 #, c-format msgid " user `%s'\n" msgstr " Benutzer `%s'\n" -#: dirmngr/dirmngr_ldap.c:585 #, c-format msgid " pass `%s'\n" msgstr " Passwort `%s'\n" -#: dirmngr/dirmngr_ldap.c:587 #, c-format msgid " host `%s'\n" msgstr " Host `%s'\n" -#: dirmngr/dirmngr_ldap.c:588 #, c-format msgid " port %d\n" msgstr " Port %d\n" -#: dirmngr/dirmngr_ldap.c:590 #, c-format msgid " DN `%s'\n" msgstr " DN `%s'\n" -#: dirmngr/dirmngr_ldap.c:592 #, c-format msgid " filter `%s'\n" msgstr " Filter `%s'\n" -#: dirmngr/dirmngr_ldap.c:597 dirmngr/dirmngr_ldap.c:600 #, c-format msgid " attr `%s'\n" msgstr " Attribut `%s'\n" -#: dirmngr/dirmngr_ldap.c:606 #, c-format msgid "no host name in `%s'\n" msgstr "Kein Hostname in `%s'\n" -#: dirmngr/dirmngr_ldap.c:611 #, c-format msgid "no attribute given for query `%s'\n" msgstr "Kein Attribut für Abfrage `%s' angegeben\n" -#: dirmngr/dirmngr_ldap.c:617 msgid "WARNING: using first attribute only\n" msgstr "WARNUNG: Es wird nur das erste Attribut benutzt\n" -#: dirmngr/dirmngr_ldap.c:626 #, c-format msgid "LDAP init to `%s:%d' failed: %s\n" msgstr "LDAP Initialisierung von `%s:%d' fehlgeschlagen: %s\n" -#: dirmngr/dirmngr_ldap.c:636 #, c-format msgid "binding to `%s:%d' failed: %s\n" msgstr "Anbindung an `%s:%d' fehlgeschlagen: %s\n" -#: dirmngr/dirmngr_ldap.c:663 #, c-format msgid "searching `%s' failed: %s\n" msgstr "Suche mit `%s' fehlgeschlagen: %s\n" -#: dirmngr/dirmngr_ldap.c:695 #, c-format msgid "`%s' is not an LDAP URL\n" msgstr "`%s' ist kein LDAP URL\n" -#: dirmngr/dirmngr_ldap.c:701 #, c-format msgid "`%s' is an invalid LDAP URL\n" msgstr "`%s' ist ein ungültiger LDAP URL\n" -#: dirmngr/ldap-wrapper-ce.c:313 dirmngr/ldap-wrapper.c:639 -#: dirmngr/ldap-wrapper.c:656 #, c-format msgid "error allocating memory: %s\n" msgstr "Fehler beim Allozieren von Speicher: %s\n" -#: dirmngr/ldap-wrapper.c:210 #, c-format msgid "error printing log line: %s\n" msgstr "Fehler beim Schreiben einer Logzeile: %s\n" -#: dirmngr/ldap-wrapper.c:239 #, c-format msgid "error reading log from ldap wrapper %d: %s\n" msgstr "Fehler beim Lesen des Logs vom LDAP Wrapper %d: %s\n" -#: dirmngr/ldap-wrapper.c:276 #, c-format msgid "pth_event failed: %s\n" msgstr "pth_event() fehlgeschlagen: %s\n" -#: dirmngr/ldap-wrapper.c:296 #, c-format msgid "pth_wait failed: %s\n" msgstr "pth_wait() fehlgeschlagen: %s\n" -#: dirmngr/ldap-wrapper.c:333 #, c-format msgid "ldap wrapper %d ready" msgstr "LDAP Wrapper %d fertig" -#: dirmngr/ldap-wrapper.c:342 #, c-format msgid "ldap wrapper %d ready: timeout\n" msgstr "LDAP Wrapper %d fertig: Zeitüberschreitung\n" -#: dirmngr/ldap-wrapper.c:345 #, c-format msgid "ldap wrapper %d ready: exitcode=%d\n" msgstr "LDAP Wrapper %d fertig: Exitcode=%d\n" -#: dirmngr/ldap-wrapper.c:354 #, c-format msgid "waiting for ldap wrapper %d failed: %s\n" msgstr "Warten auf den LDAP Wrapper %d fehlgeschlagen: %s\n" -#: dirmngr/ldap-wrapper.c:366 #, c-format msgid "ldap wrapper %d stalled - killing\n" msgstr "LDAP Wrapper %d versackt - abgeschossen\n" -#: dirmngr/ldap-wrapper.c:433 #, c-format msgid "error spawning ldap wrapper reaper thread: %s\n" msgstr "Fehler beim Starten des LDAP Wrapper Kontrollthreads: %s\n" -#: dirmngr/ldap-wrapper.c:483 dirmngr/ldap-wrapper.c:504 #, c-format msgid "reading from ldap wrapper %d failed: %s\n" msgstr "Lesen vom LDAP Wrapper %d fehlgeschlagen: %s\n" -#: dirmngr/ldap.c:90 #, c-format msgid "invalid char 0x%02x in host name - not added\n" msgstr "Ungültiges Zeichen 0x%02X im Hostnamen - nicht hinzugefügt\n" -#: dirmngr/ldap.c:94 #, c-format msgid "adding `%s:%d' to the ldap server list\n" msgstr "`%s:%d' wird der LDAP Serverliste hinzugefügt\n" -#: dirmngr/ldap.c:97 dirmngr/misc.c:463 #, c-format msgid "malloc failed: %s\n" msgstr "malloc() fehlgeschlagen: %s\n" -#: dirmngr/ldap.c:602 #, c-format msgid "start_cert_fetch: invalid pattern `%s'\n" msgstr "start_cert_fetch: Ungültiges Muster `%s'\n" -#: dirmngr/ldap.c:808 msgid "ldap_search hit the size limit of the server\n" msgstr "ldap_search erreichte die Größengrenze des Servers\n" -#: dirmngr/misc.c:164 msgid "invalid canonical S-expression found\n" msgstr "Ungültige kanonische S-Expression gefunden\n" -#: dirmngr/misc.c:188 dirmngr/misc.c:222 #, c-format msgid "gcry_md_open failed: %s\n" msgstr "gcry_md_open fehlgeschlagen: %s\n" -#: dirmngr/misc.c:193 dirmngr/misc.c:227 #, c-format msgid "oops: ksba_cert_hash failed: %s\n" msgstr "Nanu: ksba_cert_hash fehlgeschlagen: %s\n" -#: dirmngr/misc.c:479 msgid "bad URL encoding detected\n" msgstr "Fehlerhafte URL Kodierung erkannt\n" -#: dirmngr/ocsp.c:81 #, c-format msgid "error reading from responder: %s\n" msgstr "Fehler beim Lesen vom Responder: %s\n" -#: dirmngr/ocsp.c:99 #, c-format msgid "response from server too large; limit is %d bytes\n" msgstr "Antwort vom Server zu lang; die Grenze sind %d Bytes\n" -#: dirmngr/ocsp.c:138 msgid "OCSP request not possible due to disabled HTTP\n" msgstr "OCSP Anfrage nicht möglich da HTTP abgeschaltet ist\n" -#: dirmngr/ocsp.c:145 #, c-format msgid "error setting OCSP target: %s\n" msgstr "Fehler beim Setzen des OCSP Ziels: %s\n" -#: dirmngr/ocsp.c:163 #, c-format msgid "error building OCSP request: %s\n" msgstr "Fehler beim Aufbauen der OCSP Anfrage: %s\n" -#: dirmngr/ocsp.c:173 #, c-format msgid "error connecting to `%s': %s\n" msgstr "Fehler beim Verbinden mit '%s': %s\n" -#: dirmngr/ocsp.c:199 dirmngr/ocsp.c:247 #, c-format msgid "error reading HTTP response for `%s': %s\n" msgstr "Fehler beim Lesen der HTTP Antwort von `%s': %s\n" -#: dirmngr/ocsp.c:232 #, c-format msgid "error accessing `%s': http status %u\n" msgstr "Fehler beim Zugreifen auf `%s': HTTP Status %u\n" -#: dirmngr/ocsp.c:257 #, c-format msgid "error parsing OCSP response for `%s': %s\n" msgstr "Fehler beim Zerlegen der OCSP Antwort für `%s': %s\n" -#: dirmngr/ocsp.c:280 dirmngr/ocsp.c:290 #, c-format msgid "OCSP responder at `%s' status: %s\n" msgstr "OCSP Responder `%s' Status: %s\n" -#: dirmngr/ocsp.c:285 #, c-format msgid "hashing the OCSP response for `%s' failed: %s\n" msgstr "Hashen der OCSP Antwort für `%s' fehlgeschlagen: %s\n" -#: dirmngr/ocsp.c:320 msgid "not signed by a default OCSP signer's certificate" msgstr "Nicht durch voreingestelltes OCSP \"Signer-Zertifikat\" signiert" -#: dirmngr/ocsp.c:409 msgid "only SHA-1 is supported for OCSP responses\n" msgstr "Lediglich SHA-1 wird bei OCSP Antworten unterstützt\n" -#: dirmngr/ocsp.c:460 #, c-format msgid "allocating list item failed: %s\n" msgstr "malloc() fehlgeschlagen: %s\n" -#: dirmngr/ocsp.c:475 #, c-format msgid "error getting responder ID: %s\n" msgstr "Fehler beim Holen der Responder-ID: %s\n" -#: dirmngr/ocsp.c:510 msgid "no suitable certificate found to verify the OCSP response\n" msgstr "" "Kein benutzbares Zertifikat zur Überprüfung der OCSP Antwort gefunden\n" -#: dirmngr/ocsp.c:549 dirmngr/validate.c:623 #, c-format msgid "issuer certificate not found: %s\n" msgstr "Herausgeberzertifikat nicht gefunden: %s\n" -#: dirmngr/ocsp.c:559 msgid "caller did not return the target certificate\n" msgstr "Aufrufer gab das Ziel Zertifikat nicht zurück\n" -#: dirmngr/ocsp.c:566 msgid "caller did not return the issuing certificate\n" msgstr "Aufrufer gab das Issuer Zertifikat nicht zurück\n" -#: dirmngr/ocsp.c:576 #, c-format msgid "failed to allocate OCSP context: %s\n" msgstr "Fehler beim Bereitstellen eines OCSP Kontext: %s\n" -#: dirmngr/ocsp.c:610 #, c-format msgid "can't get authorityInfoAccess: %s\n" msgstr "authorityInfoAccess kann nicht geholt werden: %s\n" -#: dirmngr/ocsp.c:617 msgid "no default OCSP responder defined\n" msgstr "Kein voreingestellter OCSP Responder definiert\n" -#: dirmngr/ocsp.c:623 msgid "no default OCSP signer defined\n" msgstr "Kein voreingestellter OCSP \"Signer\" definiert\n" -#: dirmngr/ocsp.c:630 #, c-format msgid "using default OCSP responder `%s'\n" msgstr "Der voreingestellte OCSP Responder `%s' wird benutzt\n" -#: dirmngr/ocsp.c:635 #, c-format msgid "using OCSP responder `%s'\n" msgstr "Der OCSP Responder `%s' wird benutzt\n" -#: dirmngr/ocsp.c:642 #, c-format msgid "failed to establish a hashing context for OCSP: %s\n" msgstr "Kontext zum Hashen von OCSP kann nicht erzeugt werden: %s\n" -#: dirmngr/ocsp.c:672 #, c-format msgid "error getting OCSP status for target certificate: %s\n" msgstr "Fehler beim Holen des OCSP Status für das Zielzertifikat: %s\n" -#: dirmngr/ocsp.c:697 #, c-format msgid "certificate status is: %s (this=%s next=%s)\n" msgstr "Zertifikatstatus ist: %s (this=%s next=%s)\n" -#: dirmngr/ocsp.c:698 msgid "good" msgstr "Gut" -#: dirmngr/ocsp.c:704 #, c-format msgid "certificate has been revoked at: %s due to: %s\n" msgstr "Zertifikat wurde widerrufen am: %s wegen: %s\n" -#: dirmngr/ocsp.c:739 msgid "OCSP responder returned a status in the future\n" msgstr "OCSP Responder gab einen Status in der Zukunft zurück\n" -#: dirmngr/ocsp.c:751 msgid "OCSP responder returned a non-current status\n" msgstr "OCSP Responder gab einen nicht aktuellen Status zurück\n" -#: dirmngr/ocsp.c:766 msgid "OCSP responder returned an too old status\n" msgstr "OCSP Responder gab einen zu alten Status zurück\n" -#: dirmngr/server.c:291 dirmngr/server.c:403 dirmngr/server.c:449 #, c-format msgid "assuan_inquire(%s) failed: %s\n" msgstr "assuan_inquire(%s) fehlgeschlagen: %s\n" -#: dirmngr/server.c:546 msgid "ldapserver missing" msgstr "LDAP Server fehlt" -#: dirmngr/server.c:616 msgid "serialno missing in cert ID" msgstr "Seriennummer fehlt in der Cert-ID" -#: dirmngr/server.c:752 dirmngr/server.c:838 dirmngr/server.c:1270 -#: dirmngr/server.c:1321 dirmngr/server.c:1578 dirmngr/server.c:1594 #, c-format msgid "assuan_inquire failed: %s\n" msgstr "assuan_inquire fehlgeschlagen: %s\n" -#: dirmngr/server.c:881 #, c-format msgid "fetch_cert_by_url failed: %s\n" msgstr "fetch_cert_by_url() fehlgeschlagen: %s\n" -#: dirmngr/server.c:893 dirmngr/server.c:924 dirmngr/server.c:1080 #, c-format msgid "error sending data: %s\n" msgstr "Fehler beim Senden der Daten: %s\n" -#: dirmngr/server.c:1028 #, c-format msgid "start_cert_fetch failed: %s\n" msgstr "start_cert_fetch fehlgeschlagen: %s\n" -#: dirmngr/server.c:1061 #, c-format msgid "fetch_next_cert failed: %s\n" msgstr "fetch_next_cert fehlgeschlagen: %s\n" -#: dirmngr/server.c:1088 #, c-format msgid "max_replies %d exceeded\n" msgstr "max_replies %d überschritten\n" -#: dirmngr/server.c:1793 #, c-format msgid "can't allocate control structure: %s\n" msgstr "Fehler beim Erzeugen der Kontrollstruktur: %s\n" -#: dirmngr/server.c:1825 #, c-format msgid "failed to initialize the server: %s\n" msgstr "Fehler beim Initialisieren des Servers: %s\n" -#: dirmngr/server.c:1833 #, c-format msgid "failed to the register commands with Assuan: %s\n" msgstr "Fehler beim Registrieren der Kommandos gegen Assuan: %s\n" -#: dirmngr/server.c:1873 #, c-format msgid "Assuan accept problem: %s\n" msgstr "Assuan accept Problem: %s\n" -#: dirmngr/server.c:1892 #, c-format msgid "Assuan processing failed: %s\n" msgstr "Assuan Verarbeitung fehlgeschlagen: %s\n" -#: dirmngr/validate.c:201 msgid "accepting root CA not marked as a CA" msgstr "" "Herausgeberzertifikat akzeptiert obgleich nicht für eine CA gekennzeichnet" -#: dirmngr/validate.c:227 msgid "CRL checking too deeply nested\n" msgstr "CRL Überprüfung ist zu tief geschachtelt\n" -#: dirmngr/validate.c:245 msgid "not checking CRL for" msgstr "keine Prüfung der CRL für" -#: dirmngr/validate.c:250 msgid "checking CRL for" msgstr "Prüfen der CRL für" -#: dirmngr/validate.c:388 msgid "running in compatibility mode - certificate chain not checked!\n" msgstr "Kompatibilitätsmodus - Zertifikatkette nicht geprüft!\n" -#: dirmngr/validate.c:532 msgid "selfsigned certificate has a BAD signature" msgstr "Das eigenbeglaubigte Zertifikat hat eine FALSCHE Signatur" -#: dirmngr/validate.c:565 #, c-format msgid "checking trustworthiness of root certificate failed: %s\n" msgstr "" "Prüfung der Vertrauenswürdigkeit des Wurzelzertifikats fehlgeschlagen: %s\n" -#: dirmngr/validate.c:742 msgid "certificate chain is good\n" msgstr "Der Zertifikatkette ist gültig\n" -#: dirmngr/validate.c:972 msgid "DSA requires the use of a 160 bit hash algorithm\n" msgstr "DSA benötigt eine 160 Bit Hashmethode\n" -#: dirmngr/validate.c:1120 msgid "certificate should have not been used for CRL signing\n" msgstr "" "Das Zertifikat hätte nicht zum Signieren einer CRL benutzt werden sollen\n" -#: tools/gpg-connect-agent.c:72 tools/gpgconf.c:80 tools/symcryptrun.c:164 msgid "quiet" msgstr "Reduzierte Informationen" -#: tools/gpg-connect-agent.c:73 msgid "print data out hex encoded" msgstr "Druckdaten hexkodiert ausgeben" -#: tools/gpg-connect-agent.c:74 msgid "decode received data lines" msgstr "Dekodiere empfangene Datenzeilen" -#: tools/gpg-connect-agent.c:76 msgid "|NAME|connect to Assuan socket NAME" msgstr "|NAME|Verbinde mit dem Assuan-Socket NAME" -#: tools/gpg-connect-agent.c:78 msgid "|ADDR|connect to Assuan server at ADDR" msgstr "|ADDR|Verbinde mit dem Assuan-Server an Adresse ADDR" -#: tools/gpg-connect-agent.c:80 msgid "run the Assuan server given on the command line" msgstr "Starten des auf der Kommandozeile angegebenen Assuan-Server" -#: tools/gpg-connect-agent.c:82 msgid "do not use extended connect mode" msgstr "Den \"extended connect\"-Modus nicht nutzen" -#: tools/gpg-connect-agent.c:84 msgid "|FILE|run commands from FILE on startup" msgstr "|DATEI|Beim Starten Kommandos aus DATEI lesen" -#: tools/gpg-connect-agent.c:85 msgid "run /subst on startup" msgstr "Nach dem Starten \"/subst\" ausführen" -#: tools/gpg-connect-agent.c:191 msgid "Usage: gpg-connect-agent [options] (-h for help)" msgstr "Aufruf: gpg-connect-agent [Optionen] (-h für Hilfe)" -#: tools/gpg-connect-agent.c:194 msgid "" "Syntax: gpg-connect-agent [options]\n" "Connect to a running agent and send commands\n" @@ -9476,236 +7487,177 @@ msgstr "" "Syntax: gpg-connect-agent [Optionen]\n" "Mit einem laufenden Agenten verbinden und Befehle senden\n" -#: tools/gpg-connect-agent.c:1218 #, c-format msgid "option \"%s\" requires a program and optional arguments\n" msgstr "Option \"%s\" erfordert ein Programm und evtl. Argumente\n" -#: tools/gpg-connect-agent.c:1229 tools/gpg-connect-agent.c:1235 -#: tools/gpg-connect-agent.c:1241 #, c-format msgid "option \"%s\" ignored due to \"%s\"\n" msgstr "Option \"%s\" wird wegen \"%s\" nicht beachtet\n" -#: tools/gpg-connect-agent.c:1339 tools/gpg-connect-agent.c:1829 #, c-format msgid "receiving line failed: %s\n" msgstr "Empfangen der Zeile schlug fehl: %s\n" -#: tools/gpg-connect-agent.c:1429 msgid "line too long - skipped\n" msgstr "Zeile zu lang - übersprungen\n" -#: tools/gpg-connect-agent.c:1433 msgid "line shortened due to embedded Nul character\n" msgstr "Zeile wegen enthaltenem Nul-Zeichen gekürzt\n" -#: tools/gpg-connect-agent.c:1801 #, c-format msgid "unknown command `%s'\n" msgstr "unbekannter Befehl `%s'\n" -#: tools/gpg-connect-agent.c:1819 #, c-format msgid "sending line failed: %s\n" msgstr "Senden der Zeile schlug fehl: %s\n" -#: tools/gpg-connect-agent.c:2184 #, c-format msgid "error sending standard options: %s\n" msgstr "Fehler beim Senden der Standardoptionen: %s\n" -#: tools/gpgconf-comp.c:481 tools/gpgconf-comp.c:589 tools/gpgconf-comp.c:659 -#: tools/gpgconf-comp.c:737 tools/gpgconf-comp.c:832 msgid "Options controlling the diagnostic output" msgstr "Optionen zur Einstellung der Diagnoseausgaben" -#: tools/gpgconf-comp.c:494 tools/gpgconf-comp.c:602 tools/gpgconf-comp.c:672 -#: tools/gpgconf-comp.c:750 tools/gpgconf-comp.c:855 msgid "Options controlling the configuration" msgstr "Optionen zur Einstellung der Konfiguration" -#: tools/gpgconf-comp.c:504 tools/gpgconf-comp.c:627 tools/gpgconf-comp.c:693 -#: tools/gpgconf-comp.c:779 tools/gpgconf-comp.c:862 msgid "Options useful for debugging" msgstr "Nützliche Optionen zur Fehlersuche" -#: tools/gpgconf-comp.c:517 tools/gpgconf-comp.c:637 tools/gpgconf-comp.c:792 msgid "Options controlling the security" msgstr "Optionen zur Einstellung der Sicherheit" -#: tools/gpgconf-comp.c:524 msgid "|N|expire SSH keys after N seconds" msgstr "|N|lasse SSH Schlüssel im Cache nach N Sekunden verfallen" -#: tools/gpgconf-comp.c:528 msgid "|N|set maximum PIN cache lifetime to N seconds" msgstr "|N|setze die maximale Lebensdauer von PINs im Cache auf N Sekunden" -#: tools/gpgconf-comp.c:532 msgid "|N|set maximum SSH key lifetime to N seconds" msgstr "|N|setze die maximale Lebenszeit von SSH Schlüsseln auf N Sekunden" -#: tools/gpgconf-comp.c:546 msgid "Options enforcing a passphrase policy" msgstr "Optionen für eine Passphrase-Policy" -#: tools/gpgconf-comp.c:549 msgid "do not allow to bypass the passphrase policy" msgstr "Einhaltung der Passphrase-Policy erzwingen" -#: tools/gpgconf-comp.c:553 msgid "|N|set minimal required length for new passphrases to N" msgstr "|N|setze die kleinste erlaubte Länge von Passphrasen auf N" -#: tools/gpgconf-comp.c:557 msgid "|N|require at least N non-alpha characters for a new passphrase" msgstr "|N|Verlange mindestens N Nicht-Buchstaben für eine neue Passphrase" -#: tools/gpgconf-comp.c:561 msgid "|FILE|check new passphrases against pattern in FILE" msgstr "|DATEI|Prüfe neue Passphrases gegen die Regelen in DATEI" -#: tools/gpgconf-comp.c:565 msgid "|N|expire the passphrase after N days" msgstr "|N|Lasse die Passphrase nach N Tagen verfallen" -#: tools/gpgconf-comp.c:569 msgid "do not allow the reuse of old passphrases" msgstr "Verbiete die Wiedernutzung alter Passphrases." -#: tools/gpgconf-comp.c:674 tools/gpgconf-comp.c:752 msgid "|NAME|use NAME as default secret key" msgstr "|NAME|NAME als voreingestellten Schlüssel benutzen" -#: tools/gpgconf-comp.c:677 tools/gpgconf-comp.c:755 msgid "|NAME|encrypt to user ID NAME as well" msgstr "|NAME|Auch an NAME verschlüsseln" -#: tools/gpgconf-comp.c:680 msgid "|SPEC|set up email aliases" msgstr "|SPEC|Email Alias festlegen" -#: tools/gpgconf-comp.c:706 msgid "Configuration for Keyservers" msgstr "Konfiguration der Schlüsselserver" -#: tools/gpgconf-comp.c:708 msgid "|URL|use keyserver at URL" msgstr "Benutze Schlüsselserver unter der URL" -#: tools/gpgconf-comp.c:711 msgid "allow PKA lookups (DNS requests)" msgstr "Erlaube PKA Zugriffe (DNS Anfragen)" -#: tools/gpgconf-comp.c:714 msgid "|MECHANISMS|use MECHANISMS to locate keys by mail address" msgstr "" "|MECHANISMEN|Benutze MECHANISMEN um Schlüssel über die Mailadresse " "aufzufinden." -#: tools/gpgconf-comp.c:764 msgid "disable all access to the dirmngr" msgstr "Jeglichen Zugriff auf den Dirmngr verhindern" -#: tools/gpgconf-comp.c:767 msgid "|NAME|use encoding NAME for PKCS#12 passphrases" msgstr "|NAME|Benutze die Kodierung NAME für PKCS#12 Passphrasen" -#: tools/gpgconf-comp.c:797 msgid "do not check CRLs for root certificates" msgstr "CRL bei Wurzelzertifikaten nicht überprüfen" -#: tools/gpgconf-comp.c:845 msgid "Options controlling the format of the output" msgstr "Optionen zum Einstellen der Ausgabeformate" -#: tools/gpgconf-comp.c:881 msgid "Options controlling the interactivity and enforcement" msgstr "Optionen zur Einstellung der Interaktivität und Geltendmachung" -#: tools/gpgconf-comp.c:891 msgid "Configuration for HTTP servers" msgstr "Konfiguration für HTTP Server" -#: tools/gpgconf-comp.c:902 msgid "use system's HTTP proxy setting" msgstr "Benutze die HTTP Proxy Einstellung des Systems" -#: tools/gpgconf-comp.c:907 msgid "Configuration of LDAP servers to use" msgstr "Konfiguration der zu nutzenden LDAP-Server" -#: tools/gpgconf-comp.c:936 msgid "LDAP server list" msgstr "Liste der LDAP Server" -#: tools/gpgconf-comp.c:944 msgid "Configuration for OCSP" msgstr "Konfiguration zu OCSP" -#: tools/gpgconf-comp.c:3091 #, c-format msgid "External verification of component %s failed" msgstr "Die externe Überprüfung der Komponente %s war nicht erfolgreich" -#: tools/gpgconf-comp.c:3241 msgid "Note that group specifications are ignored\n" msgstr "Beachten Sie, daß Gruppenspezifiaktionen ignoriert werden\n" -#: tools/gpgconf.c:61 msgid "list all components" msgstr "Liste aller Komponenten" -#: tools/gpgconf.c:62 msgid "check all programs" msgstr "Prüfe alle Programme" -#: tools/gpgconf.c:63 msgid "|COMPONENT|list options" msgstr "|KOMPONENTE|Zeige die Optionen an" -#: tools/gpgconf.c:64 msgid "|COMPONENT|change options" msgstr "|KOMPONENTE|Ändere die Optionen" -#: tools/gpgconf.c:65 msgid "|COMPONENT|check options" msgstr "|KOMPONENTE|Prüfe die Optionen" -#: tools/gpgconf.c:67 msgid "apply global default values" msgstr "Wende die gobalen Voreinstellungen an" -#: tools/gpgconf.c:69 msgid "get the configuration directories for gpgconf" msgstr "Hole die Einstellungsverzeichnisse von gpgconf" -#: tools/gpgconf.c:71 msgid "list global configuration file" msgstr "Zeige die globale Konfigurationsdatei an" -#: tools/gpgconf.c:73 msgid "check global configuration file" msgstr "Prüfe die globale Konfigurationsdatei" -#: tools/gpgconf.c:74 msgid "reload all or a given component" msgstr "\"reload\" an alle oder eine Komponente senden" -#: tools/gpgconf.c:78 msgid "use as output file" msgstr "Als Ausgabedatei benutzen" -#: tools/gpgconf.c:82 msgid "activate changes at runtime, if possible" msgstr "Aktiviere Änderungen zur Laufzeit; falls möglich" -#: tools/gpgconf.c:104 msgid "Usage: gpgconf [options] (-h for help)" msgstr "Aufruf: gpgconf [Optionen] (-h für Hilfe)" -#: tools/gpgconf.c:107 msgid "" "Syntax: gpgconf [options]\n" "Manage configuration options for tools of the GnuPG system\n" @@ -9713,23 +7665,18 @@ msgstr "" "Syntax: gpgconf {Optionen]\n" "Verwalte Konfigurationsoptionen für Programme des GnuPG Systems\n" -#: tools/gpgconf.c:213 tools/gpgconf.c:281 msgid "usage: gpgconf [options] " msgstr "Aufruf: gpgconf [Optionen] " -#: tools/gpgconf.c:215 msgid "Need one component argument" msgstr "Benötige ein Komponentenargument" -#: tools/gpgconf.c:224 tools/gpgconf.c:257 msgid "Component not found" msgstr "Komponente nicht gefunden" -#: tools/gpgconf.c:283 msgid "No argument allowed" msgstr "Argumente sind nicht erlaubt" -#: tools/symcryptrun.c:151 msgid "" "@\n" "Commands:\n" @@ -9739,35 +7686,27 @@ msgstr "" "@KBefehle:\n" " " -#: tools/symcryptrun.c:153 msgid "decryption modus" msgstr "Entschlüsselungsmodus" -#: tools/symcryptrun.c:154 msgid "encryption modus" msgstr "Verschlüsselungsmodus" -#: tools/symcryptrun.c:158 msgid "tool class (confucius)" msgstr "Toolklasse (Konfuzius)" -#: tools/symcryptrun.c:159 msgid "program filename" msgstr "Programmdateiname" -#: tools/symcryptrun.c:161 msgid "secret key file (required)" msgstr "Dateiname des geheimen Schlüssels (erforderlich)" -#: tools/symcryptrun.c:162 msgid "input file name (default stdin)" msgstr "Eingabedateiname (Standardeingabe ist voreingestellt)" -#: tools/symcryptrun.c:206 msgid "Usage: symcryptrun [options] (-h for help)" msgstr "Aufruf: symcryptrun [Optionen] (-h für Hilfe)" -#: tools/symcryptrun.c:209 msgid "" "Syntax: symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE " "[options...] COMMAND [inputfile]\n" @@ -9777,131 +7716,104 @@ msgstr "" "SCHLUESSELDATEI [Optionen...] KOMMANDO [Eingabedatei]\n" "Aufruf eines einfachen symmetrischen Verschlüsselungstool\n" -#: tools/symcryptrun.c:278 #, c-format msgid "%s on %s aborted with status %i\n" msgstr "%s auf %s brach mit Status %i ab\n" -#: tools/symcryptrun.c:285 #, c-format msgid "%s on %s failed with status %i\n" msgstr "%s auf %s schlug mit Status %i fehl\n" -#: tools/symcryptrun.c:317 #, c-format msgid "can't create temporary directory `%s': %s\n" msgstr "Das temporäre Verzeichnis `%s' kann nicht erstellt werden: %s\n" -#: tools/symcryptrun.c:357 tools/symcryptrun.c:374 #, c-format msgid "could not open %s for writing: %s\n" msgstr "%s kann nicht zum Schreiben geöffnet werden: %s\n" -#: tools/symcryptrun.c:385 #, c-format msgid "error writing to %s: %s\n" msgstr "Fehler beim Schreiben von %s: %s\n" -#: tools/symcryptrun.c:392 #, c-format msgid "error reading from %s: %s\n" msgstr "Fehler beim Lesen von %s: %s\n" -#: tools/symcryptrun.c:399 tools/symcryptrun.c:406 #, c-format msgid "error closing %s: %s\n" msgstr "Fehler beim Schließen von %s: %s\n" -#: tools/symcryptrun.c:491 msgid "no --program option provided\n" msgstr "Option --program nicht angegeben\n" -#: tools/symcryptrun.c:497 msgid "only --decrypt and --encrypt are supported\n" msgstr "nur --decrypt und --encrypt sind vorhanden\n" -#: tools/symcryptrun.c:503 msgid "no --keyfile option provided\n" msgstr "keine --keyfile -Option angegeben\n" -#: tools/symcryptrun.c:514 msgid "cannot allocate args vector\n" msgstr "Kann \"args-vector\" nicht zuteilen\n" -#: tools/symcryptrun.c:532 #, c-format msgid "could not create pipe: %s\n" msgstr "Pipe kann nicht erzeugt werden: %s\n" -#: tools/symcryptrun.c:539 #, c-format msgid "could not create pty: %s\n" msgstr "Pty kann nicht erzeugt werden: %s\n" -#: tools/symcryptrun.c:555 #, c-format msgid "could not fork: %s\n" msgstr "Kann nicht fork()en: %s\n" -#: tools/symcryptrun.c:583 #, c-format msgid "execv failed: %s\n" msgstr "Der execv()-Aufruf ist fehlgeschlagen: %s\n" -#: tools/symcryptrun.c:612 #, c-format msgid "select failed: %s\n" msgstr "Der select()-Aufruf ist fehlgeschlagen: %s\n" -#: tools/symcryptrun.c:629 #, c-format msgid "read failed: %s\n" msgstr "Lesen schlug fehl: %s\n" -#: tools/symcryptrun.c:681 #, c-format msgid "pty read failed: %s\n" msgstr "\"pty read\"-Aufruf ist fehlgeschlagen: %s\n" -#: tools/symcryptrun.c:733 #, c-format msgid "waitpid failed: %s\n" msgstr "Der waitpid()-Aufruf ist fehlgeschlagen: %s\n" -#: tools/symcryptrun.c:747 #, c-format msgid "child aborted with status %i\n" msgstr "Kind brach mit Status %i ab\n" -#: tools/symcryptrun.c:802 #, c-format msgid "cannot allocate infile string: %s\n" msgstr "Kann In-Datei-Zeichenkette keinen Speicher zuteilen: %s\n" -#: tools/symcryptrun.c:815 #, c-format msgid "cannot allocate outfile string: %s\n" msgstr "Kann Out-Datei-Zeichenkette keinen Speicher zuteilen: %s\n" -#: tools/symcryptrun.c:989 #, c-format msgid "either %s or %s must be given\n" msgstr "entweder %s oder %s muß angegeben sein\n" -#: tools/symcryptrun.c:1016 msgid "no class provided\n" msgstr "keine Klasse angegeben\n" -#: tools/symcryptrun.c:1025 #, c-format msgid "class %s is not supported\n" msgstr "Klasse %s wird nicht unterstützt\n" -#: tools/gpg-check-pattern.c:145 msgid "Usage: gpg-check-pattern [options] patternfile (-h for help)\n" msgstr "Aufruf: gpg-check-pattern [Optionen] Musterdatei (-h für Hilfe)\n" -#: tools/gpg-check-pattern.c:148 msgid "" "Syntax: gpg-check-pattern [options] patternfile\n" "Check a passphrase given on stdin against the patternfile\n" From 0fb0bb8d9a960a2473ab70a021d20639a43227e0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 31 Jan 2011 09:27:06 +0100 Subject: [PATCH 21/26] 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 +- g10/ChangeLog | 34 +++++ g10/build-packet.c | 93 ++++++-------- g10/ecdh.c | 26 ++-- g10/keygen.c | 227 ++++++++++++++++++--------------- g10/keyid.c | 21 ++-- g10/main.h | 11 +- g10/misc.c | 304 +++++++++++++++++++++++++++++++++++++++++---- g10/parse-packet.c | 205 +++++++++++------------------- g10/pkglue.c | 48 +++++-- g10/pkglue.h | 2 +- 12 files changed, 622 insertions(+), 359 deletions(-) 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 } }; diff --git a/g10/ChangeLog b/g10/ChangeLog index b27601563..f6c144d7c 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,37 @@ +2011-01-30 Werner Koch + + + * keyid.c (keygrip_from_pk): Adjust ECC cases. + * pkglue.c (pk_verify): Ditto. + + * parse-packet.c (read_size_body): Rewrite. + (parse_key): Simply ECC case. + (parse_pubkeyenc): Ditto. + + * misc.c (pubkey_get_npkey): Special case ECC. + (pubkey_get_nskey): Ditto. + (mpi_print): Support printfing of opaque values. + (openpgp_oid_to_str): New. + (pubkey_nbits): For ECC pass curve parameter. + + * ecdh.c (pk_ecdh_default_params): Change to return an opaque MPI. + + * build-packet.c (do_key): Automatically handle real and opaque + key parameters. + (write_fake_data): Return an error code. + (mpi_write): Support writing opaque MPIs. + (do_pubkey_enc): Simplify ECC handling. + +2011-01-28 Werner Koch + + * keygen.c (gen_ecc): Rewrite. Select a named curve and create a + keyspec based on that. + (pk_ecc_build_key_params): Remove. + (get_parameter_algo): Map algo number. + (ecckey_from_sexp): New. + * misc.c (map_pk_gcry_to_openpgp): New. + (openpgp_oid_from_str): New. Based on libksba code. + 2011-01-26 Werner Koch * misc.c (ecdsa_qbits_from_Q): Use unsigned int. diff --git a/g10/build-packet.c b/g10/build-packet.c index e2bbdb511..122ef15e7 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -1,6 +1,6 @@ /* build-packet.c - assemble packets and write them * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - * 2006, 2010 Free Software Foundation, Inc. + * 2006, 2010, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -160,19 +160,31 @@ build_packet( IOBUF out, PACKET *pkt ) static int mpi_write (iobuf_t out, gcry_mpi_t a) { - char buffer[(MAX_EXTERN_MPI_BITS+7)/8+2]; /* 2 is for the mpi length. */ - size_t nbytes; int rc; - nbytes = DIM(buffer); - rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a ); - if( !rc ) - rc = iobuf_write( out, buffer, nbytes ); - else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT ) + if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) { - log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a)); - /* The buffer was too small. We better tell the user about the MPI. */ - rc = gpg_error (GPG_ERR_TOO_LARGE); + size_t nbits; + const void *p; + + p = gcry_mpi_get_opaque (a, &nbits); + rc = iobuf_write (out, p, (nbits+7)/8); + } + else + { + char buffer[(MAX_EXTERN_MPI_BITS+7)/8+2]; /* 2 is for the mpi length. */ + size_t nbytes; + + nbytes = DIM(buffer); + rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a ); + if( !rc ) + rc = iobuf_write( out, buffer, nbytes ); + else if (gpg_err_code(rc) == GPG_ERR_TOO_SHORT ) + { + log_info ("mpi too large (%u bits)\n", gcry_mpi_get_nbits (a)); + /* The buffer was too small. We better tell the user about the MPI. */ + rc = gpg_error (GPG_ERR_TOO_LARGE); + } } return rc; @@ -252,19 +264,20 @@ calc_packet_length( PACKET *pkt ) return n; } -static void + +static gpg_error_t write_fake_data (IOBUF out, gcry_mpi_t a) { - if (a) - { - unsigned int n; - void *p; + unsigned int n; + void *p; - p = gcry_mpi_get_opaque ( a, &n ); - iobuf_write (out, p, (n+7)/8 ); - } + if (!a) + return 0; + p = gcry_mpi_get_opaque ( a, &n); + return iobuf_write (out, p, (n+7)/8 ); } + static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid ) { @@ -326,33 +339,11 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) } assert (npkey < nskey); - /* Writing the public parameters is easy. Except if we do an - adjustment for ECC OID and possibly KEK params for ECDH. */ - if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA - || pk->pubkey_algo == PUBKEY_ALGO_ECDH) + for (i=0; i < npkey; i++ ) { - /* Write DER of OID with preceeding length byte. */ - err = write_size_body_mpi (a, pk->pkey[0]); + err = mpi_write (a, pk->pkey[i]); if (err) goto leave; - /* Write point Q, the public key. */ - err = mpi_write (a, pk->pkey[1]); - if (err) - goto leave; - - /* Write one more public field for ECDH. */ - if (pk->pubkey_algo == PUBKEY_ALGO_ECDH) - { - err = write_size_body_mpi (a, pk->pkey[2]); - if (err) - goto leave; - } - } - else - { - for (i=0; i < npkey; i++ ) - if ((err = mpi_write (a, pk->pkey[i]))) - goto leave; } @@ -520,20 +511,8 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) if ( !n ) write_fake_data( a, enc->data[0] ); - if (enc->pubkey_algo == PUBKEY_ALGO_ECDH ) - { - /* The second field persists as a LEN+field structure, even - * though it is stored for uniformity as an MPI internally. */ - assert (n == 2); - rc = mpi_write (a, enc->data[0]); - if (!rc) - rc = write_size_body_mpi (a, enc->data[1]); - } - else - { - for (i=0; i < n && !rc ; i++ ) - rc = mpi_write(a, enc->data[i] ); - } + for (i=0; i < n && !rc ; i++ ) + rc = mpi_write (a, enc->data[i]); if (!rc) { diff --git a/g10/ecdh.c b/g10/ecdh.c index 95bd8668f..cf002b957 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -48,16 +48,17 @@ static const struct -/* Returns allocated (binary) KEK parameters; the size is returned in - sizeout. The caller must free the returned value. Returns NULL - and sets ERRNO on error. */ -byte * -pk_ecdh_default_params (unsigned int qbits, size_t *sizeout) +/* Return KEK parameters as an opaque MPI The caller must free the + returned value. Returns NULL and sets ERRNO on error. */ +gcry_mpi_t +pk_ecdh_default_params (unsigned int qbits) { - byte kek_params[4]; + byte *kek_params; int i; - byte *buffer; + kek_params = xtrymalloc (4); + if (!kek_params) + return NULL; kek_params[0] = 3; /* Number of bytes to follow. */ kek_params[1] = 1; /* Version for KDF+AESWRAP. */ @@ -78,12 +79,7 @@ pk_ecdh_default_params (unsigned int qbits, size_t *sizeout) if (DBG_CIPHER) log_printhex ("ECDH KEK params are", kek_params, sizeof(kek_params) ); - buffer = xtrymalloc (sizeof(kek_params)); - if (!buffer) - return NULL; - memcpy (buffer, kek_params, sizeof (kek_params)); - *sizeout = sizeof (kek_params); - return buffer; + return gcry_mpi_set_opaque (NULL, kek_params, 4 * 8); } @@ -411,8 +407,8 @@ gen_k (unsigned nbits) unsigned char *buffer; if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, k)) BUG (); - log_debug("ephemeral scalar MPI #0: %s\n", buffer); - gcry_free( buffer ); + log_debug ("ephemeral scalar MPI #0: %s\n", buffer); + gcry_free (buffer); } return k; 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. */ - } + /* 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"; - 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)) ); + 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 */ diff --git a/g10/keyid.c b/g10/keyid.c index 0405b8b2f..6571a51c0 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -724,17 +724,20 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array) case PUBKEY_ALGO_ECDSA: case PUBKEY_ALGO_ECDH: - err = gcry_sexp_build (&s_pkey, NULL, - "(public-key(ecc(c%m)(q%m)))", - pk->pkey[0], pk->pkey[1]); + { + char *curve = openpgp_oid_to_str (pk->pkey[0]); + if (!curve) + err = gpg_error_from_syserror (); + else + { + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(ecc(curve%s)(q%m)))", + curve, pk->pkey[1]); + xfree (curve); + } + } break; - /* case PUBKEY_ALGO_ECDH: */ - /* err = gcry_sexp_build (&s_pkey, NULL, */ - /* "(public-key(ecdh(c%m)(q%m)(p%m)))", */ - /* pk->pkey[0], pk->pkey[1], pk->pkey[2]); */ - /* break; */ - default: err = gpg_error (GPG_ERR_PUBKEY_ALGO); break; diff --git a/g10/main.h b/g10/main.h index 4cec61f9d..d76d96bc4 100644 --- a/g10/main.h +++ b/g10/main.h @@ -97,6 +97,7 @@ int openpgp_cipher_blocklen (int algo); int openpgp_cipher_test_algo( int algo ); const char *openpgp_cipher_algo_name (int algo); int map_pk_openpgp_to_gcry (int algo); +int map_pk_gcry_to_openpgp (enum gcry_pk_algos algo); int openpgp_pk_test_algo( int algo ); int openpgp_pk_test_algo2 ( int algo, unsigned int use ); int openpgp_pk_algo_usage ( int algo ); @@ -154,15 +155,21 @@ int is_valid_mailbox (const char *name); const char *get_libexecdir (void); int path_access(const char *file,int mode); -/* Temporary helpers. */ int pubkey_get_npkey( int algo ); int pubkey_get_nskey( int algo ); int pubkey_get_nsig( int algo ); int pubkey_get_nenc( int algo ); + +/* Temporary helpers. */ unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey ); int mpi_print (estream_t stream, gcry_mpi_t a, int mode); unsigned int ecdsa_qbits_from_Q (unsigned int qbits); +/* Other stuff */ +gpg_error_t openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi); +char *openpgp_oid_to_str (gcry_mpi_t a); + + /*-- status.c --*/ void set_status_fd ( int fd ); int is_status_enabled ( void ); @@ -300,7 +307,7 @@ gpg_error_t export_pubkey_buffer (ctrl_t ctrl, const char *keyspec, int export_seckeys (ctrl_t ctrl, strlist_t users); int export_secsubkeys (ctrl_t ctrl, strlist_t users); -/* dearmor.c --*/ +/*-- dearmor.c --*/ int dearmor_file( const char *fname ); int enarmor_file( const char *fname ); diff --git a/g10/misc.c b/g10/misc.c index dc2f73be4..2052e96c7 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -379,6 +379,19 @@ map_pk_openpgp_to_gcry (int algo) } } +/* Map Gcrypt public key algorithm numbers to those used by + OpenPGP. */ +int +map_pk_gcry_to_openpgp (enum gcry_pk_algos algo) +{ + switch (algo) + { + case GCRY_PK_ECDSA: return PUBKEY_ALGO_ECDSA; + case GCRY_PK_ECDH: return PUBKEY_ALGO_ECDH; + default: return algo < 110 ? algo : 0; + } +} + /* Return the block length of an OpenPGP cipher algorithm. */ int @@ -1347,35 +1360,44 @@ path_access(const char *file,int mode) -/* Temporary helper. */ +/* Return the number of public key parameters as used by OpenPGP. */ int -pubkey_get_npkey( int algo ) +pubkey_get_npkey (int algo) { size_t n; + /* ECC is special. */ + if (algo == PUBKEY_ALGO_ECDSA) + return 2; + else if (algo == PUBKEY_ALGO_ECDH) + return 3; + + /* All other algorithms match those of Libgcrypt. */ if (algo == GCRY_PK_ELG_E) algo = GCRY_PK_ELG; - else if (algo == PUBKEY_ALGO_ECDSA) - algo = GCRY_PK_ECDSA; - else if (algo == PUBKEY_ALGO_ECDH) - algo = GCRY_PK_ECDH; - if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &n)) + + if (gcry_pk_algo_info (algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &n)) n = 0; return n; } -/* Temporary helper. */ + +/* Return the number of secret key parameters as used by OpenPGP. */ int -pubkey_get_nskey( int algo ) +pubkey_get_nskey (int algo) { size_t n; + /* ECC is special. */ + if (algo == PUBKEY_ALGO_ECDSA) + return 3; + else if (algo == PUBKEY_ALGO_ECDH) + return 4; + + /* All other algorithms match those of Libgcrypt. */ if (algo == GCRY_PK_ELG_E) algo = GCRY_PK_ELG; - else if (algo == PUBKEY_ALGO_ECDSA) - algo = GCRY_PK_ECDSA; - else if (algo == PUBKEY_ALGO_ECDH) - algo = GCRY_PK_ECDH; + if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &n )) n = 0; return n; @@ -1383,33 +1405,40 @@ pubkey_get_nskey( int algo ) /* Temporary helper. */ int -pubkey_get_nsig( int algo ) +pubkey_get_nsig (int algo) { size_t n; + /* ECC is special. */ + if (algo == PUBKEY_ALGO_ECDSA) + return 2; + else if (algo == PUBKEY_ALGO_ECDH) + return 0; + if (algo == GCRY_PK_ELG_E) algo = GCRY_PK_ELG; - else if (algo == PUBKEY_ALGO_ECDSA) - algo = GCRY_PK_ECDSA; - else if (algo == PUBKEY_ALGO_ECDH) - algo = GCRY_PK_ECDH; + if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSIGN, NULL, &n)) n = 0; return n; } + /* Temporary helper. */ int -pubkey_get_nenc( int algo ) +pubkey_get_nenc (int algo) { size_t n; + /* ECC is special. */ + if (algo == PUBKEY_ALGO_ECDSA) + return 0; + else if (algo == PUBKEY_ALGO_ECDH) + return 2; + if (algo == GCRY_PK_ELG_E) algo = GCRY_PK_ELG; - else if (algo == PUBKEY_ALGO_ECDSA) - algo = GCRY_PK_ECDSA; - else if (algo == PUBKEY_ALGO_ECDH) - algo = GCRY_PK_ECDH; + if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NENCR, NULL, &n )) n = 0; return n; @@ -1442,9 +1471,16 @@ pubkey_nbits( int algo, gcry_mpi_t *key ) key[0], key[1] ); } else if( algo == PUBKEY_ALGO_ECDSA || algo == PUBKEY_ALGO_ECDH ) { - rc = gcry_sexp_build ( &sexp, NULL, - "(public-key(ecc(c%m)(q%m)))", - key[0], key[1] /* not affecting the size calculation, so use 'ecc' == 'ecdsa' */ ); + char *curve = openpgp_oid_to_str (key[0]); + if (!curve) + rc = gpg_error_from_syserror (); + else + { + rc = gcry_sexp_build (&sexp, NULL, + "(public-key(ecc(curve%s)(q%m)))", + curve, key[1]); + xfree (curve); + } } else return 0; @@ -1472,6 +1508,19 @@ mpi_print (estream_t fp, gcry_mpi_t a, int mode) n1 = gcry_mpi_get_nbits(a); n += es_fprintf (fp, "[%u bits]", n1); } + else if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) + { + unsigned int nbits; + unsigned char *p = gcry_mpi_get_opaque (a, &nbits); + if (!p) + n += es_fprintf (fp, "[invalid opaque value]"); + else + { + nbits = (nbits + 7)/8; + for (; nbits; nbits--, p++) + n += es_fprintf (fp, "%02X", *p); + } + } else { unsigned char *buffer; @@ -1501,3 +1550,206 @@ ecdsa_qbits_from_Q (unsigned int qbits) qbits /= 2; return qbits; } + + + +/* Helper for openpgp_oid_from_str. */ +static size_t +make_flagged_int (unsigned long value, char *buf, size_t buflen) +{ + int more = 0; + int shift; + + /* fixme: figure out the number of bits in an ulong and start with + that value as shift (after making it a multiple of 7) a more + straigtforward implementation is to do it in reverse order using + a temporary buffer - saves a lot of compares */ + for (more=0, shift=28; shift > 0; shift -= 7) + { + if (more || value >= (1<> shift); + value -= (value >> shift) << shift; + more = 1; + } + } + buf[buflen++] = value; + return buflen; +} + + +/* Convert the OID given in dotted decimal form in STRING to an DER + * encoding and store it as an opaque value at R_MPI. The format of + * the DER encoded is not a regular ASN.1 object but the modified + * format as used by OpenPGP for the ECC curve description. On error + * the function returns and error code an NULL is stored at R_BUG. + * Note that scanning STRING stops at the first white space + * character. */ +gpg_error_t +openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi) +{ + unsigned char *buf; + size_t buflen; + unsigned long val1, val; + const char *endp; + int arcno; + + *r_mpi = NULL; + + if (!string || !*string) + return gpg_error (GPG_ERR_INV_VALUE); + + /* We can safely assume that the encoded OID is shorter than the string. */ + buf = xtrymalloc (1 + strlen (string) + 2); + if (!buf) + return gpg_error_from_syserror (); + /* Save the first byte for the length. */ + buflen = 1; + + val1 = 0; /* Avoid compiler warning. */ + arcno = 0; + do { + arcno++; + val = strtoul (string, (char**)&endp, 10); + if (!digitp (string) || !(*endp == '.' || !*endp)) + { + xfree (buf); + return gpg_error (GPG_ERR_INV_OID_STRING); + } + if (*endp == '.') + string = endp+1; + + if (arcno == 1) + { + if (val > 2) + break; /* Not allowed, error catched below. */ + val1 = val; + } + else if (arcno == 2) + { /* Need to combine the first two arcs in one octet. */ + if (val1 < 2) + { + if (val > 39) + { + xfree (buf); + return gpg_error (GPG_ERR_INV_OID_STRING); + } + buf[buflen++] = val1*40 + val; + } + else + { + val += 80; + buflen = make_flagged_int (val, buf, buflen); + } + } + else + { + buflen = make_flagged_int (val, buf, buflen); + } + } while (*endp == '.'); + + if (arcno == 1 || buflen < 2 || buflen > 254 ) + { /* It is not possible to encode only the first arc. */ + xfree (buf); + return gpg_error (GPG_ERR_INV_OID_STRING); + } + + *buf = buflen - 1; + *r_mpi = gcry_mpi_set_opaque (NULL, buf, buflen * 8); + if (!*r_mpi) + { + xfree (buf); + return gpg_error_from_syserror (); + } + return 0; +} + + +/* Return a malloced string represenation of the OID in the opaque MPI + A. In case of an error NULL is returned and ERRNO is set. */ +char * +openpgp_oid_to_str (gcry_mpi_t a) +{ + const unsigned char *buf; + size_t length; + char *string, *p; + int n = 0; + unsigned long val, valmask; + + valmask = (unsigned long)0xfe << (8 * (sizeof (valmask) - 1)); + + if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) + { + gpg_err_set_errno (EINVAL); + return NULL; + } + + buf = gcry_mpi_get_opaque (a, &length); + length = (length+7)/8; + + /* The first bytes gives the length; check consistency. */ + if (!length || buf[0] != length -1) + { + gpg_err_set_errno (EINVAL); + return NULL; + } + /* Skip length byte. */ + length--; + buf++; + + /* To calculate the length of the string we can safely assume an + upper limit of 3 decimal characters per byte. Two extra bytes + account for the special first octect */ + string = p = xtrymalloc (length*(1+3)+2+1); + if (!string) + return NULL; + if (!buf || !length) + { + *p = 0; + return string; + } + + if (buf[0] < 40) + p += sprintf (p, "0.%d", buf[n]); + else if (buf[0] < 80) + p += sprintf (p, "1.%d", buf[n]-40); + else { + val = buf[n] & 0x7f; + while ( (buf[n]&0x80) && ++n < length ) + { + if ( (val & valmask) ) + goto badoid; /* Overflow. */ + val <<= 7; + val |= buf[n] & 0x7f; + } + val -= 80; + sprintf (p, "2.%lu", val); + p += strlen (p); + } + for (n++; n < length; n++) + { + val = buf[n] & 0x7f; + while ( (buf[n]&0x80) && ++n < length ) + { + if ( (val & valmask) ) + goto badoid; /* Overflow. */ + val <<= 7; + val |= buf[n] & 0x7f; + } + sprintf (p, ".%lu", val); + p += strlen (p); + } + + *p = 0; + return string; + + badoid: + /* Return a special OID (gnu.gnupg.badoid) to indicate the error + case. The OID is broken and thus we return one which can't do + any harm. Formally this does not need to be a bad OID but an OID + with an arc that can't be represented in a 32 bit word is more + than likely corrupt. */ + xfree (string); + return xtrystrdup ("1.3.6.1.4.1.11591.2.12242973"); +} + diff --git a/g10/parse-packet.c b/g10/parse-packet.c index a0844c7ac..83be15d8c 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -741,51 +741,57 @@ read_rest (IOBUF inp, size_t pktlen, int partial) } -/* - * Read a special size+body from inp into body[body_max_size] and - * return it in a buffer and as MPI. On success the number of - * consumed bytes will body[0]+1. The format of the content of the - * returned MPI is one byte LEN, following by LEN bytes. Caller is - * expected to pre-allocate fixed-size 255 byte buffer (or smaller - * when appropriate). - */ -static int -read_size_body (iobuf_t inp, byte *body, int body_max_size, - int pktlen, gcry_mpi_t *out ) +/* Read a special size+body from INP. On success store an opaque MPI + with it at R_DATA. On error return an error code and store NULL at + R_DATA. Even in the error case store the number of read bytes at + R_NREAD. The caller shall pass the remaining size of the packet in + PKTLEN. */ +static gpg_error_t +read_size_body (iobuf_t inp, int pktlen, size_t *r_nread, + gcry_mpi_t *r_data) { - unsigned int n; - int rc; - gcry_mpi_t result; + char buffer[256]; + char *tmpbuf; + int i, c, nbytes; - *out = NULL; + *r_nread = 0; + *r_data = NULL; - if( (n = iobuf_readbyte(inp)) == -1 ) - { - return G10ERR_INVALID_PACKET; - } - if ( n >= body_max_size || n < 2) - { - log_error("invalid size+body field\n"); - return G10ERR_INVALID_PACKET; - } - body[0] = n; - if ((n = iobuf_read(inp, body+1, n)) == -1) - { - log_error("invalid size+body field\n"); - return G10ERR_INVALID_PACKET; - } - if (n+1 > pktlen) - { - log_error("size+body field is larger than the packet\n"); - return G10ERR_INVALID_PACKET; - } - rc = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, body, n+1, NULL); - if (rc) - log_fatal ("mpi_scan failed: %s\n", gpg_strerror (rc)); + if (!pktlen) + return gpg_error (GPG_ERR_INV_PACKET); + c = iobuf_readbyte (inp); + if (c < 0) + return gpg_error (GPG_ERR_INV_PACKET); + pktlen--; + ++*r_nread; + nbytes = c; + if (nbytes < 2 || nbytes > 254) + return gpg_error (GPG_ERR_INV_PACKET); + if (nbytes > pktlen) + return gpg_error (GPG_ERR_INV_PACKET); - *out = result; + buffer[0] = nbytes; - return rc; + for (i = 0; i < nbytes; i++) + { + c = iobuf_get (inp); + if (c < 0) + return gpg_error (GPG_ERR_INV_PACKET); + ++*r_nread; + buffer[1+i] = c; + } + + tmpbuf = xtrymalloc (1 + nbytes); + if (!tmpbuf) + return gpg_error_from_syserror (); + memcpy (tmpbuf, buffer, 1 + nbytes); + *r_data = gcry_mpi_set_opaque (NULL, tmpbuf, 8 * (1 + nbytes)); + if (!*r_data) + { + xfree (tmpbuf); + return gpg_error_from_syserror (); + } + return 0; } @@ -988,46 +994,29 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, } else { - if (k->pubkey_algo == PUBKEY_ALGO_ECDH) + for (i = 0; i < ndata; i++) { - byte encr_buf[255]; - - assert (ndata == 2); - n = pktlen; - k->data[0] = mpi_read (inp, &n, 0); - pktlen -= n; - rc = read_size_body (inp, encr_buf, sizeof(encr_buf), - pktlen, k->data+1); - if (rc) - goto leave; - - if (list_mode) + if (k->pubkey_algo == PUBKEY_ALGO_ECDH && i == 1) { - es_fprintf (listfp, "\tdata: "); - mpi_print (listfp, k->data[0], mpi_print_mode ); - es_putc ('\n', listfp); - es_fprintf (listfp, "\tdata: [% 3d bytes] ", encr_buf[0]+1); - mpi_print (listfp, k->data[1], mpi_print_mode ); - es_putc ('\n', listfp); + rc = read_size_body (inp, pktlen, &n, k->data+i); + pktlen -= n; } - pktlen -= (encr_buf[0]+1); - } - else - { - for (i = 0; i < ndata; i++) + else { n = pktlen; k->data[i] = mpi_read (inp, &n, 0); pktlen -= n; - if (list_mode) - { - es_fprintf (listfp, "\tdata: "); - mpi_print (listfp, k->data[i], mpi_print_mode); - es_putc ('\n', listfp); - } if (!k->data[i]) rc = gpg_error (GPG_ERR_INV_PACKET); } + if (rc) + goto leave; + if (list_mode) + { + es_fprintf (listfp, "\tdata: "); + mpi_print (listfp, k->data[i], mpi_print_mode); + es_putc ('\n', listfp); + } } } @@ -1989,7 +1978,6 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, unknown_pubkey_warning (algorithm); } - if (!npkey) { /* Unknown algorithm - put data into an opaque MPI. */ @@ -2001,79 +1989,32 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, } else { - /* Fill in public key parameters. */ - if (algorithm == PUBKEY_ALGO_ECDSA || algorithm == PUBKEY_ALGO_ECDH) + for (i = 0; i < npkey; i++) { - /* FIXME: The code in this function ignores the errors. */ - byte name_oid[256]; - - err = read_size_body (inp, name_oid, sizeof(name_oid), - pktlen, pk->pkey+0); - if (err) - goto leave; - n = name_oid[0]; - if (list_mode) - es_fprintf (listfp, "\tpkey[0]: curve OID [%d] ...%02x %02x\n", - n, name_oid[1+n-2], name_oid[1+n-1]); - pktlen -= (n+1); - /* Set item [1], which corresponds to the public key; these - two fields are all we need to uniquely define the key/ */ - n = pktlen; - pk->pkey[1] = mpi_read( inp, &n, 0 ); - pktlen -=n; - if (!pk->pkey[1]) - err = gpg_error (GPG_ERR_INV_PACKET); - else if (list_mode) + if ((algorithm == PUBKEY_ALGO_ECDSA + || algorithm == PUBKEY_ALGO_ECDH) && (i==0 || i == 2)) { - es_fprintf (listfp, "\tpkey[1]: "); - mpi_print (listfp, pk->pkey[1], mpi_print_mode); - es_putc ('\n', listfp); - } - /* One more field for ECDH. */ - if (algorithm == PUBKEY_ALGO_ECDH) - { - /* (NAMEOID holds the KEK params.) */ - err = read_size_body (inp, name_oid, sizeof(name_oid), - pktlen, pk->pkey+2); - if (err) - goto leave; - n = name_oid[0]; - if (name_oid[1] != 1) - { - log_error ("invalid ecdh KEK parameters field type in " - "private key: understand type 1, " - "but found 0x%02x\n", name_oid[1]); - err = gpg_error (GPG_ERR_INV_PACKET); - goto leave; - } - if (list_mode) - es_fprintf (listfp, "\tpkey[2]: KEK params type=01 " - "hash:%d sym-algo:%d\n", - name_oid[1+n-2], name_oid[1+n-1]); - pktlen -= (n+1); + err = read_size_body (inp, pktlen, &n, pk->pkey+i); + pktlen -= n; } - } - else - { - for (i = 0; i < npkey; i++) + else { n = pktlen; pk->pkey[i] = mpi_read (inp, &n, 0); pktlen -= n; - if (list_mode) - { - es_fprintf (listfp, "\tpkey[%d]: ", i); - mpi_print (listfp, pk->pkey[i], mpi_print_mode); - es_putc ('\n', listfp); - } if (!pk->pkey[i]) err = gpg_error (GPG_ERR_INV_PACKET); } + if (err) + goto leave; + if (list_mode) + { + es_fprintf (listfp, "\tpkey[%d]: ", i); + mpi_print (listfp, pk->pkey[i], mpi_print_mode); + es_putc ('\n', listfp); + } } - if (err) - goto leave; } - if (list_mode) keyid_from_pk (pk, keyid); diff --git a/g10/pkglue.c b/g10/pkglue.c index 3aba4e4c1..27ee239a4 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -79,8 +79,16 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey) } else if (pkalgo == GCRY_PK_ECDSA) /* Same as GCRY_PK_ECDH */ { - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(ecdsa(c%m)(q%m)))", pkey[0], pkey[1]); + char *curve = openpgp_oid_to_str (pkey[0]); + if (!curve) + rc = gpg_error_from_syserror (); + else + { + rc = gcry_sexp_build (&s_pkey, NULL, + "(public-key(ecdsa(curve %s)(q%m)))", + curve, pkey[1]); + xfree (curve); + } } else return GPG_ERR_PUBKEY_ALGO; @@ -174,18 +182,27 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, else if (algo == PUBKEY_ALGO_ECDH) { gcry_mpi_t k; + char *curve; rc = pk_ecdh_generate_ephemeral_key (pkey, &k); if (rc) return rc; - /* Now use the ephemeral secret to compute the shared point. */ - rc = gcry_sexp_build (&s_pkey, NULL, - "(public-key(ecdh(c%m)(q%m)(p%m)))", - pkey[0], pkey[1], pkey[2]); - /* Put K into a simplified S-expression. */ - if (rc || gcry_sexp_build (&s_data, NULL, "%m", k)) - BUG (); + curve = openpgp_oid_to_str (pkey[0]); + if (!curve) + rc = gpg_error_from_syserror (); + else + { + /* Now use the ephemeral secret to compute the shared point. */ + rc = gcry_sexp_build (&s_pkey, NULL, + "(public-key(ecdh(curve%s)(q%m)))", + curve, pkey[1]); + xfree (curve); + /* FIXME: Take care of RC. */ + /* Put K into a simplified S-expression. */ + if (rc || gcry_sexp_build (&s_data, NULL, "%m", k)) + BUG (); + } } else return gpg_error (GPG_ERR_PUBKEY_ALGO); @@ -272,9 +289,16 @@ pk_check_secret_key (int algo, gcry_mpi_t *skey) } else if (gcry_pkalgo == GCRY_PK_ECDSA || gcry_pkalgo == GCRY_PK_ECDH) { - rc = gcry_sexp_build (&s_skey, NULL, - "(private-key(ecdsa(c%m)(q%m)(d%m)))", - skey[0], skey[1], skey[2] ); + char *curve = openpgp_oid_to_str (skey[0]); + if (!curve) + rc = gpg_error_from_syserror (); + else + { + rc = gcry_sexp_build (&s_skey, NULL, + "(private-key(ecdsa(curve%s)(q%m)(d%m)))", + curve, skey[1], skey[2]); + xfree (curve); + } } else return GPG_ERR_PUBKEY_ALGO; diff --git a/g10/pkglue.h b/g10/pkglue.h index 98d8c1440..eb0d7c1dc 100644 --- a/g10/pkglue.h +++ b/g10/pkglue.h @@ -32,7 +32,7 @@ int pk_check_secret_key (int algo, gcry_mpi_t *skey); /*-- ecdh.c --*/ -byte *pk_ecdh_default_params (unsigned int qbits, size_t *sizeout); +gcry_mpi_t pk_ecdh_default_params (unsigned int qbits); gpg_error_t pk_ecdh_generate_ephemeral_key (gcry_mpi_t *pkey, gcry_mpi_t *r_k); gpg_error_t pk_ecdh_encrypt_with_shared_point /* */ (int is_encrypt, gcry_mpi_t shared_mpi, From 328a642aa5ed971870a2667b06307f760fa251dc Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 31 Jan 2011 15:44:24 +0100 Subject: [PATCH 22/26] 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 +- g10/ChangeLog | 7 ++ g10/build-packet.c | 51 ++---------- g10/ecdh.c | 191 +++++++++++++++++++++++---------------------- g10/encrypt.c | 2 +- g10/packet.h | 2 +- g10/pkglue.c | 4 +- g10/pubkey-enc.c | 2 +- 9 files changed, 119 insertions(+), 147 deletions(-) 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)) { diff --git a/g10/ChangeLog b/g10/ChangeLog index f6c144d7c..587c9f158 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,10 @@ +2011-01-31 Werner Koch + + * ecdh.c (pk_ecdh_encrypt_with_shared_point): Return an opaque MPI. + + * build-packet.c (mpi_write): Rename to gpg_mpi_write and make global. + (write_size_body_mpi): Remove. + 2011-01-30 Werner Koch diff --git a/g10/build-packet.c b/g10/build-packet.c index 122ef15e7..1cdf9616c 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -157,8 +157,8 @@ build_packet( IOBUF out, PACKET *pkt ) /* * Write the mpi A to OUT. */ -static int -mpi_write (iobuf_t out, gcry_mpi_t a) +gpg_error_t +gpg_mpi_write (iobuf_t out, gcry_mpi_t a) { int rc; @@ -191,45 +191,6 @@ mpi_write (iobuf_t out, gcry_mpi_t a) } -/* - * Write a special size+body mpi A, to OUT. The format of the content - * of the MPI is one byte LEN, following by LEN bytes. - */ -gpg_error_t -write_size_body_mpi (iobuf_t out, gcry_mpi_t a) -{ - gpg_error_t err; - byte buffer[256]; /* Fixed buffer for a public parameter, max possible */ - size_t nbytes = (mpi_get_nbits (a)+7)/8; - - if (nbytes > sizeof(buffer)) - { - log_error("mpi with size+body is too large (%u bytes)\n", nbytes); - return gpg_error (GPG_ERR_TOO_LARGE); - } - - err = gcry_mpi_print (GCRYMPI_FMT_USG, buffer, sizeof(buffer), &nbytes, a); - if (err) - { - log_error ("failed to exported size+body mpi\n"); - return err; - } - if (nbytes < 2 || buffer[0] != nbytes-1) - { - if (nbytes > 2) - log_error ("internal size mismatch in mpi size+body: " - "%02x != %02x (other bytes: %02x %02x ... %02x %02x)\n", - buffer[0], nbytes-1, buffer[1], buffer[2], buffer[nbytes-2], - buffer[nbytes-1]); - else - log_error ("internal size mismatch in mpi size+body: " - "only %d bytes\n", nbytes); - return gpg_error (GPG_ERR_INV_DATA); - } - return iobuf_write (out, buffer, nbytes); -} - - /* Calculate the length of a packet described by PKT. */ u32 calc_packet_length( PACKET *pkt ) @@ -341,7 +302,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) for (i=0; i < npkey; i++ ) { - err = mpi_write (a, pk->pkey[i]); + err = gpg_mpi_write (a, pk->pkey[i]); if (err) goto leave; } @@ -436,7 +397,7 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk) { /* Non-protected key. */ for ( ; i < nskey; i++ ) - if ( (err = mpi_write (a, pk->pkey[i]))) + if ( (err = gpg_mpi_write (a, pk->pkey[i]))) goto leave; write_16 (a, ski->csum ); } @@ -512,7 +473,7 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc ) write_fake_data( a, enc->data[0] ); for (i=0; i < n && !rc ; i++ ) - rc = mpi_write (a, enc->data[i]); + rc = gpg_mpi_write (a, enc->data[i]); if (!rc) { @@ -1170,7 +1131,7 @@ do_signature( IOBUF out, int ctb, PKT_signature *sig ) if ( !n ) write_fake_data( a, sig->data[0] ); for (i=0; i < n && !rc ; i++ ) - rc = mpi_write(a, sig->data[i] ); + rc = gpg_mpi_write (a, sig->data[i] ); if (!rc) { diff --git a/g10/ecdh.c b/g10/ecdh.c index cf002b957..09ab3ed16 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -1,5 +1,5 @@ /* ecdh.c - ECDH public key operations used in public key glue code - * Copyright (C) 2010 Free Software Foundation, Inc. + * Copyright (C) 2010, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -105,11 +105,13 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, gpg_error_t err; byte *secret_x; int secret_x_size; - byte kdf_params[256]; - int kdf_params_size=0; - int nbits; + unsigned int nbits; + const unsigned char *kdf_params; + size_t kdf_params_size; int kdf_hash_algo; int kdf_encr_algo; + unsigned char message[256]; + size_t message_size; *r_result = NULL; @@ -137,12 +139,11 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, return err; } - /* fixme: explain what we are doing. */ secret_x_size = (nbits+7)/8; assert (nbytes > secret_x_size); memmove (secret_x, secret_x+1, secret_x_size); memset (secret_x+secret_x_size, 0, nbytes-secret_x_size); - + if (DBG_CIPHER) log_printhex ("ECDH shared secret X is:", secret_x, secret_x_size ); } @@ -155,38 +156,34 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, * current secret_x with a value derived from it. This will become * a KEK. */ - { - IOBUF obuf = iobuf_temp(); - err = write_size_body_mpi (obuf, pkey[2]); /* KEK params */ - - kdf_params_size = iobuf_temp_to_buffer (obuf, - kdf_params, sizeof(kdf_params)); - - if (DBG_CIPHER) - log_printhex ("ecdh KDF public key params are:", - kdf_params, kdf_params_size ); - - /* Expect 4 bytes 03 01 hash_alg symm_alg. */ - if (kdf_params_size != 4 || kdf_params[0] != 3 || kdf_params[1] != 1) - return GPG_ERR_BAD_PUBKEY; - - kdf_hash_algo = kdf_params[2]; - kdf_encr_algo = kdf_params[3]; - - if (DBG_CIPHER) - log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n", - gcry_md_algo_name (kdf_hash_algo), - openpgp_cipher_algo_name (kdf_encr_algo)); - - if (kdf_hash_algo != GCRY_MD_SHA256 - && kdf_hash_algo != GCRY_MD_SHA384 - && kdf_hash_algo != GCRY_MD_SHA512) - return GPG_ERR_BAD_PUBKEY; - if (kdf_encr_algo != GCRY_CIPHER_AES128 - && kdf_encr_algo != GCRY_CIPHER_AES192 - && kdf_encr_algo != GCRY_CIPHER_AES256) - return GPG_ERR_BAD_PUBKEY; - } + if (!gcry_mpi_get_flag (pkey[2], GCRYMPI_FLAG_OPAQUE)) + return GPG_ERR_BUG; + kdf_params = gcry_mpi_get_opaque (pkey[2], &nbits); + kdf_params_size = (nbits+7)/8; + + if (DBG_CIPHER) + log_printhex ("ecdh KDF params:", kdf_params, kdf_params_size); + + /* Expect 4 bytes 03 01 hash_alg symm_alg. */ + if (kdf_params_size != 4 || kdf_params[0] != 3 || kdf_params[1] != 1) + return GPG_ERR_BAD_PUBKEY; + + kdf_hash_algo = kdf_params[2]; + kdf_encr_algo = kdf_params[3]; + + if (DBG_CIPHER) + log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n", + openpgp_md_algo_name (kdf_hash_algo), + openpgp_cipher_algo_name (kdf_encr_algo)); + + if (kdf_hash_algo != GCRY_MD_SHA256 + && kdf_hash_algo != GCRY_MD_SHA384 + && kdf_hash_algo != GCRY_MD_SHA512) + return GPG_ERR_BAD_PUBKEY; + if (kdf_encr_algo != GCRY_CIPHER_AES128 + && kdf_encr_algo != GCRY_CIPHER_AES192 + && kdf_encr_algo != GCRY_CIPHER_AES256) + return GPG_ERR_BAD_PUBKEY; /* Build kdf_params. */ { @@ -194,18 +191,17 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, obuf = iobuf_temp(); /* variable-length field 1, curve name OID */ - err = write_size_body_mpi (obuf, pkey[0]); + err = gpg_mpi_write (obuf, pkey[0]); /* fixed-length field 2 */ iobuf_put (obuf, PUBKEY_ALGO_ECDH); /* variable-length field 3, KDF params */ - err = (err ? err : write_size_body_mpi ( obuf, pkey[2] )); + err = (err ? err : gpg_mpi_write (obuf, pkey[2])); /* fixed-length field 4 */ iobuf_write (obuf, "Anonymous Sender ", 20); /* fixed-length field 5, recipient fp */ iobuf_write (obuf, pk_fp, 20); - kdf_params_size = iobuf_temp_to_buffer (obuf, - kdf_params, sizeof(kdf_params)); + message_size = iobuf_temp_to_buffer (obuf, message, sizeof message); iobuf_close (obuf); if (err) return err; @@ -223,10 +219,10 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, err = gcry_md_open (&h, kdf_hash_algo, 0); if(err) log_bug ("gcry_md_open failed for algo %d: %s", - kdf_hash_algo, gpg_strerror (gcry_error(err))); - gcry_md_write(h, "\x00\x00\x00\x01", 4); /* counter = 1 */ - gcry_md_write(h, secret_x, secret_x_size); /* x of the point X */ - gcry_md_write(h, kdf_params, kdf_params_size); /* KDF parameters */ + kdf_hash_algo, gpg_strerror (err)); + gcry_md_write(h, "\x00\x00\x00\x01", 4); /* counter = 1 */ + gcry_md_write(h, secret_x, secret_x_size); /* x of the point X */ + gcry_md_write(h, kdf_params, kdf_params_size);/* KDF parameters */ gcry_md_final (h); @@ -320,13 +316,13 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, if (DBG_CIPHER) log_printhex ("ecdh encrypted to:", data_buf+1, data_buf[0] ); - err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, - data_buf, 1+data_buf[0], NULL); - /* (byte)size + aeswrap of DEK */ - xfree( data_buf ); - if (err) + result = gcry_mpi_set_opaque (NULL, data_buf, 8 * (1+data_buf[0])); + if (!result) { - log_error ("ecdh failed to create an MPI: %s\n", gpg_strerror (err)); + err = gpg_error_from_syserror (); + xfree (data_buf); + log_error ("ecdh failed to create an MPI: %s\n", + gpg_strerror (err)); return err; } @@ -335,55 +331,62 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, else { byte *in; + const void *p; - err = gcry_mpi_print (GCRYMPI_FMT_USG, data_buf, data_buf_size, - &nbytes, data/*in*/); - if (nbytes != data_buf_size || data_buf[0] != data_buf_size-1) + p = gcry_mpi_get_opaque (data, &nbits); + nbytes = (nbits+7)/8; + if (!p || nbytes > data_buf_size || !nbytes) + { + xfree (data_buf); + return GPG_ERR_BAD_MPI; + } + memcpy (data_buf, p, nbytes); + if (data_buf[0] != nbytes-1) { log_error ("ecdh inconsistent size\n"); xfree (data_buf); return GPG_ERR_BAD_MPI; } - in = data_buf+data_buf_size; - data_buf_size = data_buf[0]; - - if (DBG_CIPHER) - log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size); - - err = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1, - data_buf_size); - gcry_cipher_close (hd); - if (err) - { - log_error ("ecdh failed in gcry_cipher_decrypt: %s\n", - gpg_strerror (err)); - xfree (data_buf); - return err; - } - - data_buf_size -= 8; - - if (DBG_CIPHER) - log_printhex ("ecdh decrypted to :", in, data_buf_size); - - /* Padding is removed later. */ - /* if (in[data_buf_size-1] > 8 ) */ - /* { */ - /* log_error("ecdh failed at decryption: invalid padding. %02x > 8\n", */ - /* in[data_buf_size-1] ); */ - /* return GPG_ERR_BAD_KEY; */ - /* } */ + in = data_buf+data_buf_size; + data_buf_size = data_buf[0]; + + if (DBG_CIPHER) + log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size); + + err = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1, + data_buf_size); + gcry_cipher_close (hd); + if (err) + { + log_error ("ecdh failed in gcry_cipher_decrypt: %s\n", + gpg_strerror (err)); + xfree (data_buf); + return err; + } + + data_buf_size -= 8; + + if (DBG_CIPHER) + log_printhex ("ecdh decrypted to :", in, data_buf_size); + + /* Padding is removed later. */ + /* if (in[data_buf_size-1] > 8 ) */ + /* { */ + /* log_error("ecdh failed at decryption: invalid padding. %02x > 8\n", */ + /* in[data_buf_size-1] ); */ + /* return GPG_ERR_BAD_KEY; */ + /* } */ - err = gcry_mpi_scan ( &result, GCRYMPI_FMT_USG, in, data_buf_size, NULL); - xfree (data_buf); - if (err) - { - log_error ("ecdh failed to create a plain text MPI: %s\n", - gpg_strerror (err)); - return err; - } - - *r_result = result; + err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, in, data_buf_size, NULL); + xfree (data_buf); + if (err) + { + log_error ("ecdh failed to create a plain text MPI: %s\n", + gpg_strerror (err)); + return err; + } + + *r_result = result; } } diff --git a/g10/encrypt.c b/g10/encrypt.c index f52921582..8548a5739 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -921,7 +921,7 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out) { char *ustr = get_user_id_string_native (enc->keyid); log_info (_("%s/%s encrypted for: \"%s\"\n"), - gcry_pk_algo_name (enc->pubkey_algo), + openpgp_pk_algo_name (enc->pubkey_algo), openpgp_cipher_algo_name (dek->algo), ustr ); xfree (ustr); diff --git a/g10/packet.h b/g10/packet.h index d06c4c7e7..5411e524a 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -444,7 +444,7 @@ PACKET *create_gpg_control ( ctrlpkttype_t type, /*-- build-packet.c --*/ int build_packet( iobuf_t inp, PACKET *pkt ); -gpg_error_t write_size_body_mpi (iobuf_t out, gcry_mpi_t a); +gpg_error_t gpg_mpi_write (iobuf_t out, gcry_mpi_t a); u32 calc_packet_length( PACKET *pkt ); void build_sig_subpkt( PKT_signature *sig, sigsubpkttype_t type, const byte *buffer, size_t buflen ); diff --git a/g10/pkglue.c b/g10/pkglue.c index 27ee239a4..66ba48b60 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -220,8 +220,8 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t shared, public, result; /* Get the shared point and the ephemeral public key. */ - shared = mpi_from_sexp (s_ciph, "a"); - public = mpi_from_sexp (s_ciph, "b"); + shared = mpi_from_sexp (s_ciph, "s"); + public = mpi_from_sexp (s_ciph, "e"); gcry_sexp_release (s_ciph); s_ciph = NULL; if (DBG_CIPHER) diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 43f5419db..d45b4a217 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -176,7 +176,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) if (!enc->data[0] || !enc->data[1]) err = gpg_error (GPG_ERR_BAD_MPI); else - err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(a%m)(b%m)))", + err = gcry_sexp_build (&s_data, NULL, "(enc-val(ecdh(s%m)(e%m)))", enc->data[0], enc->data[1]); } else From e0d4139e19ceed9375cc7e7ba801a965d3376f7d Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 31 Jan 2011 18:19:14 +0100 Subject: [PATCH 23/26] Move OpenPGP OID helpers to common/. This is needed so that the agent will be able to export and import OpenPGP secret keys. Add test case. Removed unused function. --- common/ChangeLog | 7 ++ common/Makefile.am | 4 +- common/convert.c | 34 ------ common/openpgp-oid.c | 227 +++++++++++++++++++++++++++++++++++++++++ common/t-openpgp-oid.c | 148 +++++++++++++++++++++++++++ common/util.h | 6 +- g10/ChangeLog | 3 + g10/main.h | 4 - g10/misc.c | 201 ------------------------------------ g13/utils.h | 1 - 10 files changed, 393 insertions(+), 242 deletions(-) create mode 100644 common/openpgp-oid.c create mode 100644 common/t-openpgp-oid.c diff --git a/common/ChangeLog b/common/ChangeLog index 0150658e0..0214583b7 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,10 @@ +2011-01-31 Werner Koch + + * openpgp-oid.c: New. + * t-openpgp-oid.c: New. + + * convert.c (mpi2hex): Remove. + 2011-01-20 Werner Koch Fix bug#1313. diff --git a/common/Makefile.am b/common/Makefile.am index 110fc5f58..2539859d5 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -90,6 +90,7 @@ common_sources = \ localename.c \ session-env.c session-env.h \ userids.c userids.h \ + openpgp-oid.c \ helpfile.c # To make the code easier to read we have split home some code into @@ -160,7 +161,7 @@ if HAVE_W32_SYSTEM jnlib_tests += t-w32-reg endif module_tests = t-convert t-percent t-gettime t-sysutils t-sexputil \ - t-session-env + t-session-env t-openpgp-oid if !HAVE_W32CE_SYSTEM module_tests += t-exechelp endif @@ -192,6 +193,7 @@ t_sexputil_LDADD = $(t_common_ldadd) t_b64_LDADD = $(t_common_ldadd) t_exechelp_LDADD = $(t_common_ldadd) t_session_env_LDADD = $(t_common_ldadd) +t_openpgp_oid_LDADD = $(t_common_ldadd) diff --git a/common/convert.c b/common/convert.c index 5df6b335e..c314ec9a6 100644 --- a/common/convert.c +++ b/common/convert.c @@ -245,37 +245,3 @@ hex2str_alloc (const char *hexstring, size_t *r_count) BUG (); return result; } - -/* returns hex representation of the MPI; - * caller must free with xfree - * Returns NULL on error, never throws - */ -char * -mpi2hex( gcry_mpi_t m ) -{ -#warning we have code for this in libcrypt - size_t nbytes; - size_t nbytes2; - int rc; - byte *p; - - nbytes = (mpi_get_nbits ( m )+7)/8; - if( nbytes == 0 ) - return NULL; - p = xtrymalloc( nbytes*3+1 ); - if( p==NULL ) - return NULL; - rc = gcry_mpi_print (GCRYMPI_FMT_USG, p+2*nbytes+1, nbytes, &nbytes2, m); - if( rc ) { - xfree( p ); - return NULL; - } - - bin2hex( p+2*nbytes+1, nbytes2, p ); - p[nbytes2*2] = '\0'; - /*printf("%s:%d>>>> Created the string %s from %d bytes %02x %02x - ..., MPI was %d bytes\n", __FILE__, __LINE__, p, nbytes2, - p[2*nbytes+1], p[2*nbytes+2], nbytes); */ - return p; -} - diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c new file mode 100644 index 000000000..222c5a0b2 --- /dev/null +++ b/common/openpgp-oid.c @@ -0,0 +1,227 @@ +/* openpgp-oids.c - OID helper for OpenPGP + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include + +#include "util.h" + + +/* Helper for openpgp_oid_from_str. */ +static size_t +make_flagged_int (unsigned long value, char *buf, size_t buflen) +{ + int more = 0; + int shift; + + /* fixme: figure out the number of bits in an ulong and start with + that value as shift (after making it a multiple of 7) a more + straigtforward implementation is to do it in reverse order using + a temporary buffer - saves a lot of compares */ + for (more=0, shift=28; shift > 0; shift -= 7) + { + if (more || value >= (1<> shift); + value -= (value >> shift) << shift; + more = 1; + } + } + buf[buflen++] = value; + return buflen; +} + + +/* Convert the OID given in dotted decimal form in STRING to an DER + * encoding and store it as an opaque value at R_MPI. The format of + * the DER encoded is not a regular ASN.1 object but the modified + * format as used by OpenPGP for the ECC curve description. On error + * the function returns and error code an NULL is stored at R_BUG. + * Note that scanning STRING stops at the first white space + * character. */ +gpg_error_t +openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi) +{ + unsigned char *buf; + size_t buflen; + unsigned long val1, val; + const char *endp; + int arcno; + + *r_mpi = NULL; + + if (!string || !*string) + return gpg_error (GPG_ERR_INV_VALUE); + + /* We can safely assume that the encoded OID is shorter than the string. */ + buf = xtrymalloc (1 + strlen (string) + 2); + if (!buf) + return gpg_error_from_syserror (); + /* Save the first byte for the length. */ + buflen = 1; + + val1 = 0; /* Avoid compiler warning. */ + arcno = 0; + do { + arcno++; + val = strtoul (string, (char**)&endp, 10); + if (!digitp (string) || !(*endp == '.' || !*endp)) + { + xfree (buf); + return gpg_error (GPG_ERR_INV_OID_STRING); + } + if (*endp == '.') + string = endp+1; + + if (arcno == 1) + { + if (val > 2) + break; /* Not allowed, error catched below. */ + val1 = val; + } + else if (arcno == 2) + { /* Need to combine the first two arcs in one octet. */ + if (val1 < 2) + { + if (val > 39) + { + xfree (buf); + return gpg_error (GPG_ERR_INV_OID_STRING); + } + buf[buflen++] = val1*40 + val; + } + else + { + val += 80; + buflen = make_flagged_int (val, buf, buflen); + } + } + else + { + buflen = make_flagged_int (val, buf, buflen); + } + } while (*endp == '.'); + + if (arcno == 1 || buflen < 2 || buflen > 254 ) + { /* It is not possible to encode only the first arc. */ + xfree (buf); + return gpg_error (GPG_ERR_INV_OID_STRING); + } + + *buf = buflen - 1; + *r_mpi = gcry_mpi_set_opaque (NULL, buf, buflen * 8); + if (!*r_mpi) + { + xfree (buf); + return gpg_error_from_syserror (); + } + return 0; +} + + +/* Return a malloced string represenation of the OID in the opaque MPI + A. In case of an error NULL is returned and ERRNO is set. */ +char * +openpgp_oid_to_str (gcry_mpi_t a) +{ + const unsigned char *buf; + size_t length; + char *string, *p; + int n = 0; + unsigned long val, valmask; + + valmask = (unsigned long)0xfe << (8 * (sizeof (valmask) - 1)); + + if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) + { + gpg_err_set_errno (EINVAL); + return NULL; + } + + buf = gcry_mpi_get_opaque (a, &length); + length = (length+7)/8; + + /* The first bytes gives the length; check consistency. */ + if (!length || buf[0] != length -1) + { + gpg_err_set_errno (EINVAL); + return NULL; + } + /* Skip length byte. */ + length--; + buf++; + + /* To calculate the length of the string we can safely assume an + upper limit of 3 decimal characters per byte. Two extra bytes + account for the special first octect */ + string = p = xtrymalloc (length*(1+3)+2+1); + if (!string) + return NULL; + if (!buf || !length) + { + *p = 0; + return string; + } + + if (buf[0] < 40) + p += sprintf (p, "0.%d", buf[n]); + else if (buf[0] < 80) + p += sprintf (p, "1.%d", buf[n]-40); + else { + val = buf[n] & 0x7f; + while ( (buf[n]&0x80) && ++n < length ) + { + if ( (val & valmask) ) + goto badoid; /* Overflow. */ + val <<= 7; + val |= buf[n] & 0x7f; + } + val -= 80; + sprintf (p, "2.%lu", val); + p += strlen (p); + } + for (n++; n < length; n++) + { + val = buf[n] & 0x7f; + while ( (buf[n]&0x80) && ++n < length ) + { + if ( (val & valmask) ) + goto badoid; /* Overflow. */ + val <<= 7; + val |= buf[n] & 0x7f; + } + sprintf (p, ".%lu", val); + p += strlen (p); + } + + *p = 0; + return string; + + badoid: + /* Return a special OID (gnu.gnupg.badoid) to indicate the error + case. The OID is broken and thus we return one which can't do + any harm. Formally this does not need to be a bad OID but an OID + with an arc that can't be represented in a 32 bit word is more + than likely corrupt. */ + xfree (string); + return xtrystrdup ("1.3.6.1.4.1.11591.2.12242973"); +} diff --git a/common/t-openpgp-oid.c b/common/t-openpgp-oid.c new file mode 100644 index 000000000..80e576309 --- /dev/null +++ b/common/t-openpgp-oid.c @@ -0,0 +1,148 @@ +/* t-openpgp-oid.c - Module test for openpgp-oid.c + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include + +#include "util.h" + +#define pass() do { ; } while(0) +#define fail(a,e) \ + do { fprintf (stderr, "%s:%d: test %d failed (%s)\n", \ + __FILE__,__LINE__, (a), gpg_strerror (e)); \ + exit (1); \ + } while(0) + + +static void +test_openpgp_oid_from_str (void) +{ + static char *sample_oids[] = + { + "0.0", + "1.0", + "1.2.3", + "1.2.840.10045.3.1.7", + "1.3.132.0.34", + "1.3.132.0.35", + NULL + }; + gpg_error_t err; + gcry_mpi_t a; + int idx; + char *string; + unsigned char *p; + unsigned int nbits; + size_t length; + + err = openpgp_oid_from_str ("", &a); + if (gpg_err_code (err) != GPG_ERR_INV_VALUE) + fail (0, err); + gcry_mpi_release (a); + + err = openpgp_oid_from_str (".", &a); + if (gpg_err_code (err) != GPG_ERR_INV_OID_STRING) + fail (0, err); + gcry_mpi_release (a); + + err = openpgp_oid_from_str ("0", &a); + if (gpg_err_code (err) != GPG_ERR_INV_OID_STRING) + fail (0, err); + gcry_mpi_release (a); + + for (idx=0; sample_oids[idx]; idx++) + { + err = openpgp_oid_from_str (sample_oids[idx], &a); + if (err) + fail (idx, err); + + string = openpgp_oid_to_str (a); + if (!string) + fail (idx, gpg_error_from_syserror ()); + if (strcmp (string, sample_oids[idx])) + fail (idx, 0); + xfree (string); + + p = gcry_mpi_get_opaque (a, &nbits); + length = (nbits+7)/8; + if (!p || !length || p[0] != length - 1) + fail (idx, 0); + + gcry_mpi_release (a); + } + +} + + +static void +test_openpgp_oid_to_str (void) +{ + static struct { + const char *string; + unsigned char der[10]; + } samples[] = { + { "1.2.840.10045.3.1.7", + {8, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 }}, + + { "1.3.132.0.34", + {5, 0x2B, 0x81, 0x04, 0x00, 0x22 }}, + + { "1.3.132.0.35", + { 5, 0x2B, 0x81, 0x04, 0x00, 0x23 }}, + + { NULL }}; + gcry_mpi_t a; + int idx; + char *string; + unsigned char *p; + + for (idx=0; samples[idx].string; idx++) + { + p = xmalloc (samples[idx].der[0]+1); + memcpy (p, samples[idx].der, samples[idx].der[0]+1); + a = gcry_mpi_set_opaque (NULL, p, (samples[idx].der[0]+1)*8); + if (!a) + fail (idx, gpg_error_from_syserror ()); + + string = openpgp_oid_to_str (a); + if (!string) + fail (idx, gpg_error_from_syserror ()); + if (strcmp (string, samples[idx].string)) + fail (idx, 0); + xfree (string); + gcry_mpi_release (a); + } + +} + + + +int +main (int argc, char **argv) +{ + (void)argc; + (void)argv; + + test_openpgp_oid_from_str (); + test_openpgp_oid_to_str (); + + return 0; +} diff --git a/common/util.h b/common/util.h index 99d58e172..cf38ad4f8 100644 --- a/common/util.h +++ b/common/util.h @@ -196,7 +196,6 @@ gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata, int hex2bin (const char *string, void *buffer, size_t length); int hexcolon2bin (const char *string, void *buffer, size_t length); char *bin2hex (const void *buffer, size_t length, char *stringbuf); -char *mpi2hex (gcry_mpi_t m); char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf); const char *hex2str (const char *hexstring, char *buffer, size_t bufsize, size_t *buflen); @@ -210,6 +209,11 @@ char *percent_unescape (const char *string, int nulrepl); size_t percent_plus_unescape_inplace (char *string, int nulrepl); size_t percent_unescape_inplace (char *string, int nulrepl); +/*-- openpgp-oid.c --*/ +gpg_error_t openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi); +char *openpgp_oid_to_str (gcry_mpi_t a); + + /*-- homedir.c --*/ const char *standard_homedir (void); diff --git a/g10/ChangeLog b/g10/ChangeLog index 587c9f158..2a284e765 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,5 +1,8 @@ 2011-01-31 Werner Koch + * misc.c (make_flagged_int, openpgp_oid_from_str) + (openpgp_oid_to_str): Move to ../common/openpgp-oids.c. + * ecdh.c (pk_ecdh_encrypt_with_shared_point): Return an opaque MPI. * build-packet.c (mpi_write): Rename to gpg_mpi_write and make global. diff --git a/g10/main.h b/g10/main.h index d76d96bc4..d70c16901 100644 --- a/g10/main.h +++ b/g10/main.h @@ -165,10 +165,6 @@ unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey ); int mpi_print (estream_t stream, gcry_mpi_t a, int mode); unsigned int ecdsa_qbits_from_Q (unsigned int qbits); -/* Other stuff */ -gpg_error_t openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi); -char *openpgp_oid_to_str (gcry_mpi_t a); - /*-- status.c --*/ void set_status_fd ( int fd ); diff --git a/g10/misc.c b/g10/misc.c index 2052e96c7..dcd2bd10b 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -1552,204 +1552,3 @@ ecdsa_qbits_from_Q (unsigned int qbits) } - -/* Helper for openpgp_oid_from_str. */ -static size_t -make_flagged_int (unsigned long value, char *buf, size_t buflen) -{ - int more = 0; - int shift; - - /* fixme: figure out the number of bits in an ulong and start with - that value as shift (after making it a multiple of 7) a more - straigtforward implementation is to do it in reverse order using - a temporary buffer - saves a lot of compares */ - for (more=0, shift=28; shift > 0; shift -= 7) - { - if (more || value >= (1<> shift); - value -= (value >> shift) << shift; - more = 1; - } - } - buf[buflen++] = value; - return buflen; -} - - -/* Convert the OID given in dotted decimal form in STRING to an DER - * encoding and store it as an opaque value at R_MPI. The format of - * the DER encoded is not a regular ASN.1 object but the modified - * format as used by OpenPGP for the ECC curve description. On error - * the function returns and error code an NULL is stored at R_BUG. - * Note that scanning STRING stops at the first white space - * character. */ -gpg_error_t -openpgp_oid_from_str (const char *string, gcry_mpi_t *r_mpi) -{ - unsigned char *buf; - size_t buflen; - unsigned long val1, val; - const char *endp; - int arcno; - - *r_mpi = NULL; - - if (!string || !*string) - return gpg_error (GPG_ERR_INV_VALUE); - - /* We can safely assume that the encoded OID is shorter than the string. */ - buf = xtrymalloc (1 + strlen (string) + 2); - if (!buf) - return gpg_error_from_syserror (); - /* Save the first byte for the length. */ - buflen = 1; - - val1 = 0; /* Avoid compiler warning. */ - arcno = 0; - do { - arcno++; - val = strtoul (string, (char**)&endp, 10); - if (!digitp (string) || !(*endp == '.' || !*endp)) - { - xfree (buf); - return gpg_error (GPG_ERR_INV_OID_STRING); - } - if (*endp == '.') - string = endp+1; - - if (arcno == 1) - { - if (val > 2) - break; /* Not allowed, error catched below. */ - val1 = val; - } - else if (arcno == 2) - { /* Need to combine the first two arcs in one octet. */ - if (val1 < 2) - { - if (val > 39) - { - xfree (buf); - return gpg_error (GPG_ERR_INV_OID_STRING); - } - buf[buflen++] = val1*40 + val; - } - else - { - val += 80; - buflen = make_flagged_int (val, buf, buflen); - } - } - else - { - buflen = make_flagged_int (val, buf, buflen); - } - } while (*endp == '.'); - - if (arcno == 1 || buflen < 2 || buflen > 254 ) - { /* It is not possible to encode only the first arc. */ - xfree (buf); - return gpg_error (GPG_ERR_INV_OID_STRING); - } - - *buf = buflen - 1; - *r_mpi = gcry_mpi_set_opaque (NULL, buf, buflen * 8); - if (!*r_mpi) - { - xfree (buf); - return gpg_error_from_syserror (); - } - return 0; -} - - -/* Return a malloced string represenation of the OID in the opaque MPI - A. In case of an error NULL is returned and ERRNO is set. */ -char * -openpgp_oid_to_str (gcry_mpi_t a) -{ - const unsigned char *buf; - size_t length; - char *string, *p; - int n = 0; - unsigned long val, valmask; - - valmask = (unsigned long)0xfe << (8 * (sizeof (valmask) - 1)); - - if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) - { - gpg_err_set_errno (EINVAL); - return NULL; - } - - buf = gcry_mpi_get_opaque (a, &length); - length = (length+7)/8; - - /* The first bytes gives the length; check consistency. */ - if (!length || buf[0] != length -1) - { - gpg_err_set_errno (EINVAL); - return NULL; - } - /* Skip length byte. */ - length--; - buf++; - - /* To calculate the length of the string we can safely assume an - upper limit of 3 decimal characters per byte. Two extra bytes - account for the special first octect */ - string = p = xtrymalloc (length*(1+3)+2+1); - if (!string) - return NULL; - if (!buf || !length) - { - *p = 0; - return string; - } - - if (buf[0] < 40) - p += sprintf (p, "0.%d", buf[n]); - else if (buf[0] < 80) - p += sprintf (p, "1.%d", buf[n]-40); - else { - val = buf[n] & 0x7f; - while ( (buf[n]&0x80) && ++n < length ) - { - if ( (val & valmask) ) - goto badoid; /* Overflow. */ - val <<= 7; - val |= buf[n] & 0x7f; - } - val -= 80; - sprintf (p, "2.%lu", val); - p += strlen (p); - } - for (n++; n < length; n++) - { - val = buf[n] & 0x7f; - while ( (buf[n]&0x80) && ++n < length ) - { - if ( (val & valmask) ) - goto badoid; /* Overflow. */ - val <<= 7; - val |= buf[n] & 0x7f; - } - sprintf (p, ".%lu", val); - p += strlen (p); - } - - *p = 0; - return string; - - badoid: - /* Return a special OID (gnu.gnupg.badoid) to indicate the error - case. The OID is broken and thus we return one which can't do - any harm. Formally this does not need to be a bad OID but an OID - with an arc that can't be represented in a 32 bit word is more - than likely corrupt. */ - xfree (string); - return xtrystrdup ("1.3.6.1.4.1.11591.2.12242973"); -} - diff --git a/g13/utils.h b/g13/utils.h index 528ce16ce..cebd0436d 100644 --- a/g13/utils.h +++ b/g13/utils.h @@ -38,7 +38,6 @@ const void *find_tuple (tupledesc_t tupledesc, unsigned int tag, size_t *r_length); const void *next_tuple (tupledesc_t tupledesc, unsigned int *r_tag, size_t *r_length); -char *mpi2hex( gcry_mpi_t m ); #endif /*G13_UTILS_H*/ From 4659c923a08002a72cb4bb5b3c4e6a02d7484767 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 2 Feb 2011 15:48:54 +0100 Subject: [PATCH 24/26] 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. --- ChangeLog | 4 + agent/ChangeLog | 101 +++---- agent/cvt-openpgp.c | 86 +++--- common/util.h | 24 +- configure.ac | 16 ++ g10/ChangeLog | 15 ++ g10/ecdh.c | 81 +++--- g10/export.c | 148 +++++++--- g10/gpg.c | 3 + g10/import.c | 252 +++++++++++++----- g10/keygen.c | 57 ++-- g10/keyid.c | 97 ++++--- g10/main.h | 1 + g10/passphrase.c | 104 ++++---- include/ChangeLog | 5 + include/cipher.h | 4 +- tests/openpgp/samplekeys/README | 3 +- tests/openpgp/samplekeys/ecc-sample-1-pub.asc | 22 ++ tests/openpgp/samplekeys/ecc-sample-1-sec.asc | 25 ++ 19 files changed, 692 insertions(+), 356 deletions(-) create mode 100644 tests/openpgp/samplekeys/ecc-sample-1-pub.asc create mode 100644 tests/openpgp/samplekeys/ecc-sample-1-sec.asc diff --git a/ChangeLog b/ChangeLog index d3e7eb1a7..d79108648 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-02-01 Werner Koch + + * configure.ac (HAVE_GCRY_PK_GET_CURVE): Define if availabale. + 2011-01-20 Werner Koch * configure.ac (AC_CONFIG_FILES): Remove keyserver/. 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); diff --git a/common/util.h b/common/util.h index cf38ad4f8..fc3dd02df 100644 --- a/common/util.h +++ b/common/util.h @@ -42,6 +42,12 @@ #ifndef GPG_ERR_FULLY_CANCELED #define GPG_ERR_FULLY_CANCELED 198 #endif +#ifndef GPG_ERR_INV_CURVE +#define GPG_ERR_INV_CURVE 187 +#endif +#ifndef GPG_ERR_UNKNOWN_CURVE +#define GPG_ERR_UNKNOWN_CURVE 188 +#endif /* Hash function used with libksba. */ @@ -75,10 +81,10 @@ /* GCC attributes. */ -#if __GNUC__ >= 4 +#if __GNUC__ >= 4 # define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a))) #else -# define GNUPG_GCC_A_SENTINEL(a) +# define GNUPG_GCC_A_SENTINEL(a) #endif @@ -132,14 +138,14 @@ int answer_is_yes_no_quit (const char *s); int answer_is_okay_cancel (const char *s, int def_answer); /*-- xreadline.c --*/ -ssize_t read_line (FILE *fp, +ssize_t read_line (FILE *fp, char **addr_of_buffer, size_t *length_of_buffer, size_t *max_length); /*-- b64enc.c and b64dec.c --*/ -struct b64state -{ +struct b64state +{ unsigned int flags; int idx; int quad_count; @@ -184,9 +190,9 @@ unsigned char *make_canon_sexp_from_rsa_pk (const void *m, size_t mlen, size_t *r_len); gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen, - unsigned char const **r_n, + unsigned char const **r_n, size_t *r_nlen, - unsigned char const **r_e, + unsigned char const **r_e, size_t *r_elen); gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen, @@ -231,7 +237,7 @@ const char *dirmngr_socket_name (void); gpgconf. */ #define GNUPG_MODULE_NAME_AGENT 1 #define GNUPG_MODULE_NAME_PINENTRY 2 -#define GNUPG_MODULE_NAME_SCDAEMON 3 +#define GNUPG_MODULE_NAME_SCDAEMON 3 #define GNUPG_MODULE_NAME_DIRMNGR 4 #define GNUPG_MODULE_NAME_PROTECT_TOOL 5 #define GNUPG_MODULE_NAME_CHECK_PATTERN 6 @@ -286,7 +292,7 @@ int gnupg_compare_version (const char *a, const char *b); #ifndef HAVE_TTYNAME /* Systems without ttyname (W32) will merely return NULL. */ static inline char * -ttyname (int fd) +ttyname (int fd) { (void)fd; return NULL; diff --git a/configure.ac b/configure.ac index e24117b28..1081b2d3c 100644 --- a/configure.ac +++ b/configure.ac @@ -742,6 +742,7 @@ AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION", AM_PATH_LIBGCRYPT("$NEED_LIBGCRYPT_API:$NEED_LIBGCRYPT_VERSION", have_libgcrypt=yes,have_libgcrypt=no) +# fixme: We can remove the next two checks if we require libgcrypt 1.5. AC_CACHE_CHECK([whether Libgcrypt support ECDH], gnupg_cv_gcry_pk_ecdh, [ _gnupg_gcry_save_cflags=$CFLAGS CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS" @@ -756,6 +757,21 @@ if test "$gnupg_cv_gcry_pk_ecdh" = yes; then [Define if gcrypt.h has the enum value for ECDH.]) fi +AC_CACHE_CHECK([whether Libgcrypt has gcry_pk_get_curve], + gnupg_cv_gcry_pk_get_curve, + [ _gnupg_gcry_save_cflags=$CFLAGS + CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS" + AC_TRY_COMPILE( + [#include ], + [ return gcry_pk_get_curve (NULL, 0, NULL); ], + gnupg_cv_gcry_pk_get_curve=yes, + gnupg_cv_gcry_pk_get_curve=no) + CFLAGS=$_gnupg_gcry_save_cflags]) +if test "$gnupg_cv_gcry_pk_get_curve" = yes; then + AC_DEFINE([HAVE_GCRY_PK_GET_CURVE], 1, + [Define if gcrypt.h has gcry_pk_get_curve.]) +fi + # # libassuan is used for IPC diff --git a/g10/ChangeLog b/g10/ChangeLog index 2a284e765..bb55ff85f 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,18 @@ +2011-02-02 Werner Koch + + * import.c (transfer_secret_keys): Make sure keyids are available. + + * keyid.c (hash_public_key): Adjust for the ECC case. + +2011-02-01 Werner Koch + + * import.c (transfer_secret_keys): Implement ECC case. + + * gpg.c (main): Call setup_libgcrypt_logging. + + * keygen.c (gpg_curve_to_oid): New. + (ecckey_from_sexp): Factor curve name mapping out to new function. + 2011-01-31 Werner Koch * misc.c (make_flagged_int, openpgp_oid_from_str) diff --git a/g10/ecdh.c b/g10/ecdh.c index 09ab3ed16..f97667ae3 100644 --- a/g10/ecdh.c +++ b/g10/ecdh.c @@ -36,7 +36,7 @@ static const struct unsigned int qbits; int openpgp_hash_id; /* KEK digest algorithm. */ int openpgp_cipher_id; /* KEK cipher algorithm. */ -} kek_params_table[] = +} kek_params_table[] = /* Note: Must be sorted by ascending values for QBITS. */ { { 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES }, @@ -60,8 +60,8 @@ pk_ecdh_default_params (unsigned int qbits) if (!kek_params) return NULL; kek_params[0] = 3; /* Number of bytes to follow. */ - kek_params[1] = 1; /* Version for KDF+AESWRAP. */ - + kek_params[1] = 1; /* Version for KDF+AESWRAP. */ + /* Search for matching KEK parameter. Defaults to the strongest possible choices. Performance is not an issue here, only interoperability. */ @@ -78,7 +78,7 @@ pk_ecdh_default_params (unsigned int qbits) assert (i < DIM (kek_params_table)); if (DBG_CIPHER) log_printhex ("ECDH KEK params are", kek_params, sizeof(kek_params) ); - + return gcry_mpi_set_opaque (NULL, kek_params, 4 * 8); } @@ -88,16 +88,16 @@ pk_ecdh_default_params (unsigned int qbits) key_derivation+key_wrapping. If IS_ENCRYPT is true the function encrypts; if false, it decrypts. On success the result is stored at R_RESULT; on failure NULL is stored at R_RESULT and an error - code returned. + code returned. FIXME: explain PKEY and PK_FP. */ - + /* TODO: memory leaks (x_secret). */ gpg_error_t -pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, +pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t *pkey, gcry_mpi_t *r_result) @@ -106,8 +106,8 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, byte *secret_x; int secret_x_size; unsigned int nbits; - const unsigned char *kdf_params; - size_t kdf_params_size; + const unsigned char *kek_params; + size_t kek_params_size; int kdf_hash_algo; int kdf_encr_algo; unsigned char message[256]; @@ -139,11 +139,11 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, return err; } - secret_x_size = (nbits+7)/8; + secret_x_size = (nbits+7)/8; assert (nbytes > secret_x_size); memmove (secret_x, secret_x+1, secret_x_size); memset (secret_x+secret_x_size, 0, nbytes-secret_x_size); - + if (DBG_CIPHER) log_printhex ("ECDH shared secret X is:", secret_x, secret_x_size ); } @@ -158,24 +158,24 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, */ if (!gcry_mpi_get_flag (pkey[2], GCRYMPI_FLAG_OPAQUE)) return GPG_ERR_BUG; - kdf_params = gcry_mpi_get_opaque (pkey[2], &nbits); - kdf_params_size = (nbits+7)/8; - + kek_params = gcry_mpi_get_opaque (pkey[2], &nbits); + kek_params_size = (nbits+7)/8; + if (DBG_CIPHER) - log_printhex ("ecdh KDF params:", kdf_params, kdf_params_size); - + log_printhex ("ecdh KDF params:", kek_params, kek_params_size); + /* Expect 4 bytes 03 01 hash_alg symm_alg. */ - if (kdf_params_size != 4 || kdf_params[0] != 3 || kdf_params[1] != 1) + if (kek_params_size != 4 || kek_params[0] != 3 || kek_params[1] != 1) return GPG_ERR_BAD_PUBKEY; - - kdf_hash_algo = kdf_params[2]; - kdf_encr_algo = kdf_params[3]; - + + kdf_hash_algo = kek_params[2]; + kdf_encr_algo = kek_params[3]; + if (DBG_CIPHER) log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n", openpgp_md_algo_name (kdf_hash_algo), openpgp_cipher_algo_name (kdf_encr_algo)); - + if (kdf_hash_algo != GCRY_MD_SHA256 && kdf_hash_algo != GCRY_MD_SHA384 && kdf_hash_algo != GCRY_MD_SHA512) @@ -199,7 +199,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, /* fixed-length field 4 */ iobuf_write (obuf, "Anonymous Sender ", 20); /* fixed-length field 5, recipient fp */ - iobuf_write (obuf, pk_fp, 20); + iobuf_write (obuf, pk_fp, 20); message_size = iobuf_temp_to_buffer (obuf, message, sizeof message); iobuf_close (obuf); @@ -207,11 +207,10 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, return err; if(DBG_CIPHER) - log_printhex ("ecdh KDF message params are:", - kdf_params, kdf_params_size ); + log_printhex ("ecdh KDF message params are:", message, message_size); } - /* Derive a KEK (key wrapping key) using kdf_params and secret_x. */ + /* Derive a KEK (key wrapping key) using MESSAGE and SECRET_X. */ { gcry_md_hd_t h; int old_size; @@ -222,7 +221,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, kdf_hash_algo, gpg_strerror (err)); gcry_md_write(h, "\x00\x00\x00\x01", 4); /* counter = 1 */ gcry_md_write(h, secret_x, secret_x_size); /* x of the point X */ - gcry_md_write(h, kdf_params, kdf_params_size);/* KDF parameters */ + gcry_md_write(h, message, message_size);/* KDF parameters */ gcry_md_final (h); @@ -242,7 +241,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, if (DBG_CIPHER) log_printhex ("ecdh KEK is:", secret_x, secret_x_size ); } - + /* And, finally, aeswrap with key secret_x. */ { gcry_cipher_hd_t hd; @@ -284,7 +283,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, if (is_encrypt) { byte *in = data_buf+1+data_buf_size+8; - + /* Write data MPI into the end of data_buf. data_buf is size aeswrap data. */ err = gcry_mpi_print (GCRYMPI_FMT_USG, in, @@ -296,7 +295,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, xfree (data_buf); return err; } - + if (DBG_CIPHER) log_printhex ("ecdh encrypting :", in, data_buf_size ); @@ -325,14 +324,14 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, gpg_strerror (err)); return err; } - + *r_result = result; } else { byte *in; const void *p; - + p = gcry_mpi_get_opaque (data, &nbits); nbytes = (nbits+7)/8; if (!p || nbytes > data_buf_size || !nbytes) @@ -349,10 +348,10 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, } in = data_buf+data_buf_size; data_buf_size = data_buf[0]; - + if (DBG_CIPHER) log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size); - + err = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1, data_buf_size); gcry_cipher_close (hd); @@ -363,12 +362,12 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, xfree (data_buf); return err; } - + data_buf_size -= 8; - + if (DBG_CIPHER) log_printhex ("ecdh decrypted to :", in, data_buf_size); - + /* Padding is removed later. */ /* if (in[data_buf_size-1] > 8 ) */ /* { */ @@ -376,7 +375,7 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, /* in[data_buf_size-1] ); */ /* return GPG_ERR_BAD_KEY; */ /* } */ - + err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, in, data_buf_size, NULL); xfree (data_buf); if (err) @@ -385,11 +384,11 @@ pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, gpg_strerror (err)); return err; } - + *r_result = result; } } - + return err; } @@ -453,5 +452,3 @@ pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], sk_fp, data/*encr data as an MPI*/, skey, result); } - - diff --git a/g10/export.c b/g10/export.c index 1eb0baa8b..91a6c87f1 100644 --- a/g10/export.c +++ b/g10/export.c @@ -107,7 +107,7 @@ export_pubkeys_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, kbnode_t *keyblock_out, unsigned int options ) { int any, rc; - + rc = do_export_stream (ctrl, out, users, 0, keyblock_out, options, &any); if (!rc && !any) rc = -1; @@ -197,9 +197,9 @@ do_export (ctrl_t ctrl, strlist_t users, int secret, unsigned int options ) int any, rc; armor_filter_context_t *afx = NULL; compress_filter_context_t zfx; - + memset( &zfx, 0, sizeof zfx); - + rc = open_outfile (GNUPG_INVALID_FD, NULL, 0, &out ); if (rc) return rc; @@ -251,7 +251,7 @@ subkey_in_list_p (subkey_list_t list, KBNODE node) u32 kid[2]; keyid_from_pk (node->pkt->pkt.public_key, kid); - + for (; list; list = list->next) if (list->kid[0] == kid[0] && list->kid[1] == kid[1]) return 1; @@ -293,17 +293,17 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node) case KEYDB_SEARCH_MODE_LONG_KID: keyid_from_pk (node->pkt->pkt.public_key, kid); break; - + case KEYDB_SEARCH_MODE_FPR16: case KEYDB_SEARCH_MODE_FPR20: case KEYDB_SEARCH_MODE_FPR: fingerprint_from_pk (node->pkt->pkt.public_key, fpr,&fprlen); break; - + default: break; } - + switch(desc->mode) { case KEYDB_SEARCH_MODE_SHORT_KID: @@ -346,7 +346,7 @@ canon_pubkey_algo (int algo) case GCRY_PK_RSA: case GCRY_PK_RSA_E: case GCRY_PK_RSA_S: return GCRY_PK_RSA; - case GCRY_PK_ELG: + case GCRY_PK_ELG: case GCRY_PK_ELG_E: return GCRY_PK_ELG; default: return algo; } @@ -354,7 +354,7 @@ canon_pubkey_algo (int algo) /* Use the key transfer format given in S_PGP to create the secinfo - structure in PK and chnage the parameter array in PK to include the + structure in PK and change the parameter array in PK to include the secret parameters. */ static gpg_error_t transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) @@ -415,7 +415,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) goto bad_seckey; protect_algo = gcry_cipher_map_name (string); xfree (string); - + value = gcry_sexp_nth_data (list, 3, &valuelen); if (!value || !valuelen || valuelen > sizeof iv) goto bad_seckey; @@ -460,6 +460,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) || gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey) || !npkey || npkey >= nskey || nskey > PUBKEY_MAX_NSKEY) goto bad_seckey; + pubkey_algo = map_pk_gcry_to_openpgp (pubkey_algo); gcry_sexp_release (list); list = gcry_sexp_find_token (top_list, "skey", 0); @@ -557,6 +558,77 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) goto leave; } + /* We need to change the received parameters for ECC algorithms. + The transfer format has all parameters but OpenPGP defines that + only the OID of the curve is to be used. */ + if (pubkey_algo == PUBKEY_ALGO_ECDSA || pubkey_algo == PUBKEY_ALGO_ECDH) + { + gcry_sexp_t s_pubkey; + const char *curvename, *curveoidstr; + gcry_mpi_t mpi; + + /* We build an S-expression with the public key parameters and + ask Libgcrypt to return the matching curve name. */ + if (npkey != 6 || !skey[0] || !skey[1] || !skey[2] + || !skey[3] || !skey[4] || !skey[5] + || !skey[6] || skey[7]) + { + err = gpg_error (GPG_ERR_INTERNAL); + goto leave; + } + err = gcry_sexp_build (&s_pubkey, NULL, + "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))", + skey[0], skey[1], skey[2], skey[3], skey[4]); + if (err) + goto leave; +#ifdef HAVE_GCRY_PK_GET_CURVE + curvename = gcry_pk_get_curve (s_pubkey, 0, NULL); +#else + curvename = "?"; +#endif + gcry_sexp_release (s_pubkey); + curveoidstr = gpg_curve_to_oid (curvename, NULL); + if (!curveoidstr) + { + log_error ("no OID known for curve `%s'\n", curvename); + err = gpg_error (GPG_ERR_UNKNOWN_NAME); + goto leave; + } + err = openpgp_oid_from_str (curveoidstr, &mpi); + if (err) + goto leave; + + /* Now replace the curve parameters by the OID and shift the + rest of the parameters. */ + gcry_mpi_release (skey[0]); + skey[0] = mpi; + for (idx=1; idx <= 4; idx++) + gcry_mpi_release (skey[idx]); + skey[1] = skey[5]; + skey[2] = skey[6]; + for (idx=3; idx <= 6; idx++) + skey[idx] = NULL; + + /* Fixup the NPKEY and NSKEY to match OpenPGP reality. */ + npkey = 2; + nskey = 3; + + /* for (idx=0; skey[idx]; idx++) */ + /* { */ + /* log_info ("YYY skey[%d]:", idx); */ + /* if (gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE)) */ + /* { */ + /* void *p; */ + /* unsigned int nbits; */ + /* p = gcry_mpi_get_opaque (skey[idx], &nbits); */ + /* log_printhex (NULL, p, (nbits+7)/8); */ + /* } */ + /* else */ + /* gcry_mpi_dump (skey[idx]); */ + /* log_printf ("\n"); */ + /* } */ + } + /* Do some sanity checks. */ if (s2k_count <= 1024) { @@ -576,11 +648,17 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) err = openpgp_md_test_algo (s2k_algo); if (err) goto leave; - - /* Check that the public key parameters match. */ + + /* Check that the public key parameters match. Since Libgcrypt 1.5 + and the gcry_pk_get_curve function, gcry_mpi_cmp handles opaque + MPI correctly and thus we don't need to to do the extra + opaqueness checks. */ for (idx=0; idx < npkey; idx++) - if (gcry_mpi_get_flag (pk->pkey[idx], GCRYMPI_FLAG_OPAQUE) + if (0 +#ifndef HAVE_GCRY_PK_GET_CURVE + gcry_mpi_get_flag (pk->pkey[idx], GCRYMPI_FLAG_OPAQUE) || gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE) +#endif || gcry_mpi_cmp (pk->pkey[idx], skey[idx])) { err = gpg_error (GPG_ERR_BAD_PUBKEY); @@ -607,7 +685,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) err = gpg_error_from_syserror (); goto leave; } - + ski->is_protected = 1; ski->sha1chk = 1; ski->algo = protect_algo; @@ -636,7 +714,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) bad_seckey: err = gpg_error (GPG_ERR_BAD_SECKEY); goto leave; - + outofmem: err = gpg_error (GPG_ERR_ENOMEM); goto leave; @@ -671,7 +749,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, init_packet (&pkt); kdbhd = keydb_new (); - if (!users) + if (!users) { ndesc = 1; desc = xcalloc (ndesc, sizeof *desc); @@ -679,10 +757,10 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, } else { - for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) + for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) ; desc = xmalloc ( ndesc * sizeof *desc); - + for (ndesc=0, sl=users; sl; sl = sl->next) { if (!(err=classify_user_id (sl->d, desc+ndesc))) @@ -708,7 +786,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, goto leave; } #endif - + /* For secret key export we need to setup a decryption context. */ if (secret) { @@ -721,7 +799,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, log_error ("error getting the KEK: %s\n", gpg_strerror (err)); goto leave; } - + /* Prepare a cipher context. */ err = gcry_cipher_open (&cipherhd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_AESWRAP, 0); @@ -737,20 +815,20 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, kek = NULL; } - while (!(err = keydb_search2 (kdbhd, desc, ndesc, &descindex))) + while (!(err = keydb_search2 (kdbhd, desc, ndesc, &descindex))) { int skip_until_subkey = 0; u32 keyid[2]; PKT_public_key *pk; - if (!users) + if (!users) desc[0].mode = KEYDB_SEARCH_MODE_NEXT; /* Read the keyblock. */ release_kbnode (keyblock); keyblock = NULL; err = keydb_get_keyblock (kdbhd, &keyblock); - if (err) + if (err) { log_error (_("error reading keyblock: %s\n"), gpg_strerror (err)); goto leave; @@ -802,7 +880,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, clean_key (keyblock, opt.verbose, (options&EXPORT_MINIMAL), NULL, NULL); /* And write it. */ - for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); ) + for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); ) { if (skip_until_subkey) { @@ -835,7 +913,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, subkey and include that subkey into the output too. Need to add this subkey to a list so that it won't get processed a second time. - + So the first step here is to check that list and skip in any case if the key is in that list. @@ -843,7 +921,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, function of GnuPG < 2.1 is not able to merge secret keys and thus it is useless to output them as two separate keys and have import merge them. */ - if (subkey_in_list_p (subkey_list, node)) + if (subkey_in_list_p (subkey_list, node)) skip_until_subkey = 1; /* Already processed this one. */ else { @@ -854,7 +932,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, && exact_subkey_match_p (desc+j, node)) break; if (!(j < ndesc)) - skip_until_subkey = 1; /* No other one matching. */ + skip_until_subkey = 1; /* No other one matching. */ } } @@ -885,7 +963,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, && node->pkt->pkt.signature->revkey) { int i; - + for (i=0;ipkt->pkt.signature->numrevkeys;i++) if ( (node->pkt->pkt.signature->revkey[i]->class & 0x40)) break; @@ -904,7 +982,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, or a signature on an attrib */ while (kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE) kbctx = kbctx->next; - + continue; } @@ -913,7 +991,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, { u32 subkidbuf[2], *subkid; char *hexgrip, *serialno; - + pk = node->pkt->pkt.public_key; if (node->pkt->pkttype == PKT_PUBLIC_KEY) subkid = NULL; @@ -930,7 +1008,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, skip_until_subkey = 1; continue; } - + err = hexkeygrip_from_pk (pk, &hexgrip); if (err) { @@ -970,7 +1048,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, /* Create a key stub. */ struct seckey_info *ski; const char *s; - + pk->seckey_info = ski = xtrycalloc (1, sizeof *ski); if (!ski) { @@ -989,7 +1067,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, ski->ivlen++, s += 2) ski->iv[ski->ivlen] = xtoi_2 (s); } - + if ((options&EXPORT_SEXP_FORMAT)) err = build_sexp (out, node->pkt, &indent); else @@ -1032,7 +1110,7 @@ do_export_stream (ctrl_t ctrl, iobuf_t out, strlist_t users, int secret, realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err); if (!realkeylen) goto unwraperror; /* Invalid csexp. */ - + err = gcry_sexp_sscan (&s_skey, NULL, key, realkeylen); xfree (key); key = NULL; @@ -1252,7 +1330,7 @@ build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent) /* For some packet types we write them in a S-expression format. This is still EXPERIMENTAL and subject to change. */ -static int +static int build_sexp (iobuf_t out, PACKET *pkt, int *indent) { int rc; diff --git a/g10/gpg.c b/g10/gpg.c index 47e8b361f..6daa144be 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1959,6 +1959,9 @@ main (int argc, char **argv) NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); } + /* Use our own logging handler for Libcgrypt. */ + setup_libgcrypt_logging (); + /* Put random number into secure memory */ gcry_control (GCRYCTL_USE_SECURE_RNDPOOL); diff --git a/g10/import.c b/g10/import.c index 88abafd6a..99398c762 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1,6 +1,6 @@ /* import.c - import a key into our key storage. * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2010 Free Software Foundation, Inc. + * 2007, 2010, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -200,7 +200,7 @@ import_keys_internal (ctrl_t ctrl, iobuf_t inp, char **fnames, int nnames, rc = import (ctrl, inp2, fname, stats, fpr, fpr_len, options); iobuf_close(inp2); /* Must invalidate that ugly cache to actually close it. */ - iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, + iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char*)fname); if( rc ) log_error("import from `%s' failed: %s\n", fname, @@ -294,7 +294,7 @@ import (ctrl_t ctrl, IOBUF inp, const char* fname,struct stats_s *stats, if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY ) rc = import_one (ctrl, fname, keyblock, stats, fpr, fpr_len, options, 0); - else if( keyblock->pkt->pkttype == PKT_SECRET_KEY ) + else if( keyblock->pkt->pkttype == PKT_SECRET_KEY ) rc = import_secret_one (ctrl, fname, keyblock, stats, options); else if( keyblock->pkt->pkttype == PKT_SIGNATURE && keyblock->pkt->pkt.signature->sig_class == 0x20 ) @@ -647,7 +647,7 @@ check_prefs (ctrl_t ctrl, kbnode_t keyblock) kbnode_t node; PKT_public_key *pk; int problem=0; - + merge_keys_and_selfsig(keyblock); pk=keyblock->pkt->pkt.public_key; @@ -672,9 +672,9 @@ check_prefs (ctrl_t ctrl, kbnode_t keyblock) { if (openpgp_cipher_test_algo (prefs->value)) { - const char *algo = + const char *algo = (openpgp_cipher_test_algo (prefs->value) - ? num + ? num : openpgp_cipher_algo_name (prefs->value)); if(!problem) check_prefs_warning(pk); @@ -689,7 +689,7 @@ check_prefs (ctrl_t ctrl, kbnode_t keyblock) { const char *algo = (gcry_md_test_algo (prefs->value) - ? num + ? num : gcry_md_algo_name (prefs->value)); if(!problem) check_prefs_warning(pk); @@ -801,7 +801,7 @@ import_one (ctrl_t ctrl, log_error( _("key %s: no user ID\n"), keystr_from_pk(pk)); return 0; } - + if (opt.interactive) { if(is_status_enabled()) print_import_check (pk, uidnode->pkt->pkt.user_id); @@ -938,7 +938,7 @@ import_one (ctrl_t ctrl, size_t an; fingerprint_from_pk (pk_orig, afp, &an); - while (an < MAX_FINGERPRINT_LEN) + while (an < MAX_FINGERPRINT_LEN) afp[an++] = 0; rc = keydb_search_fpr (hd, afp); } @@ -962,7 +962,7 @@ import_one (ctrl_t ctrl, n_sigs_cleaned = fix_bad_direct_key_sigs (keyblock_orig, keyid); if (n_sigs_cleaned) commit_kbnode (&keyblock_orig); - + /* and try to merge the block */ clear_kbnode_flags( keyblock_orig ); clear_kbnode_flags( keyblock ); @@ -1032,13 +1032,13 @@ import_one (ctrl_t ctrl, stats->n_sigs_cleaned +=n_sigs_cleaned; stats->n_uids_cleaned +=n_uids_cleaned; - if (is_status_enabled ()) + if (is_status_enabled ()) print_import_ok (pk, ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0))); } else { same_key = 1; - if (is_status_enabled ()) + if (is_status_enabled ()) print_import_ok (pk, 0); if( !opt.quiet ) @@ -1107,6 +1107,37 @@ import_one (ctrl_t ctrl, } +/* Extract one MPI value from the S-expression PKEY which is expected + to hold a "public-key". Returns NULL on error. */ +static gcry_mpi_t +one_mpi_from_pkey (gcry_sexp_t pkey, const char *name, size_t namelen) +{ + gcry_sexp_t list, l2; + gcry_mpi_t a; + + list = gcry_sexp_find_token (pkey, "public-key", 0); + if (!list) + return NULL; + l2 = gcry_sexp_cadr (list); + gcry_sexp_release (list); + list = l2; + if (!list) + return NULL; + + l2 = gcry_sexp_find_token (list, name, namelen); + if (!l2) + { + gcry_sexp_release (list); + return NULL; + } + a = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l2); + gcry_sexp_release (list); + + return a; +} + + /* Transfer all the secret keys in SEC_KEYBLOCK to the gpg-agent. The function prints diagnostics and returns an error code. */ static gpg_error_t @@ -1133,6 +1164,7 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock) unsigned char *wrappedkey = NULL; size_t wrappedkeylen; char *cache_nonce = NULL; + gcry_mpi_t ecc_params[5] = {NULL, NULL, NULL, NULL, NULL}; /* Get the current KEK. */ err = agent_keywrap_key (ctrl, 0, &kek, &keklen); @@ -1148,7 +1180,8 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock) if (!err) err = gcry_cipher_setkey (cipherhd, kek, keklen); if (err) - goto leave; xfree (kek); + goto leave; + xfree (kek); kek = NULL; main_pk = NULL; @@ -1161,6 +1194,20 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock) if (!main_pk) main_pk = pk; + /* Make sure the keyids are available. */ + keyid_from_pk (pk, NULL); + if (node->pkt->pkttype == PKT_SECRET_KEY) + { + pk->main_keyid[0] = pk->keyid[0]; + pk->main_keyid[1] = pk->keyid[1]; + } + else + { + pk->main_keyid[0] = main_pk->keyid[0]; + pk->main_keyid[1] = main_pk->keyid[1]; + } + + ski = pk->seckey_info; if (!ski) BUG (); @@ -1191,34 +1238,109 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock) init_membuf (&mbuf, 50); put_membuf_str (&mbuf, "(skey"); - for (i=j=0; i < nskey; i++) + if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA + || pk->pubkey_algo == PUBKEY_ALGO_ECDH) { - if (!pk->pkey[i]) - ; /* Protected keys only have NPKEY+1 elements. */ - else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE)) - { - put_membuf_str (&mbuf, " e %b"); - format_args_buf_ptr[i] = gcry_mpi_get_opaque (pk->pkey[i], &n); - format_args_buf_int[i] = (n+7)/8; - format_args[j++] = format_args_buf_int + i; - format_args[j++] = format_args_buf_ptr + i; - } + /* We need special treatment for ECC algorithms. OpenPGP + stores only the curve name but the agent expects a full + key. This is so that we can keep all curve name + validation code out of gpg-agent. */ +#if PUBKEY_MAX_NSKEY < 7 +#error PUBKEY_MAX_NSKEY too low for ECC +#endif + char *curve = openpgp_oid_to_str (pk->pkey[0]); + if (!curve) + err = gpg_error_from_syserror (); else { - put_membuf_str (&mbuf, " _ %m"); - format_args[j++] = pk->pkey + i; +#ifdef HAVE_GCRY_PK_GET_CURVE /* Also ensures availability of get_param. */ + gcry_sexp_t cparam = gcry_pk_get_param (GCRY_PK_ECDSA, curve); +#else + gcry_sexp_t cparam = NULL; +#endif + xfree (curve); + if (!cparam) + err = gpg_error (GPG_ERR_UNKNOWN_CURVE); + else + { + const char *s; + + /* Append the curve parameters P, A, B, G and N. */ + for (i=j=0; !err && *(s = "pabgn"+i); i++) + { + ecc_params[i] = one_mpi_from_pkey (cparam, s, 1); + if (!ecc_params[i]) + err = gpg_error (GPG_ERR_INV_CURVE); + else + { + put_membuf_str (&mbuf, " _ %m"); + format_args[j++] = ecc_params+i; + } + } + gcry_sexp_release (cparam); + if (!err) + { + /* Append the public key element Q. */ + put_membuf_str (&mbuf, " _ %m"); + format_args[j++] = pk->pkey + 1; + + /* Append the secret key element D. Note that + for ECDH we need to skip PKEY[2] because this + holds the KEK which is not needed. */ + i = pk->pubkey_algo == PUBKEY_ALGO_ECDH? 3 : 2; + if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE)) + { + put_membuf_str (&mbuf, " e %b"); + format_args_buf_ptr[i] + = gcry_mpi_get_opaque (pk->pkey[i],&n); + format_args_buf_int[i] = (n+7)/8; + format_args[j++] = format_args_buf_int + i; + format_args[j++] = format_args_buf_ptr + i; + } + else + { + put_membuf_str (&mbuf, " _ %m"); + format_args[j++] = pk->pkey + i; + } + } + } + } + } + else + { + /* Standard case for the old (non-ECC) algorithms. */ + for (i=j=0; i < nskey; i++) + { + if (!pk->pkey[i]) + ; /* Protected keys only have NPKEY+1 elements. */ + else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE)) + { + put_membuf_str (&mbuf, " e %b"); + format_args_buf_ptr[i] = gcry_mpi_get_opaque (pk->pkey[i],&n); + format_args_buf_int[i] = (n+7)/8; + format_args[j++] = format_args_buf_int + i; + format_args[j++] = format_args_buf_ptr + i; + } + else + { + put_membuf_str (&mbuf, " _ %m"); + format_args[j++] = pk->pkey + i; + } } } put_membuf_str (&mbuf, ")\n"); put_membuf (&mbuf, "", 1); - { - char *format = get_membuf (&mbuf, NULL); - if (!format) - err = gpg_error_from_syserror (); - else - err = gcry_sexp_build_array (&skey, NULL, format, format_args); - xfree (format); - } + if (err) + xfree (get_membuf (&mbuf, NULL)); + else + { + char *format = get_membuf (&mbuf, NULL); + if (!format) + err = gpg_error_from_syserror (); + else + err = gcry_sexp_build_array (&skey, NULL, format, format_args); + xfree (format); + } if (err) { log_error ("error building skey array: %s\n", gpg_strerror (err)); @@ -1228,7 +1350,7 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock) if (ski->is_protected) { char countbuf[35]; - + /* Note that the IVLEN may be zero if we are working on a dummy key. We can't express that in an S-expression and thus we send dummy data for the IV. */ @@ -1289,9 +1411,9 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock) transferkey = NULL; /* Send the wrapped key to the agent. */ - { + { char *desc = gpg_format_keydesc (pk, 1, 1); - err = agent_import_key (ctrl, desc, &cache_nonce, + err = agent_import_key (ctrl, desc, &cache_nonce, wrappedkey, wrappedkeylen); xfree (desc); } @@ -1328,6 +1450,8 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock) } leave: + for (i=0; i < DIM (ecc_params); i++) + gcry_mpi_release (ecc_params[i]); xfree (cache_nonce); xfree (wrappedkey); xfree (transferkey); @@ -1392,7 +1516,7 @@ sec_to_pub_keyblock (kbnode_t sec_keyblock) * with the trust calculation. */ static int -import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock, +import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock, struct stats_s *stats, unsigned int options) { PKT_public_key *pk; @@ -1400,17 +1524,17 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock, KBNODE node, uidnode; u32 keyid[2]; int rc = 0; - + /* Get the key and print some info about it */ node = find_kbnode (keyblock, PKT_SECRET_KEY); if (!node) BUG (); - + pk = node->pkt->pkt.public_key; keyid_from_pk (pk, keyid); uidnode = find_next_kbnode (keyblock, PKT_USER_ID); - + if (opt.verbose) { log_info ("sec %4u%c/%s %s ", @@ -1423,7 +1547,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock, log_printf ("\n"); } stats->secret_read++; - + if (!uidnode) { log_error( _("key %s: no user ID\n"), keystr_from_pk (pk)); @@ -1456,10 +1580,10 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock, log_error (_("importing secret keys not allowed\n")); return 0; } -#endif - +#endif + clear_kbnode_flags (keyblock); - + if (!(options&IMPORT_MERGE_ONLY) || !have_secret_key_with_kid (keyid) ) { /* We don't have this key, insert as a new key. */ @@ -1477,7 +1601,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock, /* Fixme: We should check for an invalid keyblock and cancel the secret key import in this case. */ release_kbnode (pub_keyblock); - + /* Read the keyblock again to get the effects of a merge. */ /* Fixme: we should do this based on the fingerprint or even better let import_one return the merged @@ -1493,7 +1617,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock, if (!opt.quiet) log_info (_("key %s: secret key imported\n"), keystr_from_pk (pk)); - if (is_status_enabled ()) + if (is_status_enabled ()) print_import_ok (pk, 1|16); check_prefs (ctrl, node); } @@ -1502,11 +1626,11 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock, } } else - { + { /* We don't want to merge the secret keys. */ log_error (_("key %s: secret key part already available\n"), keystr_from_pk (pk)); - if (is_status_enabled ()) + if (is_status_enabled ()) print_import_ok (pk, 16); } @@ -1556,9 +1680,9 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats ) { byte afp[MAX_FINGERPRINT_LEN]; size_t an; - + fingerprint_from_pk (pk, afp, &an); - while (an < MAX_FINGERPRINT_LEN) + while (an < MAX_FINGERPRINT_LEN) afp[an++] = 0; rc = keydb_search_fpr (hd, afp); } @@ -1654,11 +1778,11 @@ chk_self_sigs (const char *fname, kbnode_t keyblock, int rc; u32 bsdate=0, rsdate=0; kbnode_t bsnode = NULL, rsnode = NULL; - + (void)fname; (void)pk; - for (n=keyblock; (n = find_next_kbnode (n, 0)); ) + for (n=keyblock; (n = find_next_kbnode (n, 0)); ) { if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY) { @@ -1672,7 +1796,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock, if ( n->pkt->pkttype != PKT_SIGNATURE ) continue; - + sig = n->pkt->pkt.signature; if ( keyid[0] != sig->keyid[0] || keyid[1] != sig->keyid[1] ) { @@ -1684,7 +1808,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock, import a fully-cached key which speeds things up. */ if (!opt.no_sig_cache) check_key_signature (keyblock, n, NULL); - + if ( IS_UID_SIG(sig) || IS_UID_REV(sig) ) { KBNODE unode = find_prev_kbnode( keyblock, n, PKT_USER_ID ); @@ -1694,16 +1818,16 @@ chk_self_sigs (const char *fname, kbnode_t keyblock, keystr(keyid)); return -1; /* The complete keyblock is invalid. */ } - + /* If it hasn't been marked valid yet, keep trying. */ - if (!(unode->flag&1)) + if (!(unode->flag&1)) { rc = check_key_signature (keyblock, n, NULL); if ( rc ) { if ( opt.verbose ) { - char *p = utf8_to_native + char *p = utf8_to_native (unode->pkt->pkt.user_id->name, strlen (unode->pkt->pkt.user_id->name),0); log_info (gpg_err_code(rc) == G10ERR_PUBKEY_ALGO ? @@ -1732,7 +1856,7 @@ chk_self_sigs (const char *fname, kbnode_t keyblock, n->flag |= 4; } } - else if ( IS_SUBKEY_SIG (sig) ) + else if ( IS_SUBKEY_SIG (sig) ) { /* Note that this works based solely on the timestamps like the rest of gpg. If the standard gets revocation @@ -1761,19 +1885,19 @@ chk_self_sigs (const char *fname, kbnode_t keyblock, else { /* It's valid, so is it newer? */ - if (sig->timestamp >= bsdate) + if (sig->timestamp >= bsdate) { knode->flag |= 1; /* The subkey is valid. */ if (bsnode) { /* Delete the last binding sig since this one is newer */ - bsnode->flag |= 4; + bsnode->flag |= 4; if (opt.verbose) log_info (_("key %s: removed multiple subkey" " binding\n"),keystr(keyid)); } - + bsnode = n; bsdate = sig->timestamp; } @@ -1818,12 +1942,12 @@ chk_self_sigs (const char *fname, kbnode_t keyblock, { /* Delete the last revocation sig since this one is newer. */ - rsnode->flag |= 4; + rsnode->flag |= 4; if (opt.verbose) log_info (_("key %s: removed multiple subkey" " revocation\n"),keystr(keyid)); } - + rsnode = n; rsdate = sig->timestamp; } 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) diff --git a/g10/keyid.c b/g10/keyid.c index 6571a51c0..cbcc971c3 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -39,7 +39,7 @@ #ifdef HAVE_UNSIGNED_TIME_T # define IS_INVALID_TIME_T(a) ((a) == (time_t)(-1)) -#else +#else /* Error or 32 bit time_t and value after 2038-01-19. */ # define IS_INVALID_TIME_T(a) ((a) < 0) #endif @@ -81,6 +81,11 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) if(pk->version<4) n+=2; + /* FIXME: We can avoid the extra malloc by calling only the first + mpi_print here which computes the required length and calling the + real mpi_print only at the end. The speed advantage would only be + for ECC (opaque MPIs) or if we could implement an mpi_print + variant with a callback handler to do the hashing. */ if (npkey==0 && pk->pkey[0] && gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE)) { @@ -92,25 +97,32 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) { for (i=0; i < npkey; i++ ) { - enum gcry_mpi_format fmt; - - if ((pk->pubkey_algo == PUBKEY_ALGO_ECDSA - || pk->pubkey_algo == PUBKEY_ALGO_ECDH) - && (i == 0 || i == 2)) - fmt = GCRYMPI_FMT_USG; /* Name of OID or KEK parms. */ + if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE)) + { + size_t nbits; + const void *p; + + p = gcry_mpi_get_opaque (pk->pkey[i], &nbits); + pp[i] = xmalloc ((nbits+7)/8); + memcpy (pp[i], p, (nbits+7)/8); + nn[i] = (nbits+7)/8; + n += nn[i]; + } else - fmt = GCRYMPI_FMT_PGP; - - if (gcry_mpi_print (fmt, NULL, 0, &nbytes, pk->pkey[i])) - BUG (); - pp[i] = xmalloc (nbytes); - if (gcry_mpi_print (fmt, pp[i], nbytes, &nbytes, pk->pkey[i])) - BUG (); - nn[i] = nbytes; - n += nn[i]; + { + if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, + &nbytes, pk->pkey[i])) + BUG (); + pp[i] = xmalloc (nbytes); + if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes, + &nbytes, pk->pkey[i])) + BUG (); + nn[i] = nbytes; + n += nn[i]; + } } } - + gcry_md_putc ( md, 0x99 ); /* ctb */ /* What does it mean if n is greater than than 0xFFFF ? */ gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */ @@ -127,7 +139,7 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) u16 days=0; if(pk->expiredate) days=(u16)((pk->expiredate - pk->timestamp) / 86400L); - + gcry_md_putc ( md, days >> 8 ); gcry_md_putc ( md, days ); } @@ -178,7 +190,7 @@ v3_keyid (gcry_mpi_t a, u32 *ki) BUG (); if (nbytes < 8) /* oops */ ki[0] = ki[1] = 0; - else + else { p = buffer + nbytes - 8; ki[0] = (p[0] << 24) | (p[1] <<16) | (p[2] << 8) | p[3]; @@ -215,7 +227,7 @@ keystrlen(void) const char * keystr (u32 *keyid) -{ +{ static char keyid_str[KEYID_STR_SIZE]; switch (opt.keyid_format) @@ -226,7 +238,7 @@ keystr (u32 *keyid) case KF_LONG: if (keyid[0]) - snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX", + snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX", (ulong)keyid[0], (ulong)keyid[1]); else snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]); @@ -238,12 +250,12 @@ keystr (u32 *keyid) case KF_0xLONG: if(keyid[0]) - snprintf (keyid_str, sizeof keyid_str, "0x%08lX%08lX", + snprintf (keyid_str, sizeof keyid_str, "0x%08lX%08lX", (ulong)keyid[0],(ulong)keyid[1]); else snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]); break; - + default: BUG(); } @@ -254,7 +266,7 @@ keystr (u32 *keyid) const char * keystr_with_sub (u32 *main_kid, u32 *sub_kid) -{ +{ static char buffer[KEYID_STR_SIZE+1+KEYID_STR_SIZE]; char *p; @@ -408,7 +420,7 @@ keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid ) else keyid_from_pk (&pk, keyid); } - else + else { const byte *dp = fprint; keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ; @@ -422,7 +434,7 @@ keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid ) u32 keyid_from_sig (PKT_signature *sig, u32 *keyid) { - if( keyid ) + if( keyid ) { keyid[0] = sig->keyid[0]; keyid[1] = sig->keyid[1]; @@ -437,13 +449,13 @@ namehash_from_uid (PKT_user_id *uid) if (!uid->namehash) { uid->namehash = xmalloc (20); - + if (uid->attrib_data) rmd160_hash_buffer (uid->namehash, uid->attrib_data, uid->attrib_len); else rmd160_hash_buffer (uid->namehash, uid->name, uid->len); } - + return uid->namehash; } @@ -465,7 +477,7 @@ mk_datestr (char *buffer, time_t atime) if (IS_INVALID_TIME_T (atime)) strcpy (buffer, "????" "-??" "-??"); /* Mark this as invalid. */ - else + else { tp = gmtime (&atime); sprintf (buffer,"%04d-%02d-%02d", @@ -485,7 +497,7 @@ datestr_from_pk (PKT_public_key *pk) { static char buffer[11+5]; time_t atime = pk->timestamp; - + return mk_datestr (buffer, atime); } @@ -518,7 +530,7 @@ expirestr_from_sig (PKT_signature *sig) { static char buffer[11+5]; time_t atime; - + if (!sig->expiredate) return _("never "); atime=sig->expiredate; @@ -591,7 +603,7 @@ const char * colon_datestr_from_sig (PKT_signature *sig) { static char buf[20]; - + snprintf (buf, sizeof buf, "%lu", (ulong)sig->timestamp); return buf; } @@ -621,21 +633,21 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len) const byte *dp; size_t len, nbytes; int i; - + if ( pk->version < 4 ) { if ( is_RSA(pk->pubkey_algo) ) { /* RSA in version 3 packets is special. */ gcry_md_hd_t md; - + if (gcry_md_open (&md, DIGEST_ALGO_MD5, 0)) BUG (); - if ( pubkey_get_npkey (pk->pubkey_algo) > 1 ) + if ( pubkey_get_npkey (pk->pubkey_algo) > 1 ) { for (i=0; i < 2; i++) { - if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, + if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nbytes, pk->pkey[i])) BUG (); /* fixme: Better allocate BUF on the stack */ @@ -662,10 +674,10 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len) memset (array,0,16); } } - else + else { gcry_md_hd_t md; - + md = do_fingerprint_md(pk); dp = gcry_md_read( md, 0 ); len = gcry_md_get_algo_dlen (gcry_md_get_algo (md)); @@ -677,7 +689,7 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len) pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ; gcry_md_close( md); } - + *ret_len = len; return array; } @@ -694,7 +706,7 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array) { gpg_error_t err; gcry_sexp_t s_pkey; - + if (DBG_PACKET) log_debug ("get_keygrip for public key\n"); @@ -742,7 +754,7 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array) err = gpg_error (GPG_ERR_PUBKEY_ALGO); break; } - + if (err) return err; @@ -758,7 +770,7 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array) /* FIXME: Save the keygrip in PK. */ } gcry_sexp_release (s_pkey); - + return 0; } @@ -786,4 +798,3 @@ hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip) } return err; } - diff --git a/g10/main.h b/g10/main.h index d70c16901..920d82c97 100644 --- a/g10/main.h +++ b/g10/main.h @@ -236,6 +236,7 @@ void keyedit_passwd (ctrl_t ctrl, const char *username); void show_basic_key_info (KBNODE keyblock); /*-- keygen.c --*/ +const char *gpg_curve_to_oid (const char *name, unsigned int *r_nbits); u32 parse_expire_string(const char *string); u32 ask_expire_interval(int object,const char *def_expire); u32 ask_expiredate(void); diff --git a/g10/passphrase.c b/g10/passphrase.c index f29fca72f..8065810c9 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -74,7 +74,7 @@ encode_s2k_iterations (int iterations) if (err && gpg_err_code (err) != GPG_ERR_ASS_PARAMETER) log_error (_("problem with the agent: %s\n"), gpg_strerror (err)); /* Default to 65536 which we used up to 2.0.13. */ - return 96; + return 96; } else if (mycnt >= 65011712) return 255; /* Largest possible value. */ @@ -87,7 +87,7 @@ encode_s2k_iterations (int iterations) if (iterations >= 65011712) return 255; - + /* Need count to be in the range 16-31 */ for (count=iterations>>6; count>=32; count>>=1) c++; @@ -96,13 +96,13 @@ encode_s2k_iterations (int iterations) if (S2K_DECODE_COUNT(result) < iterations) result++; - + return result; } -/* Hash a passphrase using the supplied s2k. +/* Hash a passphrase using the supplied s2k. Always needs: dek->algo, s2k->mode, s2k->hash_algo. */ static void hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k) @@ -119,20 +119,20 @@ hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k) if (gcry_md_open (&md, s2k->hash_algo, 1)) BUG (); - for (pass=0; used < dek->keylen ; pass++ ) + for (pass=0; used < dek->keylen ; pass++ ) { - if ( pass ) + if ( pass ) { gcry_md_reset (md); for (i=0; i < pass; i++ ) /* Preset the hash context. */ gcry_md_putc (md, 0 ); } - if ( s2k->mode == 1 || s2k->mode == 3 ) + if ( s2k->mode == 1 || s2k->mode == 3 ) { int len2 = pwlen + 8; ulong count = len2; - + if ( s2k->mode == 3 ) { count = S2K_DECODE_COUNT(s2k->count); @@ -146,7 +146,7 @@ hash_passphrase ( DEK *dek, char *pw, STRING2KEY *s2k) /* A little bit complicated because we need a ulong for count. */ while ( count > len2 ) /* maybe iterated+salted */ - { + { gcry_md_write ( md, s2k->salt, 8 ); gcry_md_write ( md, pw, pwlen ); count -= len2; @@ -231,7 +231,7 @@ read_passphrase_from_fd( int fd ) int i, len; char *pw; - if ( !opt.batch ) + if ( !opt.batch ) { /* Not used but we have to do a dummy read, so that it won't end up at the begin of the message if the quite usual trick to prepend the passphtrase to the message is used. */ @@ -240,12 +240,12 @@ read_passphrase_from_fd( int fd ) while (!(read (fd, buf, 1) != 1 || *buf == '\n' )) ; *buf = 0; - return; + return; } - for (pw = NULL, i = len = 100; ; i++ ) + for (pw = NULL, i = len = 100; ; i++ ) { - if (i >= len-1 ) + if (i >= len-1 ) { char *pw2 = pw; len += 100; @@ -311,35 +311,35 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, if( keyid && get_pubkey( pk, keyid ) ) { if (pk) - free_public_key( pk ); + free_public_key( pk ); pk = NULL; /* oops: no key for some reason */ } - + orig_codeset = i18n_switchto_utf8 (); if (custom_description) atext = native_to_utf8 (custom_description); else if ( !mode && pk && keyid ) - { + { char *uid; size_t uidlen; const char *algo_name = openpgp_pk_algo_name ( pk->pubkey_algo ); const char *timestr; char *maink; - + if ( !algo_name ) algo_name = "?"; #define KEYIDSTRING _(" (main key ID %s)") maink = xmalloc ( strlen (KEYIDSTRING) + keystrlen() + 20 ); - if( keyid[2] && keyid[3] && keyid[0] != keyid[2] + if( keyid[2] && keyid[3] && keyid[0] != keyid[2] && keyid[1] != keyid[3] ) sprintf( maink, KEYIDSTRING, keystr(&keyid[2]) ); else *maink = 0; - - uid = get_user_id ( keyid, &uidlen ); + + uid = get_user_id ( keyid, &uidlen ); timestr = strtimestamp (pk->timestamp); #undef KEYIDSTRING @@ -350,7 +350,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, "%u-bit %s key, ID %s,\n" \ "created %s%s.\n" ) - atext = xmalloc ( 100 + strlen (PROMPTSTRING) + atext = xmalloc ( 100 + strlen (PROMPTSTRING) + uidlen + 15 + strlen(algo_name) + keystrlen() + strlen (timestr) + strlen (maink) ); sprintf (atext, PROMPTSTRING, @@ -362,16 +362,16 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, #undef PROMPTSTRING - { + { size_t dummy; fingerprint_from_pk( pk, fpr, &dummy ); have_fpr = 1; } - + } else atext = xstrdup ( _("Enter passphrase\n") ); - + if (!mode && cacheid) my_cacheid = cacheid; @@ -387,7 +387,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext, repeat, check, &pw); - + xfree (my_prompt); xfree (atext); atext = NULL; @@ -396,14 +396,14 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, if (!rc) ; - else if (gpg_err_code (rc) == GPG_ERR_CANCELED + else if (gpg_err_code (rc) == GPG_ERR_CANCELED || gpg_err_code (rc) == GPG_ERR_FULLY_CANCELED) { log_info (_("cancelled by user\n") ); if (canceled) *canceled = 1; } - else + else { log_error (_("problem with the agent: %s\n"), gpg_strerror (rc)); /* Due to limitations in the API of the upper layers they @@ -412,7 +412,7 @@ passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, definitely not happen and let it continue without requiring a passphrase. Given that now all the upper layers handle a cancel correctly, we simply set the cancel flag now for all - errors from the agent. */ + errors from the agent. */ if (canceled) *canceled = 1; @@ -440,7 +440,7 @@ passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo ) int rc; (void)algo; - + if (!cacheid) { PKT_public_key *pk; @@ -450,7 +450,7 @@ passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo ) byte fpr[MAX_FINGERPRINT_LEN]; char hexfprbuf[2*20+1]; size_t dummy; - + pk = xcalloc (1, sizeof *pk); if ( !keyid || get_pubkey( pk, keyid ) ) { @@ -478,7 +478,7 @@ passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo ) NULL, sets it to true. MODE 0: Allow cached passphrase - 1: Ignore cached passphrase + 1: Ignore cached passphrase 2: Ditto, but create a new key 3: Allow cached passphrase; use the S2K salt as the cache ID 4: Ditto, but create a new key @@ -486,7 +486,7 @@ passphrase_clear_cache ( u32 *keyid, const char *cacheid, int algo ) DEK * passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, int cipher_algo, STRING2KEY *s2k, int mode, - const char *tryagain_text, + const char *tryagain_text, const char *custdesc, const char *custprompt, int *canceled) { @@ -499,11 +499,11 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, if (!canceled) canceled = &dummy_canceled; *canceled = 0; - + if ( !s2k ) { assert (mode != 3 && mode != 4); - /* This is used for the old rfc1991 mode + /* This is used for the old rfc1991 mode * Note: This must match the code in encode.c with opt.rfc1991 set */ s2k = &help_s2k; s2k->mode = 0; @@ -529,16 +529,16 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, /* If we do not have a passphrase available in NEXT_PW and status information are request, we print them now. */ - if ( !next_pw && is_status_enabled() ) + if ( !next_pw && is_status_enabled() ) { char buf[50]; - + if ( keyid ) { u32 used_kid[2]; char *us; - - if ( keyid[2] && keyid[3] ) + + if ( keyid[2] && keyid[3] ) { used_kid[0] = keyid[2]; used_kid[1] = keyid[3]; @@ -548,16 +548,16 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, used_kid[0] = keyid[0]; used_kid[1] = keyid[1]; } - + us = get_long_user_id_string ( keyid ); write_status_text ( STATUS_USERID_HINT, us ); xfree(us); - + snprintf (buf, sizeof buf -1, "%08lX%08lX %08lX%08lX %d 0", (ulong)keyid[0], (ulong)keyid[1], (ulong)used_kid[0], (ulong)used_kid[1], pubkey_algo ); - + write_status_text ( STATUS_NEED_PASSPHRASE, buf ); } else @@ -576,7 +576,7 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, { PKT_public_key *pk = xmalloc_clear( sizeof *pk ); char *p; - + p = get_user_id_native(keyid); tty_printf ("\n"); tty_printf (_("You need a passphrase to unlock the secret key for\n" @@ -586,7 +586,7 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, if ( !get_pubkey( pk, keyid ) ) { const char *s = openpgp_pk_algo_name ( pk->pubkey_algo ); - + tty_printf (_("%u-bit %s key, ID %s, created %s"), nbits_from_pk( pk ), s?s:"?", keystr(keyid), strtimestamp(pk->timestamp) ); @@ -610,19 +610,19 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, free_public_key( pk ); } - if ( next_pw ) + if ( next_pw ) { /* Simply return the passphrase we already have in NEXT_PW. */ pw = next_pw; next_pw = NULL; } - else if ( have_static_passphrase () ) + else if ( have_static_passphrase () ) { /* Return the passphrase we have stored in FD_PASSWD. */ pw = xmalloc_secure ( strlen(fd_passwd)+1 ); strcpy ( pw, fd_passwd ); } - else + else { if ((mode == 3 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3)) { @@ -643,7 +643,7 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, return NULL; } } - + if ( !pw || !*pw ) write_status( STATUS_MISSING_PASSPHRASE ); @@ -689,15 +689,15 @@ gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped) char *maink; char *desc; const char *prompt; - + algo_name = openpgp_pk_algo_name (pk->pubkey_algo); timestr = strtimestamp (pk->timestamp); - uid = get_user_id (pk->keyid, &uidlen); + uid = get_user_id (pk->keyid, &uidlen); orig_codeset = i18n_switchto_utf8 (); if (pk->main_keyid[0] && pk->main_keyid[1] - && pk->keyid[0] != pk->main_keyid[0] + && pk->keyid[0] != pk->main_keyid[0] && pk->keyid[1] != pk->main_keyid[1]) maink = xtryasprintf (_(" (main key ID %s)"), keystr (pk->main_keyid)); else @@ -724,7 +724,7 @@ gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped) "created %s%s.\n"), prompt, (int)uidlen, uid, - nbits_from_pk (pk), algo_name, + nbits_from_pk (pk), algo_name, keystr (pk->keyid), timestr, maink?maink:"" ); xfree (maink); @@ -735,7 +735,7 @@ gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped) if (escaped) { char *tmp = percent_plus_escape (desc); - xfree (desc); + xfree (desc); desc = tmp; } diff --git a/include/ChangeLog b/include/ChangeLog index 8dd88ffbb..81ba48bab 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2011-02-01 Werner Koch + + * cipher.h (PUBKEY_MAX_NPKEY, PUBKEY_MAX_NSKEY): Bump up to + accommodate gcrypt ECC keys. + 2011-01-21 Werner Koch * cipher.h (GCRY_PK_USAGE_CERT): Remove compatibility macros diff --git a/include/cipher.h b/include/cipher.h index 311020857..4667e8043 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -100,8 +100,8 @@ typedef struct /* Constants to allocate static MPI arrays. */ -#define PUBKEY_MAX_NPKEY 4 -#define PUBKEY_MAX_NSKEY 6 +#define PUBKEY_MAX_NPKEY 5 +#define PUBKEY_MAX_NSKEY 7 #define PUBKEY_MAX_NSIG 2 #define PUBKEY_MAX_NENC 2 diff --git a/tests/openpgp/samplekeys/README b/tests/openpgp/samplekeys/README index d38616990..fd05aa3a4 100644 --- a/tests/openpgp/samplekeys/README +++ b/tests/openpgp/samplekeys/README @@ -1,4 +1,5 @@ no-creation-time.gpg A key with a zero creation time. - +ecc-sample-1-pub.asc The first ECC sample key. +ecc-sample-1-sec.asc The first ECC sample key (secret). diff --git a/tests/openpgp/samplekeys/ecc-sample-1-pub.asc b/tests/openpgp/samplekeys/ecc-sample-1-pub.asc new file mode 100644 index 000000000..478fc3aac --- /dev/null +++ b/tests/openpgp/samplekeys/ecc-sample-1-pub.asc @@ -0,0 +1,22 @@ +The key has been generated by the first GnuPG ECC version at +http://code.google.com/p/gnupg-ecc. + +The sample key has ECDSA top key 0xBAA59D9C and a single ECDH +encryption subkey 0x4089AB73. ECDH subkey uses SHA-256 and AES-128 +with KDF. + +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.1.0-ecc (GNU/Linux) + +mFIETJPQrRMIKoZIzj0DAQcCAwQLx6e669XwjHTHe3HuROe7C1oYMXuZbaU5PjOs +xSkyxtL2D00e/jWgufuNN4ftS+6XygEtB7j1g1vnCTVF1TLmtCRlY19kc2FfZGhf +MjU2IDxvcGVucGdwQGJyYWluaHViLm9yZz6IegQTEwgAIgUCTJPQrQIbAwYLCQgH +AwIGFQgCCQoLBBYCAwECHgECF4AACgkQC6Ut8LqlnZzmXQEAiKgiSzPSpUOJcX9d +JtLJ5As98Alit2oFwzhxG7mSVmQA/RP67yOeoUtdsK6bwmRA95cwf9lBIusNjehx +XDfpHj+/uFYETJPQrRIIKoZIzj0DAQcCAwR/cMCoGEzcrqXbILqP7Rfke977dE1X +XsRJEwrzftreZYrn7jXSDoiXkRyfVkvjPZqUvB5cknsaoH/3UNLRHClxAwEIB4hh +BBgTCAAJBQJMk9CtAhsMAAoJEAulLfC6pZ2c1yYBAOSUmaQ8rkgihnepbnpK7tNz +3QEocsLEtsTCDUBGNYGyAQDclifYqsUChXlWKaw3md+yHJPcWZXzHt37c4q/MhIm +oQ== +=hMzp +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/openpgp/samplekeys/ecc-sample-1-sec.asc b/tests/openpgp/samplekeys/ecc-sample-1-sec.asc new file mode 100644 index 000000000..5ff5555f2 --- /dev/null +++ b/tests/openpgp/samplekeys/ecc-sample-1-sec.asc @@ -0,0 +1,25 @@ +The key has been generated by the first GnuPG ECC version at +http://code.google.com/p/gnupg-ecc. + +The sample key has ECDSA top key 0xBAA59D9C and a single ECDH +encryption subkey 0x4089AB73. ECDH subkey uses SHA-256 and AES-128 +with KDF. The password for the key is "ecc". + +-----BEGIN PGP PRIVATE KEY BLOCK----- +Version: GnuPG v2.1.0-ecc (GNU/Linux) + +lJ0ETJPQrRMIKoZIzj0DAQcCAwQLx6e669XwjHTHe3HuROe7C1oYMXuZbaU5PjOs +xSkyxtL2D00e/jWgufuNN4ftS+6XygEtB7j1g1vnCTVF1TLm/gMDAmHomSLb9NbE +oyWUoqgKTbZzbFR/SWmiCcuiQEhREcTyvyU1hAglj7FsBJoQ6/pbeAEQZ3bVzlNM +8F0nF8KPLPuEADF1+4CntCRlY19kc2FfZGhfMjU2IDxvcGVucGdwQGJyYWluaHVi +Lm9yZz6IegQTEwgAIgUCTJPQrQIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA +CgkQC6Ut8LqlnZzmXQEAiKgiSzPSpUOJcX9dJtLJ5As98Alit2oFwzhxG7mSVmQA +/RP67yOeoUtdsK6bwmRA95cwf9lBIusNjehxXDfpHj+/nKEETJPQrRIIKoZIzj0D +AQcCAwR/cMCoGEzcrqXbILqP7Rfke977dE1XXsRJEwrzftreZYrn7jXSDoiXkRyf +VkvjPZqUvB5cknsaoH/3UNLRHClxAwEIB/4DAwJh6Jki2/TWxKO7gHKWIcOcxYZp +CRWjlUghbKb6Q83p8GLPjKRN0USl/U1tObWdksqMXhUO0ePLWUnrbwoWYfYXg9Er +ADTgCYhhBBgTCAAJBQJMk9CtAhsMAAoJEAulLfC6pZ2c1yYA/3eJRirPQZmBno+Z +P/HOBSFWmFt4cUBGUx3oqiUd5loOAP480pb+vXx9ipljJWCJDSl/boRSuqB4hePP +qt9Rd5gNdQ== +=O8Dg +-----END PGP PRIVATE KEY BLOCK----- From 20f429f735d6e965e0660484f8286fe24fb6162b Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 2 Feb 2011 17:40:32 +0100 Subject: [PATCH 25/26] Compute the fingerprint for ECDH only on demand. This also fixes a failed assertion when using a v3 key where the fingerprint size is not 20. --- g10/ChangeLog | 6 +++ g10/encrypt.c | 129 ++++++++++++++++++++++++-------------------------- g10/pkglue.c | 27 +++++++---- g10/pkglue.h | 7 +-- 4 files changed, 90 insertions(+), 79 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index bb55ff85f..b3358c9d9 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,5 +1,11 @@ 2011-02-02 Werner Koch + * encrypt.c (write_pubkey_enc_from_list): Don't compute the + fingerprint. + * pkglue.c (pk_encrypt): Replace PK_FP by PK and compute the + fingerprint only when needed. + * pkglue.h: Include packet.h. + * import.c (transfer_secret_keys): Make sure keyids are available. * keyid.c (hash_public_key): Adjust for the ECC case. diff --git a/g10/encrypt.c b/g10/encrypt.c index 8548a5739..83b43a89e 100644 --- a/g10/encrypt.c +++ b/g10/encrypt.c @@ -84,7 +84,7 @@ encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey) /* The encrypted session key is prefixed with a one-octet algorithm id. */ buf[0] = (*seskey)->algo; memcpy( buf + 1, (*seskey)->key, (*seskey)->keylen ); - + /* We only pass already checked values to the following fucntion, thus we consider any failure as fatal. */ if (openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1)) @@ -119,7 +119,7 @@ use_mdc(PK_LIST pk_list,int algo) if(select_mdc_from_pklist(pk_list)) return 1; - + /* The keys don't support MDC, so now we do a bit of a hack - if any of the AESes or TWOFISH are in the prefs, we assume that the user can handle a MDC. This is valid for PGP 7, which can handle MDCs @@ -181,7 +181,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) memset( &zfx, 0, sizeof zfx); memset( &tfx, 0, sizeof tfx); init_packet(&pkt); - + /* Prepare iobufs. */ inp = iobuf_open(filename); if (inp) @@ -200,23 +200,23 @@ encrypt_simple (const char *filename, int mode, int use_seskey) release_progress_context (pfx); return rc; } - + handle_progress (pfx, inp, filename); - + if (opt.textmode) iobuf_push_filter( inp, text_filter, &tfx ); - + /* Due the the fact that we use don't use an IV to encrypt the session key we can't use the new mode with RFC1991 because it has no S2K salt. RFC1991 always uses simple S2K. */ if ( RFC1991 && use_seskey ) use_seskey = 0; - + cfx.dek = NULL; - if ( mode ) + if ( mode ) { int canceled; - + s2k = xmalloc_clear( sizeof *s2k ); s2k->mode = RFC1991? 0:opt.s2k_mode; s2k->hash_algo = S2K_DIGEST_ALGO; @@ -233,37 +233,37 @@ encrypt_simple (const char *filename, int mode, int use_seskey) release_progress_context (pfx); return rc; } - if (use_seskey && s2k->mode != 1 && s2k->mode != 3) + if (use_seskey && s2k->mode != 1 && s2k->mode != 3) { use_seskey = 0; log_info (_("can't use a symmetric ESK packet " "due to the S2K mode\n")); } - + if ( use_seskey ) { DEK *dek = NULL; - + seskeylen = openpgp_cipher_get_algo_keylen (default_cipher_algo ()); encrypt_seskey( cfx.dek, &dek, enckey ); xfree( cfx.dek ); cfx.dek = dek; } - + if (opt.verbose) log_info(_("using cipher %s\n"), openpgp_cipher_algo_name (cfx.dek->algo)); - + cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo); } - + if (do_compress && cfx.dek && cfx.dek->use_mdc && is_file_compressed(filename, &rc)) { if (opt.verbose) log_info(_("`%s' already compressed\n"), filename); - do_compress = 0; + do_compress = 0; } - + if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, &out ))) { iobuf_cancel (inp); @@ -272,7 +272,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) release_progress_context (pfx); return rc; } - + if ( opt.armor ) { afx = new_armor_context (); @@ -296,7 +296,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) log_error("build symkey packet failed: %s\n", g10_errstr(rc) ); xfree (enc); } - + if (!opt.no_literal) pt = setup_plaintext_name (filename, inp); @@ -347,7 +347,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey) pkt.pkttype = 0; pkt.pkt.generic = NULL; } - + /* Register the cipher filter. */ if (mode) iobuf_push_filter ( out, cipher_filter, &cfx ); @@ -359,14 +359,14 @@ encrypt_simple (const char *filename, int mode, int use_seskey) zfx.new_ctb = 1; push_compress_filter (out, &zfx, default_compress_algo()); } - + /* Do the work. */ if (!opt.no_literal) { if ( (rc = build_packet( out, &pkt )) ) log_error("build_packet failed: %s\n", g10_errstr(rc) ); } - else + else { /* User requested not to create a literal packet, so we copy the plain data. */ @@ -380,12 +380,12 @@ encrypt_simple (const char *filename, int mode, int use_seskey) } wipememory (copy_buffer, 4096); /* burn buffer */ } - + /* Finish the stuff. */ iobuf_close (inp); if (rc) iobuf_cancel(out); - else + else { iobuf_close (out); /* fixme: check returncode */ if (mode) @@ -425,7 +425,7 @@ setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek) static int -write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek, +write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek, iobuf_t out) { int rc, seskeylen = openpgp_cipher_get_algo_keylen (dek->algo); @@ -492,7 +492,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, memset( &tfx, 0, sizeof tfx); init_packet(&pkt); - if (use_symkey + if (use_symkey && (rc=setup_symkey(&symkey_s2k,&symkey_dek))) { release_progress_context (pfx); @@ -509,7 +509,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, return rc; } } - + if(PGP2) { for (work_list=pk_list; work_list; work_list=work_list->next) @@ -560,17 +560,17 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, rc = open_outfile (outputfd, filename, opt.armor? 1:0, &out); if (rc) goto leave; - + if (opt.armor) { afx = new_armor_context (); push_armor_filter (afx, out); } - + /* Create a session key. */ cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek); if (!opt.def_cipher_algo) - { + { /* Try to get it from the prefs. */ cfx.dek->algo = select_algo_from_prefs (pk_list, PREFTYPE_SYM, -1, NULL); /* The only way select_algo_from_prefs can fail here is when @@ -582,7 +582,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, if (cfx.dek->algo == -1) { cfx.dek->algo = CIPHER_ALGO_3DES; - + if (PGP2) { log_info(_("unable to use the IDEA cipher for all of the keys " @@ -610,12 +610,12 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, openpgp_cipher_algo_name (opt.def_cipher_algo), opt.def_cipher_algo); } - + cfx.dek->algo = opt.def_cipher_algo; } - + cfx.dek->use_mdc = use_mdc (pk_list,cfx.dek->algo); - + /* Only do the is-file-already-compressed check if we are using a MDC. This forces compressed files to be re-compressed if we do not have a MDC to give some protection against chosen ciphertext @@ -625,7 +625,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, { if (opt.verbose) log_info(_("`%s' already compressed\n"), filename); - do_compress = 0; + do_compress = 0; } if (rc2) { @@ -636,7 +636,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, make_session_key (cfx.dek); if (DBG_CIPHER) log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen ); - + rc = write_pubkey_enc_from_list (pk_list, cfx.dek, out); if (rc) goto leave; @@ -647,16 +647,16 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, secret key needed to decrypt. */ if(use_symkey && (rc = write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out))) goto leave; - + if (!opt.no_literal) pt = setup_plaintext_name (filename, inp); - + if (filefd != -1 && !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode ) { off_t tmpsize; int overflow; - + if ( !(tmpsize = iobuf_get_filelength(inp, &overflow)) && !overflow && opt.verbose) log_info(_("WARNING: `%s' is an empty file\n"), filename ); @@ -672,7 +672,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, else filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ - if (!opt.no_literal) + if (!opt.no_literal) { pt->timestamp = make_timestamp(); pt->mode = opt.textmode ? 't' : 'b'; @@ -693,7 +693,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, if (do_compress) { int compr_algo = opt.compress_algo; - + if (compr_algo == -1) { compr_algo = select_algo_from_prefs (pk_list, PREFTYPE_ZIP, -1, NULL); @@ -702,7 +702,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, /* Theoretically impossible to get here since uncompressed is implicit. */ } - else if (!opt.expert + else if (!opt.expert && select_algo_from_prefs(pk_list, PREFTYPE_ZIP, compr_algo, NULL) != compr_algo) { @@ -710,7 +710,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, " violates recipient preferences\n"), compress_algo_to_string(compr_algo), compr_algo); } - + /* Algo 0 means no compression. */ if (compr_algo) { @@ -719,7 +719,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, push_compress_filter (out,&zfx,compr_algo); } } - + /* Do the work. */ if (!opt.no_literal) { @@ -750,7 +750,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, iobuf_close (inp); if (rc) iobuf_cancel (out); - else + else { iobuf_close (out); /* fixme: check returncode */ write_status (STATUS_END_ENCRYPTION); @@ -779,7 +779,7 @@ encrypt_filter (void *opaque, int control, size_t size = *ret_len; encrypt_filter_context_t *efx = opaque; int rc = 0; - + if (control == IOBUFCTRL_UNDERFLOW) /* decrypt */ { BUG(); /* not used */ @@ -789,19 +789,19 @@ encrypt_filter (void *opaque, int control, if ( !efx->header_okay ) { efx->cfx.dek = xmalloc_secure_clear ( sizeof *efx->cfx.dek ); - if ( !opt.def_cipher_algo ) + if ( !opt.def_cipher_algo ) { /* Try to get it from the prefs. */ efx->cfx.dek->algo = select_algo_from_prefs (efx->pk_list, PREFTYPE_SYM, -1, NULL); - if (efx->cfx.dek->algo == -1 ) + if (efx->cfx.dek->algo == -1 ) { /* Because 3DES is implicitly in the prefs, this can only happen if we do not have any public keys in the list. */ efx->cfx.dek->algo = DEFAULT_CIPHER_ALGO; } - + /* In case 3DES has been selected, print a warning if any key does not have a preference for AES. This should help to indentify why encrypting to several @@ -810,7 +810,7 @@ encrypt_filter (void *opaque, int control, && efx->cfx.dek->algo == CIPHER_ALGO_3DES) warn_missing_aes_from_pklist (efx->pk_list); } - else + else { if (!opt.expert && select_algo_from_prefs (efx->pk_list,PREFTYPE_SYM, @@ -820,12 +820,12 @@ encrypt_filter (void *opaque, int control, "violates recipient preferences\n"), openpgp_cipher_algo_name (opt.def_cipher_algo), opt.def_cipher_algo); - + efx->cfx.dek->algo = opt.def_cipher_algo; } - + efx->cfx.dek->use_mdc = use_mdc (efx->pk_list,efx->cfx.dek->algo); - + make_session_key ( efx->cfx.dek ); if (DBG_CIPHER) log_printhex ("DEK is: ", efx->cfx.dek->key, efx->cfx.dek->keylen); @@ -841,13 +841,13 @@ encrypt_filter (void *opaque, int control, if(rc) return rc; } - + iobuf_push_filter (a, cipher_filter, &efx->cfx); - + efx->header_okay = 1; } rc = iobuf_write (a, buf, size); - + } else if (control == IOBUFCTRL_FREE) { @@ -876,11 +876,9 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out) for ( ; pk_list; pk_list = pk_list->next ) { gcry_mpi_t frame; - byte fp[MAX_FINGERPRINT_LEN]; - size_t fpn; pk = pk_list->pk; - + print_pubkey_algo_note ( pk->pubkey_algo ); enc = xmalloc_clear ( sizeof *enc ); enc->pubkey_algo = pk->pubkey_algo; @@ -894,9 +892,6 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out) compliance_failure(); } - fingerprint_from_pk (pk, fp, &fpn); - assert (fpn == 20); - /* Okay, what's going on: We have the session key somewhere in * the structure DEK and want to encode this session key in an * integer value of n bits. pubkey_nbits gives us the number of @@ -909,9 +904,9 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out) * for Elgamal). We don't need frame anymore because we have * everything now in enc->data which is the passed to * build_packet(). */ - frame = encode_session_key (pk->pubkey_algo, dek, + frame = encode_session_key (pk->pubkey_algo, dek, pubkey_nbits (pk->pubkey_algo, pk->pkey)); - rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, fp, pk->pkey); + rc = pk_encrypt (pk->pubkey_algo, enc->data, frame, pk, pk->pkey); gcry_mpi_release (frame); if (rc) log_error ("pubkey_encrypt failed: %s\n", gpg_strerror (rc) ); @@ -932,7 +927,7 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out) pkt.pkt.pubkey_enc = enc; rc = build_packet (out, &pkt); if (rc) - log_error ("build_packet(pubkey_enc) failed: %s\n", + log_error ("build_packet(pubkey_enc) failed: %s\n", g10_errstr (rc)); } free_pubkey_enc(enc); @@ -951,9 +946,9 @@ encrypt_crypt_files (ctrl_t ctrl, int nfiles, char **files, strlist_t remusr) if (opt.outfile) { log_error(_("--output doesn't work for this command\n")); - return; + return; } - + if (!nfiles) { char line[2048]; diff --git a/g10/pkglue.c b/g10/pkglue.c index 66ba48b60..836c2c3e2 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -37,7 +37,7 @@ mpi_from_sexp (gcry_sexp_t sexp, const char * item) { gcry_sexp_t list; gcry_mpi_t data; - + list = gcry_sexp_find_token (sexp, item, 0); assert (list); data = gcry_sexp_nth_mpi (list, 1, 0); @@ -151,10 +151,11 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey) /**************** * Emulate our old PK interface here - sometime in the future we might * change the internal design to directly fit to libgcrypt. + * PK is only required to compute the fingerprint for ECDH. */ int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, - const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t *pkey) + PKT_public_key *pk, gcry_mpi_t *pkey) { gcry_sexp_t s_ciph, s_data, s_pkey; int rc; @@ -179,15 +180,17 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, if (rc || gcry_sexp_build (&s_data, NULL, "%m", data)) BUG (); } - else if (algo == PUBKEY_ALGO_ECDH) + else if (algo == PUBKEY_ALGO_ECDH) { gcry_mpi_t k; char *curve; + byte fp[MAX_FINGERPRINT_LEN]; + size_t fpn; rc = pk_ecdh_generate_ephemeral_key (pkey, &k); if (rc) return rc; - + curve = openpgp_oid_to_str (pkey[0]); if (!curve) rc = gpg_error_from_syserror (); @@ -215,12 +218,14 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, if (rc) ; - else if (algo == PUBKEY_ALGO_ECDH) + else if (algo == PUBKEY_ALGO_ECDH) { gcry_mpi_t shared, public, result; + byte fp[MAX_FINGERPRINT_LEN]; + size_t fpn; /* Get the shared point and the ephemeral public key. */ - shared = mpi_from_sexp (s_ciph, "s"); + shared = mpi_from_sexp (s_ciph, "s"); public = mpi_from_sexp (s_ciph, "e"); gcry_sexp_release (s_ciph); s_ciph = NULL; @@ -230,10 +235,14 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_dump (public); log_printf ("\n"); } - + result = NULL; - rc = pk_ecdh_encrypt_with_shared_point (1 /*=encrypton*/, shared, - pk_fp, data, pkey, &result); + fingerprint_from_pk (pk, fp, &fpn); + if (fpn != 20) + rc = gpg_error (GPG_ERR_INV_LENGTH); + else + rc = pk_ecdh_encrypt_with_shared_point (1 /*=encrypton*/, shared, + fp, data, pkey, &result); gcry_mpi_release (shared); if (!rc) { diff --git a/g10/pkglue.h b/g10/pkglue.h index eb0d7c1dc..e5165f73b 100644 --- a/g10/pkglue.h +++ b/g10/pkglue.h @@ -20,14 +20,15 @@ #ifndef GNUPG_G10_PKGLUE_H #define GNUPG_G10_PKGLUE_H +#include "packet.h" /* For PKT_public_key. */ + /*-- pkglue.c --*/ gcry_mpi_t mpi_from_sexp (gcry_sexp_t sexp, const char * item); int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey); int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, - const byte fp[MAX_FINGERPRINT_LEN], - gcry_mpi_t *pkey); + PKT_public_key *pk, gcry_mpi_t *pkey); int pk_check_secret_key (int algo, gcry_mpi_t *skey); @@ -35,7 +36,7 @@ int pk_check_secret_key (int algo, gcry_mpi_t *skey); gcry_mpi_t pk_ecdh_default_params (unsigned int qbits); gpg_error_t pk_ecdh_generate_ephemeral_key (gcry_mpi_t *pkey, gcry_mpi_t *r_k); gpg_error_t pk_ecdh_encrypt_with_shared_point -/* */ (int is_encrypt, gcry_mpi_t shared_mpi, +/* */ (int is_encrypt, gcry_mpi_t shared_mpi, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t *pkey, gcry_mpi_t *out); From 0b5bcb40cf17a0e1032c113af6024c08b47d7a5c Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 3 Feb 2011 16:31:42 +0100 Subject: [PATCH 26/26] 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. --- AUTHORS | 4 +- NEWS | 18 ++-- agent/ChangeLog | 16 +++ agent/protect.c | 165 +++++++++++++++-------------- common/ChangeLog | 2 - common/convert.c | 15 ++- g10/ChangeLog | 103 +++++++++++------- g10/keygen.c | 265 ++++++++++++++++++++++++----------------------- g10/pkglue.c | 2 - g10/pubkey-enc.c | 10 +- g10/seskey.c | 28 ++--- 11 files changed, 336 insertions(+), 292 deletions(-) diff --git a/AUTHORS b/AUTHORS index 34c4881ed..64aebf86c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -11,6 +11,9 @@ Authors Ales Nyakhaychyk Translations [be] +Andrey Jivsov Assigns past and future changes for ECC. + (g10/ecdh.c. other changes to support ECC) + Birger Langkjer Translations [da] Maxim Britov Translations [ru] @@ -174,4 +177,3 @@ name gpg2keys_*. This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - diff --git a/NEWS b/NEWS index 5f9fd0ab6..f58871a67 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,8 @@ Noteworthy changes in version 2.1.0beta2 (unreleased) * Dirmngr has taken over the function of the keyserver helpers. Thus we now have a specified direct interface to keyservers via Dirmngr. + * ECC support for GPG as described by draft-jivsov-openpgp-ecc-06.txt. + Noteworthy changes in version 2.1.0beta1 (2010-10-26) ----------------------------------------------------- @@ -183,7 +185,7 @@ Noteworthy changes in version 2.0.10 (2009-01-12) the installation directory to %CSIDL_COMMON_APPDATA%/GNU/etc/gnupg. * [w32] The gnupg2.nls directory is not anymore used. The standard - locale directory is now used. + locale directory is now used. * [w32] Fixed a race condition between gpg and gpgsm in the use of temporary file names. @@ -235,7 +237,7 @@ Noteworthy changes in version 2.0.8 (2007-12-20) * The envvars XAUTHORITY and PINENTRY_USER_DATA are now passed to the Pinentry. - * Fixed the auto creation of the key stub for smartcards. + * Fixed the auto creation of the key stub for smartcards. * Fixed a rare bug in decryption using the OpenPGP card. @@ -277,7 +279,7 @@ Noteworthy changes in version 2.0.6 (2007-08-16) * GPGSM does now grok --default-key. - * GPGCONF is now aware of --default-key and --encrypt-to. + * GPGCONF is now aware of --default-key and --encrypt-to. * GPGSM does again correctly print the serial number as well the the various keyids. This was broken since 2.0.4. @@ -286,7 +288,7 @@ Noteworthy changes in version 2.0.6 (2007-08-16) * Improved Windows support. - + Noteworthy changes in version 2.0.5 (2007-07-05) ------------------------------------------------ @@ -326,7 +328,7 @@ Noteworthy changes in version 2.0.3 (2007-03-08) such messages by default which makes those programs safe again. --allow-multiple-messages returns to the old behavior. [CVE-2007-1263]. - * New --verify-option show-primary-uid-only. + * New --verify-option show-primary-uid-only. * gpgconf may now reads a global configuration file to select which options are changeable by a frontend. The new applygnupgdefaults @@ -490,7 +492,7 @@ Noteworthy changes in version 1.9.21 (2006-06-20) * Support for the CardMan 4040 PCMCIA reader (Linux 2.6.15 required). - * Scdaemon does not anymore reset cards at the end of a connection. + * Scdaemon does not anymore reset cards at the end of a connection. * Kludge to allow use of Bundesnetzagentur issued X.509 certificates. @@ -510,7 +512,7 @@ Noteworthy changes in version 1.9.20 (2005-12-20) * Basic support for qualified signatures. - * New debug tool gpgparsemail. + * New debug tool gpgparsemail. Noteworthy changes in version 1.9.19 (2005-09-12) @@ -794,7 +796,7 @@ Noteworthy changes in version 1.9.0 (2003-08-05) Copyright 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009 Free Software Foundation, Inc. + 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without 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; } - diff --git a/common/ChangeLog b/common/ChangeLog index 0214583b7..f5a707b62 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -3,8 +3,6 @@ * openpgp-oid.c: New. * t-openpgp-oid.c: New. - * convert.c (mpi2hex): Remove. - 2011-01-20 Werner Koch Fix bug#1313. diff --git a/common/convert.c b/common/convert.c index c314ec9a6..78a16c957 100644 --- a/common/convert.c +++ b/common/convert.c @@ -23,7 +23,6 @@ #include #include "util.h" -#include "gcrypt.h" /* FIXME: really needed? */ #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A')) @@ -107,14 +106,14 @@ do_bin2hex (const void *buffer, size_t length, char *stringbuf, int with_colon) { const unsigned char *s; char *p; - + if (!stringbuf) { /* Not really correct for with_colon but we don't care about the one wasted byte. */ - size_t n = with_colon? 3:2; - size_t nbytes = n * length + 1; - if (length && (nbytes-1) / n != length) + size_t n = with_colon? 3:2; + size_t nbytes = n * length + 1; + if (length && (nbytes-1) / n != length) { gpg_err_set_errno (ENOMEM); return NULL; @@ -123,7 +122,7 @@ do_bin2hex (const void *buffer, size_t length, char *stringbuf, int with_colon) if (!stringbuf) return NULL; } - + for (s = buffer, p = stringbuf; length; length--, s++) { if (with_colon && s != buffer) @@ -172,7 +171,7 @@ bin2hexcolon (const void *buffer, size_t length, char *stringbuf) buffer, the function returns NULL and won't change the existing conent of buffer. In-place conversion is possible as long as BUFFER points to HEXSTRING. - + If BUFFER is NULL and bufsize is 0 the function scans HEXSTRING but does not store anything. This may be used to find the end of hexstring. @@ -205,7 +204,7 @@ hex2str (const char *hexstring, char *buffer, size_t bufsize, size_t *buflen) { if (count > bufsize) return NULL; /* Too long. */ - + for (s=hexstring, idx=0; hexdigitp (s) && hexdigitp (s+1); s += 2) ((unsigned char*)buffer)[idx++] = xtoi_2 (s); if (need_nul) diff --git a/g10/ChangeLog b/g10/ChangeLog index b3358c9d9..d6f93239a 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,8 @@ +2011-02-03 Werner Koch + + Finished ECC integration. + Wrote change description for 2011-01-13. + 2011-02-02 Werner Koch * encrypt.c (write_pubkey_enc_from_list): Don't compute the @@ -12,36 +17,31 @@ 2011-02-01 Werner Koch - * import.c (transfer_secret_keys): Implement ECC case. - * gpg.c (main): Call setup_libgcrypt_logging. + * import.c (transfer_secret_keys): Implement ECC case. + (one_mpi_from_pkey): New. + * export.c (transfer_format_to_openpgp): Ditto. * keygen.c (gpg_curve_to_oid): New. (ecckey_from_sexp): Factor curve name mapping out to new function. 2011-01-31 Werner Koch - * misc.c (make_flagged_int, openpgp_oid_from_str) - (openpgp_oid_to_str): Move to ../common/openpgp-oids.c. - * ecdh.c (pk_ecdh_encrypt_with_shared_point): Return an opaque MPI. * build-packet.c (mpi_write): Rename to gpg_mpi_write and make global. - (write_size_body_mpi): Remove. 2011-01-30 Werner Koch - * keyid.c (keygrip_from_pk): Adjust ECC cases. * pkglue.c (pk_verify): Ditto. - * parse-packet.c (read_size_body): Rewrite. - (parse_key): Simply ECC case. + * parse-packet.c (parse_key): Simply ECC case. (parse_pubkeyenc): Ditto. * misc.c (pubkey_get_npkey): Special case ECC. (pubkey_get_nskey): Ditto. - (mpi_print): Support printfing of opaque values. + (mpi_print): Support printing of opaque values. (openpgp_oid_to_str): New. (pubkey_nbits): For ECC pass curve parameter. @@ -61,19 +61,6 @@ (get_parameter_algo): Map algo number. (ecckey_from_sexp): New. * misc.c (map_pk_gcry_to_openpgp): New. - (openpgp_oid_from_str): New. Based on libksba code. - -2011-01-26 Werner Koch - - * misc.c (ecdsa_qbits_from_Q): Use unsigned int. - - * misc.c (iobuf_read_size_body): Move and rename to .. - * parse-packet.c (read_size_body): .. here. Make static. - * misc.c (iobuf_write_size_body_mpi): Move and rename to .. - * build-packet.c (write_size_body_mpi): .. here. - (iobuf_name_oid_write, ecdh_kek_params_write, ecdh_esk_write): - Remove macros. Replace users by direct calls to - write_size_body_mpi. 2011-01-25 Werner Koch @@ -84,28 +71,17 @@ (pk_ecdh_encrypt): Remove. (pk_ecdh_encrypt_with_shared_point): Make public. - * pubkey-enc.c (get_it): Fix assertion. - Use GPG_ERR_WRONG_SECKEY instead of log_fatal. Add safety checks - for NFRAME. + * pubkey-enc.c (get_it): Fix assertion. Use GPG_ERR_WRONG_SECKEY + instead of log_fatal. Add safety checks for NFRAME. - * main.h (KEYGEN_FLAG_NO_PROTECTION, KEYGEN_FLAG_TRANSIENT_KEY): - Move back to .. - * keygen.c: .. here. - (pk_ecc_keypair_gen): Make static. - (common_key_gen): Fold back into .. - (common_gen): .. this. - (delme__pk_ecc_build_sexp): Remove unused function. - (pk_ecc_keypair_gen): Fold it into .. - (gen_ecc): .. this. + * keygen.c (pk_ecc_keypair_gen): Make static. (ask_keysize): Use proper rounding for ECC. (pk_ecc_build_key_params): Remove NBITSSTR. - * verify-stubs.c: Remove. - 2011-01-20 Werner Koch * keyserver.c: Rewrite most stuff for use with dirmngr. Get rid - of all spawn code. Work work pending. + of all spawn code. More work pending. * export.c (export_pubkeys_buffer): New. @@ -116,6 +92,57 @@ * gpg.c: Include call-dirmngr.h. (gpg_deinit_default_ctrl): Call gpg_dirmngr_deinit_session_data. +2011-01-13 Andrey Jivsov (wk) + + Integrated ECC support. Below are the changes finally merged into + the git master after some cleanup by wk until 2011-02-03. + + * ecdh.c: New. + + * sign.c (mpi_from_sexp): Remove. + (match_dsa_hash): Uses SHA-512 for ECDSA with 521 bits. + (hash_for): Support ECDSA. + (make_keysig_packet): Ditto. + + * seskey.c (encode_session_key): Add arg OPENPGP_PK_ALGO. Support + ECDH. + (encode_md_value): Map pkalgo. Extend size checks to ECDSA. + + * pubkey-enc.c (get_it): Support ECDH. + + * pkglue.c (mpi_from_sexp): Make global. + (pk_verify, pk_encrypt, pk_check_secret_key): Support ECC. + + * parse-packet.c (read_size_body): New. + (parse_pubkeyenc): Support ECC. + (parse_key): Ditto. + + * misc.c (map_pk_openpgp_to_gcry, map_pk_gcry_to_openpgp): New. + (openpgp_pk_test_algo, openpgp_pk_test_algo2): Map algo numbers. + (openpgp_pk_algo_usage): Support ECDH and ECDSA. + (openpgp_pk_algo_name): Simplify. + (ecdsa_qbits_from_Q): New. + + * mainproc.c (proc_pubkey_enc): Support ECC. + + * keyid.c (pubkey_letter): Add 'E' and 'e'. + (keygrip_from_pk): Supporf ECC. + + * keygen.c: Include pkglue.h. + (ask_algo): Add option 9 for ECDSA and ECDH. + (ask_keysize): Support ECDSA and ECDH. + (do_create): Ditto. + (gen_ecc): New. + (pk_ecc_build_key_params): New. + + * getkey.c (cache_public_key): Support ECC. + + * encrypt.c (write_pubkey_enc_from_list): Pass PK to PK_ENCRYPT + and the pkalgo to encode_session_key. + + * build-packet.c (do_key, do_pubkey_enc): Support ECC. + (write_size_body_mpi): New. + 2011-01-06 Werner Koch * gpg.c (main): Use keyserver_spec_t. 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: diff --git a/g10/pkglue.c b/g10/pkglue.c index 836c2c3e2..05f7167c2 100644 --- a/g10/pkglue.c +++ b/g10/pkglue.c @@ -184,8 +184,6 @@ pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, { gcry_mpi_t k; char *curve; - byte fp[MAX_FINGERPRINT_LEN]; - size_t fpn; rc = pk_ecdh_generate_ephemeral_key (pkey, &k); if (rc) diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index d45b4a217..1b94af54f 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -160,7 +160,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) if (!enc->data[0] || !enc->data[1]) err = gpg_error (GPG_ERR_BAD_MPI); else - err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))", + err = gcry_sexp_build (&s_data, NULL, "(enc-val(elg(a%m)(b%m)))", enc->data[0], enc->data[1]); } else if (pkalgo == GCRY_PK_RSA || pkalgo == GCRY_PK_RSA_E) @@ -185,9 +185,11 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid) if (err) goto leave; - /* fixme: only needed for ECDH. Don't compute always. */ - fingerprint_from_pk (sk, fp, &fpn); - assert (fpn == 20); + if (sk->pubkey_algo == PUBKEY_ALGO_ECDH) + { + fingerprint_from_pk (sk, fp, &fpn); + assert (fpn == 20); + } /* Decrypt. */ desc = gpg_format_keydesc (sk, 0, 1); diff --git a/g10/seskey.c b/g10/seskey.c index 2d7918d39..1f3e8ab49 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -49,10 +49,10 @@ make_session_key( DEK *dek ) 0 : GCRY_CIPHER_ENABLE_SYNC))) ) BUG(); gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM ); - for (i=0; i < 16; i++ ) + for (i=0; i < 16; i++ ) { rc = gcry_cipher_setkey (chd, dek->key, dek->keylen); - if (!rc) + if (!rc) { gcry_cipher_close (chd); return; @@ -82,7 +82,7 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) int i,n; u16 csum; gcry_mpi_t a; - + if (DBG_CIPHER) log_debug ("encode_session_key: encoding %d byte DEK", dek->keylen); @@ -102,10 +102,10 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) */ nframe = (( 1 + dek->keylen + 2 /* The value so far is always odd. */ + 7 ) & (~7)); - + /* alg+key+csum fit and the size is congruent to 8. */ assert (!(nframe%8) && nframe > 1 + dek->keylen + 2 ); - + frame = xmalloc_secure (nframe); n = 0; frame[n++] = dek->algo; @@ -122,13 +122,13 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) "[%d] %02x %02x %02x ... %02x %02x %02x\n", nframe, frame[0], frame[1], frame[2], frame[nframe-3], frame[nframe-2], frame[nframe-1]); - + if (gcry_mpi_scan (&a, GCRYMPI_FMT_USG, frame, nframe, &nframe)) BUG(); xfree(frame); return a; } - + /* The current limitation is that we can only use a session key * whose length is a multiple of BITS_PER_MPI_LIMB * I think we can live with that. @@ -136,7 +136,7 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) if (dek->keylen + 7 > nframe || !nframe) log_bug ("can't encode a %d bit key in a %d bits frame\n", dek->keylen*8, nbits ); - + /* We encode the session key in this way: * * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes) @@ -163,7 +163,7 @@ encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits) { int j, k; byte *pp; - + /* Count the zero bytes. */ for (j=k=0; j < i; j++ ) if (!p[j]) @@ -273,9 +273,9 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) i.e. 04 */ if (pkalgo == GCRY_PK_ECDSA) qbytes = ecdsa_qbits_from_Q (qbytes); - + /* Make sure it is a multiple of 8 bits. */ - + if (qbytes%8) { log_error(_("DSA requires the hash length to be a" @@ -295,11 +295,11 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) gcry_pk_algo_name (pkalgo), keystr_from_pk (pk), qbytes); return NULL; } - + qbytes /= 8; /* Check if we're too short. Too long is safe as we'll - automatically left-truncate. + automatically left-truncate. FIXME: Check against FIPS. This checks would require the use of SHA512 with ECDSA 512. I @@ -308,7 +308,7 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo) adjust it later for general case. (Note that the check will never pass for ECDSA 521 anyway as the only hash that intended to match it is SHA 512, but 512 < 521). */ - if (gcry_md_get_algo_dlen (hash_algo) + if (gcry_md_get_algo_dlen (hash_algo) < ((pkalgo == GCRY_PK_ECDSA && qbytes > (521)/8) ? 512/8 : qbytes)) { log_error (_("%s key %s requires a %zu bit or larger hash "