aboutsummaryrefslogtreecommitdiffstats
path: root/g10/sig-check.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2008-12-11 17:44:52 +0000
committerWerner Koch <[email protected]>2008-12-11 17:44:52 +0000
commit6558568912d600f6c1f66a9dda457ce9264ce1cd (patch)
treeecdd1f8288b2b3f2a5a19fb4d0b3f274005fdde2 /g10/sig-check.c
parentAdd option --no-ask for GET_PASSPHRASE. (diff)
downloadgnupg-6558568912d600f6c1f66a9dda457ce9264ce1cd.tar.gz
gnupg-6558568912d600f6c1f66a9dda457ce9264ce1cd.zip
Make gpg not depend on the RIPE-MD160 implementaion in Libgcrypt.
Fix SIG_ID computation.
Diffstat (limited to 'g10/sig-check.c')
-rw-r--r--g10/sig-check.c89
1 files changed, 56 insertions, 33 deletions
diff --git a/g10/sig-check.c b/g10/sig-check.c
index 995821c5e..c415703f7 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -130,41 +130,63 @@ signature_check2 (PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate,
* and the timestamp, but the drawback of this is, that it is
* not possible to sign more than one identical document within
* one second. Some remote batch processing applications might
- * like this feature here */
- gcry_md_hd_t md;
-
+ * like this feature here.
+ *
+ * Note that before 2.0.10, we used RIPE-MD160 for the hash
+ * and accidently didn't include the timestamp and algorithm
+ * information in the hash. Given that this feature is not
+ * commonly used and that a replay attacks detection should
+ * not solely be based on this feature (because it does not
+ * work with RSA), we take the freedom and switch to SHA-1
+ * with 2.0.10 to take advantage of hardware supported SHA-1
+ * implementations. We also include the missing information
+ * in the hash. Note also the SIG_ID as computed by gpg 1.x
+ * and gpg 2.x didn't matched either because 2.x used to print
+ * MPIs not in PGP format. */
u32 a = sig->timestamp;
- int i, nsig = pubkey_get_nsig( sig->pubkey_algo );
- byte *p, *buffer;
-
- if (gcry_md_open (&md, GCRY_MD_RMD160, 0))
- BUG ();
-
- /* FIXME: Why the hell are we updating DIGEST here??? */
- gcry_md_putc( digest, sig->pubkey_algo );
- gcry_md_putc( digest, sig->digest_algo );
- gcry_md_putc( digest, (a >> 24) & 0xff );
- gcry_md_putc( digest, (a >> 16) & 0xff );
- gcry_md_putc( digest, (a >> 8) & 0xff );
- gcry_md_putc( digest, a & 0xff );
- for(i=0; i < nsig; i++ ) {
- size_t n;
- unsigned char *tmp;
-
- if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &tmp, &n, sig->data[i]))
+ int nsig = pubkey_get_nsig( sig->pubkey_algo );
+ unsigned char *p, *buffer;
+ size_t n, nbytes;
+ int i;
+ char hashbuf[20];
+
+ nbytes = 6;
+ for (i=0; i < nsig; i++ )
+ {
+ if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &n, sig->data[i]))
BUG();
- gcry_md_write (md, tmp, n);
- xfree (tmp);
- }
- gcry_md_final (md);
- p = make_radix64_string ( gcry_md_read( md, 0 ), 20 );
- buffer = xmalloc( strlen(p) + 60 );
- sprintf( buffer, "%s %s %lu",
- p, strtimestamp( sig->timestamp ), (ulong)sig->timestamp );
- write_status_text( STATUS_SIG_ID, buffer );
- xfree(buffer);
- xfree(p);
- gcry_md_close(md);
+ nbytes += n;
+ }
+
+ /* Make buffer large enough to be later used as output buffer. */
+ if (nbytes < 100)
+ nbytes = 100;
+ nbytes += 10; /* Safety margin. */
+
+ /* Fill and hash buffer. */
+ buffer = p = xmalloc (nbytes);
+ *p++ = sig->pubkey_algo;
+ *p++ = sig->digest_algo;
+ *p++ = (a >> 24) & 0xff;
+ *p++ = (a >> 16) & 0xff;
+ *p++ = (a >> 8) & 0xff;
+ *p++ = a & 0xff;
+ nbytes -= 6;
+ for (i=0; i < nsig; i++ )
+ {
+ if (gcry_mpi_print (GCRYMPI_FMT_PGP, p, nbytes, &n, sig->data[i]))
+ BUG();
+ p += n;
+ nbytes -= n;
+ }
+ gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, buffer, p-buffer);
+
+ p = make_radix64_string (hashbuf, 20);
+ sprintf (buffer, "%s %s %lu",
+ p, strtimestamp (sig->timestamp), (ulong)sig->timestamp);
+ xfree (p);
+ write_status_text (STATUS_SIG_ID, buffer);
+ xfree (buffer);
}
return rc;
@@ -420,6 +442,7 @@ check_revocation_keys(PKT_public_key *pk,PKT_signature *sig)
hash_public_key(md,pk);
rc=signature_check(sig,md);
cache_sig_result(sig,rc);
+ gcry_md_close (md);
break;
}
}