From cvs at cvs.gnupg.org Tue Mar 1 13:30:06 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 01 Mar 2011 13:30:06 +0100 Subject: [git] KSBA - branch, master, updated. debian/libksba-1.1.0-11-g0b81a5a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "KSBA is a library to access X.509 certificates and CMS data.". The branch, master has been updated via 0b81a5a30f4b57c80b379cd974914400c622f168 (commit) via 1e5eea7461428c84f24dd97aef442c98b14e8280 (commit) from 4768923e5800c2cb65dbcdeeae2d866b6de5d74a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0b81a5a30f4b57c80b379cd974914400c622f168 Author: Werner Koch Date: Tue Mar 1 12:41:00 2011 +0100 Prepare 1.2 release diff --git a/ChangeLog b/ChangeLog index bdb1780..ab252d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-03-01 Werner Koch + + Release 1.2.0. + + * configure.ac: Bump LT version to C19/A11/R0. + 2011-02-25 Werner Koch * configure.ac (KSBA_CONFIG_HOST): New. diff --git a/NEWS b/NEWS index a47c37f..5cc047e 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -Noteworthy changes in version 1.2.0 +Noteworthy changes in version 1.2.0 (2011-03-01) ------------------------------------------------ * New functions to allow the creation of X.509 certificates. diff --git a/configure.ac b/configure.ac index fc0b34e..fcfb450 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # configure.ac - for libksba # Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, -# 2010 g10 Code GmbH +# 2010, 2011 g10 Code GmbH # # This file is part of KSBA # @@ -26,7 +26,7 @@ min_automake_version="1.10" # 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], [1.2.0]) -m4_define([my_issvn], [yes]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) @@ -42,8 +42,8 @@ AC_INIT([libksba], # (Interfaces added: CURRENT++, AGE++, REVISION=0) # (No interfaces changed: REVISION++) # Please remember to document interface changes in the NEWS file. -LIBKSBA_LT_CURRENT=18 -LIBKSBA_LT_AGE=10 +LIBKSBA_LT_CURRENT=19 +LIBKSBA_LT_AGE=11 LIBKSBA_LT_REVISION=0 #------------------- # If the API is changed in an incompatible way: increment the next counter. commit 1e5eea7461428c84f24dd97aef442c98b14e8280 Author: Werner Koch Date: Tue Mar 1 12:36:19 2011 +0100 Fix setting of not-before date diff --git a/src/certreq.c b/src/certreq.c index e91c5b2..d9737bf 100644 --- a/src/certreq.c +++ b/src/certreq.c @@ -747,7 +747,7 @@ build_cri (ksba_certreq_t cr) { tp[-2] = TYPE_UTC_TIME; tp[-1] = 13; - memcpy (tp, cr->x509.not_before, 6); + memcpy (tp, cr->x509.not_before+2, 6); tp += 6; memcpy (tp, cr->x509.not_before+9, 6); tp += 6; ----------------------------------------------------------------------- Summary of changes: ChangeLog | 6 ++++++ NEWS | 2 +- configure.ac | 8 ++++---- src/certreq.c | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) hooks/post-receive -- KSBA is a library to access X.509 certificates and CMS data. http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 1 15:12:48 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 01 Mar 2011 15:12:48 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-16-g28c157b Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 28c157b55cf6db6b6988def5c9512e388c512b10 (commit) via bb6d1b48f61d483fc75a17b4d140c489afe43ef0 (commit) via dfdda3b344e525f4fdb5e2c07ac63b52e501941f (commit) from cf8878cb18f3ad830994b77f6ee05b5d47a1c557 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 28c157b55cf6db6b6988def5c9512e388c512b10 Author: Werner Koch Date: Tue Mar 1 14:42:56 2011 +0100 Support X.509 certificate creation. Using "gpgsm --genkey" allows the creation of a self-signed certificate via a new prompt. Using "gpgsm --genkey --batch" should allow the creation of arbitrary certificates controlled by a parameter file. An example parameter file is Key-Type: RSA Key-Length: 1024 Key-Grip: 2C50DC6101C10C9C643E315FE3EADCCBC24F4BEA Key-Usage: sign, encrypt Serial: random Name-DN: CN=some test key Name-Email: foo at example.org Name-Email: bar at exmaple.org Hash-Algo: SHA384 not-after: 2038-01-16 12:44 This creates a self-signed X.509 certificate using the key given by the keygrip and using SHA-384 as hash algorithm. The keyword signing-key can be used to sign the certificate with a different key. See sm/certreggen.c for details. diff --git a/NEWS b/NEWS index f58871a..1255b34 100644 --- a/NEWS +++ b/NEWS @@ -19,9 +19,13 @@ 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. + LDAP, DNS and mail backends are not yet implemented. * ECC support for GPG as described by draft-jivsov-openpgp-ecc-06.txt. + * New GPGSM feature to create certificates from a parameter file. + Add prompt to the --gen-key UI to create self-signed certificates. + Noteworthy changes in version 2.1.0beta1 (2010-10-26) ----------------------------------------------------- diff --git a/doc/DETAILS b/doc/DETAILS index 8998d87..5870927 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -793,7 +793,8 @@ Unattended key generation This feature allows unattended generation of keys controlled by a parameter file. To use this feature, you use --gen-key together with --batch and feed the parameters either from stdin or from a file given -on the commandline. +on the commandline. The description below is only for GPG; GPGSM has +a similar feature, see the file sm/certreqgen.c for a description. The format of this file is as follows: o Text only, line length is limited to about 1000 chars. @@ -1220,6 +1221,8 @@ OIDs below the GnuPG arc: 1.3.6.1.4.1.11591.2 GnuPG 1.3.6.1.4.1.11591.2.1 notation 1.3.6.1.4.1.11591.2.1.1 pkaAddress + 1.3.6.1.4.1.11591.2.2 X.509 extensions + 1.3.6.1.4.1.11591.2.2.1 standaloneCertificate 1.3.6.1.4.1.11591.2.12242973 invalid encoded OID diff --git a/sm/ChangeLog b/sm/ChangeLog index 22db032..44e4eb3 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,24 @@ +2011-03-01 Werner Koch + + * certreqgen.c (pSERIAL, pISSUERDN, pNOTBEFORE, pNOTAFTER) + (pSIGNINGKEY, pHASHALGO): New. + (reqgen_ctrl_s): Remove field WRITER. + (read_parameters): Support new keywords. Change arg WRITER to + OUT_FP; pass that to proc_parameters. + (proc_parameters): Add arg WRITER. Check values of new keywords. + Create writer object here. Support generation of certificates. + (create_request): Take new arg SIGKEY. Allow for hash algorithms + other than SHA-1. Set serialno and other values for certificate + creation. + (gpgsm_genkey): Do not create writer object but pass output stream + to read_parameters. + * certreqgen-ui.c (gpgsm_gencertreq_tty): Ask for self-signed. + * misc.c (transform_sigval): New. + +2011-02-25 Werner Koch + + * certreqgen.c (create_request): Add arg SIGKEY. + 2010-11-25 Werner Koch * base64.c (gpgsm_create_writer): Remove arg FP which is not used @@ -2876,7 +2897,7 @@ h2007-11-22 Werner Koch Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, - 2010 Free Software Foundation, Inc. + 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/sm/certreqgen-ui.c b/sm/certreqgen-ui.c index 526a182..b5b4219 100644 --- a/sm/certreqgen-ui.c +++ b/sm/certreqgen-ui.c @@ -1,5 +1,5 @@ /* certreqgen-ui.c - Simple user interface for certreqgen.c - * Copyright (C) 2007, 2010 Free Software Foundation, Inc. + * Copyright (C) 2007, 2010, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -145,6 +145,7 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream) char *result = NULL; int i; const char *s, *s2; + int selfsigned; answer = NULL; init_membuf (&mb_email, 100); @@ -346,6 +347,11 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream) ask_mb_lines (&mb_email, "Name-URI: "); + /* Want a self-signed certificate? */ + selfsigned = tty_get_answer_is_yes + (_("Create self-signed certificate? (y/N) ")); + + /* Put it all together. */ store_key_value_lf (&mb_result, "Key-Type: ", keytype); { @@ -353,10 +359,12 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream) snprintf (numbuf, sizeof numbuf, "%u", nbits); store_key_value_lf (&mb_result, "Key-Length: ", numbuf); } - store_key_value_lf (&mb_result, "Key-Usage: ", keyusage); - store_key_value_lf (&mb_result, "Name-DN: ", subject_name); if (keygrip) store_key_value_lf (&mb_result, "Key-Grip: ", keygrip); + store_key_value_lf (&mb_result, "Key-Usage: ", keyusage); + if (selfsigned) + store_key_value_lf (&mb_result, "Serial: ", "random"); + store_key_value_lf (&mb_result, "Name-DN: ", subject_name); if (store_mb_lines (&mb_result, &mb_email)) goto mem_error; if (store_mb_lines (&mb_result, &mb_dns)) @@ -368,14 +376,13 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream) if (!result) goto mem_error; - tty_printf (_("Parameters to be used for the certificate request:\n")); + tty_printf (_("These parameters are used:\n")); for (s=result; (s2 = strchr (s, '\n')); s = s2+1, i++) tty_printf (" %.*s\n", (int)(s2-s), s); tty_printf ("\n"); - - if (!tty_get_answer_is_yes ("Really create request? (y/N) ")) - goto leave; + if (!tty_get_answer_is_yes ("Proceed with creation? (y/N) ")) + goto leave; /* Now create a parameter file and generate the key. */ fp = es_fopenmem (0, "w+"); @@ -386,8 +393,9 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream) } es_fputs (result, fp); es_rewind (fp); - tty_printf (_("Now creating certificate request. " - "This may take a while ...\n")); + tty_printf (_("Now creating %s. " + "This may take a while ...\n"), + selfsigned?_("self-signed certificate"):_("certificate request")); { int save_pem = ctrl->create_pem; ctrl->create_pem = 1; /* Force creation of PEM. */ @@ -395,7 +403,13 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream) ctrl->create_pem = save_pem; } if (!err) - tty_printf (_("Ready. You should now send this request to your CA.\n")); + { + if (selfsigned) + tty_printf (_("Ready.\n")); + else + tty_printf + (_("Ready. You should now send this request to your CA.\n")); + } goto leave; diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 4218908..7d0bfbd 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -1,6 +1,6 @@ -/* certreqgen.c - Generate a key and a certification request - * Copyright (C) 2002, 2003, 2005, 2007, - * 2010 Free Software Foundation, Inc. +/* certreqgen.c - Generate a key and a certification [request] + * Copyright (C) 2002, 2003, 2005, 2007, 2010, + * 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -43,6 +43,7 @@ The format of the native parameter file is follows: Perform the key generation. Note that an implicit commit is done at the next "Key-Type" parameter. %certfile + [Not yet implemented!] Do not write the certificate to the keyDB but to . This must be given before the first commit to take place, duplicate specification of the same filename @@ -51,35 +52,83 @@ The format of the native parameter file is follows: and all keys are written to that file. If a new filename is given, this file is created (and overwrites an existing one). Both control statements must be given. + o The order of the parameters does not matter except for "Key-Type" which must be the first parameter. The parameters are only for the generated keyblock and parameters from previous key generations are not used. Some syntactically checks may be performed. + The currently defined parameters are: + Key-Type: Starts a new parameter block by giving the type of the primary key. The algorithm must be capable of signing. This is a required parameter. For now the only supported algorithm is "rsa". + Key-Length: Length of the key in bits. Default is 2048. - Key-Grip: hexstring + + Key-Grip: This is optional and used to generate a request for an already existing key. Key-Length will be ignored when given, + Key-Usage: Space or comma delimited list of key usage, allowed values are "encrypt" and "sign". This is used to generate the KeyUsage extension. Please make sure that the algorithm is capable of this usage. Default is to allow encrypt and sign. - Name-DN: subject name + + Name-DN: This is the DN name of the subject in rfc2253 format. + Name-Email: The is an email address for the altSubjectName + Name-DNS: The is an DNS name for the altSubjectName + Name-URI: The is an URI for the altSubjectName + The following parameters are only used if a certificate (and not + a certificate signing request) is requested: + + Serial: + If this parameter is given an X.509 certificate will be + generated. SN is expected to be a hex string representing an + unsigned integer of arbitary length. The special value + "random" can be used to crete a 64 bit random serial number. + + Issuer-DN: + This is the DN name of the issuer in rfc2253 format. If it is + not set the subject DN will be used instead. This creates a + self-signed certificate. Only in this case a special GnuPG + extension will then be included in the certificate to mark it + as a standalone certificate. + + Creation-Date: + Set the notBefore date of the certificate. Either a date like + "1986-04-26" or a full timestamp like "19860426T042640" may be + used. The time is considered to be UTC. If it is not given + the current date is used. + + Expire-Date: + Set the notBefore date of the certificate. Either a date like + "1986-04-26" or a full timestamp like "19860426T042640" may be + used. The time is considered to be UTC. If it is not given a + default value is used. + + Signing-Key: + This gives the keygrip of the key used to sign the + certificate. If it is not given a self-signed certificate + will be created. + + Hash-Algo: + Use HASH-ALGO for this certificate. The supported hash + algorithms are: "sha-1", "sha-256", "sha-384" and "sha-512". + "sha-1" is the default. + Here is an example: $ cat >foo <lnr); + xfree (cardkeyid); + return gpg_error (GPG_ERR_INV_PARAMETER); + } + } + } + + /* Check the optional issuer DN. */ + string = get_parameter_value (para, pISSUERDN, 0); + if (string) + { + err = ksba_dn_teststr (string, 0, &erroff, &errlen); + if (err) + { + r = get_parameter (para, pISSUERDN, 0); + if (gpg_err_code (err) == GPG_ERR_UNKNOWN_NAME) + log_error (_("line %d: invalid issuer name label `%.*s'\n"), + r->lnr, (int)errlen, string+erroff); + else + log_error (_("line %d: invalid issuer name `%s' at pos %d\n"), + r->lnr, string, (int)erroff); + xfree (cardkeyid); + return gpg_error (GPG_ERR_INV_PARAMETER); + } + } + + /* Check the optional creation date. */ + string = get_parameter_value (para, pNOTBEFORE, 0); + if (string && !string2isotime (NULL, string)) + { + r = get_parameter (para, pNOTBEFORE, 0); + log_error (_("line %d: invalid date given\n"), r->lnr); + xfree (cardkeyid); + return gpg_error (GPG_ERR_INV_PARAMETER); + } + + + /* Check the optional expire date. */ + string = get_parameter_value (para, pNOTAFTER, 0); + if (string && !string2isotime (NULL, string)) + { + r = get_parameter (para, pNOTAFTER, 0); + log_error (_("line %d: invalid date given\n"), r->lnr); + xfree (cardkeyid); + return gpg_error (GPG_ERR_INV_PARAMETER); + } + + /* Get the optional signing key. */ + string = get_parameter_value (para, pSIGNINGKEY, 0); + if (string) + { + rc = gpgsm_agent_readkey (ctrl, 0, string, &sigkey); + if (rc) + { + r = get_parameter (para, pKEYTYPE, 0); + log_error (_("line %d: error getting signing key by keygrip `%s'" + ": %s\n"), r->lnr, s, gpg_strerror (rc)); + xfree (cardkeyid); + return rc; + } + } + + /* Check the optional hash-algo. */ + { + int mdalgo; + + string = get_parameter_value (para, pHASHALGO, 0); + if (string && !((mdalgo = gcry_md_map_name (string)) + && (mdalgo == GCRY_MD_SHA1 + || mdalgo == GCRY_MD_SHA256 + || mdalgo == GCRY_MD_SHA384 + || mdalgo == GCRY_MD_SHA512))) + { + r = get_parameter (para, pHASHALGO, 0); + log_error (_("line %d: invalid hash algorithm given\n"), r->lnr); + xfree (cardkeyid); + return gpg_error (GPG_ERR_INV_PARAMETER); + } + } + + /* Create or retrieve the public key. */ if (cardkeyid) /* Take the key from the current smart card. */ { rc = gpgsm_agent_readkey (ctrl, 1, cardkeyid, &public); @@ -547,6 +710,7 @@ proc_parameters (ctrl_t ctrl, r = get_parameter (para, pKEYTYPE, 0); log_error (_("line %d: error reading key `%s' from card: %s\n"), r->lnr, cardkeyid, gpg_strerror (rc)); + xfree (sigkey); xfree (cardkeyid); return rc; } @@ -559,11 +723,12 @@ proc_parameters (ctrl_t ctrl, r = get_parameter (para, pKEYTYPE, 0); log_error (_("line %d: error getting key by keygrip `%s': %s\n"), r->lnr, s, gpg_strerror (rc)); + xfree (sigkey); xfree (cardkeyid); return rc; } } - else /* Generate new key. */ + else if (!outctrl->dryrun) /* Generate new key. */ { sprintf (numbuf, "%u", nbits); snprintf ((char*)keyparms, DIM (keyparms)-1, @@ -575,12 +740,45 @@ proc_parameters (ctrl_t ctrl, r = get_parameter (para, pKEYTYPE, 0); log_error (_("line %d: key generation failed: %s <%s>\n"), r->lnr, gpg_strerror (rc), gpg_strsource (rc)); + xfree (sigkey); xfree (cardkeyid); return rc; } } - rc = create_request (ctrl, para, cardkeyid, public, outctrl); + + if (!outctrl->dryrun) + { + Base64Context b64writer = NULL; + ksba_writer_t writer; + int create_cert ; + + create_cert = !!get_parameter_value (para, pSERIAL, 0); + + ctrl->pem_name = create_cert? "CERTIFICATE" : "CERTIFICATE REQUEST"; + rc = gpgsm_create_writer (&b64writer, ctrl, out_fp, &writer); + if (rc) + log_error ("can't create writer: %s\n", gpg_strerror (rc)); + else + { + rc = create_request (ctrl, para, cardkeyid, public, sigkey, writer); + if (!rc) + { + rc = gpgsm_finish_writer (b64writer); + if (rc) + log_error ("write failed: %s\n", gpg_strerror (rc)); + else + { + gpgsm_status (ctrl, STATUS_KEY_CREATED, "P"); + log_info ("certificate%s created\n", + create_cert?"":" request"); + } + } + gpgsm_destroy_writer (b64writer); + } + } + + xfree (sigkey); xfree (public); xfree (cardkeyid); @@ -595,25 +793,34 @@ create_request (ctrl_t ctrl, struct para_data_s *para, const char *carddirect, ksba_const_sexp_t public, - struct reqgen_ctrl_s *outctrl) + ksba_const_sexp_t sigkey, + ksba_writer_t writer) { ksba_certreq_t cr; gpg_error_t err; gcry_md_hd_t md; ksba_stop_reason_t stopreason; int rc = 0; - const char *s; + const char *s, *string; unsigned int use; int seq; char *buf, *p; size_t len; char numbuf[30]; + ksba_isotime_t atime; + int certmode = 0; + int mdalgo; err = ksba_certreq_new (&cr); if (err) return err; - rc = gcry_md_open (&md, GCRY_MD_SHA1, 0); + string = get_parameter_value (para, pHASHALGO, 0); + if (string) + mdalgo = gcry_md_map_name (string); + else + mdalgo = GCRY_MD_SHA1; + rc = gcry_md_open (&md, mdalgo, 0); if (rc) { log_error ("md_open failed: %s\n", gpg_strerror (rc)); @@ -623,7 +830,7 @@ create_request (ctrl_t ctrl, gcry_md_start_debug (md, "cr.cri"); ksba_certreq_set_hash_function (cr, HASH_FNC, md); - ksba_certreq_set_writer (cr, outctrl->writer); + ksba_certreq_set_writer (cr, writer); err = ksba_certreq_add_subject (cr, get_parameter_value (para, pNAMEDN, 0)); if (err) @@ -720,7 +927,7 @@ create_request (ctrl_t ctrl, goto leave; } - + /* Set key usage flags. */ use = get_parameter_uint (para, pKEYUSAGE); if (use == GCRY_PK_USAGE_SIGN) { @@ -749,6 +956,170 @@ create_request (ctrl_t ctrl, } + /* See whether we want to create an X.509 certificate. */ + string = get_parameter_value (para, pSERIAL, 0); + if (string) + { + certmode = 1; + + /* Store the serial number. */ + if (!strcmp (string, "random")) + { + char snbuf[3+8+1]; + + memcpy (snbuf, "(8:", 3); + gcry_create_nonce (snbuf+3, 8); + /* Clear high bit to guarantee a positive integer. */ + snbuf[3] &= 0x7f; + snbuf[3+8] = ')'; + err = ksba_certreq_set_serial (cr, snbuf); + } + else + { + char *hexbuf; + + /* Allocate a buffer large enough to prefix the string with + a '0' so to have an even number of digits. Prepend two + further '0' so that the binary result will have a leading + 0 byte and thus can't be the representation of a negative + number. Note that ksba_certreq_set_serial strips all + unneeded leading 0 bytes. */ + hexbuf = p = xtrymalloc (2 + 1 + strlen (string) + 1); + if (!hexbuf) + { + err = gpg_error_from_syserror (); + goto leave; + } + if ((strlen (string) & 1)) + *p++ = '0'; + *p++ = '0'; + *p++ = '0'; + strcpy (p, string); + for (p=hexbuf, len=0; p[0] && p[1]; p += 2) + ((unsigned char*)hexbuf)[len++] = xtoi_2 (s); + /* Now build the S-expression. */ + snprintf (numbuf, DIM(numbuf), "%u:", (unsigned int)len); + buf = p = xtrymalloc (1 + strlen (numbuf) + len + 1 + 1); + if (!buf) + { + err = gpg_error_from_syserror (); + xfree (hexbuf); + goto leave; + } + p = stpcpy (stpcpy (buf, "("), numbuf); + memcpy (p, hexbuf, len); + p += len; + strcpy (p, ")"); + xfree (hexbuf); + err = ksba_certreq_set_serial (cr, buf); + xfree (buf); + } + if (err) + { + log_error ("error setting the serial number: %s\n", + gpg_strerror (err)); + goto leave; + } + + + /* Store the issuer DN. If no issuer DN is given and no signing + key has been set we add the standalone extension and the + basic constraints to mark it as a self-signed CA + certificate. */ + string = get_parameter_value (para, pISSUERDN, 0); + if (string) + { + /* Issuer DN given. Note that this may be the same as the + subject DN and thus this could as well be a self-signed + certificate. However the caller needs to explicitly + specify basicConstraints and so forth. */ + err = ksba_certreq_set_issuer (cr, string); + if (err) + { + log_error ("error setting the issuer DN: %s\n", + gpg_strerror (err)); + goto leave; + } + + } + else if (!string && !sigkey) + { + /* Self-signed certificate requested. Add basicConstraints + and the custom GnuPG standalone extension. */ + err = ksba_certreq_add_extension (cr, oidstr_basicConstraints, 1, + "\x30\x03\x01\x01\xff", 5); + if (err) + goto leave; + err = ksba_certreq_add_extension (cr, oidstr_standaloneCertificate, 0, + "\x01\x01\xff", 3); + if (err) + goto leave; + } + + /* Store the creation date. */ + string = get_parameter_value (para, pNOTBEFORE, 0); + if (string) + { + if (!string2isotime (atime, string)) + BUG (); /* We already checked the value. */ + } + else + gnupg_get_isotime (atime); + err = ksba_certreq_set_validity (cr, 0, atime); + if (err) + { + log_error ("error setting the creation date: %s\n", + gpg_strerror (err)); + goto leave; + } + + + /* Store the expire date. If it is not given, libksba inserts a + default value. */ + string = get_parameter_value (para, pNOTAFTER, 0); + if (string) + { + if (!string2isotime (atime, string)) + BUG (); /* We already checked the value. */ + err = ksba_certreq_set_validity (cr, 1, atime); + if (err) + { + log_error ("error setting the expire date: %s\n", + gpg_strerror (err)); + goto leave; + } + } + + + /* Figure out the signing algorithm. If no sigkey has been + given we set it to the public key to create a self-signed + certificate. */ + if (!sigkey) + sigkey = public; + + { + unsigned char *siginfo; + + err = transform_sigval (sigkey, + gcry_sexp_canon_len (sigkey, 0, NULL, NULL), + mdalgo, &siginfo, NULL); + if (!err) + { + err = ksba_certreq_set_siginfo (cr, siginfo); + xfree (siginfo); + } + if (err) + { + log_error ("error setting the siginfo: %s\n", + gpg_strerror (err)); + rc = err; + goto leave; + } + } + } + else + sigkey = public; + do { err = ksba_certreq_build (cr, &stopreason); @@ -764,17 +1135,17 @@ create_request (ctrl_t ctrl, size_t n; unsigned char grip[20]; char hexgrip[41]; - unsigned char *sigval; + unsigned char *sigval, *newsigval; size_t siglen; - n = gcry_sexp_canon_len (public, 0, NULL, NULL); + n = gcry_sexp_canon_len (sigkey, 0, NULL, NULL); if (!n) { log_error ("libksba did not return a proper S-Exp\n"); rc = gpg_error (GPG_ERR_BUG); goto leave; } - rc = gcry_sexp_sscan (&s_pkey, NULL, (const char*)public, n); + rc = gcry_sexp_sscan (&s_pkey, NULL, (const char*)sigkey, n); if (rc) { log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (rc)); @@ -790,14 +1161,15 @@ create_request (ctrl_t ctrl, gcry_sexp_release (s_pkey); bin2hex (grip, 20, hexgrip); - log_info ("about to sign CSR for key: &%s\n", hexgrip); + log_info ("about to sign the %s for key: &%s\n", + certmode? "certificate":"CSR", hexgrip); if (carddirect) rc = gpgsm_scd_pksign (ctrl, carddirect, NULL, - gcry_md_read(md, GCRY_MD_SHA1), - gcry_md_get_algo_dlen (GCRY_MD_SHA1), - GCRY_MD_SHA1, - &sigval, &siglen); + gcry_md_read (md, mdalgo), + gcry_md_get_algo_dlen (mdalgo), + mdalgo, + &sigval, &siglen); else { char *orig_codeset; @@ -810,9 +1182,9 @@ create_request (ctrl_t ctrl, " more.\n")); i18n_switchback (orig_codeset); rc = gpgsm_agent_pksign (ctrl, hexgrip, desc, - gcry_md_read(md, GCRY_MD_SHA1), - gcry_md_get_algo_dlen (GCRY_MD_SHA1), - GCRY_MD_SHA1, + gcry_md_read(md, mdalgo), + gcry_md_get_algo_dlen (mdalgo), + mdalgo, &sigval, &siglen); xfree (desc); } @@ -822,8 +1194,14 @@ create_request (ctrl_t ctrl, goto leave; } - err = ksba_certreq_set_sig_val (cr, sigval); + err = transform_sigval (sigval, siglen, mdalgo, + &newsigval, NULL); xfree (sigval); + if (!err) + { + err = ksba_certreq_set_sig_val (cr, newsigval); + xfree (newsigval); + } if (err) { log_error ("failed to store the sig_val: %s\n", @@ -850,18 +1228,8 @@ int gpgsm_genkey (ctrl_t ctrl, estream_t in_stream, estream_t out_stream) { int rc; - Base64Context b64writer = NULL; - ksba_writer_t writer; - ctrl->pem_name = "CERTIFICATE REQUEST"; - rc = gpgsm_create_writer (&b64writer, ctrl, out_stream, &writer); - if (rc) - { - log_error ("can't create writer: %s\n", gpg_strerror (rc)); - goto leave; - } - - rc = read_parameters (ctrl, in_stream, writer); + rc = read_parameters (ctrl, in_stream, out_stream); if (rc) { log_error ("error creating certificate request: %s <%s>\n", @@ -869,17 +1237,6 @@ gpgsm_genkey (ctrl_t ctrl, estream_t in_stream, estream_t out_stream) goto leave; } - rc = gpgsm_finish_writer (b64writer); - if (rc) - { - log_error ("write failed: %s\n", gpg_strerror (rc)); - goto leave; - } - - gpgsm_status (ctrl, STATUS_KEY_CREATED, "P"); - log_info ("certificate request created\n"); - leave: - gpgsm_destroy_writer (b64writer); return rc; } diff --git a/sm/gpgsm.h b/sm/gpgsm.h index 54d4aff..31cd951 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -429,6 +429,10 @@ int gpgsm_dirmngr_run_command (ctrl_t ctrl, const char *command, /*-- misc.c --*/ void setup_pinentry_env (void); +gpg_error_t transform_sigval (const unsigned char *sigval, size_t sigvallen, + int mdalgo, + unsigned char **r_newsigval, + size_t *r_newsigvallen); diff --git a/sm/keylist.c b/sm/keylist.c index 1d6ce6e..fc903ba 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -186,6 +186,7 @@ static struct /* GnuPG extensions */ { "1.3.6.1.4.1.11591.2.1.1", "pkaAddress" }, + { "1.3.6.1.4.1.11591.2.2.1", "standaloneCertificate" }, /* Extensions used by the Bundesnetzagentur. */ { "1.3.6.1.4.1.8301.3.5", "validityModel" }, diff --git a/sm/misc.c b/sm/misc.c index 2d6cdd6..4c6293f 100644 --- a/sm/misc.c +++ b/sm/misc.c @@ -1,5 +1,5 @@ /* misc.c - Miscellaneous fucntions - * Copyright (C) 2004, 2009 Free Software Foundation, Inc. + * Copyright (C) 2004, 2009, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -31,6 +31,9 @@ #include "gpgsm.h" #include "i18n.h" #include "sysutils.h" +#include "../common/tlv.h" +#include "../common/sexp-parse.h" + /* Setup the environment so that the pinentry is able to get all required information. This is used prior to an exec of the @@ -86,3 +89,130 @@ setup_pinentry_env (void) #endif /*!HAVE_W32_SYSTEM*/ } + + + +/* Transform a sig-val style s-expression as returned by Libgcrypt to + one which includes an algorithm identifier encoding the public key + and the hash algorithm. The public key algorithm is taken directly + from SIGVAL and the hash algorithm is given by MDALGO. This is + required because X.509 merges the public key algorithm and the hash + algorithm into one OID but Libgcrypt is not aware of that. The + function ignores missing parameters so that it can also be used to + create an siginfo value as expected by ksba_certreq_set_siginfo. + To create a siginfo s-expression a public-key s-expression may be + used instead of a sig-val. We only support RSA for now. */ +gpg_error_t +transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo, + unsigned char **r_newsigval, size_t *r_newsigvallen) +{ + gpg_error_t err; + const unsigned char *buf, *tok; + size_t buflen, toklen; + int depth, last_depth1, last_depth2; + int is_pubkey = 0; + const unsigned char *rsa_s = NULL; + size_t rsa_s_len; + const char *oid; + gcry_sexp_t sexp; + + *r_newsigval = NULL; + if (r_newsigvallen) + *r_newsigvallen = 0; + + buf = sigval; + buflen = sigvallen; + depth = 0; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (tok && toklen == 7 && !memcmp ("sig-val", tok, toklen)) + ; + else if (tok && toklen == 10 && !memcmp ("public-key", tok, toklen)) + is_pubkey = 1; + else + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (!tok || toklen != 3 || memcmp ("rsa", tok, toklen)) + return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO); + + last_depth1 = depth; + while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)) + && depth && depth >= last_depth1) + { + if (tok) + return gpg_error (GPG_ERR_UNKNOWN_SEXP); + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (tok && toklen == 1) + { + const unsigned char **mpi; + size_t *mpi_len; + + switch (*tok) + { + case 's': mpi = &rsa_s; mpi_len = &rsa_s_len; break; + default: mpi = NULL; mpi_len = NULL; break; + } + if (mpi && *mpi) + return gpg_error (GPG_ERR_DUP_VALUE); + + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (tok && mpi) + { + *mpi = tok; + *mpi_len = toklen; + } + } + + /* Skip to the end of the list. */ + last_depth2 = depth; + while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)) + && depth && depth >= last_depth2) + ; + if (err) + return err; + } + if (err) + return err; + + /* Map the hash algorithm to an OID. */ + switch (mdalgo) + { + case GCRY_MD_SHA1: + oid = "1.2.840.113549.1.1.5"; /* sha1WithRSAEncryption */ + break; + + case GCRY_MD_SHA256: + oid = "1.2.840.113549.1.1.11"; /* sha256WithRSAEncryption */ + break; + + case GCRY_MD_SHA384: + oid = "1.2.840.113549.1.1.12"; /* sha384WithRSAEncryption */ + break; + + case GCRY_MD_SHA512: + oid = "1.2.840.113549.1.1.13"; /* sha512WithRSAEncryption */ + break; + + default: + return gpg_error (GPG_ERR_DIGEST_ALGO); + } + + if (rsa_s && !is_pubkey) + err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(s%b)))", + oid, (int)rsa_s_len, rsa_s); + else + err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s))", oid); + if (err) + return err; + err = make_canon_sexp (sexp, r_newsigval, r_newsigvallen); + gcry_sexp_release (sexp); + + return err; +} commit bb6d1b48f61d483fc75a17b4d140c489afe43ef0 Author: Werner Koch Date: Tue Mar 1 14:28:59 2011 +0100 Update some M4 files and AUTHORS. diff --git a/AUTHORS b/AUTHORS index de27957..d690e77 100644 --- a/AUTHORS +++ b/AUTHORS @@ -14,6 +14,8 @@ Ales Nyakhaychyk Translations [be] Andrey Jivsov Assigns past and future changes for ECC. (g10/ecdh.c. other changes to support ECC) +Ben Kibbey Assigns past and future changes. + Birger Langkjer Translations [da] Maxim Britov Translations [ru] @@ -123,6 +125,8 @@ Werner Koch Assigns GNU Privacy Guard and future changes. Yosiaki IIDA Translations [ja] +Yutaka Niibe Assigns Past and Future Changes + (scd/) Other authors @@ -145,7 +149,7 @@ by Colin Tuckley and Daniel Leidert for the GNU/Debian distribution. Copyright ========= -GnuPG is distributed under the GNU General Public License, version 2 +GnuPG is distributed under the GNU General Public License, version 3 or later. A few files are under the Lesser General Public License, a few other files carry the all permissive license note as found at the bottom of this file. Certain files in keyserver/ allow one specific @@ -168,7 +172,7 @@ name gpg2keys_*. ========= Copyright 1998, 1999, 2000, 2001, 2002, 2004, 2005, - 2006, 2007, 2008, 2010 Free Software Foundation, Inc. + 2006, 2007, 2008, 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/ChangeLog b/ChangeLog index 17d049f..4acd121 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-02-25 Werner Koch + + * configure.ac: Require libksba 1.2. + 2011-02-04 Werner Koch * autogen.sh: Ensure that the git pre-commit hoom has been diff --git a/configure.ac b/configure.ac index f79ff53..e372d33 100644 --- a/configure.ac +++ b/configure.ac @@ -49,7 +49,7 @@ NEED_LIBASSUAN_API=2 NEED_LIBASSUAN_VERSION=2.0.0 NEED_KSBA_API=1 -NEED_KSBA_VERSION=1.1.0 +NEED_KSBA_VERSION=1.2.0 PACKAGE=$PACKAGE_NAME diff --git a/m4/ChangeLog b/m4/ChangeLog index c633468..29af1fb 100644 --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,7 @@ +2011-02-25 Werner Koch + + * ksba.m4: Update from git master. + 2011-02-23 Werner Koch * libgcrypt.m4, gpg-error.m4: Update from their GIT masters. diff --git a/m4/gpg-error.m4 b/m4/gpg-error.m4 index 8d82925..2e5a0ab 100644 --- a/m4/gpg-error.m4 +++ b/m4/gpg-error.m4 @@ -1,5 +1,5 @@ # gpg-error.m4 - autoconf macro to detect libgpg-error. -# Copyright (C) 2002, 2003, 2004 g10 Code GmbH +# Copyright (C) 2002, 2003, 2004, 2011 g10 Code GmbH # # This file is free software; as a special exception the author gives # unlimited permission to copy and/or distribute it, with or without @@ -14,7 +14,8 @@ dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) dnl Test for libgpg-error and define GPG_ERROR_CFLAGS and GPG_ERROR_LIBS dnl AC_DEFUN([AM_PATH_GPG_ERROR], -[ AC_ARG_WITH(gpg-error-prefix, +[ AC_REQUIRE([AC_CANONICAL_HOST]) + AC_ARG_WITH(gpg-error-prefix, AC_HELP_STRING([--with-gpg-error-prefix=PFX], [prefix where GPG Error is installed (optional)]), gpg_error_config_prefix="$withval", gpg_error_config_prefix="") @@ -53,10 +54,9 @@ AC_DEFUN([AM_PATH_GPG_ERROR], GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG $gpg_error_config_args --libs` AC_MSG_RESULT([yes ($gpg_error_config_version)]) ifelse([$2], , :, [$2]) - if test x"$host" != x ; then - gpg_error_config_host=`$GPG_ERROR_CONFIG $gpg_error_config_args --host 2>/dev/null || echo none` - if test x"$gpg_error_config_host" != xnone ; then - if test x"$gpg_error_config_host" != x"$host" ; then + gpg_error_config_host=`$GPG_ERROR_CONFIG $gpg_error_config_args --host 2>/dev/null || echo none` + if test x"$gpg_error_config_host" != xnone ; then + if test x"$gpg_error_config_host" != x"$host" ; then AC_MSG_WARN([[ *** *** The config script $GPG_ERROR_CONFIG was @@ -65,7 +65,6 @@ AC_DEFUN([AM_PATH_GPG_ERROR], *** You may want to use the configure option --with-gpg-error-prefix *** to specify a matching config script. ***]]) - fi fi fi else diff --git a/m4/ksba.m4 b/m4/ksba.m4 index 1100387..73b2e26 100644 --- a/m4/ksba.m4 +++ b/m4/ksba.m4 @@ -15,13 +15,14 @@ dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) dnl Test for libksba and define KSBA_CFLAGS and KSBA_LIBS dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed dnl with the API version to also check the API compatibility. Example: -dnl a MINIMUN-VERSION of 1:1.0.7 won't pass the test unless the installed +dnl a MINIMUN-VERSION of 1:1.0.7 won't pass the test unless the installed dnl version of libksba is at least 1.0.7 *and* the API number is 1. Using dnl this features allows to prevent build against newer versions of libksba dnl with a changed API. dnl AC_DEFUN([AM_PATH_KSBA], -[ AC_ARG_WITH(ksba-prefix, +[AC_REQUIRE([AC_CANONICAL_HOST]) + AC_ARG_WITH(ksba-prefix, AC_HELP_STRING([--with-ksba-prefix=PFX], [prefix where KSBA is installed (optional)]), ksba_config_prefix="$withval", ksba_config_prefix="") @@ -60,7 +61,7 @@ AC_DEFUN([AM_PATH_KSBA], sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'` if test "$major" -gt "$req_major"; then ok=yes - else + else if test "$major" -eq "$req_major"; then if test "$minor" -gt "$req_minor"; then ok=yes @@ -99,6 +100,19 @@ AC_DEFUN([AM_PATH_KSBA], KSBA_CFLAGS=`$KSBA_CONFIG $ksba_config_args --cflags` KSBA_LIBS=`$KSBA_CONFIG $ksba_config_args --libs` ifelse([$2], , :, [$2]) + libksba_config_host=`$LIBKSBA_CONFIG $ksba_config_args --host 2>/dev/null || echo none` + if test x"$libksba_config_host" != xnone ; then + if test x"$libksba_config_host" != x"$host" ; then + AC_MSG_WARN([[ +*** +*** The config script $LIBKSBA_CONFIG was +*** built for $libksba_config_host and thus may not match the +*** used host $host. +*** You may want to use the configure option --with-libksba-prefix +*** to specify a matching config script. +***]]) + fi + fi else KSBA_CFLAGS="" KSBA_LIBS="" diff --git a/m4/libgcrypt.m4 b/m4/libgcrypt.m4 index 831dc0c..6cf482f 100644 --- a/m4/libgcrypt.m4 +++ b/m4/libgcrypt.m4 @@ -1,5 +1,5 @@ dnl Autoconf macros for libgcrypt -dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc. +dnl Copyright (C) 2002, 2004, 2011 Free Software Foundation, Inc. dnl dnl This file is free software; as a special exception the author gives dnl unlimited permission to copy and/or distribute it, with or without @@ -21,7 +21,8 @@ dnl this features allows to prevent build against newer versions of libgcrypt dnl with a changed API. dnl AC_DEFUN([AM_PATH_LIBGCRYPT], -[ AC_ARG_WITH(libgcrypt-prefix, +[ AC_REQUIRE([AC_CANONICAL_HOST]) + AC_ARG_WITH(libgcrypt-prefix, AC_HELP_STRING([--with-libgcrypt-prefix=PFX], [prefix where LIBGCRYPT is installed (optional)]), libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="") @@ -98,10 +99,9 @@ AC_DEFUN([AM_PATH_LIBGCRYPT], LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags` LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs` ifelse([$2], , :, [$2]) - if test x"$host" != x ; then - libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none` - if test x"$libgcrypt_config_host" != xnone ; then - if test x"$libgcrypt_config_host" != x"$host" ; then + libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none` + if test x"$libgcrypt_config_host" != xnone ; then + if test x"$libgcrypt_config_host" != x"$host" ; then AC_MSG_WARN([[ *** *** The config script $LIBGCRYPT_CONFIG was @@ -110,7 +110,6 @@ AC_DEFUN([AM_PATH_LIBGCRYPT], *** You may want to use the configure option --with-libgcrypt-prefix *** to specify a matching config script. ***]]) - fi fi fi else commit dfdda3b344e525f4fdb5e2c07ac63b52e501941f Author: Werner Koch Date: Tue Mar 1 14:22:41 2011 +0100 Add new functions to convert iso time strings. diff --git a/common/ChangeLog b/common/ChangeLog index f6380c6..cebc0ec 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,11 @@ +2011-02-27 Werner Koch + + * gettime.c (isotime2epoch): Factor check code out to .. + (isotime_p): .. new. + (isotime_human_p): New. + (string2isotime): New. + * t-gettime.c (test_string2isotime): New. + 2011-02-11 Andrey Jivsov * openpgp-oid.c (openpgp_oid_to_str): Use unsigned int for diff --git a/common/gettime.c b/common/gettime.c index 27dc845..e5462a7 100644 --- a/common/gettime.c +++ b/common/gettime.c @@ -1,5 +1,5 @@ /* gettime.c - Wrapper for time functions - * Copyright (C) 1998, 2002, 2007 Free Software Foundation, Inc. + * Copyright (C) 1998, 2002, 2007, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -179,29 +179,162 @@ scan_isodatestr( const char *string ) return stamp; } -/* Scan am ISO timestamp and return an Epoch based timestamp. The only - supported format is "yyyymmddThhmmss" delimited by white space, nul, a - colon or a comma. Returns (time_t)(-1) for an invalid string. */ -time_t -isotime2epoch (const char *string) + +int +isotime_p (const char *string) { const char *s; - int year, month, day, hour, minu, sec; - struct tm tmbuf; int i; if (!*string) - return (time_t)(-1); + return 0; for (s=string, i=0; i < 8; i++, s++) if (!digitp (s)) - return (time_t)(-1); + return 0; if (*s != 'T') - return (time_t)(-1); + return 0; for (s++, i=9; i < 15; i++, s++) if (!digitp (s)) - return (time_t)(-1); + return 0; if ( !(!*s || (isascii (*s) && isspace(*s)) || *s == ':' || *s == ',')) - return (time_t)(-1); /* Wrong delimiter. */ + return 0; /* Wrong delimiter. */ + + return 1; +} + + +/* Scan a string and return true if the string represents the human + readable format of an ISO time. This format is: + yyyy-mm-dd[ hh[:mm[:ss]]] + Scanning stops at the second space or at a comma. */ +int +isotime_human_p (const char *string) +{ + const char *s; + int i; + + if (!*string) + return 0; + for (s=string, i=0; i < 4; i++, s++) + if (!digitp (s)) + return 0; + if (*s != '-') + return 0; + s++; + if (!digitp (s) || !digitp (s+1) || s[2] != '-') + return 0; + i = atoi_2 (s); + if (i < 1 || i > 12) + return 0; + s += 3; + if (!digitp (s) || !digitp (s+1)) + return 0; + i = atoi_2 (s); + if (i < 1 || i > 31) + return 0; + s += 2; + if (!*s || *s == ',') + return 1; /* Okay; only date given. */ + if (!spacep (s)) + return 0; + s++; + if (spacep (s)) + return 1; /* Okay, second space stops scanning. */ + if (!digitp (s) || !digitp (s+1)) + return 0; + i = atoi_2 (s); + if (i < 0 || i > 23) + return 0; + s += 2; + if (!*s || *s == ',') + return 1; /* Okay; only date and hour given. */ + if (*s != ':') + return 0; + s++; + if (!digitp (s) || !digitp (s+1)) + return 0; + i = atoi_2 (s); + if (i < 0 || i > 59) + return 0; + s += 2; + if (!*s || *s == ',') + return 1; /* Okay; only date, hour and minute given. */ + if (*s != ':') + return 0; + s++; + if (!digitp (s) || !digitp (s+1)) + return 0; + i = atoi_2 (s); + if (i < 0 || i > 60) + return 0; + s += 2; + if (!*s || *s == ',' || spacep (s)) + return 1; /* Okay; date, hour and minute and second given. */ + + return 0; /* Unexpected delimiter. */ +} + +/* Convert a standard isotime or a human readable variant into an + isotime structure. The allowed formats are those described by + isotime_p and isotime_human_p. The function returns 0 on failure + or the length of the scanned string on success. */ +size_t +string2isotime (gnupg_isotime_t atime, const char *string) +{ + gnupg_isotime_t dummyatime; + + if (!atime) + atime = dummyatime; + + atime[0] = 0; + if (isotime_p (string)) + { + memcpy (atime, string, 15); + atime[15] = 0; + return 15; + } + if (!isotime_human_p (string)) + return 0; + atime[0] = string[0]; + atime[1] = string[1]; + atime[2] = string[2]; + atime[3] = string[3]; + atime[4] = string[5]; + atime[5] = string[6]; + atime[6] = string[8]; + atime[7] = string[9]; + atime[8] = 'T'; + memset (atime+9, '0', 6); + atime[15] = 0; + if (!spacep (string+10)) + return 10; + if (spacep (string+11)) + return 11; /* As per def, second space stops scanning. */ + atime[9] = string[11]; + atime[10] = string[12]; + if (string[13] != ':') + return 13; + atime[11] = string[14]; + atime[12] = string[15]; + if (string[16] != ':') + return 16; + atime[13] = string[17]; + atime[14] = string[18]; + return 19; +} + + +/* Scan an ISO timestamp and return an Epoch based timestamp. The only + supported format is "yyyymmddThhmmss" delimited by white space, nul, a + colon or a comma. Returns (time_t)(-1) for an invalid string. */ +time_t +isotime2epoch (const char *string) +{ + int year, month, day, hour, minu, sec; + struct tm tmbuf; + + if (!isotime_p (string)) + return (time_t)(-1); year = atoi_4 (string); month = atoi_2 (string + 4); diff --git a/common/gettime.h b/common/gettime.h index 731be56..4199369 100644 --- a/common/gettime.h +++ b/common/gettime.h @@ -34,6 +34,9 @@ void gnupg_set_time (time_t newtime, int freeze); int gnupg_faked_time_p (void); u32 make_timestamp (void); u32 scan_isodatestr (const char *string); +int isotime_p (const char *string); +int isotime_human_p (const char *string); +size_t string2isotime (gnupg_isotime_t atime, const char *string); time_t isotime2epoch (const char *string); void epoch2isotime (gnupg_isotime_t timebuf, time_t atime); u32 add_days_to_timestamp (u32 stamp, u16 days); diff --git a/common/t-gettime.c b/common/t-gettime.c index 1cfde69..79c3d43 100644 --- a/common/t-gettime.c +++ b/common/t-gettime.c @@ -1,5 +1,5 @@ /* t-gettime.c - Module test for gettime.c - * Copyright (C) 2007 Free Software Foundation, Inc. + * Copyright (C) 2007, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -89,6 +89,90 @@ test_isotime2epoch (void) +static void +test_string2isotime (void) +{ + struct { + const char *string; + size_t result; + const char *expected; + } array [] = { + { "19700101T000001", 15, "19700101T000001" }, + { "19700101T235959", 15, "19700101T235959" }, + { "19980815T143712", 15, "19980815T143712" }, + { "19700101T000000", 15, "19700101T000000" }, + { "19691231T235959", 15, "19691231T235959" }, + { "19000101T000000", 15, "19000101T000000" }, + { "", 0, "" }, + { "19000101T00000", 0, "" }, + { "20010101t123456", 0, "" }, + { "20010101T123456", 15, "20010101T123456" }, + { "20070629T160000", 15, "20070629T160000" }, + { "20070629T160000:", 15, "20070629T160000" }, + { "20070629T160000,", 15, "20070629T160000" }, + { "20070629T160000 ", 15, "20070629T160000" }, + { "20070629T160000\n", 15,"20070629T160000" }, + { "20070629T160000.", 0, "" }, + { "1066-03-20", 10, "10660320T000000" }, + { "1066-03-20,", 10, "10660320T000000" }, + { "1066-03-20:", 0, "" }, + { "1066-03-20 00", 13, "10660320T000000" }, + { "1066-03-20 01", 13, "10660320T010000" }, + { "1066-03-20 23", 13, "10660320T230000" }, + { "1066-03-20 24", 0, "" }, + { "1066-03-20 00:", 0, "" }, + { "1066-03-20 00:3", 0, "" }, + { "1066-03-20 00:31", 16, "10660320T003100" }, + { "1066-03-20 00:31:47", 19, "10660320T003147" }, + { "1066-03-20 00:31:47 ", 19, "10660320T003147" }, + { "1066-03-20 00:31:47,", 19, "10660320T003147" }, + { "1066-03-20 00:31:47:", 0, "" }, + { "1-03-20 00:31:47:", 0, "" }, + { "10-03-20 00:31:47:", 0, "" }, + { "106-03-20 00:31:47:", 0, "" }, + { "1066-23-20 00:31:47:", 0, "" }, + { "1066-00-20 00:31:47:", 0, "" }, + { "1066-0-20 00:31:47:", 0, "" }, + { "1066-01-2 00:31:47:", 0, "" }, + { "1066-01-2 00:31:47:", 0, "" }, + { "1066-01-32 00:31:47:", 0, "" }, + { "1066-01-00 00:31:47:", 0, "" }, + { "1066-03-20 00:31:47:",11, "10660320T000000" }, + { "1066-03-2000:31:47:", 0, "" }, + { "10666-03-20 00:31:47:", 0, "" }, + { NULL, 0 } + }; + int idx; + size_t result; + gnupg_isotime_t tbuf; + + for (idx=0; array[idx].string; idx++) + { + result = string2isotime (tbuf, array[idx].string); + if (result != array[idx].result) + { + fail (idx); + if (verbose) + fprintf (stderr, "string `%s' expected: %d, got: %d\n", + array[idx].string, (int)array[idx].result, (int)result); + } + else if (result && strlen (tbuf) != 15) + { + fail (idx); + if (verbose) + fprintf (stderr, "string `%s' invalid isotime returned\n", + array[idx].string); + } + else if (result && strcmp (array[idx].expected, tbuf)) + { + fail (idx); + if (verbose) + fprintf (stderr, "string `%s' bad isotime '%s' returned\n", + array[idx].string, tbuf); + } + } +} + int main (int argc, char **argv) @@ -97,6 +181,7 @@ main (int argc, char **argv) verbose = 1; test_isotime2epoch (); + test_string2isotime (); return !!errcount; } diff --git a/common/tlv.c b/common/tlv.c index 54ef6fc..61f770e 100644 --- a/common/tlv.c +++ b/common/tlv.c @@ -238,14 +238,14 @@ _parse_ber_header (unsigned char const **buffer, size_t *size, is the pointer to the S-expression and BUFLEN is a pointer to the length of this S-expression (used to validate the syntax). Both are updated to reflect the new position. The token itself is - returned as a pointer into the orginal buffer at TOK and TOKLEN. + returned as a pointer into the original buffer at TOK and TOKLEN. If a parentheses is the next token, TOK will be set to NULL. - TOKLEN is checked to be within the bounds. On error a error code - is returned and all pointers should are not guaranteed to point to - a meanigful value. DEPTH should be initialized to 0 and will + TOKLEN is checked to be within the bounds. On error an error code + is returned and no pointer is not guaranteed to point to + a meaningful value. DEPTH should be initialized to 0 and will reflect on return the actual depth of the tree. To detect the end of the S-expression it is advisable to check DEPTH after a - successful return: + successful return. depth = 0; while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)) diff --git a/common/tlv.h b/common/tlv.h index c7fafd5..fd57e1e 100644 --- a/common/tlv.h +++ b/common/tlv.h @@ -90,15 +90,15 @@ gpg_error_t _parse_ber_header (unsigned char const **buffer, size_t *size, GPG_ERR_SOURCE_DEFAULT) -/* Return the next token of an canconical encoded S-expression. BUF +/* Return the next token of an canonical encoded S-expression. BUF is the pointer to the S-expression and BUFLEN is a pointer to the length of this S-expression (used to validate the syntax). Both are updated to reflect the new position. The token itself is - returned as a pointer into the orginal buffer at TOK and TOKLEN. + returned as a pointer into the original buffer at TOK and TOKLEN. If a parentheses is the next token, TOK will be set to NULL. - TOKLEN is checked to be within the bounds. On error a error code - is returned and all pointers should are not guaranteed to point to - a meanigful value. DEPTH should be initialized to 0 and will + TOKLEN is checked to be within the bounds. On error an error code + is returned and no pointer is not guaranteed to point to + a meaningful value. DEPTH should be initialized to 0 and will reflect on return the actual depth of the tree. To detect the end of the S-expression it is advisable to check DEPTH after a successful return. */ ----------------------------------------------------------------------- Summary of changes: AUTHORS | 8 +- ChangeLog | 4 + NEWS | 4 + common/ChangeLog | 8 + common/gettime.c | 159 ++++++++++++++++-- common/gettime.h | 3 + common/t-gettime.c | 87 +++++++++- common/tlv.c | 10 +- common/tlv.h | 10 +- configure.ac | 2 +- doc/DETAILS | 5 +- m4/ChangeLog | 4 + m4/gpg-error.m4 | 13 +- m4/ksba.m4 | 20 ++- m4/libgcrypt.m4 | 13 +- sm/ChangeLog | 23 +++- sm/certreqgen-ui.c | 34 +++- sm/certreqgen.c | 493 ++++++++++++++++++++++++++++++++++++++++++++------- sm/gpgsm.h | 4 + sm/keylist.c | 1 + sm/misc.c | 132 ++++++++++++++- 21 files changed, 912 insertions(+), 125 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 1 17:32:35 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 01 Mar 2011 17:32:35 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-17-g00f8b68 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 00f8b68505ae3195a862a5235063f6f0d71edc27 (commit) from 28c157b55cf6db6b6988def5c9512e388c512b10 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 00f8b68505ae3195a862a5235063f6f0d71edc27 Author: Werner Koch Date: Tue Mar 1 17:08:49 2011 +0100 Move parameter file description to the manual. diff --git a/doc/ChangeLog b/doc/ChangeLog index be20c57..32ce715 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,8 @@ +2011-03-01 Werner Koch + + * gpgsm.texi (CSR and certificate creation): New. + * gpg.texi (Unattended GPG key generation): New. + 2010-10-29 David Shaw * gpg.texi (GPG Configuration Options): Clarify that show-photos @@ -191,7 +196,7 @@ * qualified.txt: Add new BnetzA certs 12R and 13R. * com-certs.pem: Ditto. - * examples/trustlist.txt: Ditto. + * examples/trustlist.txt: Ditto. 2008-06-19 Werner Koch @@ -477,7 +482,7 @@ 2007-02-18 Werner Koch - * gpg.texi (GPG Esoteric Options): No card reader options for gpg2. + * gpg.texi (GPG Esoteric Options): No card reader options for gpg2. 2007-02-14 Werner Koch @@ -552,7 +557,7 @@ * instguide.texi (Installation): New. * assuan.texi (Assuan): Removed. Use the libassuan manual instead. - * gnupg.texi: Reflect these changes. + * gnupg.texi: Reflect these changes. * gpg.texi: Make some parts depend on the "gpgone" set command. This allows us to use the same source for gpg1 and gpg2. @@ -707,7 +712,7 @@ * gnupg.texi: Include gpg.texi * tools.texi: Add a few @command markups. - * gpgsm.texi: Ditto + * gpgsm.texi: Ditto * gpg-agent.texi: Ditto. * scdaemon.texi: Ditto. @@ -725,7 +730,7 @@ expected pinentry filename. Changed license of the manual stuff to GPL. - + * gnupg.texi (Top): New menu item Helper Tools. * tools.texi (Helper Tools): New. @@ -831,7 +836,7 @@ 2002-05-14 Werner Koch * Makefile.am, gpgsm.texi: New. - + Copyright 2002, 2004, 2005, 2006, 2007, 2008, 2010 Free Software Foundation, Inc. This file is free software; as a special exception the author gives diff --git a/doc/DETAILS b/doc/DETAILS index 5870927..543ae4d 100644 --- a/doc/DETAILS +++ b/doc/DETAILS @@ -785,199 +785,12 @@ would result in: Key generation ============== - See the Libcrypt manual. +See the Libcrypt manual. Unattended key generation ========================= -This feature allows unattended generation of keys controlled by a -parameter file. To use this feature, you use --gen-key together with ---batch and feed the parameters either from stdin or from a file given -on the commandline. The description below is only for GPG; GPGSM has -a similar feature, see the file sm/certreqgen.c for a description. - -The format of this file is as follows: - o Text only, line length is limited to about 1000 chars. - o You must use UTF-8 encoding to specify non-ascii characters. - o Empty lines are ignored. - o Leading and trailing spaces are ignored. - o A hash sign as the first non white space character indicates a comment line. - o Control statements are indicated by a leading percent sign, the - arguments are separated by white space from the keyword. - o Parameters are specified by a keyword, followed by a colon. Arguments - are separated by white space. - o The first parameter must be "Key-Type", control statements - may be placed anywhere. - o Key generation takes place when either the end of the parameter file - is reached, the next "Key-Type" parameter is encountered or at the - control statement "%commit" - o Control statements: - %echo - Print . - %dry-run - Suppress actual key generation (useful for syntax checking). - %commit - Perform the key generation. An implicit commit is done - at the next "Key-Type" parameter. - %pubring - %secring - Do not write the key to the default or commandline given - keyring but to . This must be given before the first - commit to take place, duplicate specification of the same filename - is ignored, the last filename before a commit is used. - The filename is used until a new filename is used (at commit points) - and all keys are written to that file. If a new filename is given, - this file is created (and overwrites an existing one). - GnuPG < 2.1: Both control statements must be given. - GnuPG >= 2.1: "%secring" is now a no-op. - %ask-passphrase - Enable a mode where the command "passphrase" is ignored and - instead the usual passphrase dialog is used. This does not - make sense for batch key generation; however the unattended - key generation feature is also used by GUIs and this feature - relinquishes the GUI from implementing its own passphrase - entry code. This is a global option. - %no-ask-passphrase - Disable the ask-passphrase mode. - %no-protection - With GnuPG 2.1 it is not anymore possible to specify a - passphrase for unattended key generation. The passphrase - command is simply ignored and %ask-passpharse is thus - implicitly enabled. Using this option allows to the creation - of keys without any passphrases. This option is mainly - intended for regression tests. - %transient-key - If given the keys are created using a faster and a somewhat - less secure random number generator. This option may be used - for keys which are only used for a short time and do not - require full cryptographic strength. It takes only effect if - used together with the option no-protection. - - o The order of the parameters does not matter except for "Key-Type" - which must be the first parameter. The parameters are only for the - generated keyblock and parameters from previous key generations are not - used. Some syntactically checks may be performed. - The currently defined parameters are: - Key-Type: | - Starts a new parameter block by giving the type of the primary - key. The algorithm must be capable of signing. This is a - required parameter. It may be "default" to use the default - one; in this case don't give a Key-Usage and use "default" for - the Subkey-Type. - Key-Length: - Length of the key in bits. The default is returned by running - the command "gpg --gpgconf-list". - Key-Usage: - Space or comma delimited list of key usage, allowed values are - "encrypt", "sign", and "auth". This is used to generate the - key flags. Please make sure that the algorithm is capable of - this usage. Note that OpenPGP requires that all primary keys - are capable of certification, so no matter what usage is given - here, the "cert" flag will be on. If no Key-Usage is - specified and the key-type is not "default", all allowed - usages for that particular algorithm are used; if it is not - given but "default" is used the usage will be "sign". - Subkey-Type: | - This generates a secondary key. Currently only one subkey - can be handled. "default" is also supported. - Subkey-Length: - Length of the subkey in bits. The default is returned by running - the command "gpg --gpgconf-list". - Subkey-Usage: - Similar to Key-Usage. - Passphrase: - If you want to specify a passphrase for the secret key, - enter it here. Default is not to use any passphrase. - Name-Real: - Name-Comment: - Name-Email: - The 3 parts of a key. Remember to use UTF-8 here. - If you don't give any of them, no user ID is created. - Expire-Date: |([d|w|m|y]) - Set the expiration date for the key (and the subkey). It may - either be entered in ISO date format (2000-08-15) or as number - of days, weeks, month or years. The special notation - "seconds=N" is also allowed to directly give an Epoch - value. Without a letter days are assumed. Note that there is - no check done on the overflow of the type used by OpenPGP for - timestamps. Thus you better make sure that the given value - make sense. Although OpenPGP works with time intervals, GnuPG - uses an absolute value internally and thus the last year we - can represent is 2105. - Creation-Date: - Set the creation date of the key as stored in the key - information and which is also part of the fingerprint - calculation. Either a date like "1986-04-26" or a full - timestamp like "19860426T042640" may be used. The time is - considered to be UTC. If it is not given the current time - is used. - Preferences: - Set the cipher, hash, and compression preference values for - this key. This expects the same type of string as "setpref" - in the --edit menu. - Revoker: : [sensitive] - Add a designated revoker to the generated key. Algo is the - public key algorithm of the designated revoker (i.e. RSA=1, - DSA=17, etc.) Fpr is the fingerprint of the designated - revoker. The optional "sensitive" flag marks the designated - revoker as sensitive information. Only v4 keys may be - designated revokers. - Handle: - This is an optional parameter only used with the status lines - KEY_CREATED and KEY_NOT_CREATED. STRING may be up to 100 - characters and should not contain spaces. It is useful for - batch key generation to associate a key parameter block with a - status line. - Keyserver: - This is an optional parameter that specifies the preferred - keyserver URL for the key. - - -Here is an example on how to create a key: -$ cat >foo < -ssb 1024g/8F70E2C0 2000-03-09 - -If you want to create a key with the default algorithms you would -use these parameters: - - %echo Generating a default key - Key-Type: default - Subkey-Type: default - Name-Real: Joe Tester - Name-Comment: with stupid passphrase - Name-Email: joe at foo.bar - Expire-Date: 0 - Passphrase: abc - %pubring foo.pub - %secring foo.sec - # Do a commit here, so that we can later print "done" :-) - %commit - %echo done - - +The the manual for a description. Layout of the TrustDB diff --git a/doc/gpg.texi b/doc/gpg.texi index 63cc7b6..0ed8c4e 100644 --- a/doc/gpg.texi +++ b/doc/gpg.texi @@ -32,7 +32,7 @@ gpg .IR dir ] .RB [ \-\-options .IR file ] -.RI [ options ] +.RI [ options ] .I command .RI [ args ] @end ifset @@ -57,7 +57,7 @@ gpg2 .IR dir ] .RB [ \-\-options .IR file ] -.RI [ options ] +.RI [ options ] .I command .RI [ args ] @end ifset @@ -98,16 +98,16 @@ page and at @inforef{Top,GnuPG 1,gpg}. @mancont @menu -* GPG Commands:: List of all commands. -* GPG Options:: List of all options. -* GPG Configuration:: Configuration files. -* GPG Examples:: Some usage examples. +* GPG Commands:: List of all commands. +* GPG Options:: List of all options. +* GPG Configuration:: Configuration files. +* GPG Examples:: Some usage examples. Developer information: - at c * Unattended Usage:: Using @command{gpg} from other programs. - at c * GPG Protocol:: The protocol the server mode uses. +* Unattended Usage of GPG:: Using @command{gpg} from other programs. @end menu + at c * GPG Protocol:: The protocol the server mode uses. @c ******************************************* @@ -303,7 +303,7 @@ secret key is not usable (for example, if it was created via @opindex list-sigs Same as @option{--list-keys}, but the signatures are listed too. @ifclear gpgone -This command has the same effect as +This command has the same effect as using @option{--list-keys} with @option{--with-sig-list}. @end ifclear @@ -326,7 +326,7 @@ Same as @option{--list-sigs}, but the signatures are verified. Note that for performance reasons the revocation status of a signing key is not shown. @ifclear gpgone -This command has the same effect as +This command has the same effect as using @option{--list-keys} with @option{--with-sig-check}. @end ifclear @@ -2204,7 +2204,7 @@ a numeric value or by a keyword: @item none No debugging at all. A value of less than 1 may be used instead of the keyword. - at item basic + at item basic Some basic debug messages. A value between 1 and 2 may be used instead of the keyword. @item advanced @@ -2613,7 +2613,7 @@ Allow processing of multiple OpenPGP messages contained in a single file or stream. Some programs that call GPG are not prepared to deal with multiple messages being processed together, so this option defaults to no. Note that versions of GPG prior to 1.4.7 always allowed multiple -messages. +messages. Warning: Do not use this option unless you need it as a temporary workaround! @@ -2833,7 +2833,7 @@ translation is loaded from @code{@var{gpgdir}/gnupg.nls/@var{langid}.mo}. Here @var{gpgdir} is the directory out of which the gpg binary has been loaded. If it can't be loaded the Registry is tried and as last resort the native Windows -locale system is used. +locale system is used. @end table @@ -2964,11 +2964,264 @@ Before you report a bug you should first search the mailing list archives for similar problems and second check whether such a bug has already been reported to our bug tracker at http://bugs.gnupg.org . + at c ******************************************* + at c *************** ************** + at c *************** UNATTENDED ************** + at c *************** ************** + at c ******************************************* + at manpause + at node Unattended Usage of GPG + at section Unattended Usage + + at command{gpg} is often used as a backend engine by other software. To help +with this a machine interface has been defined to have an unambiguous +way to do this. The options @option{--status-fd} and @option{--batch} +are almost always required for this. + + at menu +* Unattended GPG key generation:: Unattended key generation + at end menu + + + at node Unattended GPG key generation,,,Unattended Usage of GPG + at section Unattended key generation + +The command @option{--gen-key} may be used along with the option + at option{--batch} for unattended key generation. The parameters are +either read from stdin or given as a file on the command line. +The format of the parameter file is as follows: + + at itemize @bullet + at item Text only, line length is limited to about 1000 characters. + at item UTF-8 encoding must be used to specify non-ASCII characters. + at item Empty lines are ignored. + at item Leading and trailing while space is ignored. + at item A hash sign as the first non white space character indicates +a comment line. + at item Control statements are indicated by a leading percent sign, the +arguments are separated by white space from the keyword. + at item Parameters are specified by a keyword, followed by a colon. Arguments +are separated by white space. + at item +The first parameter must be @samp{Key-Type}; control statements may be +placed anywhere. + at item +The order of the parameters does not matter except for @samp{Key-Type} +which must be the first parameter. The parameters are only used for +the generated keyblock (primary and subkeys); parameters from previous +sets are not used. Some syntactically checks may be performed. + at item +Key generation takes place when either the end of the parameter file +is reached, the next @samp{Key-Type} parameter is encountered or at the +control statement @samp{%commit} is encountered. + at end itemize + + at noindent +Control statements: + + at table @asis + + at item %echo @var{text} +Print @var{text} as diagnostic. + + at item %dry-run +Suppress actual key generation (useful for syntax checking). + + at item %commit +Perform the key generation. Note that an implicit commit is done at +the next @asis{Key-Type} parameter. + + at item %pubring @var{filename} + at itemx %secring @var{filename} +Do not write the key to the default or commandline given keyring but +to @var{filename}. This must be given before the first commit to take +place, duplicate specification of the same filename is ignored, the +last filename before a commit is used. The filename is used until a +new filename is used (at commit points) and all keys are written to +that file. If a new filename is given, this file is created (and +overwrites an existing one). For gnuPG versions prior to 2.1, both +control statements must be given. For GnuPG 2.1 and later + at samp{%secring} is a no-op. + + at item %ask-passphrase + at itemx %no-ask-passphrase +Enable (or disable) a mode where the command @option{passphrase} is +ignored and instead the usual passphrase dialog is used. This does +not make sense for batch key generation; however the unattended key +generation feature is also used by GUIs and this feature relinquishes +the GUI from implementing its own passphrase entry code. These are +global control statements and affect all future key genrations. + + at item %no-protection +Since GnuPG version 2.1 it is not anymore possible to specify a +passphrase for unattended key generation. The passphrase command is +simply ignored and @samp{%ask-passpharse} is thus implicitly enabled. +Using this option allows the creation of keys without any passphrase +protection. This option is mainly intended for regression tests. + + at item %transient-key +If given the keys are created using a faster and a somewhat less +secure random number generator. This option may be used for keys +which are only used for a short time and do not require full +cryptographic strength. It takes only effect if used together with +the control statement @samp{%no-protection}. + + at end table + + at noindent +General Parameters: + + at table @asis + + at item Key-Type: @var{algo} +Starts a new parameter block by giving the type of the primary +key. The algorithm must be capable of signing. This is a required +parameter. @var{algo} may either be an OpenPGP algorithm number or a +string with the algorithm name. The special value @samp{default} may +be used for @var{algo} to create the default key type; in this case a + at samp{Key-Usage} shall not be given and @samp{default} also be used +for @samp{Subkey-Type}. + + at item Key-Length: @var{nbits} +The requested length of the generated key in bits. The default is +returned by running the command @samp{gpg2 --gpgconf-list}. + + at item Key-Grip: @var{hexstring} +This is optional and used to generate a CSR or certificatet for an +already existing key. Key-Length will be ignored when given. + + at item Key-Usage: @var{usage-list} +Space or comma delimited list of key usages. Allowed values are + at samp{encrypt}, @samp{sign}, and @samp{auth}. This is used to +generate the key flags. Please make sure that the algorithm is +capable of this usage. Note that OpenPGP requires that all primary +keys are capable of certification, so no matter what usage is given +here, the @samp{cert} flag will be on. If no @samp{Key-Usage} is +specified and the @samp{Key-Type} is not @samp{default}, all allowed +usages for that particular algorithm are used; if it is not given but + at samp{default} is used the usage will be @samp{sign}. + + at item Subkey-Type: @var{algo} +This generates a secondary key (subkey). Currently only one subkey +can be handled. See also @samp{Key-Type} above. + + at item Subkey-Length: @var{nbits} +Length of the secondary key (subkey) in bits. The default is returned +by running the command @samp{gpg2 --gpgconf-list}". + + at item Subkey-Usage: @var{usage-list} +Key usage lists for a subkey; similar to @samp{Key-Usage}. + + at item Passphrase: @var{string} +If you want to specify a passphrase for the secret key, +enter it here. Default is not to use any passphrase. + + at item Name-Real: @var{name} + at itemx Name-Comment: @var{comment} + at itemx Name-Email: @var{email} +The three parts of a user name. Remember to use UTF-8 encoding here. +If you don't give any of them, no user ID is created. + + at item Expire-Date: @var{iso-date}|(@var{number}[d|w|m|y]) +Set the expiration date for the key (and the subkey). It may either +be entered in ISO date format (2000-08-15) or as number of days, +weeks, month or years. The special notation "seconds=N" is also +allowed to directly give an Epoch value. Without a letter days are +assumed. Note that there is no check done on the overflow of the type +used by OpenPGP for timestamps. Thus you better make sure that the +given value make sense. Although OpenPGP works with time intervals, +GnuPG uses an absolute value internally and thus the last year we can +represent is 2105. + + at item Ceation-Date: @var{iso-date} +Set the creation date of the key as stored in the key information and +which is also part of the fingerprint calculation. Either a date like +"1986-04-26" or a full timestamp like "19860426T042640" may be used. +The time is considered to be UTC. If it is not given the current time +is used. + + at item Preferences: @var{string} +Set the cipher, hash, and compression preference values for this key. +This expects the same type of string as the sub-command @samp{setpref} +in the @option{--edit-key} menu. + + at item Revoker: @var{algo}:@var{fpr} [sensitive] +Add a designated revoker to the generated key. Algo is the public key +algorithm of the designated revoker (i.e. RSA=1, DSA=17, etc.) + at var{fpr} is the fingerprint of the designated revoker. The optional + at samp{sensitive} flag marks the designated revoker as sensitive +information. Only v4 keys may be designated revokers. + + at item Keyserver: @var{string} +This is an optional parameter that specifies the preferred keyserver +URL for the key. + + at item Handle: @var{string} +This is an optional parameter only used with the status lines +KEY_CREATED and KEY_NOT_CREATED. @var{string} may be up to 100 +characters and should not contain spaces. It is useful for batch key +generation to associate a key parameter block with a status line. + + at end table + + at noindent +Here is an example on how to create a key: + at smallexample +$ cat >foo < +ssb 1024g/8F70E2C0 2000-03-09 + at end smallexample + + + at noindent +If you want to create a key with the default algorithms you would use +these parameters: + at smallexample + %echo Generating a default key + Key-Type: default + Subkey-Type: default + Name-Real: Joe Tester + Name-Comment: with stupid passphrase + Name-Email: joe@@foo.bar + Expire-Date: 0 + Passphrase: abc + %pubring foo.pub + %secring foo.sec + # Do a commit here, so that we can later print "done" :-) + %commit + %echo done + at end smallexample + + + + @mansect see also @ifset isman - at command{gpgv}(1), + at command{gpgv}(1), @ifclear gpgone - at command{gpgsm}(1), + at command{gpgsm}(1), @command{gpg-agent}(1) @end ifclear @end ifset diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index 530169a..2beaf2d 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -21,7 +21,7 @@ .IR dir ] .RB [ \-\-options .IR file ] -.RI [ options ] +.RI [ options ] .I command .RI [ args ] @end ifset @@ -124,7 +124,7 @@ in the keybox or those set with the @option{--local-user} option. @opindex verify Check a signature file for validity. Depending on the arguments a detached signature may also be checked. - + @item --server @opindex server Run in server mode and wait for commands on the @code{stdin}. @@ -150,7 +150,7 @@ Certain maintenance operations are done by an external program call @command{gpg-protect-tool}; this is usually not installed in a directory listed in the PATH variable. This command provides a simple wrapper to access this tool. @var{arguments} are passed verbatim to this command; -use @samp{--help} to get a list of supported operations. +use @samp{--help} to get a list of supported operations. @end table @@ -165,13 +165,15 @@ use @samp{--help} to get a list of supported operations. @table @gnupgtabopt @item --gen-key @opindex gen-key -This command allows the creation of a certificate signing request. It -is commonly used along with the @option{--output} option to save the -created CSR into a file. If used with the @option{--batch} a parameter -file is used to create the CSR. +This command allows the creation of a certificate signing request or a +self-signed certificate. It is commonly used along with the + at option{--output} option to save the created CSR or certificate into a +file. If used with the @option{--batch} a parameter file is used to +create the CSR or certificate and it is further possible to create +non-self-signed certificates. @item --list-keys - at itemx -k + at itemx -k @opindex list-keys List all available certificates stored in the local key database. Note that the displayed data might be reformatted for better human @@ -186,7 +188,7 @@ is available. @item --list-external-keys @var{pattern} @opindex list-keys List certificates matching @var{pattern} using an external server. This -utilizes the @code{dirmngr} service. +utilizes the @code{dirmngr} service. @item --list-chain @opindex list-chain @@ -289,7 +291,7 @@ smartcard is not yet supported. @command{GPGSM} features a bunch of options to control the exact behaviour and to change the default configuration. - at menu + at menu * Configuration Options:: How to change the configuration. * Certificate Options:: Certificate related options. * Input and Output:: Input and Output. @@ -337,7 +339,7 @@ Specify an agent program to be used for secret key operations. The default value is the @file{/usr/local/bin/gpg-agent}. This is only used as a fallback when the environment variable @code{GPG_AGENT_INFO} is not set or a running agent can't be connected. - + @item --dirmngr-program @var{file} @opindex dirmnr-program Specify a dirmngr program to be used for @acronym{CRL} checks. The @@ -412,7 +414,7 @@ the loading for short time intervals (e.g. 30 minutes). This option is useful to make sure that a fresh CRL is available for certificates hold in the keybox. The suggested way of doing this is by using it along with the option @option{--with-validation} for a key listing -command. This option should not be used in a configuration file. +command. This option should not be used in a configuration file. @item --enable-ocsp @itemx --disable-ocsp @@ -422,7 +424,7 @@ Be default @acronym{OCSP} checks are disabled. The enable option may be used to enable OCSP checks via Dirmngr. If @acronym{CRL} checks are also enabled, CRLs will be used as a fallback if for some reason an OCSP request won't succeed. Note, that you have to allow OCSP -requests in Dirmngr's configuration too (option +requests in Dirmngr's configuration too (option @option{--allow-ocsp} and configure dirmngr properly. If you don't do so you will get the error code @samp{Not supported}. @@ -470,9 +472,9 @@ for a reason. @itemx -a @opindex armor @opindex -a -Create PEM encoded output. Default is binary output. +Create PEM encoded output. Default is binary output. - at item --base64 + at item --base64 @opindex base64 Create Base-64 encoded output; i.e. PEM without the header lines. @@ -542,7 +544,7 @@ secret key. @opindex with-validation When doing a key listing, do a full validation check for each key and print the result. This is usually a slow operation because it -requires a CRL lookup and other operations. +requires a CRL lookup and other operations. When used along with --import, a validation of the certificate to import is done and only imported if it succeeds the test. Note that @@ -580,7 +582,7 @@ Use the cipher algorithm with the ASN.1 object identifier @var{oid} for encryption. For convenience the strings @code{3DES}, @code{AES} and @code{AES256} may be used instead of their OIDs. The default is @code{3DES} (1.2.840.113549.3.7). - + @item --digest-algo @code{name} Use @code{name} as the message digest algorithm. Usually this algorithm is deduced from the respective signing certificate. This @@ -635,7 +637,7 @@ a numeric value or by a keyword: @item none No debugging at all. A value of less than 1 may be used instead of the keyword. - at item basic + at item basic Some basic debug messages. A value between 1 and 2 may be used instead of the keyword. @item advanced @@ -664,8 +666,8 @@ and may be given in usual C-Syntax. The currently defined bits are: @table @code @item 0 (1) X.509 or OpenPGP protocol related data - at item 1 (2) -values of big number integers + at item 1 (2) +values of big number integers @item 2 (4) low level crypto operations @item 5 (32) @@ -771,7 +773,7 @@ like this: @c man:.RS @example # Allowed policies -2.289.9.9 +2.289.9.9 @end example @c man:.RE @@ -813,7 +815,7 @@ certificates, appropriate notices will be shown to indicate this fact. @item help.txt @cindex help.txt -This is plain text file with a few help entries used with +This is plain text file with a few help entries used with @command{pinentry} as well as a large list of help items for @command{gpg} and @command{gpgsm}. The standard file has English help texts; to install localized versions use filenames like @file{help.LL.txt} @@ -886,14 +888,12 @@ $ gpgsm -er goo@@bar.net ciphertext @end example - at c man end - - @c ******************************************* @c *************** ************** @c *************** UNATTENDED ************** @c *************** ************** @c ******************************************* + at manpause @node Unattended Usage @section Unattended Usage @@ -905,6 +905,7 @@ but may also be used in the standard operation mode by using the @menu * Automated signature checking:: Automated signature checking. +* CSR and certificate creation:: CSR and certificate creation. @end menu @node Automated signature checking,,,Unattended Usage @@ -925,7 +926,7 @@ signature of a message itself as expired. It is a sound practise to consider such a signature still as valid but additional information should be displayed. Depending on the subcase @command{gpgsm} will issue these status codes: - @table @asis + @table @asis @item signature valid and nothing did expire @code{GOODSIG}, @code{VALIDSIG}, @code{TRUST_FULLY} @item signature valid but at least one certificate has expired @@ -951,13 +952,156 @@ this is a missing certificate. @end table + at node CSR and certificate creation,,,Unattended Usage + at section CSR and certificate creation + +The command @option{--gen-key} may be used along with the option + at option{--batch} to either create a certificate signing request (CSR) or an +X.509 certificate. The is controlled by a parameter file; the format +of this file is as follows: + + at itemize @bullet + at item Text only, line length is limited to about 1000 characters. + at item UTF-8 encoding must be used to specify non-ASCII characters. + at item Empty lines are ignored. + at item Leading and trailing while space is ignored. + at item A hash sign as the first non white space character indicates +a comment line. + at item Control statements are indicated by a leading percent sign, the +arguments are separated by white space from the keyword. + at item Parameters are specified by a keyword, followed by a colon. Arguments +are separated by white space. + at item The first parameter must be @samp{Key-Type}, control statements +may be placed anywhere. + at item +The order of the parameters does not matter except for @samp{Key-Type} +which must be the first parameter. The parameters are only used for +the generated CSR/certificate; parameters from previous sets are not +used. Some syntactically checks may be performed. + at item +Key generation takes place when either the end of the parameter file +is reached, the next @samp{Key-Type} parameter is encountered or at the +control statement @samp{%commit} is encountered. + at end itemize + + at noindent +Control statements: + + at table @asis + + at item %echo @var{text} +Print @var{text} as diagnostic. + + at item %dry-run +Suppress actual key generation (useful for syntax checking). + + at item %commit +Perform the key generation. Note that an implicit commit is done at +the next @asis{Key-Type} parameter. + + at c %certfile <filename> + at c [Not yet implemented!] + at c Do not write the certificate to the keyDB but to <filename>. + at c This must be given before the first + at c commit to take place, duplicate specification of the same filename + at c is ignored, the last filename before a commit is used. + at c The filename is used until a new filename is used (at commit points) + at c and all keys are written to that file. If a new filename is given, + at c this file is created (and overwrites an existing one). + at c Both control statements must be given. + at end table + + at noindent +General Parameters: + + at table @asis + + at item Key-Type: @var{algo} +Starts a new parameter block by giving the type of the primary +key. The algorithm must be capable of signing. This is a required +parameter. The only supported value for @var{algo} is @samp{rsa}. + + at item Key-Length: @var{nbits} +The requested length of a generated key in bits. Defaults to 2048. + + at item Key-Grip: @var{hexstring} +This is optional and used to generate a CSR or certificatet for an +already existing key. Key-Length will be ignored when given. + + at item Key-Usage: @var{usage-list} +Space or comma delimited list of key usage, allowed values are + at samp{encrypt} and @samp{sign}. This is used to generate the keyUsage +extension. Please make sure that the algorithm is capable of this +usage. Default is to allow encrypt and sign. + + at item Name-DN: @var{subject-name} +This is the Distinguished Name (DN) of the subject in RFC-2253 format. + + at item Name-Email: @var{string} +This is an email address for the altSubjectName. This parameter is +optional but may occur several times to add several email addresses to +a certificate. + + at item Name-DNS: @var{string} +The is an DNS name for the altSubjectName. This parameter is optional +but may occur several times to add several DNS names to a certificate. + + at item Name-URI: @var{string} +This is an URI for the altSubjectName. This parameter is optional but +may occur several times to add several URIs to a certificate. + at end table + + at noindent +Additional parameters used to create a certificate (in contrast to a +certificate signing request): + + at table @asis + + at item Serial: @var{sn} +If this parameter is given an X.509 certificate will be generated. + at var{sn} is expected to be a hex string representing an unsigned +integer of arbitary length. The special value @samp{random} can be +used to create a 64 bit random serial number. + + at item Issuer-DN: @var{issuer-name} +This is the DN name of the issuer in rfc2253 format. If it is not set +it will default to the subject DN and a special GnuPG extension will +be included in the certificate to mark it as a standalone certificate. + + at item Creation-Date: @var{iso-date} + at itemx Not-Before: @var{iso-date} +Set the notBefore date of the certificate. Either a date like + at samp{1986-04-26} or @samp{1986-04-26 12:00} or a standard ISO +timestamp like @samp{19860426T042640} may be used. The time is +considered to be UTC. If it is not given the current date is used. + + at item Expire-Date: @var{iso-date} + at itemx Not-After: @var{iso-date} +Set the notAfter date of the certificate. Either a date like + at samp{2063-04-05} or @samp{2063-04-05 17:00} or a standard ISO +timestamp like @samp{20630405T170000} may be used. The time is +considered to be UTC. If it is not given a default value in the not +too far future is used. + + at item Signing-Key: @var{keygrip} +This gives the keygrip of the key used to sign the certificate. If it +is not given a self-signed certificate will be created. For +compatibility with future versions, it is suggested to prefix the +keygrip with a @samp{&}. + + at item Hash-Algo: @var{hash-algo} +Use @var{hash-algo} for this CSR or certificate. The supported hash +algorithms are: @samp{sha1}, @samp{sha256}, @samp{sha384} and + at samp{sha512}; they may also be specified with uppercase letters. The +default is @samp{sha1}. + + at end table @c ******************************************* @c *************** ***************** @c *************** ASSSUAN ***************** @c *************** ***************** @c ******************************************* - at manpause @node GPGSM Protocol @section The Protocol the Server Mode Uses. @@ -1037,11 +1181,11 @@ should consider this session failed. The option armor encodes the output in @acronym{PEM} format, the @code{--base64} option applies just a base 64 encoding. No option creates binary output (@acronym{BER}). - + The actual encryption is done using the command @example - ENCRYPT + ENCRYPT @end example It takes the plaintext from the @code{INPUT} command, writes to the @@ -1097,7 +1241,7 @@ Write the output to file descriptor @var{m}. If a detached signature is requested, only the signature is written. @example - SIGN [--detached] + SIGN [--detached] @end example Sign the data set with the INPUT command and write it to the sink set by @@ -1149,7 +1293,7 @@ token is used to store the key. Configuration options to @command{GPGSM} can be used to restrict the use of this command. @example - GENKEY + GENKEY @end example @command{GPGSM} checks whether this command is allowed and then does an @@ -1161,7 +1305,7 @@ key parameters in the native format: C: D foo:fgfgfg C: D bar C: END - at end example + at end example Please note that the server may send Status info lines while reading the data lines from the client. After this the key generation takes place @@ -1197,7 +1341,7 @@ The list commands commands are affected by the option where mode may be: @table @code - at item 0 + at item 0 Use default (which is usually the same as 1). @item 1 List only the internal keys. @@ -1208,7 +1352,7 @@ List internal and external keys. @end table Note that options are valid for the entire session. - + @node GPGSM EXPORT @subsection Export certificates @@ -1294,7 +1438,7 @@ The leading two dashes usually used with @var{opt} shall not be given. @mansect see also @ifset isman - at command{gpg2}(1), + at command{gpg2}(1), @command{gpg-agent}(1) @end ifset @include see-also-note.texi diff --git a/sm/certreqgen.c b/sm/certreqgen.c index 7d0bfbd..e854474 100644 --- a/sm/certreqgen.c +++ b/sm/certreqgen.c @@ -19,127 +19,20 @@ */ /* -The format of the native parameter file is follows: - o Text only, line length is limited to about 1000 chars. - o You must use UTF-8 encoding to specify non-ascii characters. - o Empty lines are ignored. - o Leading and trailing spaces are ignored. - o A hash sign as the first non white space character is a comment line. - o Control statements are indicated by a leading percent sign, the - arguments are separated by white space from the keyword. - o Parameters are specified by a keyword, followed by a colon. Arguments - are separated by white space. - o The first parameter must be "Key-Type", control statements - may be placed anywhere. - o Key generation takes place when either the end of the parameter file - is reached, the next "Key-Type" parameter is encountered or at the - controlstatement "%commit" - o Control statements: - %echo <text> - Print <text>. - %dry-run - Suppress actual key generation (useful for syntax checking). - %commit - Perform the key generation. Note that an implicit commit is done - at the next "Key-Type" parameter. - %certfile <filename> - [Not yet implemented!] - Do not write the certificate to the keyDB but to <filename>. - This must be given before the first - commit to take place, duplicate specification of the same filename - is ignored, the last filename before a commit is used. - The filename is used until a new filename is used (at commit points) - and all keys are written to that file. If a new filename is given, - this file is created (and overwrites an existing one). - Both control statements must be given. - - o The order of the parameters does not matter except for "Key-Type" - which must be the first parameter. The parameters are only for the - generated keyblock and parameters from previous key generations are not - used. Some syntactically checks may be performed. - - The currently defined parameters are: - - Key-Type: <algo> - Starts a new parameter block by giving the type of the - primary key. The algorithm must be capable of signing. - This is a required parameter. For now the only supported - algorithm is "rsa". - - Key-Length: <length-in-bits> - Length of the key in bits. Default is 2048. - - Key-Grip: <hexstring> - This is optional and used to generate a request for an already - existing key. Key-Length will be ignored when given, - - Key-Usage: <usage-list> - Space or comma delimited list of key usage, allowed values are - "encrypt" and "sign". This is used to generate the KeyUsage extension. - Please make sure that the algorithm is capable of this usage. Default - is to allow encrypt and sign. - - Name-DN: <subject_name> - This is the DN name of the subject in rfc2253 format. - - Name-Email: <string> - The is an email address for the altSubjectName - - Name-DNS: <string> - The is an DNS name for the altSubjectName - - Name-URI: <string> - The is an URI for the altSubjectName - - The following parameters are only used if a certificate (and not - a certificate signing request) is requested: - - Serial: <sn> - If this parameter is given an X.509 certificate will be - generated. SN is expected to be a hex string representing an - unsigned integer of arbitary length. The special value - "random" can be used to crete a 64 bit random serial number. - - Issuer-DN: <issuer_name> - This is the DN name of the issuer in rfc2253 format. If it is - not set the subject DN will be used instead. This creates a - self-signed certificate. Only in this case a special GnuPG - extension will then be included in the certificate to mark it - as a standalone certificate. - - Creation-Date: <iso-date> - Set the notBefore date of the certificate. Either a date like - "1986-04-26" or a full timestamp like "19860426T042640" may be - used. The time is considered to be UTC. If it is not given - the current date is used. - - Expire-Date: <iso-date> - Set the notBefore date of the certificate. Either a date like - "1986-04-26" or a full timestamp like "19860426T042640" may be - used. The time is considered to be UTC. If it is not given a - default value is used. - - Signing-Key: <keygrip> - This gives the keygrip of the key used to sign the - certificate. If it is not given a self-signed certificate - will be created. - - Hash-Algo: <hash-algo> - Use HASH-ALGO for this certificate. The supported hash - algorithms are: "sha-1", "sha-256", "sha-384" and "sha-512". - "sha-1" is the default. - -Here is an example: -$ cat >foo <<EOF -%echo Generating a standard key -Key-Type: RSA -Key-Length: 2048 -Name-DN: CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=D?sseldorf,C=DE -Name-Email: joe at foo.bar -# Do a commit here, so that we can later print "done" :-) -%commit -%echo done -EOF + The format of the parameter file is described in the manual under + "Unattended Usage". + + Here is an example: + $ cat >foo <<EOF + %echo Generating a standard key + Key-Type: RSA + Key-Length: 2048 + Name-DN: CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Ddorf,C=DE + Name-Email: joe at foo.bar + # Do a commit here, so that we can later print a "done" + %commit + %echo done + EOF */ ----------------------------------------------------------------------- Summary of changes: doc/ChangeLog | 17 ++- doc/DETAILS | 191 +------------------------------------- doc/gpg.texi | 283 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- doc/gpgsm.texi | 214 +++++++++++++++++++++++++++++++++++------- sm/certreqgen.c | 135 +++----------------------- 5 files changed, 474 insertions(+), 366 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 2 10:18:45 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 02 Mar 2011 10:18:45 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-23-gb7f74f5 Message-ID: <E1PuhVm-0000LV-GH@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via b7f74f5b46a28d200627ab9b67763891190a8e15 (commit) via cb803a4b2789d1300e201236c86945daf58c667f (commit) via fa58a834ff994267307a344151bdc344590ecb47 (commit) via 528d77a0ccad4e54480ea4f069b4bbc28779b3ce (commit) via 0706511b6d10561e97381554e404a960538ee342 (commit) via 2165925baeaa42f611b75718f3b2e9b37c53e417 (commit) from 00f8b68505ae3195a862a5235063f6f0d71edc27 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b7f74f5b46a28d200627ab9b67763891190a8e15 Author: Werner Koch <wk at gnupg.org> Date: Wed Mar 2 09:50:12 2011 +0100 Add comment to last patch. diff --git a/agent/ChangeLog b/agent/ChangeLog index f8156bc..783089e 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,6 +1,8 @@ 2011-03-02 Ben Kibbey <bjk at luxsci.net> (wk) * command.c (cmd_clear_passphrase): Add option --mode=normal. + (cmd_keyinfo): Add option --data. + (do_one_keyinfo): Return CACHED status. Add arg DATA. 2011-02-07 Werner Koch <wk at g10code.com> @@ -2928,7 +2930,7 @@ Fri Aug 18 14:27:14 CEST 2000 Werner Koch <wk at openit.de> Copyright 2001, 2002, 2003, 2004, 2005, - 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + 2007, 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/command.c b/agent/command.c index b6f5cfb..79b9b97 100644 --- a/agent/command.c +++ b/agent/command.c @@ -954,13 +954,13 @@ static const char hlp_keyinfo[] = "IDSTR is the IDSTR used to distinguish keys on a smartcard. If it\n" " is not known a dash is used instead.\n" "\n" - "CACHED is 1 if the key was found in the key cache. If not, a '-'\n" - "is used instead.\n" + "CACHED is 1 if the passphrase for the key was found in the key cache.\n" + " If not, a '-' is used instead.\n" "\n" "More information may be added in the future."; static gpg_error_t do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, - int data) + int data) { gpg_error_t err; char hexgrip[40+1]; @@ -969,7 +969,7 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, char *serialno = NULL; char *idstr = NULL; const char *keytypestr; - char *cached; + const char *cached; char *pw; err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info); @@ -987,6 +987,9 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, else keytypestr = "-"; + /* Here we have a little race by doing the cache check separately + from the retrieval function. Given that the cache flag is only a + hint, it should not really matter. */ pw = agent_get_cache (hexgrip, CACHE_MODE_NORMAL); cached = pw ? "1" : "-"; xfree (pw); @@ -1006,16 +1009,20 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, idstr? idstr : "-", cached, NULL); - else { - char *string = xtryasprintf ("%s %s %s %s %s\n", hexgrip, keytypestr, - serialno? serialno : "-", idstr? idstr : "-", cached); - - if (!string) - err = gpg_error_from_syserror (); + else + { + char *string; - err = assuan_send_data(ctx, string, strlen(string)); - xfree(string); - } + string = xtryasprintf ("%s %s %s %s %s\n", + hexgrip, keytypestr, + serialno? serialno : "-", + idstr? idstr : "-", cached); + if (!string) + err = gpg_error_from_syserror (); + else + err = assuan_send_data (ctx, string, strlen(string)); + xfree (string); + } leave: xfree (shadow_info); commit cb803a4b2789d1300e201236c86945daf58c667f Author: Ben Kibbey <bjk at luxsci.net> Date: Tue Mar 1 21:18:45 2011 -0500 Added option --data to KEYINFO to return the result with a data response. diff --git a/agent/command.c b/agent/command.c index ddcb067..b6f5cfb 100644 --- a/agent/command.c +++ b/agent/command.c @@ -930,13 +930,13 @@ cmd_readkey (assuan_context_t ctx, char *line) static const char hlp_keyinfo[] = - "KEYINFO [--list] <keygrip>\n" + "KEYINFO [--list] [--data] <keygrip>\n" "\n" "Return information about the key specified by the KEYGRIP. If the\n" "key is not available GPG_ERR_NOT_FOUND is returned. If the option\n" "--list is given the keygrip is ignored and information about all\n" "available keys are returned. The information is returned as a\n" - "status line with this format:\n" + "status line unless --data was specified, with this format:\n" "\n" " KEYINFO <keygrip> <type> <serialno> <idstr> <cached>\n" "\n" @@ -959,7 +959,8 @@ static const char hlp_keyinfo[] = "\n" "More information may be added in the future."; static gpg_error_t -do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip) +do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx, + int data) { gpg_error_t err; char hexgrip[40+1]; @@ -997,13 +998,25 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip) goto leave; } - err = agent_write_status (ctrl, "KEYINFO", - hexgrip, - keytypestr, - serialno? serialno : "-", - idstr? idstr : "-", - cached, - NULL); + if (!data) + err = agent_write_status (ctrl, "KEYINFO", + hexgrip, + keytypestr, + serialno? serialno : "-", + idstr? idstr : "-", + cached, + NULL); + else { + char *string = xtryasprintf ("%s %s %s %s %s\n", hexgrip, keytypestr, + serialno? serialno : "-", idstr? idstr : "-", cached); + + if (!string) + err = gpg_error_from_syserror (); + + err = assuan_send_data(ctx, string, strlen(string)); + xfree(string); + } + leave: xfree (shadow_info); xfree (serialno); @@ -1020,8 +1033,10 @@ cmd_keyinfo (assuan_context_t ctx, char *line) unsigned char grip[20]; DIR *dir = NULL; int list_mode; + int opt_data; list_mode = has_option (line, "--list"); + opt_data = has_option (line, "--data"); line = skip_options (line); if (list_mode) @@ -1056,7 +1071,7 @@ cmd_keyinfo (assuan_context_t ctx, char *line) if ( hex2bin (hexgrip, grip, 20) < 0 ) continue; /* Bad hex string. */ - err = do_one_keyinfo (ctrl, grip); + err = do_one_keyinfo (ctrl, grip, ctx, opt_data); if (err) goto leave; } @@ -1067,7 +1082,7 @@ cmd_keyinfo (assuan_context_t ctx, char *line) err = parse_keygrip (ctx, line, grip); if (err) goto leave; - err = do_one_keyinfo (ctrl, grip); + err = do_one_keyinfo (ctrl, grip, ctx, opt_data); } leave: commit fa58a834ff994267307a344151bdc344590ecb47 Author: Ben Kibbey <bjk at luxsci.net> Date: Tue Mar 1 20:29:08 2011 -0500 Let KEYINFO show the cached status of a key grip. diff --git a/agent/command.c b/agent/command.c index 9533db7..ddcb067 100644 --- a/agent/command.c +++ b/agent/command.c @@ -938,7 +938,7 @@ static const char hlp_keyinfo[] = "available keys are returned. The information is returned as a\n" "status line with this format:\n" "\n" - " KEYINFO <keygrip> <type> <serialno> <idstr>\n" + " KEYINFO <keygrip> <type> <serialno> <idstr> <cached>\n" "\n" "KEYGRIP is the keygrip.\n" "\n" @@ -954,6 +954,9 @@ static const char hlp_keyinfo[] = "IDSTR is the IDSTR used to distinguish keys on a smartcard. If it\n" " is not known a dash is used instead.\n" "\n" + "CACHED is 1 if the key was found in the key cache. If not, a '-'\n" + "is used instead.\n" + "\n" "More information may be added in the future."; static gpg_error_t do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip) @@ -965,6 +968,8 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip) char *serialno = NULL; char *idstr = NULL; const char *keytypestr; + char *cached; + char *pw; err = agent_key_info_from_file (ctrl, grip, &keytype, &shadow_info); if (err) @@ -981,6 +986,10 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip) else keytypestr = "-"; + pw = agent_get_cache (hexgrip, CACHE_MODE_NORMAL); + cached = pw ? "1" : "-"; + xfree (pw); + if (shadow_info) { err = parse_shadow_info (shadow_info, &serialno, &idstr); @@ -993,6 +1002,7 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip) keytypestr, serialno? serialno : "-", idstr? idstr : "-", + cached, NULL); leave: xfree (shadow_info); commit 528d77a0ccad4e54480ea4f069b4bbc28779b3ce Author: Werner Koch <wk at gnupg.org> Date: Wed Mar 2 09:11:40 2011 +0100 Rename Ben's new option. diff --git a/agent/ChangeLog b/agent/ChangeLog index 0390275..f8156bc 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,7 @@ +2011-03-02 Ben Kibbey <bjk at luxsci.net> (wk) + + * command.c (cmd_clear_passphrase): Add option --mode=normal. + 2011-02-07 Werner Koch <wk at g10code.com> * pksign.c (do_encode_dsa): Enforce multipe of 8 bits only for DSA. diff --git a/agent/command.c b/agent/command.c index 63f59d4..9533db7 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1267,20 +1267,20 @@ cmd_get_passphrase (assuan_context_t ctx, char *line) static const char hlp_clear_passphrase[] = - "CLEAR_PASSPHRASE [--agent] <cache_id>\n" + "CLEAR_PASSPHRASE [--mode=normal] <cache_id>\n" "\n" "may be used to invalidate the cache entry for a passphrase. The\n" "function returns with OK even when there is no cached passphrase.\n" - "The --agent option is used to clear an entry for a cacheid added by\n" - "the agent.\n"; + "The --mode=normal option is used to clear an entry for a cacheid\n" + "added by the agent.\n"; static gpg_error_t cmd_clear_passphrase (assuan_context_t ctx, char *line) { char *cacheid = NULL; char *p; - int opt_agent; + int opt_normal; - opt_agent = has_option (line, "--agent"); + opt_normal = has_option (line, "--mode=normal"); line = skip_options (line); /* parse the stuff */ @@ -1293,8 +1293,8 @@ cmd_clear_passphrase (assuan_context_t ctx, char *line) if (!cacheid || !*cacheid || strlen (cacheid) > 50) return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID"); - agent_put_cache (cacheid, opt_agent ? CACHE_MODE_NORMAL : CACHE_MODE_USER, - NULL, 0); + agent_put_cache (cacheid, opt_normal ? CACHE_MODE_NORMAL : CACHE_MODE_USER, + NULL, 0); return 0; } commit 0706511b6d10561e97381554e404a960538ee342 Author: Ben Kibbey <bjk at luxsci.net> Date: Sun Feb 27 08:35:16 2011 -0500 Added CLEAR_PASSPHRASE option --agent to search the cache for a cacheid with a mode of CACHE_MODE_NORMAL. These cache modes are created with PKDECRYPT. diff --git a/agent/command.c b/agent/command.c index 330c851..63f59d4 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1267,15 +1267,21 @@ cmd_get_passphrase (assuan_context_t ctx, char *line) static const char hlp_clear_passphrase[] = - "CLEAR_PASSPHRASE <cache_id>\n" + "CLEAR_PASSPHRASE [--agent] <cache_id>\n" "\n" "may be used to invalidate the cache entry for a passphrase. The\n" - "function returns with OK even when there is no cached passphrase."; + "function returns with OK even when there is no cached passphrase.\n" + "The --agent option is used to clear an entry for a cacheid added by\n" + "the agent.\n"; static gpg_error_t cmd_clear_passphrase (assuan_context_t ctx, char *line) { char *cacheid = NULL; char *p; + int opt_agent; + + opt_agent = has_option (line, "--agent"); + line = skip_options (line); /* parse the stuff */ for (p=line; *p == ' '; p++) @@ -1287,7 +1293,8 @@ cmd_clear_passphrase (assuan_context_t ctx, char *line) if (!cacheid || !*cacheid || strlen (cacheid) > 50) return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of cacheID"); - agent_put_cache (cacheid, CACHE_MODE_USER, NULL, 0); + agent_put_cache (cacheid, opt_agent ? CACHE_MODE_NORMAL : CACHE_MODE_USER, + NULL, 0); return 0; } commit 2165925baeaa42f611b75718f3b2e9b37c53e417 Author: Werner Koch <wk at gnupg.org> Date: Wed Mar 2 09:04:16 2011 +0100 Fix doc/Makefile target online diff --git a/doc/Makefile.am b/doc/Makefile.am index 17539fc..9c15c64 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -6,12 +6,12 @@ # 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 <http://www.gnu.org/licenses/>. @@ -44,9 +44,9 @@ info_TEXINFOS = gnupg.texi dist_pkgdata_DATA = qualified.txt com-certs.pem $(helpfiles) nobase_dist_doc_DATA = FAQ DETAILS HACKING TRANSLATE OpenPGP KEYSERVER \ - $(examples) + $(examples) -#dist_html_DATA = +#dist_html_DATA = gnupg_TEXINFOS = \ @@ -129,16 +129,16 @@ gnupg.texi : $(gnupg_TEXINFOS) online: gnupg.html gnupg.pdf set -e; \ echo "Uploading current manuals to www.gnupg.org ..."; \ - cp gnupg-logo.png gnupg.html/; \ + cp $(srcdir)/gnupg-logo.png gnupg.html/; \ user=werner ; dashdevel="" ; \ - if echo "@PACKAGE_VERSION@" | grep -- "-svn" >/dev/null; then \ + if echo "@PACKAGE_VERSION@" | grep -- "-git" >/dev/null; then \ dashdevel="-devel" ; \ else \ rsync -v gnupg.pdf $${user}@cvs.gnupg.org:webspace/manuals/ ; \ fi ; \ cd gnupg.html ; \ rsync -vr --exclude='.svn' . \ - $${user}@cvs.gnupg.org:webspace/manuals/gnupg$${dashdevel}/ + $${user}@cvs.gnupg.org:webspace/manuals/gnupg$${dashdevel}/ # Note that you need a recent version of emacs23 with org-mode 7.01h faq.txt faq.html: faq.org @@ -160,4 +160,3 @@ faq-online: faq.txt faq.html scp faq.html $${user}@ftp.gnupg.org:webspace/manuals/GnuPG-FAQ.html ; \ scp faq.txt $${user}@ftp.gnupg.org:gcrypt/gnupg/GnuPG-FAQ.txt ; \ echo "...ready" - ----------------------------------------------------------------------- Summary of changes: agent/ChangeLog | 8 +++++- agent/command.c | 69 +++++++++++++++++++++++++++++++++++++++++++------------ doc/Makefile.am | 15 +++++------ 3 files changed, 68 insertions(+), 24 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 2 16:04:19 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 02 Mar 2011 16:04:19 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-24-g1c09def Message-ID: <E1Pumu9-0007oi-OP@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 1c09def22d97de3738a2bec4970504bfc155680b (commit) from b7f74f5b46a28d200627ab9b67763891190a8e15 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1c09def22d97de3738a2bec4970504bfc155680b Author: Werner Koch <wk at gnupg.org> Date: Wed Mar 2 15:35:10 2011 +0100 Fix usage of SHA-2 algorithm with OpenPGP cards. This was a regression in 2.1 introduced due to having the agent do the signing in contrast to the old "SCD PKSIGN" command which accesses the scdaemon directly and passed the hash algorithm. The hash algorithm is used by app-openpgp.c only for a sanity check. diff --git a/agent/ChangeLog b/agent/ChangeLog index 783089e..7ec8789 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,8 @@ +2011-03-02 Werner Koch <wk at g10code.com> + + * call-scd.c (hash_algo_option): New. + (agent_card_pksign): Use it with PKSIGN. + 2011-03-02 Ben Kibbey <bjk at luxsci.net> (wk) * command.c (cmd_clear_passphrase): Add option --mode=normal. diff --git a/agent/agent.h b/agent/agent.h index 1ec736c..3319c36 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -365,6 +365,7 @@ int agent_card_pksign (ctrl_t ctrl, const char *keyid, int (*getpin_cb)(void *, const char *, char*, size_t), void *getpin_cb_arg, + int mdalgo, const unsigned char *indata, size_t indatalen, unsigned char **r_buf, size_t *r_buflen); int agent_card_pkdecrypt (ctrl_t ctrl, diff --git a/agent/call-scd.c b/agent/call-scd.c index 40770ab..710589f 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -796,13 +796,33 @@ inq_needpin (void *opaque, const char *line) } +/* Helper returning a command option to describe the used hash + algorithm. See scd/command.c:cmd_pksign. */ +static const char * +hash_algo_option (int algo) +{ + switch (algo) + { + case GCRY_MD_MD5 : return "--hash=md5"; + case GCRY_MD_RMD160: return "--hash=rmd160"; + case GCRY_MD_SHA1 : return "--hash=sha1"; + case GCRY_MD_SHA224: return "--hash=sha224"; + case GCRY_MD_SHA256: return "--hash=sha256"; + case GCRY_MD_SHA384: return "--hash=sha384"; + case GCRY_MD_SHA512: return "--hash=sha512"; + default: return ""; + } +} -/* Create a signature using the current card */ + +/* Create a signature using the current card. MDALGO is either 0 or + gives the digest algorithm. */ int agent_card_pksign (ctrl_t ctrl, const char *keyid, int (*getpin_cb)(void *, const char *, char*, size_t), void *getpin_cb_arg, + int mdalgo, const unsigned char *indata, size_t indatalen, unsigned char **r_buf, size_t *r_buflen) { @@ -837,9 +857,11 @@ agent_card_pksign (ctrl_t ctrl, inqparm.getpin_cb = getpin_cb; inqparm.getpin_cb_arg = getpin_cb_arg; inqparm.passthru = 0; - snprintf (line, DIM(line)-1, - ctrl->use_auth_call? "PKAUTH %s":"PKSIGN %s", keyid); - line[DIM(line)-1] = 0; + if (ctrl->use_auth_call) + snprintf (line, sizeof line, "PKAUTH %s", keyid); + else + snprintf (line, sizeof line, "PKSIGN %s %s", + hash_algo_option (mdalgo), keyid); rc = assuan_transact (ctrl->scd_local->ctx, line, membuf_data_cb, &data, inq_needpin, &inqparm, diff --git a/agent/divert-scd.c b/agent/divert-scd.c index f4787b5..f176a6b 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -347,7 +347,7 @@ divert_pksign (ctrl_t ctrl, int save = ctrl->use_auth_call; ctrl->use_auth_call = 1; rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, - digest, digestlen, &sigval, &siglen); + algo, digest, digestlen, &sigval, &siglen); ctrl->use_auth_call = save; } else @@ -359,7 +359,7 @@ divert_pksign (ctrl_t ctrl, if (!rc) { rc = agent_card_pksign (ctrl, kid, getpin_cb, ctrl, - data, ndata, &sigval, &siglen); + algo, data, ndata, &sigval, &siglen); xfree (data); } } diff --git a/g10/ChangeLog b/g10/ChangeLog index 0eebbef..65e97a9 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,8 @@ +2011-03-02 Werner Koch <wk at g10code.com> + + * call-agent.c (agent_scd_pksign, agent_scd_pkdecrypt) + (hash_algo_option): Remove these unused functions. + 2011-02-10 Werner Koch <wk at g10code.com> * seskey.c (encode_md_value): Change last fix to avoid a diff --git a/g10/call-agent.c b/g10/call-agent.c index 6333586..03ea168 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -914,144 +914,6 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length) } -/* Helper returning a command option to describe the used hash - algorithm. See scd/command.c:cmd_pksign. */ -static const char * -hash_algo_option (int algo) -{ - switch (algo) - { - case GCRY_MD_RMD160: return "--hash=rmd160"; - case GCRY_MD_SHA1 : return "--hash=sha1"; - case GCRY_MD_SHA224: return "--hash=sha224"; - case GCRY_MD_SHA256: return "--hash=sha256"; - case GCRY_MD_SHA384: return "--hash=sha384"; - case GCRY_MD_SHA512: return "--hash=sha512"; - case GCRY_MD_MD5 : return "--hash=md5"; - default: return ""; - } -} - - -/* Send a sign command to the scdaemon via gpg-agent's pass thru - mechanism. */ -int -agent_scd_pksign (const char *serialno, int hashalgo, - const unsigned char *indata, size_t indatalen, - unsigned char **r_buf, size_t *r_buflen) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - membuf_t data; - size_t len; - - /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */ - - *r_buf = NULL; - *r_buflen = 0; - - rc = start_agent (NULL, 1); - if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT - || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED) - rc = 0; /* We check later. */ - if (rc) - return rc; - - if (indatalen*2 + 50 > DIM(line)) - return gpg_error (GPG_ERR_GENERAL); - - rc = select_openpgp (serialno); - if (rc) - return rc; - - strcpy (line, "SCD SETDATA "); - bin2hex (indata, indatalen, line + strlen (line)); - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return rc; - - init_membuf (&data, 1024); - /* if (!hashalgo) /\* Temporary test hack. *\/ */ - /* snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno); */ - /* else */ - snprintf (line, DIM(line)-1, "SCD PKSIGN %s %s", - hash_algo_option (hashalgo), serialno); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data, - default_inq_cb, NULL, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - } - else - *r_buf = get_membuf (&data, r_buflen); - - status_sc_op_failure (rc); - return rc; -} - - -/* Decrypt INDATA of length INDATALEN using the card identified by - SERIALNO. Return the plaintext in a nwly allocated buffer stored - at the address of R_BUF. - - Note, we currently support only RSA or more exactly algorithms - taking one input data element. */ -int -agent_scd_pkdecrypt (const char *serialno, - const unsigned char *indata, size_t indatalen, - unsigned char **r_buf, size_t *r_buflen) -{ - int rc; - char line[ASSUAN_LINELENGTH]; - membuf_t data; - size_t len; - - *r_buf = NULL; - rc = start_agent (NULL, 1); - if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT - || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED) - rc = 0; /* We check later. */ - if (rc) - return rc; - - /* FIXME: use secure memory where appropriate */ - if (indatalen*2 + 50 > DIM(line)) - return gpg_error (GPG_ERR_GENERAL); - - rc = select_openpgp (serialno); - if (rc) - return rc; - - strcpy (line, "SCD SETDATA "); - bin2hex (indata, indatalen, line + strlen (line)); - - rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return rc; - - init_membuf (&data, 1024); - snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno); - line[DIM(line)-1] = 0; - rc = assuan_transact (agent_ctx, line, - membuf_data_cb, &data, - default_inq_cb, NULL, NULL, NULL); - if (rc) - { - xfree (get_membuf (&data, &len)); - } - else - { - *r_buf = get_membuf (&data, r_buflen); - if (!*r_buf) - rc = gpg_error (GPG_ERR_ENOMEM); - } - - status_sc_op_failure (rc); - return rc; -} - /* Send a READCERT command to the SCdaemon. */ diff --git a/g10/call-agent.h b/g10/call-agent.h index 337847d..1e7e15a 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -98,16 +98,6 @@ int agent_scd_writekey (int keyno, const char *serialno, int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force, const char *serialno, u32 createtime); -/* Send a PKSIGN command to the SCdaemon. */ -int agent_scd_pksign (const char *keyid, int hashalgo, - const unsigned char *indata, size_t indatalen, - unsigned char **r_buf, size_t *r_buflen); - -/* Send a PKDECRYPT command to the SCdaemon. */ -int agent_scd_pkdecrypt (const char *serialno, - const unsigned char *indata, size_t indatalen, - unsigned char **r_buf, size_t *r_buflen); - /* Send a READKEY command to the SCdaemon. */ int agent_scd_readcert (const char *certidstr, void **r_buf, size_t *r_buflen); ----------------------------------------------------------------------- Summary of changes: agent/ChangeLog | 5 ++ agent/agent.h | 1 + agent/call-scd.c | 30 ++++++++++-- agent/divert-scd.c | 4 +- g10/ChangeLog | 5 ++ g10/call-agent.c | 138 ---------------------------------------------------- g10/call-agent.h | 10 ---- 7 files changed, 39 insertions(+), 154 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 2 17:22:36 2011 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 02 Mar 2011 17:22:36 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-25-g682da55 Message-ID: <E1Puo7t-000108-Kt@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 682da55aa985afcbae3b16686ad96bb77ad87adf (commit) from 1c09def22d97de3738a2bec4970504bfc155680b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 682da55aa985afcbae3b16686ad96bb77ad87adf Author: NIIBE Yutaka <gniibe at fsij.org> Date: Thu Jan 13 16:38:31 2011 +0900 fix wLangId in ccid-driver.c This is not a part of pin pad support series of mine. As I found the bug while I am preparing the patches, I report this. As CCID protocol is little endian, wLangId of US English = 0x0409 is represented as two bytes of 0x09 then 0x04. It is really confusing that the code like following is floating around: pin_verify -> wLangId = HOST_TO_CCID_16(0x0904); But, it is 0x0409 (not 0x0904). It is defined in the documentation: http://www.usb.org/developers/docs/USB_LANGIDs.pdf and origin of this table is Microsoft. We can see it at: http://msdn.microsoft.com/en-us/library/bb165625%28VS.80%29.aspx Yes, it would be better not to hard-code 0x0409. It would be better to try current locale of the user, or to use the first entry of string descriptor. I don't have time to implement such a thing... diff --git a/scd/ccid-driver.c b/scd/ccid-driver.c index 2abb6b5..eb19625 100644 --- a/scd/ccid-driver.c +++ b/scd/ccid-driver.c @@ -3136,8 +3136,8 @@ ccid_transceive_secure (ccid_driver_t handle, if (pinlen_min && pinlen_max && pinlen_min == pinlen_max) msg[17] |= 0x01; /* Max size reached. */ msg[18] = 0xff; /* bNumberMessage: Default. */ - msg[19] = 0x04; /* wLangId-High. */ - msg[20] = 0x09; /* wLangId-Low: English FIXME: use the first entry. */ + msg[19] = 0x09; /* wLangId-Low: English FIXME: use the first entry. */ + msg[20] = 0x04; /* wLangId-High. */ msg[21] = 0; /* bMsgIndex. */ /* bTeoProlog follows: */ msg[22] = handle->nonnull_nad? ((1 << 4) | 0): 0; ----------------------------------------------------------------------- Summary of changes: scd/ccid-driver.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 3 15:24:08 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 03 Mar 2011 15:24:08 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-28-gaeb3242 Message-ID: <E1Pv8kd-0004I2-Ic@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via aeb324273afdb1999e2b3ea3471fe28856a6d3b1 (commit) via ea41f5b4c19dade3a89d486ce1c2530ac11226cc (commit) via 892793888e3b328bff032b0b3e8b5098ffeb9b7f (commit) from 682da55aa985afcbae3b16686ad96bb77ad87adf (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit aeb324273afdb1999e2b3ea3471fe28856a6d3b1 Author: Werner Koch <wk at gnupg.org> Date: Thu Mar 3 12:57:31 2011 +0100 Minor code cleanups. * keyid.c (hash_public_key): Remove shadowing NBITS. * misc.c (pubkey_nbits): Replace GCRY_PK_ by PUBKEY_ALGO_. (get_signature_count): Remove warning. diff --git a/g10/ChangeLog b/g10/ChangeLog index cdacc6f..df424a3 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,5 +1,10 @@ 2011-03-03 Werner Koch <wk at g10code.com> + * keyid.c (hash_public_key): Remove shadowing NBITS. + + * misc.c (pubkey_nbits): Replace GCRY_PK_ by PUBKEY_ALGO_. + (get_signature_count): Remove warning. + * armor.c (armor_filter): Don't take a copy of radbuf while writing the checksum. This works around a faulty gcc 4.4 warning. diff --git a/g10/keyid.c b/g10/keyid.c index cbcc971..d08ccee 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -99,7 +99,6 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk) { 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); diff --git a/g10/misc.c b/g10/misc.c index f2ab984..e0c57a1 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -569,7 +569,8 @@ get_signature_count (PKT_public_key *pk) { #ifdef ENABLE_CARD_SUPPORT struct agent_card_info_s info; -#warning fixme: We should check that the correct card has been inserted + + (void)pk; if (!agent_scd_getattr ("SIG-COUNTER",&info)) return info.sig_counter; else @@ -1453,20 +1454,17 @@ pubkey_nbits( int algo, gcry_mpi_t *key ) int rc, nbits; gcry_sexp_t sexp; -#warning FIXME: We are mixing OpenPGP And CGrypt Ids - assert( algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH ); - - if( algo == GCRY_PK_DSA ) { + if( algo == PUBKEY_ALGO_DSA ) { rc = gcry_sexp_build ( &sexp, NULL, "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", key[0], key[1], key[2], key[3] ); } - else if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) { + else if( algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E ) { rc = gcry_sexp_build ( &sexp, NULL, "(public-key(elg(p%m)(g%m)(y%m)))", key[0], key[1], key[2] ); } - else if( algo == GCRY_PK_RSA ) { + else if( is_RSA (algo) ) { rc = gcry_sexp_build ( &sexp, NULL, "(public-key(rsa(n%m)(e%m)))", key[0], key[1] ); commit ea41f5b4c19dade3a89d486ce1c2530ac11226cc Author: Werner Koch <wk at gnupg.org> Date: Thu Mar 3 12:40:54 2011 +0100 Fix faulty gcc warnings diff --git a/g10/ChangeLog b/g10/ChangeLog index 65e97a9..cdacc6f 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,8 @@ +2011-03-03 Werner Koch <wk at g10code.com> + + * armor.c (armor_filter): Don't take a copy of radbuf while + writing the checksum. This works around a faulty gcc 4.4 warning. + 2011-03-02 Werner Koch <wk at g10code.com> * call-agent.c (agent_scd_pksign, agent_scd_pkdecrypt) diff --git a/g10/armor.c b/g10/armor.c index 3948916..43ebb2e 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -1182,21 +1182,20 @@ armor_filter( void *opaque, int control, crc = afx->crc; idx = afx->idx; idx2 = afx->idx2; - for(i=0; i < idx; i++ ) - radbuf[i] = afx->radbuf[i]; if( idx ) { - c = bintoasc[(*radbuf>>2)&077]; + c = bintoasc[(afx->radbuf[0]>>2)&077]; iobuf_put(a, c); if( idx == 1 ) { - c = bintoasc[((*radbuf << 4) & 060) & 077]; + c = bintoasc[((afx->radbuf[0] << 4) & 060) & 077]; iobuf_put(a, c); iobuf_put(a, '='); iobuf_put(a, '='); } else { /* 2 */ - c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077]; + c = bintoasc[(((afx->radbuf[0]<<4)&060) + |((afx->radbuf[1]>>4)&017))&077]; iobuf_put(a, c); - c = bintoasc[((radbuf[1] << 2) & 074) & 077]; + c = bintoasc[((afx->radbuf[1] << 2) & 074) & 077]; iobuf_put(a, c); iobuf_put(a, '='); } diff --git a/sm/ChangeLog b/sm/ChangeLog index 44e4eb3..dc5989a 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,8 @@ +2011-03-03 Werner Koch <wk at g10code.com> + + * base64.c (base64_finish_write): Do not copy to radbuf to get rid + of a faulty gcc 4.4 "used uninitialized" warning. + 2011-03-01 Werner Koch <wk at g10code.com> * certreqgen.c (pSERIAL, pISSUERDN, pNOTBEFORE, pNOTAFTER) diff --git a/sm/base64.c b/sm/base64.c index 1539e2a..4a67d61 100644 --- a/sm/base64.c +++ b/sm/base64.c @@ -484,8 +484,8 @@ plain_writer_cb (void *cb_value, const void *buffer, size_t count) static int base64_finish_write (struct writer_cb_parm_s *parm) { - unsigned char radbuf[4]; - int i, c, idx, quad_count; + unsigned char *radbuf; + int c, idx, quad_count; estream_t stream = parm->stream; if (!parm->wrote_begin) @@ -494,11 +494,10 @@ base64_finish_write (struct writer_cb_parm_s *parm) /* flush the base64 encoding */ idx = parm->base64.idx; quad_count = parm->base64.quad_count; - for (i=0; i < idx; i++) - radbuf[i] = parm->base64.radbuf[i]; - if (idx) { + radbuf = parm->base64.radbuf; + c = bintoasc[(*radbuf>>2)&077]; es_putc (c, stream); if (idx == 1) diff --git a/tools/no-libgcrypt.c b/tools/no-libgcrypt.c index 4967576..9e52566 100644 --- a/tools/no-libgcrypt.c +++ b/tools/no-libgcrypt.c @@ -157,5 +157,6 @@ gcry_create_nonce (void *buffer, size_t length) const char * gcry_cipher_algo_name (int algo) { + (void)algo; return "?"; } commit 892793888e3b328bff032b0b3e8b5098ffeb9b7f Author: Werner Koch <wk at gnupg.org> Date: Thu Mar 3 11:51:04 2011 +0100 Simplify the management of the stream list in estream.c diff --git a/common/ChangeLog b/common/ChangeLog index cebc0ec..6253867 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,14 @@ +2011-03-03 Werner Koch <wk at g10code.com> + + * estream.c (struct estream_list): Rename to estream_list_s and + simplify. A double linked list is overkill for our purpose. + (do_list_add, do_list_remove): Adjust accordingly. + (_es_get_std_stream): Ditto. + (do_list_iterate, estream_iterator_t): Remove; it is used only at + one place. + (es_fflush): Replace iteration function. Also lock each stream + while flushing all streams. + 2011-02-27 Werner Koch <wk at g10code.com> * gettime.c (isotime2epoch): Factor check code out to .. diff --git a/common/estream.c b/common/estream.c index a73d1f2..5b55674 100644 --- a/common/estream.c +++ b/common/estream.c @@ -1,5 +1,5 @@ /* estream.c - Extended Stream I/O Library - * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010 g10 Code GmbH + * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011 g10 Code GmbH * * This file is part of Libestream. * @@ -254,28 +254,26 @@ typedef struct estream_internal *estream_internal_t; #define ESTREAM_UNLOCK(stream) ESTREAM_MUTEX_UNLOCK (stream->intern->lock) #define ESTREAM_TRYLOCK(stream) ESTREAM_MUTEX_TRYLOCK (stream->intern->lock) -/* Stream list. */ - -typedef struct estream_list *estream_list_t; - -struct estream_list +/* A linked list to hold active stream objects. */ +struct estream_list_s { - estream_t car; - estream_list_t cdr; - estream_list_t *prev_cdr; + struct estream_list_s *next; + estream_t stream; /* Entry is not used if NULL. */ }; - +typedef struct estream_list_s *estream_list_t; static estream_list_t estream_list; -static estream_mutex_t estream_list_lock; - -#define ESTREAM_LIST_LOCK ESTREAM_MUTEX_LOCK (estream_list_lock) -#define ESTREAM_LIST_UNLOCK ESTREAM_MUTEX_UNLOCK (estream_list_lock) /* File descriptors registered to be used as the standard file handles. */ static int custom_std_fds[3]; static unsigned char custom_std_fds_valid[3]; +/* A lock object for the estream list and the custom_std_fds array. */ +static estream_mutex_t estream_list_lock; +#define ESTREAM_LIST_LOCK ESTREAM_MUTEX_LOCK (estream_list_lock) +#define ESTREAM_LIST_UNLOCK ESTREAM_MUTEX_UNLOCK (estream_list_lock) + +/* Error code replacements. */ #ifndef EOPNOTSUPP # define EOPNOTSUPP ENOSYS #endif @@ -372,75 +370,63 @@ map_w32_to_errno (DWORD w32_err) */ /* Add STREAM to the list of registered stream objects. If - WITH_LOCKED_LIST is true we assumed that the list of streams is - already locked. */ + WITH_LOCKED_LIST is true it is assumed that the list of streams is + already locked. The implementation is straightforward: We first + look for an unused entry in the list and use that; if none is + available we put a new item at the head. We drawback of the + strategy never to shorten the list is that a one time allocation of + many streams will lead to scanning unused entries later. If that + turns out to be a problem, we may either free some items from the + list or append new entries at the end; or use a table. Returns 0 + on success; on error or non-zero is returned and ERRNO set. */ static int do_list_add (estream_t stream, int with_locked_list) { - estream_list_t list_obj; - int ret; + estream_list_t item; - list_obj = mem_alloc (sizeof (*list_obj)); - if (! list_obj) - ret = -1; - else + if (!with_locked_list) + ESTREAM_LIST_LOCK; + + for (item = estream_list; item && item->stream; item = item->next) + ; + if (!item) { - if (!with_locked_list) - ESTREAM_LIST_LOCK; - list_obj->car = stream; - list_obj->cdr = estream_list; - list_obj->prev_cdr = &estream_list; - if (estream_list) - estream_list->prev_cdr = &list_obj->cdr; - estream_list = list_obj; - if (!with_locked_list) - ESTREAM_LIST_UNLOCK; - ret = 0; + item = mem_alloc (sizeof *item); + if (item) + { + item->next = estream_list; + estream_list = item; + } } + if (item) + item->stream = stream; - return ret; + if (!with_locked_list) + ESTREAM_LIST_UNLOCK; + + return item? 0 : -1; } /* Remove STREAM from the list of registered stream objects. */ static void do_list_remove (estream_t stream, int with_locked_list) { - estream_list_t list_obj; + estream_list_t item; if (!with_locked_list) ESTREAM_LIST_LOCK; - for (list_obj = estream_list; list_obj; list_obj = list_obj->cdr) - if (list_obj->car == stream) + + for (item = estream_list; item; item = item->next) + if (item->stream == stream) { - *list_obj->prev_cdr = list_obj->cdr; - if (list_obj->cdr) - list_obj->cdr->prev_cdr = list_obj->prev_cdr; - mem_free (list_obj); - break; + item->stream = NULL; + break; } + if (!with_locked_list) ESTREAM_LIST_UNLOCK; } -/* Type of an stream-iterator-function. */ -typedef int (*estream_iterator_t) (estream_t stream); - -/* Iterate over list of registered streams, calling ITERATOR for each - of them. */ -static int -do_list_iterate (estream_iterator_t iterator) -{ - estream_list_t list_obj; - int ret = 0; - - ESTREAM_LIST_LOCK; - for (list_obj = estream_list; list_obj; list_obj = list_obj->cdr) - ret |= (*iterator) (list_obj->car); - ESTREAM_LIST_UNLOCK; - - return ret; -} - /* @@ -487,6 +473,14 @@ do_deinit (void) { /* Flush all streams. */ es_fflush (NULL); + + /* We should release the estream_list. However there is one + problem: That list is also used to search for the standard + estream file descriptors. If we would remove the entire list, + any use of es_foo in another atexit function may re-create the + list and the streams with possible undesirable effects. Given + that we don't close the stream either, it should not matter that + we keep the list and let the OS clean it up at process end. */ } @@ -2905,11 +2899,11 @@ _es_get_std_stream (int fd) fd %= 3; /* We only allow 0, 1 or 2 but we don't want to return an error. */ ESTREAM_LIST_LOCK; - for (list_obj = estream_list; list_obj; list_obj = list_obj->cdr) - if (list_obj->car->intern->is_stdstream - && list_obj->car->intern->stdstream_fd == fd) + for (list_obj = estream_list; list_obj; list_obj = list_obj->next) + if (list_obj->stream && list_obj->stream->intern->is_stdstream + && list_obj->stream->intern->stdstream_fd == fd) { - stream = list_obj->car; + stream = list_obj->stream; break; } if (!stream) @@ -3241,8 +3235,20 @@ es_fflush (estream_t stream) ESTREAM_UNLOCK (stream); } else - err = do_list_iterate (do_fflush); + { + estream_list_t item; + err = 0; + ESTREAM_LIST_LOCK; + for (item = estream_list; item; item = item->next) + if (item->stream) + { + ESTREAM_LOCK (item->stream); + err |= do_fflush (item->stream); + ESTREAM_UNLOCK (item->stream); + } + ESTREAM_LIST_UNLOCK; + } return err ? EOF : 0; } ----------------------------------------------------------------------- Summary of changes: common/ChangeLog | 11 ++++ common/estream.c | 138 ++++++++++++++++++++++++++------------------------ g10/ChangeLog | 10 ++++ g10/armor.c | 11 ++-- g10/keyid.c | 1 - g10/misc.c | 12 ++--- sm/ChangeLog | 5 ++ sm/base64.c | 9 ++-- tools/no-libgcrypt.c | 1 + 9 files changed, 113 insertions(+), 85 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 3 16:44:13 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 03 Mar 2011 16:44:13 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-29-g35205e1 Message-ID: <E1PvA07-0005bS-OF@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 35205e13005248178da145944671f28f600be7be (commit) from aeb324273afdb1999e2b3ea3471fe28856a6d3b1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 35205e13005248178da145944671f28f600be7be Author: Werner Koch <wk at gnupg.org> Date: Thu Mar 3 16:16:24 2011 +0100 Print the secret keyinfo stuff with --card-status again. diff --git a/g10/ChangeLog b/g10/ChangeLog index df424a3..9026077 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,5 +1,9 @@ 2011-03-03 Werner Koch <wk at g10code.com> + * keylist.c (print_card_key_info): Re-implement using the agent. + * card-util.c (card_status) [GNUPG_MAJOR_VERSION!=1]: Call + print_card_key_info. + * keyid.c (hash_public_key): Remove shadowing NBITS. * misc.c (pubkey_nbits): Replace GCRY_PK_ by PUBKEY_ALGO_. diff --git a/g10/card-util.c b/g10/card-util.c index 2b7ac74..0ffb18d 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -581,32 +581,34 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen) if ( thefpr && !fpr_is_ff (thefpr) && !get_pubkey_byfprint (pk, thefpr, 20)) { + kbnode_t keyblock = NULL; + print_pubkey_info (fp, pk); #if GNUPG_MAJOR_VERSION == 1 - { - kbnode_t keyblock = NULL; + if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) ) + print_card_key_info (fp, keyblock); + else if ( !get_keyblock_byfprint (&keyblock, thefpr, 20) ) + { + release_kbnode (keyblock); + keyblock = NULL; - if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) ) - print_card_key_info (fp, keyblock); - else if ( !get_keyblock_byfprint (&keyblock, thefpr, 20) ) - { - release_kbnode (keyblock); - keyblock = NULL; - - if (!auto_create_card_key_stub (info.serialno, - info.fpr1valid? info.fpr1:NULL, - info.fpr2valid? info.fpr2:NULL, - info.fpr3valid? info.fpr3:NULL)) - { - if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) ) - print_card_key_info (fp, keyblock); - } - } + if (!auto_create_card_key_stub (info.serialno, + info.fpr1valid? info.fpr1:NULL, + info.fpr2valid? info.fpr2:NULL, + info.fpr3valid? info.fpr3:NULL)) + { + if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) ) + print_card_key_info (fp, keyblock); + } + } - release_kbnode (keyblock); - } -#endif /* GNUPG_MAJOR_VERSION == 1 */ +#else /* GNUPG_MAJOR_VERSION != 1 */ + if (!get_keyblock_byfprint (&keyblock, thefpr, 20)) + print_card_key_info (fp, keyblock); +#endif /* GNUPG_MAJOR_VERSION != 1 */ + + release_kbnode (keyblock); } else tty_fprintf (fp, "[none]\n"); diff --git a/g10/keylist.c b/g10/keylist.c index ba2a954..968aa95 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -180,50 +180,58 @@ print_pubkey_info (estream_t fp, PKT_public_key * pk) void print_card_key_info (estream_t fp, kbnode_t keyblock) { - /* KBNODE node; */ - /* int i; */ -#warning Fixme: Needs to be adjusted to gpg-agent - /* for (node = keyblock; node; node = node->next) */ - /* { */ - /* if (node->pkt->pkttype == PKT_SECRET_KEY */ - /* || (node->pkt->pkttype == PKT_SECRET_SUBKEY)) */ - /* { */ - /* PKT_public_key *pk = node->pkt->pkt.public_key; */ - - /* tty_fprintf (fp, "%s%c %4u%c/%s ", */ - /* node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb", */ - /* (sk->protect.s2k.mode == 1001) ? '#' : */ - /* (sk->protect.s2k.mode == 1002) ? '>' : ' ', */ - /* nbits_from_sk (sk), */ - /* pubkey_letter (sk->pubkey_algo), keystr_from_sk (sk)); */ - /* tty_fprintf (fp, _("created: %s"), datestr_from_sk (sk)); */ - /* tty_fprintf (fp, " "); */ - /* tty_fprintf (fp, _("expires: %s"), expirestr_from_sk (sk)); */ - /* if (sk->is_protected && sk->protect.s2k.mode == 1002) */ - /* { */ - /* tty_fprintf (fp, "\n "); */ - /* tty_fprintf (fp, _("card-no: ")); */ - /* if (sk->protect.ivlen == 16 */ - /* && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6)) */ - /* { */ - /* /\* This is an OpenPGP card. *\/ */ - /* for (i = 8; i < 14; i++) */ - /* { */ - /* if (i == 10) */ - /* tty_fprintf (fp, " "); */ - /* tty_fprintf (fp, "%02X", sk->protect.iv[i]); */ - /* } */ - /* } */ - /* else */ - /* { */ - /* /\* Something is wrong: Print all. *\/ */ - /* for (i = 0; i < sk->protect.ivlen; i++) */ - /* tty_fprintf (fp, "%02X", sk->protect.iv[i]); */ - /* } */ - /* } */ - /* tty_fprintf (fp, "\n"); */ - /* } */ - /* } */ + kbnode_t node; + char *hexgrip; + char *serialno; + int s2k_char; + + for (node = keyblock; node; node = node->next) + { + if (node->pkt->pkttype == PKT_PUBLIC_KEY + || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) + { + int rc; + PKT_public_key *pk = node->pkt->pkt.public_key; + + serialno = NULL; + rc = hexkeygrip_from_pk (pk, &hexgrip); + if (rc) + { + log_error ("error computing a keygrip: %s\n", gpg_strerror (rc)); + s2k_char = '?'; + } + else if (!agent_get_keyinfo (NULL, hexgrip, &serialno)) + s2k_char = serialno? '>':' '; + else + s2k_char = '#'; /* Key not found. */ + + tty_fprintf (fp, "%s%c %4u%c/%s ", + node->pkt->pkttype == PKT_PUBLIC_KEY ? "sec" : "ssb", + s2k_char, nbits_from_pk (pk), + pubkey_letter (pk->pubkey_algo), keystr_from_pk (pk)); + tty_fprintf (fp, _("created: %s"), datestr_from_pk (pk)); + tty_fprintf (fp, " "); + tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk)); + if (serialno) + { + tty_fprintf (fp, "\n "); + tty_fprintf (fp, _("card-no: ")); + if (strlen (serialno) == 32 + && !strncmp (serialno, "D27600012401", 12)) + { + /* This is an OpenPGP card. Print the relevant part. */ + /* Example: D2760001240101010001000003470000 */ + /* xxxxyyyyyyyy */ + tty_fprintf (fp, "%.*s %.*s", 4, serialno+16, 8, serialno+20); + } + else + tty_fprintf (fp, "%s", serialno); + } + tty_fprintf (fp, "\n"); + xfree (hexgrip); + xfree (serialno); + } + } } #endif /*ENABLE_CARD_SUPPORT*/ ----------------------------------------------------------------------- Summary of changes: g10/ChangeLog | 4 ++ g10/card-util.c | 48 ++++++++++++++------------- g10/keylist.c | 96 +++++++++++++++++++++++++++++------------------------- 3 files changed, 81 insertions(+), 67 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 3 19:00:48 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 03 Mar 2011 19:00:48 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-30-gb786f0e Message-ID: <E1PvC8I-0008E8-GW@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via b786f0e12b93d8d61eea18c934f5731fe86402d3 (commit) from 35205e13005248178da145944671f28f600be7be (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b786f0e12b93d8d61eea18c934f5731fe86402d3 Author: Werner Koch <wk at gnupg.org> Date: Thu Mar 3 18:35:08 2011 +0100 New agent option pinentry-mode. This provides the framework and implements the ask, cancel and error. loopback will be implemented later. diff --git a/agent/ChangeLog b/agent/ChangeLog index 7ec8789..de5f3da 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,16 @@ +2011-03-03 Werner Koch <wk at g10code.com> + + * gpg-agent.c: Add option --allow-loopback-pinentry. + * command.c (option_handler): Add option pinentry-mode. + * agent.h (pinentry_mode_t): New enum. + (struct server_local_s): Add PINENTRY_MODE. + (struct opt): Add ALLOW_LOOPBACK_PINENTRY. + * call-pinentry.c (agent_askpin): Implement ask, cancel and error + pinentry modes. + (agent_get_passphrase, agent_get_confirmation): Ditto. + (agent_show_message): Return cancel if pinentry mode is not "ask". + (agent_popup_message_start): Ditto. + 2011-03-02 Werner Koch <wk at g10code.com> * call-scd.c (hash_algo_option): New. diff --git a/agent/agent.h b/agent/agent.h index 3319c36..3e01897 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -45,6 +45,18 @@ /* Maximum length of a digest. */ #define MAX_DIGEST_LEN 64 + +/* Values for the pinentry mode. */ +typedef enum + { + PINENTRY_MODE_ASK = 0, /* Ask via pinentry (default). */ + PINENTRY_MODE_CANCEL, /* Always return a cancel error. */ + PINENTRY_MODE_ERROR, /* Return error code for no pinentry. */ + PINENTRY_MODE_LOOPBACK,/* Use an inquiry to get the value. */ + } +pinentry_mode_t; + + /* A large struct name "opt" to keep global flags */ struct { @@ -67,7 +79,6 @@ struct char *startup_lc_ctype; char *startup_lc_messages; - const char *pinentry_program; /* Filename of the program to start as pinentry. */ const char *scdaemon_program; /* Filename of the program to handle @@ -105,6 +116,7 @@ struct int ignore_cache_for_signing; int allow_mark_trusted; int allow_preset_passphrase; + int allow_loopback_pinentry; int keep_tty; /* Don't switch the TTY (for pinentry) on request */ int keep_display; /* Don't switch the DISPLAY (for pinentry) on request */ int ssh_support; /* Enable ssh-agent emulation. */ @@ -149,6 +161,9 @@ struct server_control_s char *lc_ctype; char *lc_messages; + /* The current pinentry mode. */ + pinentry_mode_t pinentry_mode; + struct { int algo; unsigned char value[MAX_DIGEST_LEN]; diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index c570e38..4c30f6d 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -742,6 +742,14 @@ agent_askpin (ctrl_t ctrl, if (opt.batch) return 0; /* fixme: we should return BAD PIN */ + if (ctrl->pinentry_mode != PINENTRY_MODE_ASK) + { + if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL) + return gpg_error (GPG_ERR_CANCELED); + /*FIXME: Implement loopback mode. */ + return gpg_error (GPG_ERR_NO_PIN_ENTRY); + } + if (!pininfo || pininfo->max_length < 1) return gpg_error (GPG_ERR_INV_VALUE); if (!desc_text && pininfo->min_digits) @@ -895,6 +903,14 @@ agent_get_passphrase (ctrl_t ctrl, if (opt.batch) return gpg_error (GPG_ERR_BAD_PASSPHRASE); + if (ctrl->pinentry_mode != PINENTRY_MODE_ASK) + { + if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL) + return gpg_error (GPG_ERR_CANCELED); + + return gpg_error (GPG_ERR_NO_PIN_ENTRY); + } + rc = start_pinentry (ctrl); if (rc) return rc; @@ -981,6 +997,14 @@ agent_get_confirmation (ctrl_t ctrl, int rc; char line[ASSUAN_LINELENGTH]; + if (ctrl->pinentry_mode != PINENTRY_MODE_ASK) + { + if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL) + return gpg_error (GPG_ERR_CANCELED); + + return gpg_error (GPG_ERR_NO_PIN_ENTRY); + } + rc = start_pinentry (ctrl); if (rc) return rc; @@ -1046,7 +1070,7 @@ agent_get_confirmation (ctrl_t ctrl, /* Pop up the PINentry, display the text DESC and a button with the - text OK_BTN (which may be NULL to use the default of "OK") and waut + text OK_BTN (which may be NULL to use the default of "OK") and wait for the user to hit this button. The return value is not relevant. */ int @@ -1055,6 +1079,9 @@ agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn) int rc; char line[ASSUAN_LINELENGTH]; + if (ctrl->pinentry_mode != PINENTRY_MODE_ASK) + return gpg_error (GPG_ERR_CANCELED); + rc = start_pinentry (ctrl); if (rc) return rc; @@ -1123,6 +1150,9 @@ agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn) char line[ASSUAN_LINELENGTH]; pth_attr_t tattr; + if (ctrl->pinentry_mode != PINENTRY_MODE_ASK) + return gpg_error (GPG_ERR_CANCELED); + rc = start_pinentry (ctrl); if (rc) return rc; diff --git a/agent/command.c b/agent/command.c index 79b9b97..b4b9b9e 100644 --- a/agent/command.c +++ b/agent/command.c @@ -2402,6 +2402,24 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0; else if (!strcmp (key, "allow-pinentry-notify")) ctrl->server_local->allow_pinentry_notify = 1; + else if (!strcmp (key, "pinentry-mode")) + { + if (!strcmp (value, "ask") || !strcmp (value, "default")) + ctrl->pinentry_mode = PINENTRY_MODE_ASK; + else if (!strcmp (value, "cancel")) + ctrl->pinentry_mode = PINENTRY_MODE_CANCEL; + else if (!strcmp (value, "error")) + ctrl->pinentry_mode = PINENTRY_MODE_ERROR; + else if (!strcmp (value, "loopback")) + { + if (opt.allow_loopback_pinentry) + ctrl->pinentry_mode = PINENTRY_MODE_LOOPBACK; + else + err = gpg_error (GPG_ERR_NOT_SUPPORTED); + } + else + err = gpg_error (GPG_ERR_INV_VALUE); + } else err = gpg_error (GPG_ERR_UNKNOWN_OPTION); diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index e5af91e..c64b32f 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -105,6 +105,7 @@ enum cmd_and_opt_values oIgnoreCacheForSigning, oAllowMarkTrusted, oAllowPresetPassphrase, + oAllowLoopbackPinentry, oKeepTTY, oKeepDISPLAY, oSSHSupport, @@ -179,6 +180,8 @@ static ARGPARSE_OPTS opts[] = { N_("allow clients to mark keys as \"trusted\"")}, { oAllowPresetPassphrase, "allow-preset-passphrase", 0, N_("allow presetting passphrase")}, + { oAllowLoopbackPinentry, "allow-loopback-pinentry", 0, + N_("allow presetting passphrase")}, { oSSHSupport, "enable-ssh-support", 0, N_("enable ssh-agent emulation") }, { oWriteEnvFile, "write-env-file", 2|8, N_("|FILE|write environment settings also to FILE")}, @@ -549,6 +552,8 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) case oAllowPresetPassphrase: opt.allow_preset_passphrase = 1; break; + case oAllowLoopbackPinentry: opt.allow_loopback_pinentry = 1; break; + default: return 0; /* not handled */ } diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index cb5f7d7..280670b 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -2,7 +2,7 @@ @c This is part of the GnuPG manual. @c For copying conditions, see the file gnupg.texi. - at c Note that we use this texinfo file for all versions of GnuPG: + at c Note that we use this texinfo file for all versions of GnuPG: @c 2.0 and 2.1. The macro "gpgtwoone" controls parts which are only @c valid for GnuPG 2.1 and later. @@ -26,23 +26,23 @@ .IR dir ] .RB [ \-\-options .IR file ] -.RI [ options ] +.RI [ options ] .br .B gpg-agent .RB [ \-\-homedir .IR dir ] .RB [ \-\-options .IR file ] -.RI [ options ] -.B \-\-server +.RI [ options ] +.B \-\-server .br .B gpg-agent .RB [ \-\-homedir .IR dir ] .RB [ \-\-options .IR file ] -.RI [ options ] -.B \-\-daemon +.RI [ options ] +.B \-\-daemon .RI [ command_line ] @end ifset @@ -106,7 +106,7 @@ fi It reads the data out of the file and exports the variables. If you don't use Secure Shell, you don't need the last two export statements. @end ifclear - + @noindent You should always add the following lines to your @code{.bashrc} or whatever initialization file is used for all shell invocations: @@ -235,7 +235,7 @@ a numeric value or a keyword: @item none No debugging at all. A value of less than 1 may be used instead of the keyword. - at item basic + at item basic Some basic debug messages. A value between 1 and 2 may be used instead of the keyword. @item advanced @@ -263,8 +263,8 @@ usual C-Syntax. The currently defined bits are: @table @code @item 0 (1) X.509 or OpenPGP protocol related data - at item 1 (2) -values of big number integers + at item 1 (2) +values of big number integers @item 2 (4) low level crypto operations @item 5 (32) @@ -348,6 +348,12 @@ Allow clients to mark keys as trusted, i.e. put them into the @file{trustlist.txt} file. This is by default not allowed to make it harder for users to inadvertently accept Root-CA keys. + at anchor{option --allow-loopback-pinentry} + at item --allow-loopback-pinentry + at opindex allow-loopback-pinentry +Allow clients to use the loopback pinentry features; see the option + at option{pinentry-mode} for details. + @item --ignore-cache-for-signing @opindex ignore-cache-for-signing This option will let @command{gpg-agent} bypass the passphrase cache for all @@ -398,7 +404,7 @@ to 1. Check the passphrase against the pattern given in @var{file}. When entering a new passphrase matching one of these pattern a warning will be displayed. @var{file} should be an absolute filename. The default is -not to use any pattern file. +not to use any pattern file. Security note: It is known that checking a passphrase against a list of pattern or even against a complete dictionary is not very effective to @@ -408,7 +414,7 @@ behavior and optionally to run a passphrase cracker regularly on all users passphrases to catch the very simple ones. @item --max-passphrase-days @var{n} - at opindex max-passphrase-days + at opindex max-passphrase-days Ask the user to change the passphrase if @var{n} days have passed since the last change. With @option{--enforce-passphrase-constraints} set the user may not bypass this check. @@ -477,10 +483,10 @@ option has been enabled. @itemx --lc-ctype @var{string} @itemx --lc-messages @var{string} @itemx --xauthority @var{string} - at opindex display - at opindex ttyname - at opindex ttytype - at opindex lc-ctype + at opindex display + at opindex ttyname + at opindex ttytype + at opindex lc-ctype @opindex lc-messages @opindex xauthority These options are used with the server mode to pass localization @@ -563,7 +569,7 @@ agent. By default they may all be found in the current home directory two dashes may not be entered and the option may not be abbreviated. This file is also read after a @code{SIGHUP} however only a few options will actually have an effect. This default name may be - changed on the command line (@pxref{option --options}). + changed on the command line (@pxref{option --options}). You should backup this file. @item trustlist.txt @@ -576,21 +582,21 @@ agent. By default they may all be found in the current home directory allows to cut and paste the fingerprint from a key listing output. If the line is prefixed with a @code{!} the key is explicitly marked as not trusted. - + Here is an example where two keys are marked as ultimately trusted and one as not trusted: - + @example # CN=Wurzel ZS 3,O=Intevation GmbH,C=DE A6935DD34EF3087973C706FC311AA2CCF733765B S - + # CN=PCA-1-Verwaltung-02/O=PKI-1-Verwaltung/C=DE - DC:BD:69:25:48:BD:BB:7E:31:6E:BB:80:D3:00:80:35:D4:F8:A6:CD S + DC:BD:69:25:48:BD:BB:7E:31:6E:BB:80:D3:00:80:35:D4:F8:A6:CD S # CN=Root-CA/O=Schlapphuete/L=Pullach/C=DE !14:56:98:D3:FE:9C:CA:5A:31:6E:BC:81:D3:11:4E:00:90:A3:44:C2 S @end example - + Before entering a key into this file, you need to ensure its authenticity. How to do this depends on your organisation; your administrator might have already entered those keys which are deemed @@ -625,7 +631,7 @@ fails, try again using the chain validation model. @end table - + @item sshcontrol @cindex sshcontrol This file is used when support for the secure shell agent protocol has @@ -641,11 +647,11 @@ optional field for arbitrary flags. A non-zero TTL overrides the global default as set by @option{--default-cache-ttl-ssh}. The keygrip may be prefixed with a @code{!} to disable an entry entry. - + The following example lists exactly one key. Note that keys available through a OpenPGP smartcard in the active smartcard reader are implicitly added to this list; i.e. there is no need to list them. - + @example # Key added on 2005-02-25 15:08:29 5A6592BF45DC73BD876874A28FD4639282E29B52 0 @@ -675,7 +681,7 @@ a small helper script is provided to create these files (@pxref{addgnupghome}). @node Agent Signals @section Use of some signals. A running @command{gpg-agent} may be controlled by signals, i.e. using -the @command{kill} command to send a signal to the process. +the @command{kill} command to send a signal to the process. Here is a list of supported signals: @@ -714,7 +720,7 @@ This signal is used for internal purposes. @end table - at c + at c @c Examples @c @mansect examples @@ -757,7 +763,7 @@ and add something like (for Bourne shells) @noindent to your shell initialization file (e.g. @file{~/.bashrc}). - at c + at c @c Assuan Protocol @c @manpause @@ -800,6 +806,7 @@ secret keys. * Agent UPDATESTARTUPTTY:: Change the Standard Display * Agent GETEVENTCOUNTER:: Get the Event Counters * Agent GETINFO:: Return information about the process +* Agent OPTION:: Set options for the session @end menu @node Agent PKDECRYPT @@ -831,13 +838,13 @@ text. C: D xxxx) C: END @end example - + Please note that the server may send status info lines while reading the data lines from the client. The data send is a SPKI like S-Exp with this structure: @example - (enc-val + (enc-val (<algo> (<param_name1> <mpi>) ... @@ -850,20 +857,20 @@ the parameters depend on the algorithm. The agent does return an error if there is an inconsistency. If the decryption was successful the decrypted data is returned by -means of "D" lines. +means of "D" lines. Here is an example session: @example C: PKDECRYPT S: INQUIRE CIPHERTEXT - C: D (enc-val elg (a 349324324) + C: D (enc-val elg (a 349324324) C: D (b 3F444677CA))) C: END S: # session key follows S: D (value 1234567890ABCDEF0) S: OK descryption successful - at end example + at end example @node Agent PKSIGN @@ -911,8 +918,8 @@ different algorithms. The agent does then some checks, asks for the passphrase and as a result the server returns the signature as an SPKI like S-expression in "D" lines: - at example - (sig-val + at example + (sig-val (<algo> (<param_name1> <mpi>) ... @@ -960,7 +967,7 @@ option allows to choose the storage location. To get the secret key out of the PSE, a special export tool has to be used. @example - GENKEY + GENKEY @end example Invokes the key generation process and the server will then inquire @@ -1095,13 +1102,13 @@ Known sequences with the pattern @@foo@@ are replaced according to this table: @table @code - at item @@FPR16@@ + at item @@FPR16@@ Format the fingerprint according to gpg rules for a v3 keys. - at item @@FPR20@@ + at item @@FPR20@@ Format the fingerprint according to gpg rules for a v4 keys. @item @@FPR@@ Choose an appropriate format to format the fingerprint. - at item @@@@ + at item @@@@ Replaced by a single @code{@@} @end table @@ -1123,7 +1130,7 @@ arguments the agent returns a cached passphrase or an error. By convention either the hexified fingerprint of the key shall be used for @var{cache_id} or an arbitrary string prefixed with the name of the calling application and a colon: Like @code{gpg:somestring}. - + @var{error_message} is either a single @code{X} for no error message or a string to be shown as an error message like (e.g. "invalid passphrase"). Blanks must be percent escaped or replaced by @code{+}'. @@ -1147,7 +1154,7 @@ has been found in the cache. If the option @option{--no-ask} is used and the passphrase is not in the cache the user will not be asked to enter a passphrase but the error -code @code{GPG_ERR_NO_DATA} is returned. +code @code{GPG_ERR_NO_DATA} is returned. If the option @option{--qualitybar} is used and a minimum passphrase length has been configured, a visual indication of the entered @@ -1279,11 +1286,75 @@ Return the name of the socket used for SSH connections. If SSH support has not been enabled the error @code{GPG_ERR_NO_DATA} will be returned. @end table + at node Agent OPTION + at subsection Set options for the session + +Here is a list of session options which are not yet described with +other commands. The general syntax for an Assuan option is: + + at smallexample +OPTION @var{key}=@var{value} + at end smallexample + + at noindent +Supported @var{key}s are: + + at table @code + at item agent-awareness +This may be used to tell gpg-agent of which gpg-agent version the +client is aware of. gpg-agent uses this information to enable +features which might break older clients. + + at item putenv +Change the session's environment to be used for the +Pinentry. Valid values are: + + @table @code + @item @var{name} + Delete envvar @var{name} + @item @var{name}= + Set envvar @var{name} to the empty string + @item @var{name}=@var{value} + Set envvar @var{name} to the string @var{value}. + @end table + + at item use-cache-for-signing +See Assuan command @code{PKSIGN}. + + at item allow-pinentry-notify +This does not need any value. It is used to enable the +PINENTRY_LAUNCHED inquiry. + + at item pinentry-mode +This option is used to change the operation mode of the pinentry. The +following values are defined: + + @table @code + @item ask + This is the default mode which pops up a pinentry as needed. + + @item cancel + Instead of popping up a pinentry, return the error code + @code{GPG_ERR_CANCELED}. + + @item error + Instead of popping up a pinentry, return the error code + @code{GPG_ERR_NO_PIN_ENTRY}. + + @item loopback + Use a loopback pinentry. This fakes a pinentry by using inquiries + back to the caller to ask for a passphrase. This option may only be + set if the agent has been configured for that. + Use the @xref{option --allow-loopback-pinentry}. + + @end table + at end table + @mansect see also @ifset isman - at command{gpg2}(1), - at command{gpgsm}(1), + at command{gpg2}(1), + at command{gpgsm}(1), @command{gpg-connect-agent}(1), @command{scdaemon}(1) @end ifset ----------------------------------------------------------------------- Summary of changes: agent/ChangeLog | 13 ++++ agent/agent.h | 17 +++++- agent/call-pinentry.c | 32 ++++++++++- agent/command.c | 18 ++++++ agent/gpg-agent.c | 5 ++ doc/gpg-agent.texi | 157 +++++++++++++++++++++++++++++++++++------------- 6 files changed, 197 insertions(+), 45 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Fri Mar 4 10:04:27 2011 From: cvs at cvs.gnupg.org (by Ben Kibbey) Date: Fri, 04 Mar 2011 10:04:27 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-31-g3582e2e Message-ID: <E1PvQEf-0001Dx-Sn@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 3582e2efa4cf1fd955d8ebe848e0a996ab15305e (commit) from b786f0e12b93d8d61eea18c934f5731fe86402d3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3582e2efa4cf1fd955d8ebe848e0a996ab15305e Author: Ben Kibbey <bjk at luxsci.net> Date: Thu Mar 3 22:20:08 2011 -0500 Added option --inquire to PRESET_PASSPHRASE. Note that the inquired passphrase will be truncated to the first encountered null byte. diff --git a/agent/ChangeLog b/agent/ChangeLog index de5f3da..f4be533 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,7 @@ +2011-03-03 Ben Kibbey <bjk at luxsci.net> + + * command.c (cmd_preset_passphrase): Add option --inquire. + 2011-03-03 Werner Koch <wk at g10code.com> * gpg-agent.c: Add option --allow-loopback-pinentry. diff --git a/agent/command.c b/agent/command.c index b4b9b9e..9df72aa 100644 --- a/agent/command.c +++ b/agent/command.c @@ -1528,25 +1528,29 @@ cmd_passwd (assuan_context_t ctx, char *line) static const char hlp_preset_passphrase[] = - "PRESET_PASSPHRASE <string_or_keygrip> <timeout> <hexstring>\n" + "PRESET_PASSPHRASE [--inquire] <string_or_keygrip> <timeout> [<hexstring>]\n" "\n" "Set the cached passphrase/PIN for the key identified by the keygrip\n" "to passwd for the given time, where -1 means infinite and 0 means\n" "the default (currently only a timeout of -1 is allowed, which means\n" "to never expire it). If passwd is not provided, ask for it via the\n" - "pinentry module."; + "pinentry module unless --inquire is passed in which case the passphrase\n" + "is retrieved from the client via a server inquire.\n"; static gpg_error_t cmd_preset_passphrase (assuan_context_t ctx, char *line) { int rc; char *grip_clear = NULL; - char *passphrase = NULL; + unsigned char *passphrase = NULL; int ttl; size_t len; + int opt_inquire; if (!opt.allow_preset_passphrase) return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase"); + opt_inquire = has_option (line, "--inquire"); + line = skip_options (line); grip_clear = line; while (*line && (*line != ' ' && *line != '\t')) line++; @@ -1577,17 +1581,35 @@ cmd_preset_passphrase (assuan_context_t ctx, char *line) required. */ if (*line) { + if (opt_inquire) + { + rc = set_error (GPG_ERR_ASS_PARAMETER, + "both --inquire and passphrase specified"); + goto leave; + } + /* Do in-place conversion. */ passphrase = line; if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL)) rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring"); } + else if (opt_inquire) + { + /* Note that the passphrase will be truncated at any null byte and the + * limit is 480 characters. */ + rc = assuan_inquire (ctx, "PASSPHRASE", &passphrase, &len, 480); + } else rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required"); if (!rc) - rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl); + { + rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl); + if (opt_inquire) + xfree (passphrase); + } +leave: return leave_cmd (ctx, rc); } ----------------------------------------------------------------------- Summary of changes: agent/ChangeLog | 4 ++++ agent/command.c | 30 ++++++++++++++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 8 12:49:27 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 08 Mar 2011 12:49:27 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-32-g327af90 Message-ID: <E1Pwuhp-0004Fr-F2@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 327af90594204db9683fcee5c8c6b8098c8da37a (commit) from 3582e2efa4cf1fd955d8ebe848e0a996ab15305e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 327af90594204db9683fcee5c8c6b8098c8da37a Author: Werner Koch <wk at gnupg.org> Date: Tue Mar 8 12:23:59 2011 +0100 Require libgcrypt 1.5 Without Libgcrypt 1.5 is was not possible to use ECC keys. ECC is major new feature and thus it does not make sense to allow building with an older Libgcrypt without supporting ECC. Also fixed a few missing prototypes. diff --git a/ChangeLog b/ChangeLog index 4acd121..a48eedc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-03-08 Werner Koch <wk at g10code.com> + + * configure.ac: Require libgcrypt 1.5.0. + (HAVE_GCRY_PK_ECDH, HAVE_GCRY_PK_GET_CURVE): Remove. + (utmp.h): Check for header. + 2011-02-25 Werner Koch <wk at g10code.com> * configure.ac: Require libksba 1.2. diff --git a/README b/README index 7d61211..03da25e 100644 --- a/README +++ b/README @@ -30,7 +30,7 @@ OpenPGP-only version. BUILD INSTRUCTIONS ================== -GnuPG 2.0 depends on the following packages: +GnuPG 2.1 depends on the following packages: libgpg-error (ftp://ftp.gnupg.org/gcrypt/libgpg-error/) libgcrypt (ftp://ftp.gnupg.org/gcrypt/libgcrypt/) @@ -76,8 +76,8 @@ You may run to view the default directories used by GnuPG. -MIGRATION FROM 1.4 or 2.0 -========================= +MIGRATION FROM 1.4 or 2.0 to 2.1 +================================ The major change in 2.1 is that gpg-agent now takes care of the OpenPGP secret keys (those managed by GPG). The former secring.gpg @@ -100,9 +100,10 @@ will start the gpg-agent as needed. In general there is no more need to set the GPG_AGENT_INFO environment variable. The SSH_AUTH_SOCK environment variable should be set to a fixed value. -GPG's smartcard commands --card-edit and --card-status as well as the -card related sub-commands of --edit-key are not yet supported. -However, signing and decryption with a smartcard does work. +GPG's smartcard commands --card-edit and --card-status as well as some +of the card related sub-commands of --edit-key are not yet fully +supported. However, signing and decryption with a smartcard does +work. The Dirmngr is now part of GnuPG proper. Thus there is no more need to install the separate dirmngr package. The directroy layout of diff --git a/agent/ChangeLog b/agent/ChangeLog index f4be533..b636c50 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,7 @@ +2011-03-08 Werner Koch <wk at g10code.com> + + * cvt-openpgp.c (GCRY_PK_ECDH) [!HAVE_GCRY_PK_ECDH]: Remove. + 2011-03-03 Ben Kibbey <bjk at luxsci.net> * command.c (cmd_preset_passphrase): Add option --inquire. diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index 6904593..1595a32 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -28,13 +28,6 @@ #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 diff --git a/configure.ac b/configure.ac index e372d33..f265dc3 100644 --- a/configure.ac +++ b/configure.ac @@ -43,7 +43,7 @@ development_version=no NEED_GPG_ERROR_VERSION=1.8 NEED_LIBGCRYPT_API=1 -NEED_LIBGCRYPT_VERSION=1.4.6 +NEED_LIBGCRYPT_VERSION=1.5.0 NEED_LIBASSUAN_API=2 NEED_LIBASSUAN_VERSION=2.0.0 @@ -742,40 +742,6 @@ 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" - AC_TRY_COMPILE( - [#include <gcrypt.h>], - [ 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 - -AC_CACHE_CHECK([whether Libgcrypt has gcry_pk_get_curve], - gnupg_cv_gcry_pk_get_curve, - [ _gnupg_gcry_save_cflags=$CFLAGS - _gnupg_gcry_save_libs=$LIBS - CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS" - LIBS="$LIBS $LIBGCRYPT_LIBS" - AC_TRY_LINK( - [#include <gcrypt.h>], - [ return gcry_pk_get_curve (NULL, 0, NULL); ], - gnupg_cv_gcry_pk_get_curve=yes, - gnupg_cv_gcry_pk_get_curve=no) - LIBS=$_gnupg_gcry_save_libs - 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 # @@ -1172,7 +1138,7 @@ fi AC_MSG_NOTICE([checking for header files]) AC_HEADER_STDC AC_CHECK_HEADERS([string.h unistd.h langinfo.h termio.h locale.h getopt.h \ - pty.h pwd.h inttypes.h signal.h]) + pty.h utmp.h pwd.h inttypes.h signal.h]) AC_HEADER_TIME @@ -1636,7 +1602,7 @@ if test "$have_libgcrypt" = "no"; then *** *** You need libgcrypt to build this program. ** This library is for example available at -*** ftp://ftp.gnupg.org/gcrypt/libgcrypt/ +*** ftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/ *** (at least version $NEED_LIBGCRYPT_VERSION using API $NEED_LIBGCRYPT_API is required.) ***]]) fi diff --git a/g10/call-dirmngr.h b/g10/call-dirmngr.h index 43636ea..933303d 100644 --- a/g10/call-dirmngr.h +++ b/g10/call-dirmngr.h @@ -25,6 +25,8 @@ gpg_error_t gpg_dirmngr_ks_search (ctrl_t ctrl, const char *searchstr, gpg_error_t (*cb)(void*, char *), void *cb_value); gpg_error_t gpg_dirmngr_ks_get (ctrl_t ctrl, char *pattern[], estream_t *r_fp); +gpg_error_t gpg_dirmngr_ks_fetch (ctrl_t ctrl, + const char *url, estream_t *r_fp); gpg_error_t gpg_dirmngr_ks_put (ctrl_t ctrl, void *data, size_t datalen, kbnode_t keyblock); diff --git a/g10/export.c b/g10/export.c index 47185e3..191f68b 100644 --- a/g10/export.c +++ b/g10/export.c @@ -581,11 +581,7 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) 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) @@ -649,17 +645,10 @@ transfer_format_to_openpgp (gcry_sexp_t s_pgp, PKT_public_key *pk) if (err) goto leave; - /* 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. */ + /* Check that the public key parameters match. Note that since + Libgcrypt 1.5 gcry_mpi_cmp handles opaque MPI correctly. */ for (idx=0; idx < npkey; idx++) - 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])) + if (gcry_mpi_cmp (pk->pkey[idx], skey[idx])) { err = gpg_error (GPG_ERR_BAD_PUBKEY); goto leave; diff --git a/g10/import.c b/g10/import.c index 99398c7..39968ff 100644 --- a/g10/import.c +++ b/g10/import.c @@ -1253,11 +1253,8 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock) err = gpg_error_from_syserror (); else { -#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); diff --git a/include/cipher.h b/include/cipher.h index db2196e..191e197 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -22,12 +22,6 @@ #include <gcrypt.h> -/* Macros for compatibility with older libgcrypt versions. */ -#ifndef HAVE_GCRY_PK_ECDH -# define GCRY_PK_ECDH 302 -#endif - - /* Constants for OpenPGP. */ #define CIPHER_ALGO_NONE /* 0 */ GCRY_CIPHER_NONE diff --git a/tools/ChangeLog b/tools/ChangeLog index ae591db..3888802 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,7 @@ +2011-03-08 Werner Koch <wk at g10code.com> + + * symcryptrun.c [HAVE_UTMP_H]: Include utmp.h. + 2011-02-23 Werner Koch <wk at g10code.com> * gpgconf.c: Add command --kill. diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c index 1d882a1..c75f637 100644 --- a/tools/symcryptrun.c +++ b/tools/symcryptrun.c @@ -74,6 +74,9 @@ #ifdef HAVE_PTY_H #include <pty.h> #endif +#ifdef HAVE_UTMP_H +#include <utmp.h> +#endif #include <ctype.h> #ifdef HAVE_LOCALE_H #include <locale.h> ----------------------------------------------------------------------- Summary of changes: ChangeLog | 6 ++++++ README | 13 +++++++------ agent/ChangeLog | 4 ++++ agent/cvt-openpgp.c | 7 ------- configure.ac | 40 +++------------------------------------- g10/call-dirmngr.h | 2 ++ g10/export.c | 17 +++-------------- g10/import.c | 5 +---- include/cipher.h | 6 ------ tools/ChangeLog | 4 ++++ tools/symcryptrun.c | 3 +++ 11 files changed, 33 insertions(+), 74 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 8 14:21:20 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 08 Mar 2011 14:21:20 +0100 Subject: [git] GCRYPT - branch, master, updated. post-nuke-of-trailing-ws-18-gbf823c5 Message-ID: <E1Pww8j-0005xJ-UZ@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via bf823c5acb713488771c9000242b36ab13649da4 (commit) from e7f33df5e5b102f3c07a6dac1bfd1376f4f9267b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bf823c5acb713488771c9000242b36ab13649da4 Author: Werner Koch <wk at gnupg.org> Date: Tue Mar 8 13:56:49 2011 +0100 Shorten BUILD_REVISION macro diff --git a/ChangeLog b/ChangeLog index e499f15..c72b1c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-08 Werner Koch <wk at g10code.com> + + * configure.ac (BUILD_REVISION): Use new git_brevis macro. + 2011-02-23 Werner Koch <wk at g10code.com> * configure.ac (LIBGCRYPT_CONFIG_HOST): New. diff --git a/configure.ac b/configure.ac index 618a5ee..f9e3593 100644 --- a/configure.ac +++ b/configure.ac @@ -55,7 +55,8 @@ LIBGCRYPT_CONFIG_API_VERSION=1 NEED_GPG_ERROR_VERSION=1.8 is_development_version=my_issvn -BUILD_REVISION=m4_if(git_revision,[],[svn_revision],[git_revision]) +m4_define([git_brevis],m4_esyscmd(printf "%u" 0x[]m4_substr(git_revision,0,4))) +BUILD_REVISION=m4_if(git_revision,[],[svn_revision],[git_brevis]) PACKAGE=$PACKAGE_NAME VERSION=$PACKAGE_VERSION ----------------------------------------------------------------------- Summary of changes: ChangeLog | 4 ++++ configure.ac | 3 ++- 2 files changed, 6 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 8 14:24:43 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 08 Mar 2011 14:24:43 +0100 Subject: [git] GnuPG - tag, gnupg-2.1.0beta2, created. post-nuke-of-trailing-ws-33-g444f2fe Message-ID: <E1PwwC1-0006Ar-0m@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The tag, gnupg-2.1.0beta2 has been created at 444f2fe1cdfe0924e2f55aff4e38eb88742153d4 (commit) - Log ----------------------------------------------------------------- commit 444f2fe1cdfe0924e2f55aff4e38eb88742153d4 Author: Werner Koch <wk at gnupg.org> Date: Tue Mar 8 12:56:45 2011 +0100 Prepare for 1.5.0beta2 ----------------------------------------------------------------------- hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Tue Mar 8 14:24:39 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 08 Mar 2011 14:24:39 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-34-g87a6a1c Message-ID: <E1PwwBw-0006AP-Kp@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 87a6a1c3fe4b86a7db30fcce4d1e21e86d561e0f (commit) via 444f2fe1cdfe0924e2f55aff4e38eb88742153d4 (commit) from 327af90594204db9683fcee5c8c6b8098c8da37a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 87a6a1c3fe4b86a7db30fcce4d1e21e86d561e0f Author: Werner Koch <wk at gnupg.org> Date: Tue Mar 8 14:00:04 2011 +0100 Post beta release updates diff --git a/NEWS b/NEWS index 6f368c8..beadfc3 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Noteworthy changes in version 2.1.0beta3 +----------------------------------------------------- + + Noteworthy changes in version 2.1.0beta2 (2011-03-08) ----------------------------------------------------- diff --git a/configure.ac b/configure.ac index 622ab0a..f265dc3 100644 --- a/configure.ac +++ b/configure.ac @@ -24,8 +24,8 @@ 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.0beta2]) -m4_define([my_issvn], [no]) +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 \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) commit 444f2fe1cdfe0924e2f55aff4e38eb88742153d4 Author: Werner Koch <wk at gnupg.org> Date: Tue Mar 8 12:56:45 2011 +0100 Prepare for 1.5.0beta2 diff --git a/ChangeLog b/ChangeLog index a48eedc..2118a1e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2011-03-08 Werner Koch <wk at g10code.com> + Release 2.1.0beta2. + * configure.ac: Require libgcrypt 1.5.0. (HAVE_GCRY_PK_ECDH, HAVE_GCRY_PK_GET_CURVE): Remove. (utmp.h): Check for header. diff --git a/NEWS b/NEWS index 1255b34..6f368c8 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -Noteworthy changes in version 2.1.0beta2 (unreleased) +Noteworthy changes in version 2.1.0beta2 (2011-03-08) ----------------------------------------------------- * TMPDIR is now also honored when creating a socket using diff --git a/configure.ac b/configure.ac index f265dc3..622ab0a 100644 --- a/configure.ac +++ b/configure.ac @@ -24,8 +24,8 @@ 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_issvn], [yes]) +m4_define([my_version], [2.1.0beta2]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) diff --git a/po/de.po b/po/de.po index 16a8801..dab6c57 100644 --- a/po/de.po +++ b/po/de.po @@ -1,6 +1,6 @@ # GnuPG German translation # Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# 2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc. # Walter Koch <koch at u32.de>, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006 # Merged with the gnupg 1.9.23 translation by Werner Koch on 2006-09-25. @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: gnupg-2.1.0\n" "Report-Msgid-Bugs-To: translations at gnupg.org\n" -"PO-Revision-Date: 2011-02-10 20:53+0100\n" +"PO-Revision-Date: 2011-03-08 12:47+0100\n" "Last-Translator: Werner Koch <wk at gnupg.org>\n" "Language-Team: German <de at li.org>\n" "MIME-Version: 1.0\n" @@ -4279,7 +4279,9 @@ msgid "unknown option `%s'\n" msgstr "Unbekannte Option '%s'\n" msgid "ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n" -msgstr "Der ?ffentliche ECDSA Schl?ssel mu? ein Vielfaches von 8 Bit als L?nge haben\n" +msgstr "" +"Der ?ffentliche ECDSA Schl?ssel mu? ein Vielfaches von 8 Bit als L?nge " +"haben\n" #, c-format msgid "File `%s' exists. " @@ -4808,7 +4810,8 @@ msgstr "%s-Schl?ssel %s verwendet ein unsicheres (%zu-Bit) Hashverfahren\n" #, c-format msgid "%s key %s requires a %zu bit or larger hash (hash is %s\n" -msgstr "%s-Schl?ssel %s ben?tigt einen mindestens %zu Bit langen Hash (Hash ist %s)\n" +msgstr "" +"%s-Schl?ssel %s ben?tigt einen mindestens %zu Bit langen Hash (Hash ist %s)\n" msgid "WARNING: signature digest conflict in message\n" msgstr "WARNUNG: Widersprechende Hashverfahren in der signierten Nachricht\n" @@ -5815,6 +5818,31 @@ msgid "line %d: not a valid email address\n" msgstr "Zeile %d: Keine g?ltige E-Mailadresse\n" #, c-format +msgid "line %d: invalid serial number\n" +msgstr "Zeile %d: Ung?ltige Seriennummer\n" + +#, c-format +msgid "line %d: invalid issuer name label `%.*s'\n" +msgstr "Zeile %d: ung?ltiger Issuer-Name-Label `%.*s'\n" + +#, c-format +msgid "line %d: invalid issuer name `%s' at pos %d\n" +msgstr "Zeile %d: ung?ltiger Herausgeber `%s' in Spalte %d\n" + +#, c-format +msgid "line %d: invalid date given\n" +msgstr "Zeile %d: Ung?ltiges Datum\n" + +#, c-format +msgid "line %d: error getting signing key by keygrip `%s': %s\n" +msgstr "" +"Zeile %d: Fehler beim Holen des Signaturschl?ssels per \"Keygrip\" `%s': %s\n" + +#, c-format +msgid "line %d: invalid hash algorithm given\n" +msgstr "Zeile %d: Ung?ltiges Hashverfahren\n" + +#, 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" @@ -5918,12 +5946,23 @@ msgstr " (Optional. Beenden mit einer leeren Zeile):\n" msgid "Enter URIs" msgstr "Bitte geben Sie die URIs ein" -msgid "Parameters to be used for the certificate request:\n" -msgstr "Parameter die f?r die Zertifikatsanforderung benutzt werden sollen:\n" +msgid "Create self-signed certificate? (y/N) " +msgstr "Ein eigenbeglaubigtes Zertifikat erzeugen? (j/N) " -msgid "Now creating certificate request. This may take a while ...\n" -msgstr "" -"Die Zertifikatsanforderung wird erzeugt. Dies kann einen Moment dauern ...\n" +msgid "These parameters are used:\n" +msgstr "Verwendete Parameter:\n" + +msgid "Now creating self-signed certificate. " +msgstr "Das eigenbeglaubigte Zertifikat wird erzeugt. " + +msgid "Now creating certificate request. " +msgstr "Die Zertifikatsanforderung wird erzeugt. " + +msgid "This may take a while ...\n" +msgstr "Dies kann einen Moment dauern ...\n" + +msgid "Ready.\n" +msgstr "Fertig.\n" msgid "Ready. You should now send this request to your CA.\n" msgstr "Fertig. Sie sollten nun diese Anforderung an die CA senden.\n" @@ -7664,6 +7703,9 @@ msgstr "Pr?fe die globale Konfigurationsdatei" msgid "reload all or a given component" msgstr "\"reload\" an alle oder eine Komponente senden" +msgid "kill a given component" +msgstr "\"kill\" an eine Komponente senden" + msgid "use as output file" msgstr "Als Ausgabedatei benutzen" @@ -7836,6 +7878,13 @@ msgstr "" "Syntax: gpg-check-pattern [optionen] Musterdatei\n" "Die von stdin gelesene Passphrase gegen die Musterdatei pr?fen\n" +#~ msgid "self-signed certificate" +#~ msgstr "eigenbeglaubigtes Zertifikat" + +#~ msgid "Parameters to be used for the certificate request:\n" +#~ msgstr "" +#~ "Parameter die f?r die Zertifikatsanforderung benutzt werden sollen:\n" + #~ msgid "WARNING: unable to parse URI %s\n" #~ msgstr "WARNUNG: die URI %s kann nicht analysiert werden\n" diff --git a/sm/certreqgen-ui.c b/sm/certreqgen-ui.c index b5b4219..236d53b 100644 --- a/sm/certreqgen-ui.c +++ b/sm/certreqgen-ui.c @@ -393,9 +393,12 @@ gpgsm_gencertreq_tty (ctrl_t ctrl, estream_t output_stream) } es_fputs (result, fp); es_rewind (fp); - tty_printf (_("Now creating %s. " - "This may take a while ...\n"), - selfsigned?_("self-signed certificate"):_("certificate request")); + if (selfsigned) + tty_printf ("%s", _("Now creating self-signed certificate. ")); + else + tty_printf ("%s", _("Now creating certificate request. ")); + tty_printf ("%s", _("This may take a while ...\n")); + { int save_pem = ctrl->create_pem; ctrl->create_pem = 1; /* Force creation of PEM. */ ----------------------------------------------------------------------- Summary of changes: ChangeLog | 2 + NEWS | 6 ++++- po/de.po | 67 +++++++++++++++++++++++++++++++++++++++++++++------- sm/certreqgen-ui.c | 9 ++++-- 4 files changed, 71 insertions(+), 13 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 9 18:14:52 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 09 Mar 2011 18:14:52 +0100 Subject: [git] GCRYPT - branch, master, updated. post-nuke-of-trailing-ws-19-g9730275 Message-ID: <E1PxMG4-0001lQ-Gc@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 9730275d294b4d9cbbb2453541f001c95f5f31a3 (commit) from bf823c5acb713488771c9000242b36ab13649da4 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9730275d294b4d9cbbb2453541f001c95f5f31a3 Author: Werner Koch <wk at gnupg.org> Date: Wed Mar 9 17:47:44 2011 +0100 New function gcry_kdf_derive This allows us to factor the S2k code from gpg and gpg-agent out to libgcrypt. Created a bunch of test vectors using a hacked gpg 1.4. The function also implements PBKDF2; tested against the RFC-6070 test vectors. diff --git a/NEWS b/NEWS index 979ad40..add5152 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ Noteworthy changes in version 1.5.x (unreleased) ------------------------------------------------ + * New function gcry_kdf_derive implementing OpenPGP S2K algorithms + and PBKDF2. + * Support for WindowsCE. * Support ECDH. @@ -46,6 +49,7 @@ Noteworthy changes in version 1.5.x (unreleased) gcry_pk_get_curve NEW. gcry_pk_get_param NEW. GCRYCTL_DISABLE_HWF NEW. + gcry_kdf_derive NEW. * Interface changes relative to the 1.4.2 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/cipher/ChangeLog b/cipher/ChangeLog index 7e00da7..3fba314 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,7 @@ +2011-03-09 Werner Koch <wk at g10code.com> + + * kdf.c: New. + 2011-02-22 Werner Koch <wk at g10code.com> * rijndael.c (aesni_cleanup_2_4): New. diff --git a/cipher/Makefile.am b/cipher/Makefile.am index cdc6dfc..cbeace8 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -35,7 +35,7 @@ libcipher_la_DEPENDENCIES = $(GCRYPT_MODULES) libcipher_la_LIBADD = $(GCRYPT_MODULES) libcipher_la_SOURCES = \ -cipher.c pubkey.c ac.c md.c \ +cipher.c pubkey.c ac.c md.c kdf.c \ hmac-tests.c \ bithelp.h \ primegen.c \ diff --git a/cipher/kdf.c b/cipher/kdf.c new file mode 100644 index 0000000..d981022 --- /dev/null +++ b/cipher/kdf.c @@ -0,0 +1,278 @@ +/* kdf.c - Key Derivation Functions + * Copyright (C) 1998, 2011 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser general Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "g10lib.h" +#include "cipher.h" +#include "ath.h" + + +/* Transform a passphrase into a suitable key of length KEYSIZE and + store this key in the caller provided buffer KEYBUFFER. The caller + must provide an HASHALGO, a valid ALGO and depending on that algo a + SALT of 8 bytes and the number of ITERATIONS. Code taken from + gnupg/agent/protect.c:hash_passphrase. */ +gpg_err_code_t +openpgp_s2k (const void *passphrase, size_t passphraselen, + int algo, int hashalgo, + const void *salt, size_t saltlen, + unsigned long iterations, + size_t keysize, void *keybuffer) +{ + gpg_err_code_t ec; + gcry_md_hd_t md; + char *key = keybuffer; + int pass, i; + int used = 0; + int secmode; + + if ((algo == GCRY_KDF_SALTED_S2K || algo == GCRY_KDF_ITERSALTED_S2K) + && (!salt || saltlen != 8)) + return GPG_ERR_INV_VALUE; + + secmode = gcry_is_secure (passphrase) || gcry_is_secure (keybuffer); + + ec = gpg_err_code (gcry_md_open (&md, hashalgo, + secmode? GCRY_MD_FLAG_SECURE : 0)); + if (ec) + return ec; + + for (pass=0; used < keysize; pass++) + { + if (pass) + { + gcry_md_reset (md); + for (i=0; i < pass; i++) /* Preset the hash context. */ + gcry_md_putc (md, 0); + } + + if (algo == GCRY_KDF_SALTED_S2K || algo == GCRY_KDF_ITERSALTED_S2K) + { + int len2 = passphraselen + 8; + unsigned long count = len2; + + if (algo == GCRY_KDF_ITERSALTED_S2K) + { + count = iterations; + if (count < len2) + count = len2; + } + + while (count > len2) + { + gcry_md_write (md, salt, saltlen); + gcry_md_write (md, passphrase, passphraselen); + count -= len2; + } + if (count < saltlen) + gcry_md_write (md, salt, count); + else + { + gcry_md_write (md, salt, saltlen); + count -= saltlen; + gcry_md_write (md, passphrase, count); + } + } + else + gcry_md_write (md, passphrase, passphraselen); + + gcry_md_final (md); + i = gcry_md_get_algo_dlen (hashalgo); + if (i > keysize - used) + i = keysize - used; + memcpy (key+used, gcry_md_read (md, hashalgo), i); + used += i; + } + gcry_md_close (md); + return 0; +} + + +/* Transform a passphrase into a suitable key of length KEYSIZE and + store this key in the caller provided buffer KEYBUFFER. The caller + must provide PRFALGO which indicates the pseudorandom function to + use: This shall be the algorithms id of a hash algorithm; it is + used in HMAC mode. SALT is a salt of length SALTLEN and ITERATIONS + gives the number of iterations. */ +gpg_err_code_t +pkdf2 (const void *passphrase, size_t passphraselen, + int hashalgo, + const void *salt, size_t saltlen, + unsigned long iterations, + size_t keysize, void *keybuffer) +{ + gpg_err_code_t ec; + gcry_md_hd_t md; + int secmode; + unsigned int dklen = keysize; + char *dk = keybuffer; + unsigned int hlen; /* Output length of the digest function. */ + unsigned int l; /* Rounded up number of blocks. */ + unsigned int r; /* Number of octets in the last block. */ + char *sbuf; /* Malloced buffer to concatenate salt and iter + as well as space to hold TBUF and UBUF. */ + char *tbuf; /* Buffer for T; ptr into SBUF, size is HLEN. */ + char *ubuf; /* Buffer for U; ptr into SBUF, size is HLEN. */ + unsigned int lidx; /* Current block number. */ + unsigned long iter; /* Current iteration number. */ + unsigned int i; + + if (!salt || !saltlen || !iterations || !dklen) + return GPG_ERR_INV_VALUE; + + hlen = gcry_md_get_algo_dlen (hashalgo); + if (!hlen) + return GPG_ERR_DIGEST_ALGO; + + secmode = gcry_is_secure (passphrase) || gcry_is_secure (keybuffer); + + /* We ignore step 1 from pksc5v2.1 which demands a check that dklen + is not larger that 0xffffffff * hlen. */ + + /* Step 2 */ + l = ((dklen - 1)/ hlen) + 1; + r = dklen - (l - 1) * hlen; + + /* Setup buffers and prepare a hash context. */ + sbuf = (secmode + ? gcry_malloc_secure (saltlen + 4 + hlen + hlen) + : gcry_malloc (saltlen + 4 + hlen + hlen)); + if (!sbuf) + return gpg_err_code_from_syserror (); + tbuf = sbuf + saltlen + 4; + ubuf = tbuf + hlen; + + ec = gpg_err_code (gcry_md_open (&md, hashalgo, + (GCRY_MD_FLAG_HMAC + | (secmode?GCRY_MD_FLAG_SECURE:0)))); + if (ec) + { + gcry_free (sbuf); + return ec; + } + + /* Step 3 and 4. */ + memcpy (sbuf, salt, saltlen); + for (lidx = 1; lidx <= l; lidx++) + { + for (iter = 0; iter < iterations; iter++) + { + ec = gpg_err_code (gcry_md_setkey (md, passphrase, passphraselen)); + if (ec) + { + gcry_md_close (md); + gcry_free (sbuf); + return ec; + } + if (!iter) /* Compute U_1: */ + { + sbuf[saltlen] = (lidx >> 24); + sbuf[saltlen + 1] = (lidx >> 16); + sbuf[saltlen + 2] = (lidx >> 8); + sbuf[saltlen + 3] = lidx; + gcry_md_write (md, sbuf, saltlen + 4); + memcpy (ubuf, gcry_md_read (md, 0), hlen); + memcpy (tbuf, ubuf, hlen); + } + else /* Compute U_(2..c): */ + { + gcry_md_write (md, ubuf, hlen); + memcpy (ubuf, gcry_md_read (md, 0), hlen); + for (i=0; i < hlen; i++) + tbuf[i] ^= ubuf[i]; + } + } + if (lidx == l) /* Last block. */ + memcpy (dk, tbuf, r); + else + { + memcpy (dk, tbuf, hlen); + dk += hlen; + } + } + + gcry_md_close (md); + gcry_free (sbuf); + return 0; +} + + +/* Derive a key from a passphrase. KEYSIZE gives the requested size + of the keys in octets. KEYBUFFER is a caller provided buffer + filled on success with the derived key. The input passphrase is + taken from (PASSPHRASE,PASSPHRASELEN) which is an arbitrary memory + buffer. ALGO specifies the KDF algorithm to use; these are the + constants GCRY_KDF_*. SUBALGO specifies an algorithm used + internally by the KDF algorithms; this is usually a hash algorithm + but certain KDF algorithm may use it differently. {SALT,SALTLEN} + is a salt as needed by most KDF algorithms. ITERATIONS is a + positive integer parameter to most KDFs. 0 is returned on success, + or an error code on failure. */ +gpg_error_t +gcry_kdf_derive (const void *passphrase, size_t passphraselen, + int algo, int subalgo, + const void *salt, size_t saltlen, + unsigned long iterations, + size_t keysize, void *keybuffer) +{ + gpg_err_code_t ec; + + if (!passphrase || !passphraselen) + { + ec = GPG_ERR_INV_DATA; + goto leave; + } + if (!keybuffer || !keysize) + { + ec = GPG_ERR_INV_VALUE; + goto leave; + } + + + switch (algo) + { + case GCRY_KDF_SIMPLE_S2K: + case GCRY_KDF_SALTED_S2K: + case GCRY_KDF_ITERSALTED_S2K: + ec = openpgp_s2k (passphrase, passphraselen, algo, subalgo, + salt, saltlen, iterations, keysize, keybuffer); + break; + + case GCRY_KDF_PBKDF1: + ec = GPG_ERR_UNSUPPORTED_ALGORITHM; + break; + + case GCRY_KDF_PBKDF2: + ec = pkdf2 (passphrase, passphraselen, subalgo, + salt, saltlen, iterations, keysize, keybuffer); + break; + + default: + ec = GPG_ERR_UNKNOWN_ALGORITHM; + break; + } + + leave: + return gpg_error (ec); +} diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index 3a0a5fc..e441263 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -12,7 +12,7 @@ This manual is for Libgcrypt (version @value{VERSION}, @value{UPDATED}), which is GNU's library of cryptographic building blocks. -Copyright @copyright{} 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Copyright @copyright{} 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document @@ -68,6 +68,7 @@ section entitled ``GNU General Public License''. * Symmetric cryptography:: How to use symmetric cryptography. * Public Key cryptography:: How to use public key cryptography. * Hashing:: How to use hash and MAC algorithms. +* Key Derivation:: How to derive keys from strings * Random Numbers:: How to work with random numbers. * S-expressions:: How to manage S-expressions. * MPI library:: How to work with multi-precision-integers. @@ -3930,6 +3931,65 @@ does implicitly stop debugging. @end deftypefun + at c ******************************************************* + at c ******************* KDF ***************************** + at c ******************************************************* + at node Key Derivation + at chapter Key Derivation + + at acronym{Libgcypt} provides a general purpose function to derive keys +from strings. + + at deftypefun gpg_error_t gcry_kdf_derive ( @ + @w{const void *@var{passphrase}}, @w{size_t @var{passphraselen}}, @ + @w{int @var{algo}}, @w{int @var{subalgo}}, @ + @w{const void *@var{salt}}, @w{size_t @var{saltlen}}, @ + @w{unsigned long @var{iterations}}, @ + @w{size_t @var{keysize}}, @w{void *@var{keybuffer}} ) + + +Derive a key from a passphrase. @var{keysize} gives the requested +size of the keys in octets. @var{keybuffer} is a caller provided +buffer filled on success with the derived key. The input passphrase +is taken from @var{passphrase} which is an arbitrary memory buffer of + at var{passphraselen} octets. @var{algo} specifies the KDF algorithm to +use; see below. @var{subalgo} specifies an algorithm used internally +by the KDF algorithms; this is usually a hash algorithm but certain +KDF algorithms may use it differently. @var{salt} is a salt of length + at var{saltlen} octets, as needed by most KDF algorithms. + at var{iterations} is a positive integer parameter to most KDFs. + + at noindent +On success 0 is returned; on failure an error code. + + at noindent +Currently supported KDFs (parameter @var{algo}): + + at table @code + at item GCRY_KDF_SIMPLE_S2K +The OpenPGP simple S2K algorithm (cf. RFC4880). Its use is strongly +deprecated. @var{salt} and @var{iterations} are not needed and may be +passed as @code{NULL}/@code{0}. + + at item GCRY_KDF_SALTED_S2K +The OpenPGP salted S2K algorithm (cf. RFC4880). Usually not used. + at var{iterations} is not needed and may be passed as @code{0}. @var{saltlen} +must be given as 8. + + at item GCRY_KDF_ITERSALTED_S2K +The OpenPGP iterated+salted S2K algorithm (cf. RFC4880). This is the +default for most OpenPGP applications. @var{saltlen} must be given as +8. Note that OpenPGP defines a special encoding of the + at var{iterations}; however this function takes the plain decoded +iteration count. + + at item GCRY_KDF_PBKDF2 +The PKCS#5 Passphrase Based Key Derivation Function number 2. + + at end table + at end deftypefun + + @c ********************************************************** @c ******************* Random ***************************** @c ********************************************************** diff --git a/src/ChangeLog b/src/ChangeLog index 98f38db..9ef6c5d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,10 @@ +2011-03-09 Werner Koch <wk at g10code.com> + + * gcrypt.h.in (gcry_kdf_algos): New. + (gcry_kdf_derive): New. + * visibility.c (gcry_kdf_derive): New. + * visibility.h, libgcrypt.vers, libgcrypt.def: Add gcry_kdf_derive. + 2011-02-23 Werner Koch <wk at g10code.com> * libgcrypt-config.in: Add option --host. diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index 3cd8e7f..f67c19a 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -1658,6 +1658,33 @@ gcry_error_t gcry_ac_name_to_id (const char *name, #endif /*GCRYPT_NO_DEPRECATED*/ +/****************************** + * * + * Key Derivation Functions * + * * + ******************************/ + +/* Algorithm IDs for the KDFs. */ +enum gcry_kdf_algos + { + GCRY_KDF_NONE = 0, + GCRY_KDF_SIMPLE_S2K = 16, + GCRY_KDF_SALTED_S2K = 17, + GCRY_KDF_ITERSALTED_S2K = 19, + GCRY_KDF_PBKDF1 = 33, + GCRY_KDF_PBKDF2 = 34 + }; + +/* Derive a key from a passphrase. */ +gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen, + int algo, int subalgo, + const void *salt, size_t saltlen, + unsigned long iterations, + size_t keysize, void *keybuffer); + + + + /************************************ * * * Random Generating Functions * diff --git a/src/libgcrypt.def b/src/libgcrypt.def index ac3d575..031b941 100644 --- a/src/libgcrypt.def +++ b/src/libgcrypt.def @@ -235,3 +235,5 @@ EXPORTS gcry_pk_get_curve @192 gcry_pk_get_param @193 + + gcry_kdf_derive @194 diff --git a/src/libgcrypt.vers b/src/libgcrypt.vers index fbeb47b..5a617cc 100644 --- a/src/libgcrypt.vers +++ b/src/libgcrypt.vers @@ -75,6 +75,8 @@ GCRYPT_1.2 { gcry_ac_data_to_sexp; gcry_ac_data_from_sexp; gcry_ac_io_init; gcry_ac_io_init_va; + gcry_kdf_derive; + gcry_prime_check; gcry_prime_generate; gcry_prime_group_generator; gcry_prime_release_factors; diff --git a/src/visibility.c b/src/visibility.c index 2d203f9..2fccb01 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -1210,6 +1210,17 @@ gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm) return 0; } +gpg_error_t +gcry_kdf_derive (const void *passphrase, size_t passphraselen, + int algo, int hashalgo, + const void *salt, size_t saltlen, + unsigned long iterations, + size_t keysize, void *keybuffer) +{ + return _gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo, + salt, saltlen, iterations, keysize, keybuffer); +} + void gcry_randomize (void *buffer, size_t length, enum gcry_random_level level) { diff --git a/src/visibility.h b/src/visibility.h index ea00b89..3c1e8aa 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -153,6 +153,8 @@ #define gcry_ac_io_init _gcry_ac_io_init #define gcry_ac_io_init_va _gcry_ac_io_init_va +#define gcry_kdf_derive _gcry_kdf_derive + #define gcry_prime_check _gcry_prime_check #define gcry_prime_generate _gcry_prime_generate #define gcry_prime_group_generator _gcry_prime_group_generator @@ -501,6 +503,8 @@ void gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n); #undef gcry_ac_io_init #undef gcry_ac_io_init_va +#undef gcry_kdf_derive + #undef gcry_prime_check #undef gcry_prime_generate #undef gcry_prime_group_generator @@ -715,6 +719,8 @@ MARK_VISIBLE (gcry_ac_data_from_sexp) MARK_VISIBLE (gcry_ac_io_init) MARK_VISIBLE (gcry_ac_io_init_va) +MARK_VISIBLE (gcry_kdf_derive) + MARK_VISIBLE (gcry_prime_check) MARK_VISIBLE (gcry_prime_generate) MARK_VISIBLE (gcry_prime_group_generator) diff --git a/tests/Makefile.am b/tests/Makefile.am index bf26f68..c34bb96 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -20,7 +20,7 @@ TESTS = version t-mpi-bit prime register ac ac-schemes ac-data basic \ mpitests tsexp keygen pubkey hmac keygrip fips186-dsa aeswrap \ - curves + curves t-kdf # random.c uses fork() thus a test for W32 does not make any sense. diff --git a/tests/t-kdf.c b/tests/t-kdf.c new file mode 100644 index 0000000..7209525 --- /dev/null +++ b/tests/t-kdf.c @@ -0,0 +1,974 @@ +/* t-kdf.c - KDF regression tests + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <assert.h> + +#include "../src/gcrypt.h" + +#ifndef DIM +# define DIM(v) (sizeof(v)/sizeof((v)[0])) +#endif + +/* Program option flags. */ +static int verbose; +static int error_count; + +static void +fail (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + error_count++; +} + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + + +static void +check_openpgp (void) +{ + /* Test vectors manually created with gpg 1.4 derived code: In + passphrase.c:hash_passpharse, add this code to the end of the + function: + + ===8<=== + printf ("{\n" + " \""); + for (i=0; i < pwlen; i++) + { + if (i && !(i%16)) + printf ("\"\n \""); + printf ("\\x%02x", ((const unsigned char *)pw)[i]); + } + printf ("\", %d,\n", pwlen); + + printf (" %s, %s,\n", + s2k->mode == 0? "GCRY_KDF_SIMPLE_S2K": + s2k->mode == 1? "GCRY_KDF_SALTED_S2K": + s2k->mode == 3? "GCRY_KDF_ITERSALTED_S2K":"?", + s2k->hash_algo == DIGEST_ALGO_MD5 ? "GCRY_MD_MD5" : + s2k->hash_algo == DIGEST_ALGO_SHA1 ? "GCRY_MD_SHA1" : + s2k->hash_algo == DIGEST_ALGO_RMD160? "GCRY_MD_RMD160" : + s2k->hash_algo == DIGEST_ALGO_SHA256? "GCRY_MD_SHA256" : + s2k->hash_algo == DIGEST_ALGO_SHA384? "GCRY_MD_SHA384" : + s2k->hash_algo == DIGEST_ALGO_SHA512? "GCRY_MD_SHA512" : + s2k->hash_algo == DIGEST_ALGO_SHA224? "GCRY_MD_SHA224" : "?"); + + if (s2k->mode == 0) + printf (" NULL, 0,\n"); + else + { + printf (" \""); + for (i=0; i < 8; i++) + printf ("\\x%02x", (unsigned int)s2k->salt[i]); + printf ("\", %d,\n", 8); + } + + if (s2k->mode == 3) + printf (" %lu,\n", (unsigned long)S2K_DECODE_COUNT(s2k->count)); + else + printf (" 0,\n"); + + printf (" %d,\n", (int)dek->keylen); + + printf (" \""); + for (i=0; i < dek->keylen; i++) + { + if (i && !(i%16)) + printf ("\"\n \""); + printf ("\\x%02x", ((unsigned char *)dek->key)[i]); + } + printf ("\"\n},\n"); + ===>8=== + + Then prepare a file x.inp with utf8 encoding: + + ===8<=== + 0 aes md5 1024 a + 0 aes md5 1024 ab + 0 aes md5 1024 abc + 0 aes md5 1024 abcd + 0 aes md5 1024 abcde + 0 aes md5 1024 abcdef + 0 aes md5 1024 abcdefg + 0 aes md5 1024 abcdefgh + 0 aes md5 1024 abcdefghi + 0 aes md5 1024 abcdefghijklmno + 0 aes md5 1024 abcdefghijklmnop + 0 aes md5 1024 abcdefghijklmnopq + 0 aes md5 1024 Long_sentence_used_as_passphrase + 0 aes md5 1024 With_utf8_umlauts:???? + 0 aes sha1 1024 a + 0 aes sha1 1024 ab + 0 aes sha1 1024 abc + 0 aes sha1 1024 abcd + 0 aes sha1 1024 abcde + 0 aes sha1 1024 abcdef + 0 aes sha1 1024 abcdefg + 0 aes sha1 1024 abcdefgh + 0 aes sha1 1024 abcdefghi + 0 aes sha1 1024 abcdefghijklmno + 0 aes sha1 1024 abcdefghijklmnop + 0 aes sha1 1024 abcdefghijklmnopq + 0 aes sha1 1024 abcdefghijklmnopqr + 0 aes sha1 1024 abcdefghijklmnopqrs + 0 aes sha1 1024 abcdefghijklmnopqrst + 0 aes sha1 1024 abcdefghijklmnopqrstu + 0 aes sha1 1024 Long_sentence_used_as_passphrase + 0 aes256 sha1 1024 Long_sentence_used_as_passphrase + 0 aes sha1 1024 With_utf8_umlauts:???? + 3 aes sha1 1024 a + 3 aes sha1 1024 ab + 3 aes sha1 1024 abc + 3 aes sha1 1024 abcd + 3 aes sha1 1024 abcde + 3 aes sha1 1024 abcdef + 3 aes sha1 1024 abcdefg + 3 aes sha1 1024 abcdefgh + 3 aes sha1 1024 abcdefghi + 3 aes sha1 1024 abcdefghijklmno + 3 aes sha1 1024 abcdefghijklmnop + 3 aes sha1 1024 abcdefghijklmnopq + 3 aes sha1 1024 abcdefghijklmnopqr + 3 aes sha1 1024 abcdefghijklmnopqrs + 3 aes sha1 1024 abcdefghijklmnopqrst + 3 aes sha1 1024 abcdefghijklmnopqrstu + 3 aes sha1 1024 With_utf8_umlauts:???? + 3 aes sha1 1024 Long_sentence_used_as_passphrase + 3 aes sha1 10240 Long_sentence_used_as_passphrase + 3 aes sha1 102400 Long_sentence_used_as_passphrase + 3 aes192 sha1 1024 a + 3 aes192 sha1 1024 abcdefg + 3 aes192 sha1 1024 abcdefghi + 3 aes192 sha1 1024 abcdefghi + 3 aes192 sha1 1024 Long_sentence_used_as_passphrase + 3 aes256 sha1 1024 a + 3 aes256 sha1 1024 abcdefg + 3 aes256 sha1 1024 abcdefghi + 3 aes256 sha1 1024 abcdefghi + 3 aes256 sha1 1024 Long_sentence_used_as_passphrase + 0 aes sha256 1024 Long_sentence_used_as_passphrase + 1 aes sha256 1024 Long_sentence_used_as_passphrase + 3 aes sha256 1024 Long_sentence_used_as_passphrase + 3 aes sha256 10240 Long_sentence_used_as_passphrase + 3 aes sha384 1024 Long_sentence_used_as_passphrase + 3 aes sha512 1024 Long_sentence_used_as_passphrase + 3 aes256 sha512 1024 Long_sentence_used_as_passphrase + 3 3des sha512 1024 Long_sentence_used_as_passphrase + ===>8=== + + and finally using a proper utf-8 enabled shell, run: + + cat x.inp | while read mode cipher digest count pass dummy; do \ + ./gpg </dev/null -o /dev/null -c --passphrase "$pass" \ + --s2k-mode $mode --s2k-digest $digest --s2k-count $count \ + --cipher-algo $cipher ; done >x.out + */ + static struct { + const char *p; /* Passphrase. */ + size_t plen; /* Length of P. */ + int algo; + int hashalgo; + const char *salt; + size_t saltlen; + unsigned long c; /* Iterations. */ + int dklen; /* Requested key length. */ + const char *dk; /* Derived key. */ + int disabled; + } tv[] = { + { + "\x61", 1, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8\x31\xc3\x99\xe2\x69\x77\x26\x61" + }, + { + "\x61\x62", 2, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\x18\x7e\xf4\x43\x61\x22\xd1\xcc\x2f\x40\xdc\x2b\x92\xf0\xeb\xa0" + }, + { + "\x61\x62\x63", 3, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f\x72" + }, + { + "\x61\x62\x63\x64", 4, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\xe2\xfc\x71\x4c\x47\x27\xee\x93\x95\xf3\x24\xcd\x2e\x7f\x33\x1f" + }, + { + "\x61\x62\x63\x64\x65", 5, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\xab\x56\xb4\xd9\x2b\x40\x71\x3a\xcc\x5a\xf8\x99\x85\xd4\xb7\x86" + }, + { + "\x61\x62\x63\x64\x65\x66", 6, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\xe8\x0b\x50\x17\x09\x89\x50\xfc\x58\xaa\xd8\x3c\x8c\x14\x97\x8e" + }, + { + "\x61\x62\x63\x64\x65\x66\x67", 7, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\x7a\xc6\x6c\x0f\x14\x8d\xe9\x51\x9b\x8b\xd2\x64\x31\x2c\x4d\x64" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68", 8, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\xe8\xdc\x40\x81\xb1\x34\x34\xb4\x51\x89\xa7\x20\xb7\x7b\x68\x18" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\x8a\xa9\x9b\x1f\x43\x9f\xf7\x12\x93\xe9\x53\x57\xba\xc6\xfd\x94" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\x8a\x73\x19\xdb\xf6\x54\x4a\x74\x22\xc9\xe2\x54\x52\x58\x0e\xa5" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\x1d\x64\xdc\xe2\x39\xc4\x43\x7b\x77\x36\x04\x1d\xb0\x89\xe1\xb9" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" + "\x71", 17, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\x9a\x8d\x98\x45\xa6\xb4\xd8\x2d\xfc\xb2\xc2\xe3\x51\x62\xc8\x30" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\x35\x2a\xf0\xfc\xdf\xe9\xbb\x62\x16\xfc\x99\x9d\x8d\x58\x05\xcb" + }, + { + "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74" + "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, + NULL, 0, + 0, + 16, + "\x21\xa4\xeb\xd8\xfd\xf0\x59\x25\xd1\x32\x31\xdb\xe7\xf2\x13\x5d" + }, + { + "\x61", 1, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\x86\xf7\xe4\x37\xfa\xa5\xa7\xfc\xe1\x5d\x1d\xdc\xb9\xea\xea\xea" + }, + { + "\x61\x62", 2, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\xda\x23\x61\x4e\x02\x46\x9a\x0d\x7c\x7b\xd1\xbd\xab\x5c\x9c\x47" + }, + { + "\x61\x62\x63", 3, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\xa9\x99\x3e\x36\x47\x06\x81\x6a\xba\x3e\x25\x71\x78\x50\xc2\x6c" + }, + { + "\x61\x62\x63\x64", 4, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\x81\xfe\x8b\xfe\x87\x57\x6c\x3e\xcb\x22\x42\x6f\x8e\x57\x84\x73" + }, + { + "\x61\x62\x63\x64\x65", 5, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\x03\xde\x6c\x57\x0b\xfe\x24\xbf\xc3\x28\xcc\xd7\xca\x46\xb7\x6e" + }, + { + "\x61\x62\x63\x64\x65\x66", 6, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\x1f\x8a\xc1\x0f\x23\xc5\xb5\xbc\x11\x67\xbd\xa8\x4b\x83\x3e\x5c" + }, + { + "\x61\x62\x63\x64\x65\x66\x67", 7, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\x2f\xb5\xe1\x34\x19\xfc\x89\x24\x68\x65\xe7\xa3\x24\xf4\x76\xec" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68", 8, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\x42\x5a\xf1\x2a\x07\x43\x50\x2b\x32\x2e\x93\xa0\x15\xbc\xf8\x68" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\xc6\x3b\x19\xf1\xe4\xc8\xb5\xf7\x6b\x25\xc4\x9b\x8b\x87\xf5\x7d" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\x29\x38\xdc\xc2\xe3\xaa\x77\x98\x7c\x7e\x5d\x4a\x0f\x26\x96\x67" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\x14\xf3\x99\x52\x88\xac\xd1\x89\xe6\xe5\x0a\x7a\xf4\x7e\xe7\x09" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" + "\x71", 17, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\xd8\x3d\x62\x1f\xcd\x2d\x4d\x29\x85\x54\x70\x43\xa7\xa5\xfd\x4d" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" + "\x71\x72", 18, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\xe3\x81\xfe\x42\xc5\x7e\x48\xa0\x82\x17\x86\x41\xef\xfd\x1c\xb9" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" + "\x71\x72\x73", 19, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\x89\x3e\x69\xff\x01\x09\xf3\x45\x9c\x42\x43\x01\x3b\x3d\xe8\xb1" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" + "\x71\x72\x73\x74", 20, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\x14\xa2\x3a\xd7\x0f\x2a\x5d\xd7\x25\x57\x5d\xe6\xc4\x3e\x1c\xdd" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" + "\x71\x72\x73\x74\x75", 21, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\xec\xa9\x86\xb9\x5d\x58\x7f\x34\xd7\x1c\xa7\x75\x2a\x4e\x00\x10" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\x3e\x1b\x9a\x50\x7d\x6e\x9a\xd8\x93\x64\x96\x7a\x3f\xcb\x27\x3f" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 32, + "\x3e\x1b\x9a\x50\x7d\x6e\x9a\xd8\x93\x64\x96\x7a\x3f\xcb\x27\x3f" + "\xc3\x7b\x3a\xb2\xef\x4d\x68\xaa\x9c\xd7\xe4\x88\xee\xd1\x5e\x70" + }, + { + "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74" + "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, + NULL, 0, + 0, + 16, + "\xe0\x4e\x1e\xe3\xad\x0b\x49\x7c\x7a\x5f\x37\x3b\x4d\x90\x3c\x2e" + }, + { + "\x61", 1, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x6d\x47\xe3\x68\x5d\x2c\x36\x16", 8, + 1024, + 16, + "\x41\x9f\x48\x6e\xbf\xe6\xdd\x05\x9a\x72\x23\x17\x44\xd8\xd3\xf3" + }, + { + "\x61\x62", 2, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x7c\x34\x78\xfb\x28\x2d\x25\xc7", 8, + 1024, + 16, + "\x0a\x9d\x09\x06\x43\x3d\x4f\xf9\x87\xd6\xf7\x48\x90\xde\xd1\x1c" + }, + { + "\x61\x62\x63", 3, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\xc3\x16\x37\x2e\x27\xf6\x9f\x6f", 8, + 1024, + 16, + "\xf8\x27\xa0\x07\xc6\xcb\xdd\xf1\xfe\x5c\x88\x3a\xfc\xcd\x84\x4d" + }, + { + "\x61\x62\x63\x64", 4, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\xf0\x0c\x73\x38\xb7\xc3\xd5\x14", 8, + 1024, + 16, + "\x9b\x5f\x26\xba\x52\x3b\xcd\xd9\xa5\x2a\xef\x3c\x03\x4d\xd1\x52" + }, + { + "\x61\x62\x63\x64\x65", 5, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\xe1\x7d\xa2\x36\x09\x59\xee\xc5", 8, + 1024, + 16, + "\x94\x9d\x5b\x1a\x5a\x66\x8c\xfa\x8f\x6f\x22\xaf\x8b\x60\x9f\xaf" + }, + { + "\x61\x62\x63\x64\x65\x66", 6, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\xaf\xa7\x0c\x68\xdf\x7e\xaa\x27", 8, + 1024, + 16, + "\xe5\x38\xf4\x39\x62\x27\xcd\xcc\x91\x37\x7f\x1b\xdc\x58\x64\x27" + }, + { + "\x61\x62\x63\x64\x65\x66\x67", 7, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x40\x57\xb2\x9d\x5f\xbb\x11\x4f", 8, + 1024, + 16, + "\xad\xa2\x33\xd9\xdd\xe0\xfb\x94\x8e\xcc\xec\xcc\xb3\xa8\x3a\x9e" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68", 8, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x38\xf5\x65\xc5\x0f\x8c\x19\x61", 8, + 1024, + 16, + "\xa0\xb0\x3e\x29\x76\xe6\x8f\xa0\xd8\x34\x8f\xa4\x2d\xfd\x65\xee" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\xc3\xb7\x99\xcc\xda\x2d\x05\x7b", 8, + 1024, + 16, + "\x27\x21\xc8\x99\x5f\xcf\x20\xeb\xf2\xd9\xff\x6a\x69\xff\xad\xe8" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x7d\xd8\x68\x8a\x1c\xc5\x47\x22", 8, + 1024, + 16, + "\x0f\x96\x7a\x12\x23\x54\xf6\x92\x61\x67\x07\xb4\x68\x17\xb8\xaa" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x8a\x95\xd4\x88\x0b\xb8\xe9\x9d", 8, + 1024, + 16, + "\xcc\xe4\xc8\x82\x53\x32\xf1\x93\x5a\x00\xd4\x7f\xd4\x46\xfa\x07" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" + "\x71", 17, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\xb5\x22\x48\xa6\xc4\xad\x74\x67", 8, + 1024, + 16, + "\x0c\xe3\xe0\xee\x3d\x8f\x35\xd2\x35\x14\x14\x29\x0c\xf1\xe3\x34" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" + "\x71\x72", 18, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\xac\x9f\x04\x63\x83\x0e\x3c\x95", 8, + 1024, + 16, + "\x49\x0a\x04\x68\xa8\x2a\x43\x6f\xb9\x73\x94\xb4\x85\x9a\xaa\x0e" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" + "\x71\x72\x73", 19, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x03\x6f\x60\x30\x3a\x19\x61\x0d", 8, + 1024, + 16, + "\x15\xe5\x9b\xbf\x1c\xf0\xbe\x74\x95\x1a\xb2\xc4\xda\x09\xcd\x99" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" + "\x71\x72\x73\x74", 20, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x51\x40\xa5\x57\xf5\x28\xfd\x03", 8, + 1024, + 16, + "\xa6\xf2\x7e\x6b\x30\x4d\x8d\x67\xd4\xa2\x7f\xa2\x57\x27\xab\x96" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" + "\x71\x72\x73\x74\x75", 21, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x4c\xf1\x10\x11\x04\x70\xd3\x6e", 8, + 1024, + 16, + "\x2c\x50\x79\x8d\x83\x23\xac\xd6\x22\x29\x37\xaf\x15\x0d\xdd\x8f" + }, + { + "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74" + "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\xfe\x3a\x25\xcb\x78\xef\xe1\x21", 8, + 1024, + 16, + "\x2a\xb0\x53\x08\xf3\x2f\xd4\x6e\xeb\x01\x49\x5d\x87\xf6\x27\xf6" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x04\x97\xd0\x02\x6a\x44\x2d\xde", 8, + 1024, + 16, + "\x57\xf5\x70\x41\xa0\x9b\x8c\x09\xca\x74\xa9\x22\xa5\x82\x2d\x17" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\xdd\xf3\x31\x7c\xce\xf4\x81\x26", 8, + 10240, + 16, + "\xc3\xdd\x01\x6d\xaf\xf6\x58\xc8\xd7\x79\xb4\x40\x00\xb5\xe8\x0b" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x95\xd6\x72\x4e\xfb\xe1\xc3\x1a", 8, + 102400, + 16, + "\xf2\x3f\x36\x7f\xb4\x6a\xd0\x3a\x31\x9e\x65\x11\x8e\x2b\x99\x9b" + }, + { + "\x61", 1, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x6d\x69\x15\x18\xe4\x13\x42\x82", 8, + 1024, + 24, + "\x28\x0c\x7e\xf2\x31\xf6\x1c\x6b\x5c\xef\x6a\xd5\x22\x64\x97\x91" + "\xe3\x5e\x37\xfd\x50\xe2\xfc\x6c" + }, + { + "\x61\x62\x63\x64\x65\x66\x67", 7, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x9b\x76\x5e\x81\xde\x13\xdf\x15", 8, + 1024, + 24, + "\x91\x1b\xa1\xc1\x7b\x4f\xc3\xb1\x80\x61\x26\x08\xbe\x53\xe6\x50" + "\x40\x6f\x28\xed\xc6\xe6\x67\x55" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x7a\xac\xcc\x6e\x15\x56\xbd\xa1", 8, + 1024, + 24, + "\xfa\x7e\x20\x07\xb6\x47\xb0\x09\x46\xb8\x38\xfb\xa1\xaf\xf7\x75" + "\x2a\xfa\x77\x14\x06\x54\xcb\x34" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x1c\x68\xf8\xfb\x98\xf7\x8c\x39", 8, + 1024, + 24, + "\xcb\x1e\x86\xf5\xe0\xe4\xfb\xbf\x71\x34\x99\x24\xf4\x39\x8c\xc2" + "\x8e\x25\x1c\x4c\x96\x47\x22\xe8" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x10\xa9\x4e\xc1\xa5\xec\x17\x52", 8, + 1024, + 24, + "\x0f\x83\xa2\x77\x92\xbb\xe4\x58\x68\xc5\xf2\x14\x6e\x6e\x2e\x6b" + "\x98\x17\x70\x92\x07\x44\xe0\x51" + }, + { + "\x61", 1, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\xef\x8f\x37\x61\x8f\xab\xae\x4f", 8, + 1024, + 32, + "\x6d\x65\xae\x86\x23\x91\x39\x98\xec\x1c\x23\x44\xb6\x0d\xad\x32" + "\x54\x46\xc7\x23\x26\xbb\xdf\x4b\x54\x6e\xd4\xc2\xfa\xc6\x17\x17" + }, + { + "\x61\x62\x63\x64\x65\x66\x67", 7, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\xaa\xfb\xd9\x06\x7d\x7c\x40\xaf", 8, + 1024, + 32, + "\x7d\x10\x54\x13\x3c\x43\x7a\xb3\x54\x1f\x38\xd4\x8f\x70\x0a\x09" + "\xe2\xfa\xab\x97\x9a\x70\x16\xef\x66\x68\xca\x34\x2e\xce\xfa\x1f" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x58\x03\x4f\x56\x8b\x97\xd4\x98", 8, + 1024, + 32, + "\xf7\x40\xb1\x25\x86\x0d\x35\x8f\x9f\x91\x2d\xce\x04\xee\x5a\x04" + "\x9d\xbd\x44\x23\x4c\xa6\xbb\xab\xb0\xd0\x56\x82\xa9\xda\x47\x16" + }, + { + "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\x5d\x41\x3d\xa3\xa7\xfc\x5d\x0c", 8, + 1024, + 32, + "\x4c\x7a\x86\xed\x81\x8a\x94\x99\x7d\x4a\xc4\xf7\x1c\xf8\x08\xdb" + "\x09\x35\xd9\xa3\x2d\x22\xde\x32\x2d\x74\x38\xe5\xc8\xf2\x50\x6e" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, + "\xca\xa7\xdc\x59\xce\x31\xe7\x49", 8, + 1024, + 32, + "\x67\xe9\xd6\x29\x49\x1c\xb6\xa0\x85\xe8\xf9\x8b\x85\x47\x3a\x7e" + "\xa7\xee\x89\x52\x6f\x19\x00\x53\x93\x07\x0a\x8b\xb9\xa8\x86\x94" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA256, + NULL, 0, + 0, + 16, + "\x88\x36\x78\x6b\xd9\x5a\x62\xff\x47\xd3\xfb\x79\xc9\x08\x70\x56" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_SALTED_S2K, GCRY_MD_SHA256, + "\x05\x8b\xfe\x31\xaa\xf3\x29\x11", 8, + 0, + 16, + "\xb2\x42\xfe\x5e\x09\x02\xd9\x62\xb9\x35\xf3\xa8\x43\x80\x9f\xb1" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA256, + "\xd3\x4a\xea\xc9\x97\x1b\xcc\x83", 8, + 1024, + 16, + "\x35\x37\x99\x62\x07\x26\x68\x23\x05\x47\xb2\xa0\x0b\x2b\x2b\x8d" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA256, + "\x5e\x71\xbd\x00\x5f\x96\xc4\x23", 8, + 10240, + 16, + "\xa1\x6a\xee\xba\xde\x73\x25\x25\xd1\xab\xa0\xc5\x7e\xc6\x39\xa7" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA384, + "\xc3\x08\xeb\x17\x62\x08\x89\xef", 8, + 1024, + 16, + "\x9b\x7f\x0c\x81\x6f\x71\x59\x9b\xd5\xf6\xbf\x3a\x86\x20\x16\x33" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512, + "\xe6\x7d\x13\x6b\x39\xe3\x44\x05", 8, + 1024, + 16, + "\xc8\xcd\x4b\xa4\xf3\xf1\xd5\xb0\x59\x06\xf0\xbb\x89\x34\x6a\xad" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512, + "\xed\x7d\x30\x47\xe4\xc3\xf8\xb6", 8, + 1024, + 32, + "\x89\x7a\xef\x70\x97\xe7\x10\xdb\x75\xcc\x20\x22\xab\x7b\xf3\x05" + "\x4b\xb6\x2e\x17\x11\x9f\xd6\xeb\xbf\xdf\x4d\x70\x59\xf0\xf9\xe5" + }, + { + "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" + "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, + GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512, + "\xbb\x1a\x45\x30\x68\x62\x6d\x63", 8, + 1024, + 24, + "\xde\x5c\xb8\xd5\x75\xf6\xad\x69\x5b\xc9\xf6\x2f\xba\xeb\xfb\x36" + "\x34\xf2\xb8\xee\x3b\x37\x21\xb7" + } + }; + int tvidx; + gpg_error_t err; + unsigned char outbuf[32]; + int i; + + for (tvidx=0; tvidx < DIM(tv); tvidx++) + { + if (tv[tvidx].disabled) + continue; + if (verbose) + fprintf (stderr, "checking S2K test vector %d\n", tvidx); + assert (tv[tvidx].dklen <= sizeof outbuf); + err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen, + tv[tvidx].algo, tv[tvidx].hashalgo, + tv[tvidx].salt, tv[tvidx].saltlen, + tv[tvidx].c, tv[tvidx].dklen, outbuf); + if (err) + fail ("s2k test %d failed: %s\n", tvidx, gpg_strerror (err)); + else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen)) + { + fail ("s2k test %d failed: mismatch\n", tvidx); + fputs ("got:", stderr); + for (i=0; i < tv[tvidx].dklen; i++) + fprintf (stderr, " %02x", outbuf[i]); + putc ('\n', stderr); + } + } +} + + +static void +check_pbkdf2 (void) +{ + /* Test vectors are from RFC-6070. */ + static struct { + const char *p; /* Passphrase. */ + size_t plen; /* Length of P. */ + const char *salt; + size_t saltlen; + unsigned long c; /* Iterations. */ + int dklen; /* Requested key length. */ + const char *dk; /* Derived key. */ + int disabled; + } tv[] = { + { + "password", 8, + "salt", 4, + 1, + 20, + "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9" + "\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6" + }, + { + "password", 8, + "salt", 4, + 2, + 20, + "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e" + "\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57" + }, + { + "password", 8, + "salt", 4, + 4096, + 20, + "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad" + "\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1" + }, + { + "password", 8, + "salt", 4, + 16777216, + 20, + "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94" + "\x5b\x3d\x6b\xa2\x15\x8c\x26\x34\xe9\x84", + 1 /* This test takes too long. */ + }, + { + "passwordPASSWORDpassword", 24, + "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, + 4096, + 25, + "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8" + "\xd8\x36\x62\xc0\xe4\x4a\x8b\x29\x1a\x96" + "\x4c\xf2\xf0\x70\x38" + }, + { + "pass\0word", 9, + "sa\0lt", 5, + 4096, + 16, + "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37" + "\xd7\xf0\x34\x25\xe0\xc3" + } + }; + int tvidx; + gpg_error_t err; + unsigned char outbuf[32]; + int i; + + for (tvidx=0; tvidx < DIM(tv); tvidx++) + { + if (tv[tvidx].disabled) + continue; + if (verbose) + fprintf (stderr, "checking PBKDF2 test vector %d\n", tvidx); + assert (tv[tvidx].dklen <= sizeof outbuf); + err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen, + GCRY_KDF_PBKDF2, GCRY_MD_SHA1, + tv[tvidx].salt, tv[tvidx].saltlen, + tv[tvidx].c, tv[tvidx].dklen, outbuf); + if (err) + fail ("pbkdf2 test %d failed: %s\n", tvidx, gpg_strerror (err)); + else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen)) + { + fail ("pbkdf2 test %d failed: mismatch\n", tvidx); + fputs ("got:", stderr); + for (i=0; i < tv[tvidx].dklen; i++) + fprintf (stderr, " %02x", outbuf[i]); + putc ('\n', stderr); + } + } +} + + +int +main (int argc, char **argv) +{ + int debug = 0; + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + + check_openpgp (); + check_pbkdf2 (); + + return error_count ? 1 : 0; +} ----------------------------------------------------------------------- Summary of changes: NEWS | 4 + cipher/ChangeLog | 4 + cipher/Makefile.am | 2 +- cipher/kdf.c | 278 +++++++++++++++ doc/gcrypt.texi | 62 ++++- src/ChangeLog | 7 + src/gcrypt.h.in | 27 ++ src/libgcrypt.def | 2 + src/libgcrypt.vers | 2 + src/visibility.c | 11 + src/visibility.h | 6 + tests/Makefile.am | 2 +- tests/t-kdf.c | 974 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 1378 insertions(+), 3 deletions(-) create mode 100644 cipher/kdf.c create mode 100644 tests/t-kdf.c hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 9 20:53:30 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 09 Mar 2011 20:53:30 +0100 Subject: [git] Assuan - branch, master, updated. libassuan-2.0.1-32-gb00ae50 Message-ID: <E1PxOjZ-0004fR-7P@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPC library used by GnuPG". The branch, master has been updated via b00ae5099d3e6eda3cb7d1d1cfb0cbfd87e918f1 (commit) via 5666ade7de25239a36afe0f279b46a0deff1a867 (commit) via 79bb873edd4696fc56a0aaf91c9d11c3791691c0 (commit) from 8660e89916d7e0d0df59939affd07c6ed78a7313 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b00ae5099d3e6eda3cb7d1d1cfb0cbfd87e918f1 Author: Werner Koch <wk at gnupg.org> Date: Wed Mar 9 20:28:18 2011 +0100 Replace strcasecmp by ascii_strcasecmp variant/ diff --git a/src/ChangeLog b/src/ChangeLog index 0ba2a2c..a27401d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2011-03-09 Werner Koch <wk at g10code.com> + + * assuan-handler.c (assuan_register_command): Use my_strcasecmp. + 2011-03-06 Ben Kibbey <bjk at luxsci.net> * assuan-socket-connect.c (assuan_socket_connect_fd): Finalize a diff --git a/src/assuan-handler.c b/src/assuan-handler.c index 799d058..692bdd0 100644 --- a/src/assuan-handler.c +++ b/src/assuan-handler.c @@ -1,4 +1,4 @@ -/* assuan-handler.c - dispatch commands +/* assuan-handler.c - dispatch commands Copyright (C) 2001, 2002, 2003, 2007, 2009 Free Software Foundation, Inc. This file is part of Assuan. @@ -53,7 +53,7 @@ std_handler_nop (assuan_context_t ctx, char *line) { return PROCESS_DONE (ctx, 0); /* okay */ } - + static gpg_error_t std_handler_cancel (assuan_context_t ctx, char *line) { @@ -115,7 +115,7 @@ std_handler_option (assuan_context_t ctx, char *line) return PROCESS_DONE (ctx, ctx->option_handler_fnc (ctx, key, value)); return PROCESS_DONE (ctx, 0); } - + static gpg_error_t std_handler_bye (assuan_context_t ctx, char *line) { @@ -128,13 +128,13 @@ std_handler_bye (assuan_context_t ctx, char *line) ctx->process_complete = 1; return PROCESS_DONE (ctx, 0); } - + static gpg_error_t std_handler_auth (assuan_context_t ctx, char *line) { return PROCESS_DONE (ctx, set_error (ctx, GPG_ERR_NOT_IMPLEMENTED, NULL)); } - + static gpg_error_t std_handler_reset (assuan_context_t ctx, char *line) { @@ -150,7 +150,7 @@ std_handler_reset (assuan_context_t ctx, char *line) } return PROCESS_DONE (ctx, err); } - + static gpg_error_t std_handler_help (assuan_context_t ctx, char *line) { @@ -168,7 +168,7 @@ std_handler_help (assuan_context_t ctx, char *line) for (i = 0; i < ctx->cmdtbl_used; i++) { n = strlen (ctx->cmdtbl[i].name); - helpstr = ctx->cmdtbl[i].helpstr; + helpstr = ctx->cmdtbl[i].helpstr; if (helpstr && !strncmp (ctx->cmdtbl[i].name, helpstr, n) && (!helpstr[n] || helpstr[n] == '\n' || helpstr[n] == ' ') @@ -191,7 +191,7 @@ std_handler_help (assuan_context_t ctx, char *line) line[n] = c; if (!ctx->cmdtbl[i].name) return PROCESS_DONE (ctx, set_error (ctx,GPG_ERR_UNKNOWN_COMMAND,NULL)); - helpstr = ctx->cmdtbl[i].helpstr; + helpstr = ctx->cmdtbl[i].helpstr; if (!helpstr) return PROCESS_DONE (ctx, set_error (ctx, GPG_ERR_NOT_FOUND, NULL)); do @@ -295,7 +295,7 @@ std_handler_output (assuan_context_t ctx, char *line) { gpg_error_t rc; assuan_fd_t fd, oldfd; - + rc = assuan_command_parse_fd (ctx, line, &fd); if (rc) return PROCESS_DONE (ctx, rc); @@ -340,7 +340,7 @@ static struct { { "RESET", std_handler_reset, 1 }, { "END", std_handler_end, 1 }, { "HELP", std_handler_help, 1 }, - + { "INPUT", std_handler_input, 0 }, { "OUTPUT", std_handler_output, 0 }, { NULL, NULL, 0 } @@ -354,11 +354,11 @@ static struct { * @handler: The handler function to be called or NULL to use a default * handler. * HELPSTRING - * + * * Register a handler to be used for a given command. Note that * several default handlers are already regsitered with a new context. * This function however allows to override them. - * + * * Return value: 0 on success or an error code **/ gpg_error_t @@ -389,7 +389,7 @@ assuan_register_command (assuan_context_t ctx, const char *cmd_name, if (!handler) handler = dummy_handler; /* Last resort is the dummy handler. */ } - + if (!ctx->cmdtbl) { ctx->cmdtbl_size = 50; @@ -411,7 +411,7 @@ assuan_register_command (assuan_context_t ctx, const char *cmd_name, for (i=0; i<ctx->cmdtbl_used; i++) { - if (!strcasecmp(ctx->cmdtbl[i].name, cmd_name)) + if (!my_strcasecmp (cmd_name, ctx->cmdtbl[i].name)) { cmd_index = i; break; @@ -530,7 +530,7 @@ _assuan_register_std_commands (assuan_context_t ctx) if (rc) return rc; } - } + } return 0; } @@ -585,8 +585,8 @@ dispatch_command (assuan_context_t ctx, char *line, int linelen) ; if (p==line) return PROCESS_DONE - (ctx, set_error (ctx, GPG_ERR_ASS_SYNTAX, "leading white-space")); - if (*p) + (ctx, set_error (ctx, GPG_ERR_ASS_SYNTAX, "leading white-space")); + if (*p) { /* Skip over leading WS after the keyword */ *p++ = 0; while ( *p == ' ' || *p == '\t') @@ -652,26 +652,26 @@ assuan_process_done (assuan_context_t ctx, gpg_error_t rc) if (!rc && ctx->outbound.data.error) rc = ctx->outbound.data.error; } - + /* Error handling. */ if (!rc) { if (ctx->process_complete) { /* No error checking because the peer may have already - disconnect. */ + disconnect. */ assuan_write_line (ctx, "OK closing connection"); ctx->finish_handler (ctx); } else rc = assuan_write_line (ctx, ctx->okay_line ? ctx->okay_line : "OK"); } - else + else { char errline[300]; const char *text = ctx->err_no == rc ? ctx->err_str : NULL; char ebuf[50]; - + gpg_strerror_r (rc, ebuf, sizeof (ebuf)); sprintf (errline, "ERR %d %.50s <%.30s>%s%.100s", rc, ebuf, gpg_strsource (rc), @@ -679,10 +679,10 @@ assuan_process_done (assuan_context_t ctx, gpg_error_t rc) rc = assuan_write_line (ctx, errline); } - + if (ctx->post_cmd_notify_fnc) ctx->post_cmd_notify_fnc (ctx, rc); - + ctx->flags.confidential = 0; if (ctx->okay_line) { @@ -816,11 +816,11 @@ process_request (assuan_context_t ctx) /** * assuan_process: * @ctx: assuan context - * + * * This function is used to handle the assuan protocol after a * connection has been established using assuan_accept(). This is the * main protocol handler. - * + * * Return value: 0 on success or an error code if the assuan operation * failed. Note, that no error is returned for operational errors. **/ @@ -844,18 +844,18 @@ assuan_process (assuan_context_t ctx) * @what: 0 for read fds, 1 for write fds * @fdarray: Caller supplied array to store the FDs * @fdarraysize: size of that array - * + * * Return all active filedescriptors for the given context. This * function can be used to select on the fds and call * assuan_process_next() if there is an active one. The first fd in * the array is the one used for the command connection. * * Note, that write FDs are not yet supported. - * + * * Return value: number of FDs active and put into @fdarray or -1 on * error which is most likely a too small fdarray. **/ -int +int assuan_get_active_fds (assuan_context_t ctx, int what, assuan_fd_t *fdarray, int fdarraysize) { @@ -917,14 +917,14 @@ assuan_get_data_fp (assuan_context_t ctx) #if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN) if (ctx->outbound.data.fp) return ctx->outbound.data.fp; - + #ifdef HAVE_FUNOPEN ctx->outbound.data.fp = funopen (ctx, 0, fun1_cookie_write, 0, _assuan_cookie_write_flush); #else ctx->outbound.data.fp = funopen (ctx, 0, fun2_cookie_write, 0, _assuan_cookie_write_flush); -#endif +#endif ctx->outbound.data.error = 0; return ctx->outbound.data.fp; commit 5666ade7de25239a36afe0f279b46a0deff1a867 Author: bjk at luxsci.net <bjk at luxsci.net> Date: Sun Mar 6 16:18:45 2011 -0500 Added assuan_socket_connect_fd() to attach an existing socket file descriptor to a context. diff --git a/src/ChangeLog b/src/ChangeLog index 5568549..0ba2a2c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2011-03-06 Ben Kibbey <bjk at luxsci.net> + + * assuan-socket-connect.c (assuan_socket_connect_fd): Finalize a + context connection from an already connected socket descriptor. + * assuan.h.in (assuan_socket_connect_fd): New prototype. + 2011-03-05 Ben Kibbey <bjk at luxsci.net> * assuan-handler.c (assuan_register_command): Let an existing command diff --git a/src/assuan-socket-connect.c b/src/assuan-socket-connect.c index fa3db4b..cb8f9d0 100644 --- a/src/assuan-socket-connect.c +++ b/src/assuan-socket-connect.c @@ -97,6 +97,69 @@ parse_portno (const char *str, uint16_t *r_port) } +static gpg_error_t +_assuan_connect_finalize(assuan_context_t ctx, int fd, unsigned int flags) +{ + gpg_error_t err; + + ctx->engine.release = _assuan_client_release; + ctx->engine.readfnc = _assuan_simple_read; + ctx->engine.writefnc = _assuan_simple_write; + ctx->engine.sendfd = NULL; + ctx->engine.receivefd = NULL; + ctx->finish_handler = _assuan_client_finish; + ctx->inbound.fd = fd; + ctx->outbound.fd = fd; + ctx->max_accepts = -1; + + if (flags & ASSUAN_SOCKET_CONNECT_FDPASSING) + _assuan_init_uds_io (ctx); + + /* initial handshake */ + { + assuan_response_t response; + int off; + + err = _assuan_read_from_server (ctx, &response, &off, 0); + if (err) + TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect", ctx, + "can't connect to server: %s\n", gpg_strerror (err)); + else if (response != ASSUAN_RESPONSE_OK) + { + char *sname = _assuan_encode_c_string (ctx, ctx->inbound.line); + if (sname) + { + TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect", ctx, + "can't connect to server: %s", sname); + _assuan_free (ctx, sname); + } + err = _assuan_error (ctx, GPG_ERR_ASS_CONNECT_FAILED); + } + } + + return err; +} + + +/* Attach an existing connected file descriptor FD to an allocated handle CTX + * and initialize the connection. + */ +gpg_error_t +assuan_socket_connect_fd (assuan_context_t ctx, int fd, unsigned int flags) +{ + gpg_error_t err; + + if (!ctx || fd < 0) + return GPG_ERR_INV_ARG; + + err = _assuan_connect_finalize(ctx, fd, flags); + + if (err) + _assuan_reset (ctx); + + return err; +} + /* Make a connection to the Unix domain socket NAME and return a new Assuan context in CTX. SERVER_PID is currently not used but may @@ -268,41 +331,8 @@ assuan_socket_connect (assuan_context_t ctx, const char *name, return _assuan_error (ctx, GPG_ERR_ASS_CONNECT_FAILED); } - ctx->engine.release = _assuan_client_release; - ctx->engine.readfnc = _assuan_simple_read; - ctx->engine.writefnc = _assuan_simple_write; - ctx->engine.sendfd = NULL; - ctx->engine.receivefd = NULL; - ctx->finish_handler = _assuan_client_finish; - ctx->inbound.fd = fd; - ctx->outbound.fd = fd; - ctx->max_accepts = -1; + err = _assuan_connect_finalize(ctx, fd, flags); - if (flags & ASSUAN_SOCKET_CONNECT_FDPASSING) - _assuan_init_uds_io (ctx); - - /* initial handshake */ - { - assuan_response_t response; - int off; - - err = _assuan_read_from_server (ctx, &response, &off, 0); - if (err) - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect", ctx, - "can't connect to server: %s\n", gpg_strerror (err)); - else if (response != ASSUAN_RESPONSE_OK) - { - char *sname = _assuan_encode_c_string (ctx, ctx->inbound.line); - if (sname) - { - TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect", ctx, - "can't connect to server: %s", sname); - _assuan_free (ctx, sname); - } - err = _assuan_error (ctx, GPG_ERR_ASS_CONNECT_FAILED); - } - } - if (err) _assuan_reset (ctx); diff --git a/src/assuan.h.in b/src/assuan.h.in index 426fc4c..9ff263f 100644 --- a/src/assuan.h.in +++ b/src/assuan.h.in @@ -358,6 +358,10 @@ gpg_error_t assuan_pipe_connect (assuan_context_t ctx, gpg_error_t assuan_socket_connect (assuan_context_t ctx, const char *name, pid_t server_pid, unsigned int flags); +/*-- assuan-socket-connect.c --*/ +gpg_error_t assuan_socket_connect_fd (assuan_context_t ctx, int fd, + unsigned int flags); + /*-- context.c --*/ pid_t assuan_get_pid (assuan_context_t ctx); struct _assuan_peercred diff --git a/src/libassuan.def b/src/libassuan.def index 575966d..9287486 100644 --- a/src/libassuan.def +++ b/src/libassuan.def @@ -104,6 +104,7 @@ EXPORTS __assuan_socket @83 __assuan_connect @84 assuan_register_pre_cmd_notify @85 + assuan_socket_connect_fd @86 ; END diff --git a/src/libassuan.vers b/src/libassuan.vers index 6311ff1..8126fab 100644 --- a/src/libassuan.vers +++ b/src/libassuan.vers @@ -99,6 +99,7 @@ LIBASSUAN_1.0 { assuan_write_line; assuan_write_status; assuan_free; + assuan_socket_connect_fd; __assuan_close; __assuan_pipe; commit 79bb873edd4696fc56a0aaf91c9d11c3791691c0 Author: bjk at luxsci.net <bjk at luxsci.net> Date: Sat Mar 5 20:06:57 2011 -0500 Let an existing command previously registered with assuan_register_command() be updated with new values. This fixes overriding the HELP command for example. diff --git a/src/ChangeLog b/src/ChangeLog index a12b9cb..5568549 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,8 @@ +2011-03-05 Ben Kibbey <bjk at luxsci.net> + + * assuan-handler.c (assuan_register_command): Let an existing command + be updated to the new values. + 2011-02-28 Werner Koch <wk at g10code.com> * libassuan.vers: Fold LIBASSUAN_1.1 block into LIBASSUAN_1.0. diff --git a/src/assuan-handler.c b/src/assuan-handler.c index cb271fa..799d058 100644 --- a/src/assuan-handler.c +++ b/src/assuan-handler.c @@ -365,7 +365,7 @@ gpg_error_t assuan_register_command (assuan_context_t ctx, const char *cmd_name, assuan_handler_t handler, const char *help_string) { - int i; + int i, cmd_index = -1; const char *s; if (cmd_name && !*cmd_name) @@ -409,10 +409,21 @@ assuan_register_command (assuan_context_t ctx, const char *cmd_name, ctx->cmdtbl_size += 50; } - ctx->cmdtbl[ctx->cmdtbl_used].name = cmd_name; - ctx->cmdtbl[ctx->cmdtbl_used].handler = handler; - ctx->cmdtbl[ctx->cmdtbl_used].helpstr = help_string; - ctx->cmdtbl_used++; + for (i=0; i<ctx->cmdtbl_used; i++) + { + if (!strcasecmp(ctx->cmdtbl[i].name, cmd_name)) + { + cmd_index = i; + break; + } + } + + if (cmd_index == -1) + cmd_index = ctx->cmdtbl_used++; + + ctx->cmdtbl[cmd_index].name = cmd_name; + ctx->cmdtbl[cmd_index].handler = handler; + ctx->cmdtbl[cmd_index].helpstr = help_string; return 0; } ----------------------------------------------------------------------- Summary of changes: src/ChangeLog | 15 +++++++ src/assuan-handler.c | 79 ++++++++++++++++++++--------------- src/assuan-socket-connect.c | 98 ++++++++++++++++++++++++++++--------------- src/assuan.h.in | 4 ++ src/libassuan.def | 1 + src/libassuan.vers | 1 + 6 files changed, 130 insertions(+), 68 deletions(-) hooks/post-receive -- IPC library used by GnuPG http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 10 15:55:58 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 10 Mar 2011 15:55:58 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-35-g35c731d Message-ID: <E1PxgZ3-0000Rk-5J@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via 35c731d88937c6711d27660d08cdb8d458dee848 (commit) from 87a6a1c3fe4b86a7db30fcce4d1e21e86d561e0f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 35c731d88937c6711d27660d08cdb8d458dee848 Author: Werner Koch <wk at gnupg.org> Date: Thu Mar 10 15:27:10 2011 +0100 Support pkcs#12 import of PBES2 encoded data. This is so that we read compatible with gnutls's certtool. Only AES-128 is supported. The latest Libgcrypt from git is required. Fixes bug#1321. diff --git a/sm/ChangeLog b/sm/ChangeLog index dc5989a..30e71ba 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,12 @@ +2011-03-10 Werner Koch <wk at g10code.com> + + * minip12.c (oid_pkcs5PBKDF2, oid_pkcs5PBES2, oid_aes128_CBC): New. + (set_key_iv_pbes2): New. + (crypt_block): Add args IV and IVLEN. Call set_key_iv_pbes2. + (decrypt_block): Add args IV and IVLEN. + (parse_bag_encrypted_data): Hack to support PBES2 data. + (parse_bag_data): Ditto. + 2011-03-03 Werner Koch <wk at g10code.com> * base64.c (base64_finish_write): Do not copy to radbuf to get rid diff --git a/sm/minip12.c b/sm/minip12.c index 10f7c99..7b53a81 100644 --- a/sm/minip12.c +++ b/sm/minip12.c @@ -1,5 +1,5 @@ /* minip12.c - A minimal pkcs-12 implementation. - * Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc. + * Copyright (C) 2002, 2003, 2004, 2006, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -104,6 +104,12 @@ static unsigned char const oid_pbeWithSHAAnd40BitRC2_CBC[10] = { static unsigned char const oid_x509Certificate_for_pkcs_12[10] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x16, 0x01 }; +static unsigned char const oid_pkcs5PBKDF2[9] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0C }; +static unsigned char const oid_pkcs5PBES2[9] = { + 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x05, 0x0D }; +static unsigned char const oid_aes128_CBC[9] = { + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02 }; static unsigned char const oid_rsaEncryption[9] = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 }; @@ -447,9 +453,54 @@ set_key_iv (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter, } +static int +set_key_iv_pbes2 (gcry_cipher_hd_t chd, char *salt, size_t saltlen, int iter, + const void *iv, size_t ivlen, const char *pw, int algo) +{ + unsigned char *keybuf; + size_t keylen; + int rc; + + keylen = gcry_cipher_get_algo_keylen (algo); + if (!keylen) + return -1; + keybuf = gcry_malloc_secure (keylen); + if (!keybuf) + return -1; + + rc = gcry_kdf_derive (pw, strlen (pw), + GCRY_KDF_PBKDF2, GCRY_MD_SHA1, + salt, saltlen, iter, keylen, keybuf); + if (rc) + { + log_error ("gcry_kdf_derive failed: %s\n", gpg_strerror (rc)); + gcry_free (keybuf); + return -1; + } + + rc = gcry_cipher_setkey (chd, keybuf, keylen); + gcry_free (keybuf); + if (rc) + { + log_error ("gcry_cipher_setkey failed: %s\n", gpg_strerror (rc)); + return -1; + } + + + rc = gcry_cipher_setiv (chd, iv, ivlen); + if (rc) + { + log_error ("gcry_cipher_setiv failed: %s\n", gpg_strerror (rc)); + return -1; + } + return 0; +} + + static void crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen, - int iter, const char *pw, int cipher_algo, int encrypt) + int iter, const void *iv, size_t ivlen, + const char *pw, int cipher_algo, int encrypt) { gcry_cipher_hd_t chd; int rc; @@ -461,8 +512,11 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen, wipememory (buffer, length); return; } - if (set_key_iv (chd, salt, saltlen, iter, pw, - cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24)) + + if (cipher_algo == GCRY_CIPHER_AES128 + ? set_key_iv_pbes2 (chd, salt, saltlen, iter, iv, ivlen, pw, cipher_algo) + : set_key_iv (chd, salt, saltlen, iter, pw, + cipher_algo == GCRY_CIPHER_RFC2268_40? 5:24)) { wipememory (buffer, length); goto leave; @@ -495,7 +549,8 @@ crypt_block (unsigned char *buffer, size_t length, char *salt, size_t saltlen, static void decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length, char *salt, size_t saltlen, - int iter, const char *pw, int cipher_algo, + int iter, const void *iv, size_t ivlen, + const char *pw, int cipher_algo, int (*check_fnc) (const void *, size_t)) { static const char * const charsets[] = { @@ -566,7 +621,7 @@ decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length, charsets[charsetidx]); } memcpy (plaintext, ciphertext, length); - crypt_block (plaintext, length, salt, saltlen, iter, + crypt_block (plaintext, length, salt, saltlen, iter, iv, ivlen, convertedpw? convertedpw:pw, cipher_algo, 0); if (check_fnc (plaintext, length)) break; /* Decryption succeeded. */ @@ -618,12 +673,14 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length, const char *where; char salt[20]; size_t saltlen; + char iv[16]; unsigned int iter; unsigned char *plain = NULL; int bad_pass = 0; unsigned char *cram_buffer = NULL; size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */ int is_3des = 0; + int is_pbes2 = 0; gcry_mpi_t *result = NULL; int result_count; @@ -683,35 +740,111 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length, n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); is_3des = 1; } + else if (!ti.class && ti.tag == TAG_OBJECT_ID + && ti.length == DIM(oid_pkcs5PBES2) + && !memcmp (p, oid_pkcs5PBES2, ti.length)) + { + p += ti.length; + n -= ti.length; + is_pbes2 = 1; + } else goto bailout; - where = "rc2or3des-params"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_OCTET_STRING - || ti.length < 8 || ti.length > 20 ) - goto bailout; - saltlen = ti.length; - memcpy (salt, p, saltlen); - p += saltlen; - n -= saltlen; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_INTEGER || !ti.length ) - goto bailout; - for (iter=0; ti.length; ti.length--) + if (is_pbes2) + { + where = "pkcs5PBES2-params"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (!(!ti.class && ti.tag == TAG_OBJECT_ID + && ti.length == DIM(oid_pkcs5PBKDF2) + && !memcmp (p, oid_pkcs5PBKDF2, ti.length))) + goto bailout; /* Not PBKDF2. */ + p += ti.length; + n -= ti.length; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (!(!ti.class && ti.tag == TAG_OCTET_STRING + && ti.length >= 8 && ti.length < sizeof salt)) + goto bailout; /* No salt or unsupported length. */ + saltlen = ti.length; + memcpy (salt, p, saltlen); + p += saltlen; + n -= saltlen; + + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (!(!ti.class && ti.tag == TAG_INTEGER && ti.length)) + goto bailout; /* No valid iteration count. */ + for (iter=0; ti.length; ti.length--) + { + iter <<= 8; + iter |= (*p++) & 0xff; + n--; + } + /* Note: We don't support the optional parameters but assume + that the algorithmIdentifier follows. */ + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (!(!ti.class && ti.tag == TAG_OBJECT_ID + && ti.length == DIM(oid_aes128_CBC) + && !memcmp (p, oid_aes128_CBC, ti.length))) + goto bailout; /* Not AES-128. */ + p += ti.length; + n -= ti.length; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (!(!ti.class && ti.tag == TAG_OCTET_STRING && ti.length == sizeof iv)) + goto bailout; /* Bad IV. */ + memcpy (iv, p, sizeof iv); + p += sizeof iv; + n -= sizeof iv; + } + else { - iter <<= 8; - iter |= (*p++) & 0xff; - n--; + where = "rc2or3des-params"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_OCTET_STRING + || ti.length < 8 || ti.length > 20 ) + goto bailout; + saltlen = ti.length; + memcpy (salt, p, saltlen); + p += saltlen; + n -= saltlen; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_INTEGER || !ti.length ) + goto bailout; + for (iter=0; ti.length; ti.length--) + { + iter <<= 8; + iter |= (*p++) & 0xff; + n--; + } } - where = "rc2or3des-ciphertext"; + where = "rc2or3desoraes-ciphertext"; if (parse_tag (&p, &n, &ti)) goto bailout; @@ -735,7 +868,8 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length, else goto bailout; - log_info ("%lu bytes of %s encrypted text\n",ti.length,is_3des?"3DES":"RC2"); + log_info ("%lu bytes of %s encrypted text\n",ti.length, + is_pbes2?"AES128":is_3des?"3DES":"RC2"); plain = gcry_malloc_secure (ti.length); if (!plain) @@ -743,8 +877,10 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length, log_error ("error allocating decryption buffer\n"); goto bailout; } - decrypt_block (p, plain, ti.length, salt, saltlen, iter, pw, - is_3des? GCRY_CIPHER_3DES : GCRY_CIPHER_RFC2268_40, + decrypt_block (p, plain, ti.length, salt, saltlen, iter, + iv, is_pbes2?16:0, pw, + is_pbes2 ? GCRY_CIPHER_AES128 : + is_3des ? GCRY_CIPHER_3DES : GCRY_CIPHER_RFC2268_40, bag_decrypted_data_p); n = ti.length; startoffset = 0; @@ -950,7 +1086,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length, that is less or equal to the cipher's block length. We can reasonable assume that all valid data will be longer than just one block. */ - if (n <= 8) + if (n <= (is_pbes2? 16:8)) n = 0; /* Skip the optional SET with the pkcs12 cert attributes. */ @@ -965,7 +1101,7 @@ parse_bag_encrypted_data (const unsigned char *buffer, size_t length, { /* The optional SET. */ p += ti.length; n -= ti.length; - if (n <= 8) + if (n <= (is_pbes2?16:8)) n = 0; if (n && parse_tag (&p, &n, &ti)) goto bailout; @@ -1049,6 +1185,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset, const char *where; char salt[20]; size_t saltlen; + char iv[16]; unsigned int iter; int len; unsigned char *plain = NULL; @@ -1056,6 +1193,7 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset, int result_count, i; unsigned char *cram_buffer = NULL; size_t consumed = 0; /* Number of bytes consumed from the orginal buffer. */ + int is_pbes2 = 0; where = "start"; if (parse_tag (&p, &n, &ti)) @@ -1119,46 +1257,126 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset, goto bailout; if (parse_tag (&p, &n, &ti)) goto bailout; - if (ti.class || ti.tag != TAG_OBJECT_ID - || ti.length != DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC) - || memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC, - DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC))) + if (ti.class == 0 && ti.tag == TAG_OBJECT_ID + && ti.length == DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC) + && !memcmp (p, oid_pbeWithSHAAnd3_KeyTripleDES_CBC, + DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC))) + { + p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); + n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); + } + else if (ti.class == 0 && ti.tag == TAG_OBJECT_ID + && ti.length == DIM(oid_pkcs5PBES2) + && !memcmp (p, oid_pkcs5PBES2, DIM(oid_pkcs5PBES2))) + { + p += DIM(oid_pkcs5PBES2); + n -= DIM(oid_pkcs5PBES2); + is_pbes2 = 1; + } + else goto bailout; - p += DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); - n -= DIM(oid_pbeWithSHAAnd3_KeyTripleDES_CBC); - where = "3des-params"; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_SEQUENCE) - goto bailout; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_OCTET_STRING - || ti.length < 8 || ti.length > 20) - goto bailout; - saltlen = ti.length; - memcpy (salt, p, saltlen); - p += saltlen; - n -= saltlen; - if (parse_tag (&p, &n, &ti)) - goto bailout; - if (ti.class || ti.tag != TAG_INTEGER || !ti.length ) - goto bailout; - for (iter=0; ti.length; ti.length--) + if (is_pbes2) + { + where = "pkcs5PBES2-params"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (!(!ti.class && ti.tag == TAG_OBJECT_ID + && ti.length == DIM(oid_pkcs5PBKDF2) + && !memcmp (p, oid_pkcs5PBKDF2, ti.length))) + goto bailout; /* Not PBKDF2. */ + p += ti.length; + n -= ti.length; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (!(!ti.class && ti.tag == TAG_OCTET_STRING + && ti.length >= 8 && ti.length < sizeof salt)) + goto bailout; /* No salt or unsupported length. */ + saltlen = ti.length; + memcpy (salt, p, saltlen); + p += saltlen; + n -= saltlen; + + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (!(!ti.class && ti.tag == TAG_INTEGER && ti.length)) + goto bailout; /* No valid iteration count. */ + for (iter=0; ti.length; ti.length--) + { + iter <<= 8; + iter |= (*p++) & 0xff; + n--; + } + /* Note: We don't support the optional parameters but assume + that the algorithmIdentifier follows. */ + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (!(!ti.class && ti.tag == TAG_OBJECT_ID + && ti.length == DIM(oid_aes128_CBC) + && !memcmp (p, oid_aes128_CBC, ti.length))) + goto bailout; /* Not AES-128. */ + p += ti.length; + n -= ti.length; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (!(!ti.class && ti.tag == TAG_OCTET_STRING && ti.length == sizeof iv)) + goto bailout; /* Bad IV. */ + memcpy (iv, p, sizeof iv); + p += sizeof iv; + n -= sizeof iv; + } + else { - iter <<= 8; - iter |= (*p++) & 0xff; - n--; + where = "3des-params"; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_SEQUENCE) + goto bailout; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_OCTET_STRING + || ti.length < 8 || ti.length > 20) + goto bailout; + saltlen = ti.length; + memcpy (salt, p, saltlen); + p += saltlen; + n -= saltlen; + if (parse_tag (&p, &n, &ti)) + goto bailout; + if (ti.class || ti.tag != TAG_INTEGER || !ti.length ) + goto bailout; + for (iter=0; ti.length; ti.length--) + { + iter <<= 8; + iter |= (*p++) & 0xff; + n--; + } } - where = "3des-ciphertext"; + where = "3desoraes-ciphertext"; if (parse_tag (&p, &n, &ti)) goto bailout; if (ti.class || ti.tag != TAG_OCTET_STRING || !ti.length ) goto bailout; - log_info ("%lu bytes of 3DES encrypted text\n", ti.length); + log_info ("%lu bytes of %s encrypted text\n", + ti.length, is_pbes2? "AES128":"3DES"); plain = gcry_malloc_secure (ti.length); if (!plain) @@ -1167,8 +1385,9 @@ parse_bag_data (const unsigned char *buffer, size_t length, int startoffset, goto bailout; } consumed += p - p_start + ti.length; - decrypt_block (p, plain, ti.length, salt, saltlen, iter, pw, - GCRY_CIPHER_3DES, + decrypt_block (p, plain, ti.length, salt, saltlen, iter, + iv, is_pbes2? 16:0, pw, + is_pbes2? GCRY_CIPHER_AES128 : GCRY_CIPHER_3DES, bag_data_p); n = ti.length; startoffset = 0; @@ -2223,7 +2442,7 @@ p12_build (gcry_mpi_t *kparms, const void *cert, size_t certlen, /* Encrypt it. */ gcry_randomize (salt, 8, GCRY_STRONG_RANDOM); - crypt_block (buffer, buflen, salt, 8, 2048, pw, + crypt_block (buffer, buflen, salt, 8, 2048, NULL, 0, pw, GCRY_CIPHER_RFC2268_40, 1); /* Encode the encrypted stuff into a bag. */ @@ -2246,7 +2465,8 @@ p12_build (gcry_mpi_t *kparms, const void *cert, size_t certlen, /* Encrypt it. */ gcry_randomize (salt, 8, GCRY_STRONG_RANDOM); - crypt_block (buffer, buflen, salt, 8, 2048, pw, GCRY_CIPHER_3DES, 1); + crypt_block (buffer, buflen, salt, 8, 2048, NULL, 0, + pw, GCRY_CIPHER_3DES, 1); /* Encode the encrypted stuff into a bag. */ if (cert && certlen) ----------------------------------------------------------------------- Summary of changes: sm/ChangeLog | 9 ++ sm/minip12.c | 356 +++++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 297 insertions(+), 68 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Thu Mar 10 19:05:31 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 10 Mar 2011 19:05:31 +0100 Subject: [git] GnuPG - branch, master, updated. post-nuke-of-trailing-ws-36-gb9bcc77 Message-ID: <E1PxjWS-0003rj-2b@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU Privacy Guard". The branch, master has been updated via b9bcc77d6ca13463c2e4bede91fc1782795f1eae (commit) from 35c731d88937c6711d27660d08cdb8d458dee848 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b9bcc77d6ca13463c2e4bede91fc1782795f1eae Author: Werner Koch <wk at gnupg.org> Date: Thu Mar 10 18:39:34 2011 +0100 Make use of gcry_kdf_derive. Factoring common code out is always a Good Thing. Also added a configure test to print an error if gcry_kdf_derive is missing in Libgcrypt. diff --git a/agent/ChangeLog b/agent/ChangeLog index b636c50..5f14306 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,7 @@ +2011-03-10 Werner Koch <wk at g10code.com> + + * protect.c (hash_passphrase): Use the new gcry_kdf_derive. + 2011-03-08 Werner Koch <wk at g10code.com> * cvt-openpgp.c (GCRY_PK_ECDH) [!HAVE_GCRY_PK_ECDH]: Remove. diff --git a/agent/protect.c b/agent/protect.c index 94de893..0b8c9b4 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -1023,70 +1023,13 @@ hash_passphrase (const char *passphrase, int hashalgo, unsigned long s2kcount, unsigned char *key, size_t keylen) { - int rc; - gcry_md_hd_t md; - int pass, i; - int used = 0; - int pwlen = strlen (passphrase); - - if ( (s2kmode != 0 && s2kmode != 1 && s2kmode != 3) - || !hashalgo || !keylen || !key || !passphrase) - 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; - - for (pass=0; used < keylen; pass++) - { - if (pass) - { - gcry_md_reset (md); - for (i=0; i < pass; i++) /* preset the hash context */ - gcry_md_putc (md, 0); - } - - if (s2kmode == 1 || s2kmode == 3) - { - int len2 = pwlen + 8; - unsigned long count = len2; - - if (s2kmode == 3) - { - count = s2kcount; - if (count < len2) - count = len2; - } - while (count > len2) - { - gcry_md_write (md, s2ksalt, 8); - gcry_md_write (md, passphrase, pwlen); - count -= len2; - } - if (count < 8) - gcry_md_write (md, s2ksalt, count); - else - { - gcry_md_write (md, s2ksalt, 8); - count -= 8; - gcry_md_write (md, passphrase, count); - } - } - else - gcry_md_write (md, passphrase, pwlen); - - gcry_md_final (md); - i = gcry_md_get_algo_dlen (hashalgo); - if (i > keylen - used) - i = keylen - used; - memcpy (key+used, gcry_md_read (md, hashalgo), i); - used += i; - } - gcry_md_close(md); - return 0; + return gcry_kdf_derive (passphrase, strlen (passphrase), + s2kmode == 3? GCRY_KDF_ITERSALTED_S2K : + s2kmode == 1? GCRY_KDF_SALTED_S2K : + s2kmode == 0? GCRY_KDF_SIMPLE_S2K : GCRY_KDF_NONE, + hashalgo, s2ksalt, 8, s2kcount, + keylen, key); } diff --git a/configure.ac b/configure.ac index f265dc3..ab40c6f 100644 --- a/configure.ac +++ b/configure.ac @@ -742,6 +742,22 @@ AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION", AM_PATH_LIBGCRYPT("$NEED_LIBGCRYPT_API:$NEED_LIBGCRYPT_VERSION", have_libgcrypt=yes,have_libgcrypt=no) +# FIxme: Remove this test after libgcrypt 1.5.0 has been released. +AC_CACHE_CHECK([whether Libgcrypt has gcry_kdf_derive], + gnupg_cv_gcry_kdf_derive, + [ _gnupg_gcry_save_cflags=$CFLAGS + _gnupg_gcry_save_libs=$LIBS + CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS" + LIBS="$LIBS $LIBGCRYPT_LIBS" + AC_TRY_LINK( + [#include <gcrypt.h>], + [ return gcry_kdf_derive (NULL,0,0,0,NULL,0,0,0,NULL); ], + gnupg_cv_gcry_kdf_derive=yes, + gnupg_cv_gcry_kdf_derive=no) + LIBS=$_gnupg_gcry_save_libs + CFLAGS=$_gnupg_gcry_save_cflags]) + + # # libassuan is used for IPC # @@ -1605,6 +1621,15 @@ if test "$have_libgcrypt" = "no"; then *** ftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/ *** (at least version $NEED_LIBGCRYPT_VERSION using API $NEED_LIBGCRYPT_API is required.) ***]]) +elif test "$gnupg_cv_gcry_kdf_derive" = no; then + die=yes + AC_MSG_NOTICE([[ +*** +*** Libgcrypt 1.5.0 has not yet been released and thus the API +*** is a bit in a flux. Your version misses the function +*** gcry_kdf_derive +*** You need to install a newer Libgcrypt version. +***]]) fi if test "$have_libassuan" = "no"; then die=yes diff --git a/g10/ChangeLog b/g10/ChangeLog index 9026077..f9edf57 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,8 @@ +2011-03-10 Werner Koch <wk at g10code.com> + + * passphrase.c (hash_passphrase): Remove. + (passphrase_to_dek_ext): Use gcry_kdf_derive. + 2011-03-03 Werner Koch <wk at g10code.com> * keylist.c (print_card_key_info): Re-implement using the agent. diff --git a/g10/passphrase.c b/g10/passphrase.c index 8065810..481d29e 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -1,6 +1,6 @@ /* passphrase.c - Get a passphrase * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, - * 2005, 2006, 2007, 2009 Free Software Foundation, Inc. + * 2005, 2006, 2007, 2009, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -101,81 +101,6 @@ encode_s2k_iterations (int iterations) } - -/* 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) -{ - gcry_md_hd_t md; - int pass, i; - int used = 0; - int pwlen = strlen(pw); - - assert ( s2k->hash_algo ); - dek->keylen = openpgp_cipher_get_algo_keylen (dek->algo); - if ( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) ) - BUG(); - - if (gcry_md_open (&md, s2k->hash_algo, 1)) - BUG (); - for (pass=0; used < dek->keylen ; 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 ) - { - int len2 = pwlen + 8; - ulong count = len2; - - if ( s2k->mode == 3 ) - { - count = S2K_DECODE_COUNT(s2k->count); - if ( count < len2 ) - count = len2; - } - - /* Fixme: To avoid DoS attacks by sending an sym-encrypted - packet with a very high S2K count, we should either cap - the iteration count or CPU seconds based timeout. */ - - /* 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; - } - if ( count < 8 ) - gcry_md_write ( md, s2k->salt, count ); - else - { - gcry_md_write ( md, s2k->salt, 8 ); - count -= 8; - gcry_md_write ( md, pw, count ); - } - } - else - gcry_md_write ( md, pw, pwlen ); - gcry_md_final( md ); - - i = gcry_md_get_algo_dlen ( s2k->hash_algo ); - if ( i > dek->keylen - used ) - i = dek->keylen - used; - - memcpy (dek->key+used, gcry_md_read (md, s2k->hash_algo), i); - used += i; - } - gcry_md_close(md); -} - - - int have_static_passphrase() { @@ -655,7 +580,24 @@ passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, if ( (!pw || !*pw) && (mode == 2 || mode == 4)) dek->keylen = 0; else - hash_passphrase (dek, pw, s2k); + { + dek->keylen = openpgp_cipher_get_algo_keylen (dek->algo); + if (!(dek->keylen > 0 && dek->keylen <= DIM(dek->key))) + BUG (); + if (gcry_kdf_derive (pw, strlen (pw), + s2k->mode == 3? GCRY_KDF_ITERSALTED_S2K : + s2k->mode == 1? GCRY_KDF_SALTED_S2K : + /* */ GCRY_KDF_SIMPLE_S2K, + s2k->hash_algo, s2k->salt, 8, + S2K_DECODE_COUNT(s2k->count), + dek->keylen, dek->key)) + { + xfree (pw); + xfree (dek); + write_status( STATUS_MISSING_PASSPHRASE ); + return NULL; + } + } if (s2k_cacheid) memcpy (dek->s2k_cacheid, s2k_cacheid, sizeof dek->s2k_cacheid); xfree(last_pw); ----------------------------------------------------------------------- Summary of changes: agent/ChangeLog | 4 ++ agent/protect.c | 69 +++----------------------------------- configure.ac | 25 ++++++++++++++ g10/ChangeLog | 5 +++ g10/passphrase.c | 96 +++++++++++------------------------------------------- 5 files changed, 59 insertions(+), 140 deletions(-) hooks/post-receive -- The GNU Privacy Guard http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 28 11:47:00 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 28 Mar 2011 11:47:00 +0200 Subject: [git] Assuan - branch, master, updated. libassuan-2.0.1-33-gb74a70f Message-ID: <E1Q48Gi-00029s-BN@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPC library used by GnuPG". The branch, master has been updated via b74a70f89d2a17b2960105d1aab8e09011dc65b2 (commit) from b00ae5099d3e6eda3cb7d1d1cfb0cbfd87e918f1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b74a70f89d2a17b2960105d1aab8e09011dc65b2 Author: Werner Koch <wk at gnupg.org> Date: Mon Mar 28 11:19:43 2011 +0200 Include sys/select.h in a test utility. This fixes bug#1328 (libassuan: ce-server fails to compile on Darwin due to missing include). diff --git a/ChangeLog b/ChangeLog index 803cb28..c26fbf7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2011-03-28 Werner Koch <wk at g10code.com> + + * configure.ac (AC_CHECK_HEADERS): Check for sys/select.h which is + needed by one test utility. + 2010-12-23 Werner Koch <wk at g10code.com> * configure.ac: Add a git commit identifier to the version. diff --git a/configure.ac b/configure.ac index b7de45b..d29c82e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # configure.ac - for libassuan # Copyright (C) 2001-2003, 2006, 2007, 2009 Free Software Foundation, Inc. -# +# # This file is part of Assuan. # # Assuan is free software; you can redistribute it and/or modify it @@ -164,9 +164,9 @@ if test "$GCC" = yes; then fi -# +# # Options depending on the host OS. -# +# have_dosish_system=no have_w32_system=no have_w32ce_system=no @@ -194,7 +194,7 @@ esac if test "$have_dosish_system" = yes; then AC_DEFINE(HAVE_DOSISH_SYSTEM,1, - [Defined if we run on some of the PCDOS like systems + [Defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2) with special properties like no file modes]) fi @@ -207,7 +207,7 @@ if test "$have_w32_system" = yes; then fi BUILD_TIMESTAMP=`date --iso-8601=minutes` AC_SUBST(BUILD_TIMESTAMP) - changequote(,)dnl + changequote(,)dnl BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'` changequote([,])dnl case "$VERSION" in @@ -254,7 +254,8 @@ AC_SUBST(LIBASSUAN_CONFIG_EXTRA_LIBS) # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([string.h locale.h sys/uio.h stdint.h inttypes.h \ - sys/types.h sys/stat.h unistd.h sys/time.h fcntl.h]) + sys/types.h sys/stat.h unistd.h sys/time.h fcntl.h \ + sys/select.h ]) AC_TYPE_UINTPTR_T AC_TYPE_UINT16_T @@ -344,14 +345,14 @@ AC_REPLACE_FUNCS(vasprintf) # AC_MSG_CHECKING(for SO_PEERCRED) AC_CACHE_VAL(assuan_cv_sys_so_peercred, - [AC_TRY_COMPILE([#include <sys/socket.h>], - [struct ucred cr; + [AC_TRY_COMPILE([#include <sys/socket.h>], + [struct ucred cr; int cl = sizeof cr; getsockopt (1, SOL_SOCKET, SO_PEERCRED, &cr, &cl);], assuan_cv_sys_so_peercred=yes, assuan_cv_sys_so_peercred=no) ]) -AC_MSG_RESULT($assuan_cv_sys_so_peercred) +AC_MSG_RESULT($assuan_cv_sys_so_peercred) if test $assuan_cv_sys_so_peercred = yes; then AC_DEFINE(HAVE_SO_PEERCRED, 1, [Defined if SO_PEERCRED is supported (Linux specific)]) diff --git a/src/assuan-handler.c b/src/assuan-handler.c index 692bdd0..bd57ca0 100644 --- a/src/assuan-handler.c +++ b/src/assuan-handler.c @@ -1,5 +1,6 @@ /* assuan-handler.c - dispatch commands - Copyright (C) 2001, 2002, 2003, 2007, 2009 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2007, 2009, + 2011 Free Software Foundation, Inc. This file is part of Assuan. diff --git a/tests/ChangeLog b/tests/ChangeLog index c2c3f56..8d402ad 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2011-03-28 Werner Koch <wk at g10code.com> + + * ce-server.c: Include sys/select.h if needed. Fixes bug#1328. + 2010-10-11 Werner Koch <wk at g10code.com> * Makefile.am (w32cetools): Move ce-server to here. @@ -68,4 +72,3 @@ 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/tests/ce-server.c b/tests/ce-server.c index 9975e53..24cf734 100644 --- a/tests/ce-server.c +++ b/tests/ce-server.c @@ -35,6 +35,9 @@ # include <sys/socket.h> # include <netinet/in.h> # include <arpa/inet.h> +# ifdef HAVE_SYS_SELECT_H +# include <sys/select.h> +# else #endif #include <errno.h> @@ -69,8 +72,8 @@ typedef struct fdinfo_s *fdinfo_t; struct state_s { /* The current working directory - access using get_cwd(). */ - char *cwd; - + char *cwd; + /* If valid, a socket in listening state created by the dataport command. */ assuan_fd_t dataport_listen_fd; @@ -113,7 +116,7 @@ my_read (assuan_fd_t fd, void *buffer, size_t size) case WSAENOTSOCK: { DWORD nread = 0; - + res = ReadFile (fd, buffer, size, &nread, NULL); if (!res) { @@ -124,7 +127,7 @@ my_read (assuan_fd_t fd, void *buffer, size_t size) break; default: - gpg_err_set_errno (EIO); + gpg_err_set_errno (EIO); } res = -1; } @@ -132,7 +135,7 @@ my_read (assuan_fd_t fd, void *buffer, size_t size) res = (int) nread; } break; - + case WSAEWOULDBLOCK: gpg_err_set_errno (EAGAIN); break; @@ -174,17 +177,17 @@ my_writen (assuan_fd_t fd, const char *buffer, size_t length) if (nwritten == -1 && WSAGetLastError () == WSAENOTSOCK) { DWORD nwrite; - + nwritten = WriteFile (fd, buffer, length, &nwrite, NULL); if (!nwritten) { switch (GetLastError ()) { - case ERROR_BROKEN_PIPE: + case ERROR_BROKEN_PIPE: case ERROR_NO_DATA: gpg_err_set_errno (EPIPE); break; - + default: gpg_err_set_errno (EIO); break; @@ -211,7 +214,7 @@ my_writen (assuan_fd_t fd, const char *buffer, size_t length) -static state_t +static state_t new_state (void) { state_t state = xcalloc (1, sizeof *state); @@ -220,8 +223,8 @@ new_state (void) state->dataport_fd = ASSUAN_INVALID_FD; return state; } - -static void + +static void release_state (state_t state) { fdinfo_t fi, fi2; @@ -285,7 +288,7 @@ wchar_to_utf8 (const wchar_t *string) n = WideCharToMultiByte (CP_ACP, 0, string, length, result, n, NULL, NULL); if (n < 0) log_fatal ("WideCharToMultiByte failed\n"); - + result[n] = 0; return result; } @@ -303,14 +306,14 @@ utf8_to_wchar (const char *string) log_fatal ("MultiByteToWideChar failed\n"); nbytes = (size_t)(n+1) * sizeof(*result); - if (nbytes / sizeof(*result) != (n+1)) + if (nbytes / sizeof(*result) != (n+1)) log_fatal ("utf8_to_wchar: integer overflow\n"); result = xmalloc (nbytes); n = MultiByteToWideChar (CP_UTF8, 0, string, length, result, n); if (n < 0) log_fatal ("MultiByteToWideChar failed\n"); result[n] = 0; - + return result; } #endif /*HAVE_W32CE_SYSTEM*/ @@ -320,7 +323,7 @@ static char * gnu_getcwd (void) { size_t size = 100; - + while (1) { char *buffer = xmalloc (size); @@ -435,7 +438,7 @@ output_notify (assuan_context_t ctx, char *line) -static const char hlp_echo[] = +static const char hlp_echo[] = "ECHO <line>\n" "\n" "Print LINE as data lines.\n"; @@ -451,7 +454,7 @@ cmd_echo (assuan_context_t ctx, char *line) -static const char hlp_cat[] = +static const char hlp_cat[] = "CAT [<filename>]\n" "\n" "Copy the content of FILENAME to the descriptor set by the OUTPUT\n" @@ -526,7 +529,7 @@ cmd_cat (assuan_context_t ctx, char *line) else nread = n; } - + if (fd_out != ASSUAN_INVALID_FD) { @@ -560,7 +563,7 @@ leave: } -static const char hlp_pwd[] = +static const char hlp_pwd[] = "PWD\n" "\n" "Print the curent working directory of this session.\n"; @@ -570,7 +573,7 @@ cmd_pwd (assuan_context_t ctx, char *line) state_t state = assuan_get_pointer (ctx); gpg_error_t err; const char *string; - + string = get_cwd (state); err = assuan_send_data (ctx, string, strlen (string)); @@ -578,7 +581,7 @@ cmd_pwd (assuan_context_t ctx, char *line) } -static const char hlp_cd[] = +static const char hlp_cd[] = "CD [dir]\n" "\n" "Change the curretn directory of the session.\n"; @@ -605,7 +608,7 @@ cmd_cd (assuan_context_t ctx, char *line) newdir = xstrdup (line); else newdir = xstrconcat (get_cwd (state), "/", line, NULL); - + while (strlen(newdir) > 1 && line[strlen(newdir)-1] == '/') line[strlen(newdir)-1] = 0; xfree (state->cwd); @@ -620,7 +623,7 @@ cmd_cd (assuan_context_t ctx, char *line) #ifdef HAVE_W32CE_SYSTEM -static const char hlp_ls[] = +static const char hlp_ls[] = "LS [<pattern>]\n" "\n" "List the files described by PATTERN.\n"; @@ -661,7 +664,7 @@ cmd_ls (assuan_context_t ctx, char *line) DWORD attr = fi.dwFileAttributes; fname = wchar_to_utf8 (fi.cFileName); - snprintf (buf, sizeof buf, + snprintf (buf, sizeof buf, "%c%c%c%c%c%c%c%c%c%c%c%c%c %7lu%c %s\n", (attr & FILE_ATTRIBUTE_DIRECTORY) ? ((attr & FILE_ATTRIBUTE_DEVICE)? 'c':'d'):'-', @@ -693,7 +696,7 @@ cmd_ls (assuan_context_t ctx, char *line) else { log_info ("FindNextFile returned %d\n", GetLastError ()); - err = gpg_error_from_syserror (); + err = gpg_error_from_syserror (); } FindClose (hd); @@ -704,7 +707,7 @@ cmd_ls (assuan_context_t ctx, char *line) #ifdef HAVE_W32CE_SYSTEM -static const char hlp_run[] = +static const char hlp_run[] = "RUN <filename> [<args>]\n" "\n" "Run the program in FILENAME with the arguments ARGS.\n" @@ -829,16 +832,16 @@ cmd_run (assuan_context_t ctx, char *line) goto leave; } - log_info ("CreateProcess ready: hProcess=%p hThread=%p" - " dwProcessID=%d dwThreadId=%d\n", + log_info ("CreateProcess ready: hProcess=%p hThread=%p" + " dwProcessID=%d dwThreadId=%d\n", pi.hProcess, pi.hThread, (int) pi.dwProcessId, (int) pi.dwThreadId); ResumeThread (pi.hThread); - CloseHandle (pi.hThread); + CloseHandle (pi.hThread); code = WaitForSingleObject (pi.hProcess, INFINITE); - switch (code) + switch (code) { case WAIT_FAILED: err = gpg_error_from_syserror ();; @@ -863,7 +866,7 @@ cmd_run (assuan_context_t ctx, char *line) err = 0; } break; - + default: err = gpg_error_from_syserror ();; log_error ("WaitForSingleObject returned unexpected " @@ -871,7 +874,7 @@ cmd_run (assuan_context_t ctx, char *line) break; } CloseHandle (pi.hProcess); - + leave: for (idx=0; idx < 3; idx++) { @@ -901,7 +904,7 @@ cmd_run (assuan_context_t ctx, char *line) -static const char hlp_newdataport[] = +static const char hlp_newdataport[] = "NEWDATAPORT\n" "\n" "Create a new dataport. The server creates a listening socket and\n" @@ -963,7 +966,7 @@ cmd_newdataport (assuan_context_t ctx, char *line) log_error ("listen() failed: %s\n", strerror (errno)); goto leave; } - + if (listen (HANDLE2SOCKET (state->dataport_listen_fd), 1)) { err = gpg_error_from_syserror (); @@ -1088,7 +1091,7 @@ cmd_dataport (assuan_context_t ctx, char *line) -static const char hlp_getinfo[] = +static const char hlp_getinfo[] = "GETINFO <what>\n" "\n" "Multipurpose function to return a variety of information.\n" @@ -1138,7 +1141,7 @@ cmd_getinfo (assuan_context_t ctx, char *line) -static const char hlp_shutdown[] = +static const char hlp_shutdown[] = "SHUTDOWN\n" "\n" "Shutdown the server process\n"; @@ -1182,7 +1185,7 @@ register_commands (assuan_context_t ctx) for (i=0; table[i].name; i++) { - rc = assuan_register_command (ctx, table[i].name, + rc = assuan_register_command (ctx, table[i].name, table[i].handler, table[i].help); if (rc) return rc; @@ -1225,7 +1228,7 @@ server (void) if (server_fd == ASSUAN_INVALID_FD) log_fatal ("socket() failed: %s\n", strerror (errno)); - if (setsockopt (HANDLE2SOCKET (server_fd), + if (setsockopt (HANDLE2SOCKET (server_fd), SOL_SOCKET, SO_REUSEADDR, (void*)&one, sizeof one)) log_error ("setsockopt(SO_REUSEADDR) failed: %s\n", strerror (errno)); @@ -1234,7 +1237,7 @@ server (void) name.sin_addr.s_addr = htonl (INADDR_ANY); if (assuan_sock_bind (server_fd, (struct sockaddr *) &name, sizeof name)) log_fatal ("bind() failed: %s\n", strerror (errno)); - if (assuan_sock_get_nonce ((struct sockaddr*)&name, sizeof name, + if (assuan_sock_get_nonce ((struct sockaddr*)&name, sizeof name, &server_nonce)) log_fatal ("assuan_sock_get_nonce failed: %s\n", strerror (errno)); @@ -1264,9 +1267,9 @@ server (void) assuan_register_input_notify (ctx, input_notify); assuan_register_output_notify (ctx, output_notify); - + state = new_state (); - + assuan_set_pointer (ctx, state); while (!shutdown_pending) @@ -1280,7 +1283,7 @@ server (void) log_error ("assuan_accept failed: %s\n", gpg_strerror (err)); break; } - + log_info ("client connected. Client's pid is %ld\n", (long)assuan_get_pid (ctx)); do @@ -1346,7 +1349,7 @@ server (void) if (err) log_error ("assuan_process failed: %s\n", gpg_strerror (err)); } - + assuan_sock_close (server_fd); assuan_release (ctx); release_state (state); @@ -1356,12 +1359,12 @@ server (void) -/* - +/* + M A I N */ -int +int main (int argc, char **argv) { gpg_error_t err; @@ -1413,4 +1416,3 @@ main (int argc, char **argv) return errorcount ? 1 : 0; } - ----------------------------------------------------------------------- Summary of changes: ChangeLog | 5 +++ configure.ac | 19 +++++----- src/assuan-handler.c | 3 +- tests/ChangeLog | 5 ++- tests/ce-server.c | 96 +++++++++++++++++++++++++------------------------ 5 files changed, 70 insertions(+), 58 deletions(-) hooks/post-receive -- IPC library used by GnuPG http://git.gnupg.org From cvs at cvs.gnupg.org Mon Mar 28 15:13:16 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Mon, 28 Mar 2011 15:13:16 +0200 Subject: [git] GCRYPT - branch, master, updated. post-nuke-of-trailing-ws-20-gdd76819 Message-ID: <E1Q4BUI-0005TT-OH@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via dd76819014c4e9d75c4b9613e888f7536c676a46 (commit) from 9730275d294b4d9cbbb2453541f001c95f5f31a3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dd76819014c4e9d75c4b9613e888f7536c676a46 Author: Werner Koch <wk at gnupg.org> Date: Mon Mar 28 14:46:36 2011 +0200 Fixed a few warnings emitted by gcc 4.6. diff --git a/cipher/ChangeLog b/cipher/ChangeLog index 3fba314..8961676 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,10 @@ +2011-03-28 Werner Koch <wk at g10code.com> + + * primegen.c (_gcry_generate_elg_prime): Make sure that PRIME is + NULL if the called func ever returns an error. + + * pubkey.c (gcry_pk_decrypt): Remove unused var PUBKEY. + 2011-03-09 Werner Koch <wk at g10code.com> * kdf.c: New. diff --git a/cipher/md.c b/cipher/md.c index 053eab1..c3b3a4f 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -1232,6 +1232,7 @@ md_stop_debug( gcry_md_hd_t md ) volatile u64 b = 42; volatile u64 c; c = a * b; + (void)c; } #endif } diff --git a/cipher/primegen.c b/cipher/primegen.c index edeb7c8..2788e34 100644 --- a/cipher/primegen.c +++ b/cipher/primegen.c @@ -738,12 +738,12 @@ gcry_mpi_t _gcry_generate_elg_prime (int mode, unsigned pbits, unsigned qbits, gcry_mpi_t g, gcry_mpi_t **ret_factors) { - gcry_err_code_t err = GPG_ERR_NO_ERROR; gcry_mpi_t prime = NULL; - err = prime_generate_internal ((mode == 1), &prime, pbits, qbits, g, - ret_factors, GCRY_WEAK_RANDOM, 0, 0, - NULL, NULL); + if (prime_generate_internal ((mode == 1), &prime, pbits, qbits, g, + ret_factors, GCRY_WEAK_RANDOM, 0, 0, + NULL, NULL)) + prime = NULL; /* (Should be NULL in the error case anyway.) */ return prime; } diff --git a/cipher/pubkey.c b/cipher/pubkey.c index d4a93c7..02eeecc 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -1755,7 +1755,6 @@ gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey) int modern, want_pkcs1, flags; gcry_err_code_t rc; gcry_module_t module_enc = NULL, module_key = NULL; - gcry_pk_spec_t *pubkey = NULL; *r_plain = NULL; @@ -1775,8 +1774,6 @@ gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey) goto leave; } - pubkey = (gcry_pk_spec_t *) module_key->spec; - rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags); if (rc) goto leave; diff --git a/mpi/ChangeLog b/mpi/ChangeLog index 227f451..7d32f5a 100644 --- a/mpi/ChangeLog +++ b/mpi/ChangeLog @@ -1,3 +1,7 @@ +2011-03-28 Werner Koch <wk at g10code.com> + + * mpi-pow.c (gcry_mpi_powm): Remove unused var RSEC. + 2011-02-01 Werner Koch <wk at g10code.com> * mpi-cmp.c (gcry_mpi_cmp): Allow comparing of opaque MPIs. diff --git a/mpi/mpi-pow.c b/mpi/mpi-pow.c index fbdb7ce..33bbebe 100644 --- a/mpi/mpi-pow.c +++ b/mpi/mpi-pow.c @@ -45,7 +45,7 @@ gcry_mpi_powm (gcry_mpi_t res, mpi_size_t esize, msize, bsize, rsize; int msign, bsign, rsign; /* Flags telling the secure allocation status of the arguments. */ - int esec, msec, bsec, rsec; + int esec, msec, bsec; /* Size of the result including space for temporary values. */ mpi_size_t size; /* Helper. */ @@ -71,7 +71,6 @@ gcry_mpi_powm (gcry_mpi_t res, esec = mpi_is_secure(expo); msec = mpi_is_secure(mod); bsec = mpi_is_secure(base); - rsec = mpi_is_secure(res); rp = res->d; ep = expo->d; diff --git a/src/dumpsexp.c b/src/dumpsexp.c index 6ea05e8..f6384d7 100644 --- a/src/dumpsexp.c +++ b/src/dumpsexp.c @@ -378,7 +378,7 @@ init_data (void) static void push_data (int c) { - + (void)c; } /* Flush and thus print the current data chunk. */ diff --git a/src/global.c b/src/global.c index 51d7f39..cbb7eb8 100644 --- a/src/global.c +++ b/src/global.c @@ -534,6 +534,10 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) err = _gcry_fips_run_selftests (1); break; +#if _GCRY_GCC_VERSION >= 40600 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wswitch" +#endif case 58: /* Init external random test. */ { void **rctx = va_arg (arg_ptr, void **); @@ -568,6 +572,13 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) _gcry_random_deinit_external_test (ctx); } break; + case 61: /* RFU */ + break; + case 62: /* RFU */ + break; +#if _GCRY_GCC_VERSION >= 40600 +# pragma GCC diagnostic pop +#endif case GCRYCTL_DISABLE_HWF: { diff --git a/tests/ChangeLog b/tests/ChangeLog index 8ef49fc..e25f134 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,7 @@ +2011-03-28 Werner Koch <wk at g10code.com> + + * random.c (readn): Remove used var P. + 2011-02-21 Werner Koch <wk at g10code.com> * version.c (main): Do a verbatim check of the version string. diff --git a/tests/random.c b/tests/random.c index 0575e8a..a243529 100644 --- a/tests/random.c +++ b/tests/random.c @@ -84,9 +84,7 @@ readn (int fd, void *buf, size_t buflen, size_t *ret_nread) { size_t nleft = buflen; int nread; - char *p; - p = buf; while ( nleft > 0 ) { nread = read ( fd, buf, nleft ); ----------------------------------------------------------------------- Summary of changes: cipher/ChangeLog | 7 +++++++ cipher/md.c | 1 + cipher/primegen.c | 8 ++++---- cipher/pubkey.c | 3 --- mpi/ChangeLog | 4 ++++ mpi/mpi-pow.c | 3 +-- src/dumpsexp.c | 2 +- src/global.c | 11 +++++++++++ tests/ChangeLog | 4 ++++ tests/random.c | 2 -- 10 files changed, 33 insertions(+), 12 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 30 11:23:55 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 30 Mar 2011 11:23:55 +0200 Subject: [git] Assuan - branch, master, updated. libassuan-2.0.1-34-gb20e8f0 Message-ID: <E1Q4qr7-0003Jz-FZ@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPC library used by GnuPG". The branch, master has been updated via b20e8f085cec6465b64a0d17772e663418791d5f (commit) from b74a70f89d2a17b2960105d1aab8e09011dc65b2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b20e8f085cec6465b64a0d17772e663418791d5f Author: Werner Koch <wk at gnupg.org> Date: Wed Mar 30 10:56:29 2011 +0200 Add a version string to the binary. diff --git a/src/ChangeLog b/src/ChangeLog index a27401d..a552201 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2011-03-30 Werner Koch <wk at g10code.com> + + * sysutils.c (_assuan_sysutils_blurb): Add version string. + 2011-03-09 Werner Koch <wk at g10code.com> * assuan-handler.c (assuan_register_command): Use my_strcasecmp. diff --git a/src/sysutils.c b/src/sysutils.c index 5a1d9de..3a23378 100644 --- a/src/sysutils.c +++ b/src/sysutils.c @@ -27,7 +27,7 @@ #ifdef HAVE_W32_SYSTEM # ifdef HAVE_WINSOCK2_H # include <winsock2.h> -# endif +# endif # include <windows.h> # ifdef HAVE_W32CE_SYSTEM # include <winioctl.h> @@ -42,11 +42,11 @@ const char * _assuan_sysutils_blurb (void) { - static const char blurb[] = + static const char blurb[] = "\n\n" - "This is Libassuan - The GnuPG IPC Library\n" + "This is Libassuan " PACKAGE_VERSION " - The GnuPG IPC Library\n" "Copyright 2000, 2002, 2003, 2004, 2007, 2008, 2009,\n" - " 2010 Free Software Foundation, Inc.\n" + " 2010, 2011 Free Software Foundation, Inc.\n" "\n\n"; return blurb; } @@ -64,7 +64,7 @@ w32_read_registry (const wchar_t *dir, const wchar_t *name) DWORD n, nbytes; wchar_t *buffer = NULL; char *result = NULL; - + if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &handle)) return NULL; /* No need for a RegClose, so return immediately. */ @@ -80,7 +80,7 @@ w32_read_registry (const wchar_t *dir, const wchar_t *name) buffer = NULL; goto out; } - + n = WideCharToMultiByte (CP_UTF8, 0, buffer, nbytes, NULL, 0, NULL, NULL); if (n < 0 || (n+1) <= 0) goto out; @@ -134,4 +134,3 @@ _assuan_getenv (const char *name) return NULL; } #endif /*HAVE_W32CE_SYSTEM*/ - ----------------------------------------------------------------------- Summary of changes: src/ChangeLog | 4 ++++ src/sysutils.c | 13 ++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) hooks/post-receive -- IPC library used by GnuPG http://git.gnupg.org From cvs at cvs.gnupg.org Wed Mar 30 11:49:34 2011 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 30 Mar 2011 11:49:34 +0200 Subject: [git] GCRYPT - branch, master, updated. post-nuke-of-trailing-ws-21-gec03338 Message-ID: <E1Q4rFv-0003oh-R7@lists.gnupg.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via ec033383618c4b3739783d31ca4dc70c9bb4fcfe (commit) from dd76819014c4e9d75c4b9613e888f7536c676a46 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ec033383618c4b3739783d31ca4dc70c9bb4fcfe Author: Werner Koch <wk at gnupg.org> Date: Wed Mar 30 11:22:56 2011 +0200 Add a version string to the binary diff --git a/ChangeLog b/ChangeLog index c72b1c5..e3ff5db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-03-30 Werner Koch <wk at g10code.com> + + * compat/compat.c (_gcry_compat_identification): Add version string. + 2011-03-08 Werner Koch <wk at g10code.com> * configure.ac (BUILD_REVISION): Use new git_brevis macro. diff --git a/compat/compat.c b/compat/compat.c index 076f520..e2a0393 100644 --- a/compat/compat.c +++ b/compat/compat.c @@ -27,7 +27,7 @@ _gcry_compat_identification (void) { static const char blurb[] = "\n\n" - "This is Libgcrypt - The GNU Crypto Library\n" + "This is Libgcrypt " PACKAGE_VERSION " - The GNU Crypto Library\n" "Copyright 2000, 2002, 2003, 2004, 2007, 2008, 2009,\n" " 2010, 2011 Free Software Foundation, Inc.\n" "\n\n"; ----------------------------------------------------------------------- Summary of changes: ChangeLog | 4 ++++ compat/compat.c | 2 +- 2 files changed, 5 insertions(+), 1 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org