[svn] gcry - r1276 - in trunk: . cipher tests
svn author wk
cvs at cvs.gnupg.org
Wed Dec 5 10:50:52 CET 2007
Author: wk
Date: 2007-12-05 10:50:50 +0100 (Wed, 05 Dec 2007)
New Revision: 1276
Modified:
trunk/NEWS
trunk/cipher/ChangeLog
trunk/cipher/pubkey.c
trunk/cipher/rsa.c
trunk/configure.ac
trunk/tests/ChangeLog
trunk/tests/pubkey.c
Log:
Fixed an internal bug in rsa.c
Allow to decryption/signing using a minimal RSA key.
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2007-12-03 10:34:28 UTC (rev 1275)
+++ trunk/NEWS 2007-12-05 09:50:50 UTC (rev 1276)
@@ -1,3 +1,7 @@
+Noteworthy changes in version 1.4.0
+------------------------------------------------
+
+
Noteworthy changes in version 1.3.2 (2007-12-03)
------------------------------------------------
Modified: trunk/cipher/ChangeLog
===================================================================
--- trunk/cipher/ChangeLog 2007-12-03 10:34:28 UTC (rev 1275)
+++ trunk/cipher/ChangeLog 2007-12-05 09:50:50 UTC (rev 1276)
@@ -1,3 +1,14 @@
+2007-12-05 Werner Koch <wk at g10code.com>
+
+ * rsa.c (secret): Fixed condition test for using CRT. Reported by
+ Dean Scarff. Fixes bug#864.
+ (_gcry_rsa_check_secret_key): Return an erro if the optional
+ parameters are missing.
+ * pubkey.c (sexp_elements_extract): Add arg ALGO_NAME. Changed all
+ callers to pass NULL. Add hack to allow for optional RSA
+ parameters.
+ (sexp_to_key): Pass algo name to sexp_elements_extract.
+
2007-12-03 Werner Koch <wk at g10code.com>
* random.c (gcry_random_add_bytes): Implement it.
Modified: trunk/cipher/pubkey.c
===================================================================
--- trunk/cipher/pubkey.c 2007-12-03 10:34:28 UTC (rev 1275)
+++ trunk/cipher/pubkey.c 2007-12-05 09:50:50 UTC (rev 1276)
@@ -751,9 +751,9 @@
/* Internal function. */
static gcry_err_code_t
sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
- gcry_mpi_t *elements)
+ gcry_mpi_t *elements, const char *algo_name)
{
- gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ gcry_err_code_t err = 0;
int i, idx;
const char *name;
gcry_sexp_t list;
@@ -761,17 +761,41 @@
for (name = element_names, idx = 0; *name && !err; name++, idx++)
{
list = gcry_sexp_find_token (key_sexp, name, 1);
- if (! list)
- err = GPG_ERR_NO_OBJ;
+ if (!list)
+ elements[idx] = NULL;
else
{
elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
gcry_sexp_release (list);
- if (! elements[idx])
+ if (!elements[idx])
err = GPG_ERR_INV_OBJ;
}
}
+ if (!err)
+ {
+ /* Check that all elements are available. */
+ for (name = element_names, idx = 0; *name; name++, idx++)
+ if (!elements[idx])
+ break;
+ if (*name)
+ {
+ err = GPG_ERR_NO_OBJ;
+ /* Some are missing. Before bailing out we test for
+ optional parameters. */
+ if (algo_name && !strcmp (algo_name, "RSA")
+ && !strcmp (element_names, "nedpqu") )
+ {
+ /* This is RSA. Test whether we got N, E and D and that
+ the optional P, Q and U are all missing. */
+ if (elements[0] && elements[1] && elements[2]
+ && !elements[3] && !elements[4] && !elements[5])
+ err = 0;
+ }
+ }
+ }
+
+
if (err)
{
for (i = 0; i < idx; i++)
@@ -884,8 +908,6 @@
* NOTE: we look through the list to find a list beginning with
* "private-key" or "public-key" - the first one found is used.
*
- * FIXME: Allow for encrypted secret keys here.
- *
* Returns: A pointer to an allocated array of MPIs if the return value is
* zero; the caller has to release this array.
*
@@ -959,7 +981,7 @@
if (is_ecc)
err = sexp_elements_extract_ecc (list, elems, array);
else
- err = sexp_elements_extract (list, elems, array);
+ err = sexp_elements_extract (list, elems, array, pubkey->name);
}
gcry_sexp_release (list);
@@ -1048,7 +1070,7 @@
err = gpg_err_code_from_errno (errno);
if (!err)
- err = sexp_elements_extract (list, elems, array);
+ err = sexp_elements_extract (list, elems, array, NULL);
gcry_sexp_release (l2);
gcry_sexp_release (list);
@@ -1190,7 +1212,7 @@
goto leave;
}
- err = sexp_elements_extract (list, elems, array);
+ err = sexp_elements_extract (list, elems, array, NULL);
leave:
gcry_sexp_release (list);
@@ -1921,7 +1943,7 @@
Test a key.
This may be used either for a public or a secret key to see whether
- internal structre is valid.
+ the internal structure is okay.
Returns: 0 or an errorcode.
Modified: trunk/cipher/rsa.c
===================================================================
--- trunk/cipher/rsa.c 2007-12-03 10:34:28 UTC (rev 1275)
+++ trunk/cipher/rsa.c 2007-12-05 09:50:50 UTC (rev 1276)
@@ -1,6 +1,6 @@
/* rsa.c - RSA function
- * Copyright (C) 1997, 1998, 1999 by Werner Koch (dd9jn)
- * Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 1997, 1998, 1999 by Werner Koch (dd9jn)
+ * Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
@@ -15,8 +15,7 @@
* 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
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/* This code uses an algorithm protected by U.S. Patent #4,405,829
@@ -357,7 +356,7 @@
static void
secret(gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
{
- if (!skey->p && !skey->q && !skey->u)
+ if (!skey->p || !skey->q || !skey->u)
{
mpi_powm (output, input, skey->d, skey->n);
}
@@ -488,7 +487,10 @@
sk.q = skey[4];
sk.u = skey[5];
- if (! check_secret_key (&sk))
+ if (!sk.p || !sk.q || !sk.u)
+ err = GPG_ERR_NO_OBJ; /* To check the key we need the optional
+ parameters. */
+ else if (!check_secret_key (&sk))
err = GPG_ERR_PUBKEY_ALGO;
return err;
@@ -529,9 +531,9 @@
sk.n = skey[0];
sk.e = skey[1];
sk.d = skey[2];
- sk.p = skey[3];
- sk.q = skey[4];
- sk.u = skey[5];
+ sk.p = skey[3]; /* Optional. */
+ sk.q = skey[4]; /* Optional. */
+ sk.u = skey[5]; /* Optional. */
y = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac 2007-12-03 10:34:28 UTC (rev 1275)
+++ trunk/configure.ac 2007-12-05 09:50:50 UTC (rev 1276)
@@ -27,8 +27,8 @@
# 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], [1.3.2])
-m4_define([my_issvn], [no])
+m4_define([my_version], [1.3.3])
+m4_define([my_issvn], [yes])
m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \
|| echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')]))
Modified: trunk/tests/ChangeLog
===================================================================
--- trunk/tests/ChangeLog 2007-12-03 10:34:28 UTC (rev 1275)
+++ trunk/tests/ChangeLog 2007-12-05 09:50:50 UTC (rev 1276)
@@ -1,3 +1,11 @@
+2007-12-05 Werner Koch <wk at g10code.com>
+
+ * pubkey.c (sample_private_key_1_1,sample_private_key_1_2): New.
+ (get_keys_sample): Add arg SECRET_VARIANT.
+ (check_run): Check all variants. Also check gcry_pk_testkey.
+ (check_keys_crypt): Add DECRYPT_FAIL_CODE.
+ (check_keys): Ditto.
+
2007-11-30 Werner Koch <wk at g10code.com>
* benchmark.c (main): Add optione --verbose and reworked the
Modified: trunk/tests/pubkey.c
===================================================================
--- trunk/tests/pubkey.c 2007-12-03 10:34:28 UTC (rev 1275)
+++ trunk/tests/pubkey.c 2007-12-05 09:50:50 UTC (rev 1276)
@@ -14,8 +14,7 @@
* 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
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
@@ -52,6 +51,43 @@
" )\n"
")\n";
+/* The same key as above but without p, q and u to test the non CRT case. */
+static const char sample_private_key_1_1[] =
+"(private-key\n"
+" (openpgp-rsa\n"
+" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
+" (e #010001#)\n"
+" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
+ "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
+ "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
+ "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
+" )\n"
+")\n";
+
+/* The same key as above but just without q to test the non CRT case. This
+ should fail. */
+static const char sample_private_key_1_2[] =
+"(private-key\n"
+" (openpgp-rsa\n"
+" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
+" (e #010001#)\n"
+" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
+ "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
+ "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
+ "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
+" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
+ "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
+" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
+ "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
+" )\n"
+")\n";
+
static const char sample_public_key_1[] =
"(public-key\n"
" (rsa\n"
@@ -79,7 +115,7 @@
static void
check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
- gcry_sexp_t plain0)
+ gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code)
{
gcry_sexp_t plain1, cipher, l;
gcry_mpi_t x0, x1;
@@ -103,7 +139,11 @@
rc = gcry_pk_decrypt (&plain1, cipher, skey);
gcry_sexp_release (cipher);
if (rc)
- die ("decryption failed: %s\n", gcry_strerror (rc));
+ {
+ if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code)
+ return; /* This is the expected failure code. */
+ die ("decryption failed: %s\n", gcry_strerror (rc));
+ }
/* Extract decrypted data. Note that for compatibility reasons, the
output of gcry_pk_decrypt depends on whether a flags lists (even
@@ -133,7 +173,8 @@
}
static void
-check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data)
+check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data,
+ gpg_err_code_t decrypt_fail_code)
{
gcry_sexp_t plain;
gcry_mpi_t x;
@@ -148,7 +189,7 @@
die ("converting data for encryption failed: %s\n",
gcry_strerror (rc));
- check_keys_crypt (pkey, skey, plain);
+ check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
gcry_sexp_release (plain);
gcry_mpi_release (x);
@@ -162,21 +203,30 @@
die ("converting data for encryption failed: %s\n",
gcry_strerror (rc));
- check_keys_crypt (pkey, skey, plain);
+ check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
gcry_sexp_release (plain);
}
static void
-get_keys_sample (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+get_keys_sample (gcry_sexp_t *pkey, gcry_sexp_t *skey, int secret_variant)
{
gcry_sexp_t pub_key, sec_key;
int rc;
+ static const char *secret;
+
+ switch (secret_variant)
+ {
+ case 0: secret = sample_private_key_1; break;
+ case 1: secret = sample_private_key_1_1; break;
+ case 2: secret = sample_private_key_1_2; break;
+ default: die ("BUG\n");
+ }
+
rc = gcry_sexp_sscan (&pub_key, NULL, sample_public_key_1,
strlen (sample_public_key_1));
- if (! rc)
- rc = gcry_sexp_sscan (&sec_key, NULL, sample_private_key_1,
- strlen (sample_private_key_1));
+ if (!rc)
+ rc = gcry_sexp_sscan (&sec_key, NULL, secret, strlen (secret));
if (rc)
die ("converting sample keys failed: %s\n", gcry_strerror (rc));
@@ -249,33 +299,44 @@
static void
check_run (void)
{
+ gpg_error_t err;
gcry_sexp_t pkey, skey;
+ int variant;
+ for (variant=0; variant < 3; variant++)
+ {
+ if (verbose)
+ fprintf (stderr, "Checking sample key (%d).\n", variant);
+ get_keys_sample (&pkey, &skey, variant);
+ /* Check gcry_pk_testkey which requires all elements. */
+ err = gcry_pk_testkey (skey);
+ if ((variant == 0 && err)
+ || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ))
+ die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err));
+ /* Run the usual check but expect an error from variant 2. */
+ check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0);
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+ }
+
if (verbose)
- fprintf (stderr, "Checking sample key.\n");
- get_keys_sample (&pkey, &skey);
- check_keys (pkey, skey, 800);
- gcry_sexp_release (pkey);
- gcry_sexp_release (skey);
-
- if (verbose)
fprintf (stderr, "Checking generated RSA key.\n");
get_keys_new (&pkey, &skey);
- check_keys (pkey, skey, 800);
+ check_keys (pkey, skey, 800, 0);
gcry_sexp_release (pkey);
gcry_sexp_release (skey);
if (verbose)
fprintf (stderr, "Checking generated Elgamal key.\n");
get_elg_key_new (&pkey, &skey, 0);
- check_keys (pkey, skey, 400 );
+ check_keys (pkey, skey, 400, 0);
gcry_sexp_release (pkey);
gcry_sexp_release (skey);
if (verbose)
fprintf (stderr, "Checking passphrase generated Elgamal key.\n");
get_elg_key_new (&pkey, &skey, 1);
- check_keys (pkey, skey, 800);
+ check_keys (pkey, skey, 800, 0);
gcry_sexp_release (pkey);
gcry_sexp_release (skey);
}
@@ -294,7 +355,7 @@
gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
if (!gcry_check_version (GCRYPT_VERSION))
- die ("version mismatch\n");
+ /*die ("version mismatch\n")*/;
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
if (debug)
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
More information about the Gnupg-commits
mailing list