summaryrefslogtreecommitdiffstats
path: root/sm
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2007-12-13 16:45:40 +0100
committerWerner Koch <wk@gnupg.org>2007-12-13 16:45:40 +0100
commit9d66580cff83d5b6cb6dc52ecc2fcfbfe1e94315 (patch)
tree7373ba64496d9695d194ed16c54abee7f5f887ba /sm
parentAllow type 20 keys only with option --rfc2440. (diff)
downloadgnupg2-9d66580cff83d5b6cb6dc52ecc2fcfbfe1e94315.tar.xz
gnupg2-9d66580cff83d5b6cb6dc52ecc2fcfbfe1e94315.zip
Allow verification of some broken S-TRUST generated signatures.
Diffstat (limited to 'sm')
-rw-r--r--sm/ChangeLog7
-rw-r--r--sm/gpgsm.c13
-rw-r--r--sm/gpgsm.h3
-rw-r--r--sm/sign.c4
-rw-r--r--sm/verify.c38
5 files changed, 54 insertions, 11 deletions
diff --git a/sm/ChangeLog b/sm/ChangeLog
index 49ed50669..032f02897 100644
--- a/sm/ChangeLog
+++ b/sm/ChangeLog
@@ -1,3 +1,10 @@
+2007-12-13 Werner Koch <wk@g10code.com>
+
+ * gpgsm.c (main): Add option --extra-digest-algo.
+ * gpgsm.h (struct): Add EXTRA_DIGEST_ALGO.
+ * verify.c (gpgsm_verify): Use it. Use the hash algorithm from
+ the signature value.
+
2007-12-11 Werner Koch <wk@g10code.com>
* certchain.c (do_validate_chain): Log AUDIT_ROOT_TRUSTED.
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index 93474b37a..71f8e2cc1 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -174,6 +174,7 @@ enum cmd_and_opt_values {
oOpenPGP,
oCipherAlgo,
oDigestAlgo,
+ oExtraDigestAlgo,
oCompressAlgo,
oCommandFD,
oNoVerbose,
@@ -388,6 +389,7 @@ static ARGPARSE_OPTS opts[] = {
{ oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
{ oDigestAlgo, "digest-algo", 2 ,
N_("|NAME|use message digest algorithm NAME")},
+ { oExtraDigestAlgo, "extra-digest-algo", 2 , "@" },
#if 0
{ oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")},
#endif
@@ -842,6 +844,7 @@ main ( int argc, char **argv)
int use_random_seed = 1;
int with_fpr = 0;
char *def_digest_string = NULL;
+ char *extra_digest_algo = NULL;
enum cmd_and_opt_values cmd = 0;
struct server_control_s ctrl;
certlist_t recplist = NULL;
@@ -1298,6 +1301,10 @@ main ( int argc, char **argv)
}
break;
+ case oExtraDigestAlgo:
+ extra_digest_algo = pargs.r.ret_str;
+ break;
+
case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
case oNoRandomSeedFile: use_random_seed = 0; break;
@@ -1441,6 +1448,12 @@ main ( int argc, char **argv)
if (our_md_test_algo(opt.def_digest_algo) )
log_error (_("selected digest algorithm is invalid\n"));
}
+ if (extra_digest_algo)
+ {
+ opt.extra_digest_algo = gcry_md_map_name (extra_digest_algo);
+ if (our_md_test_algo (opt.extra_digest_algo) )
+ log_error (_("selected digest algorithm is invalid\n"));
+ }
}
if (log_get_errorcount(0))
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index 5232ce427..8b03995e8 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -92,6 +92,9 @@ struct
char *local_user; /* NULL or argument to -u */
+ int extra_digest_algo; /* A digest algorithm also used for
+ verification of signatures. */
+
int always_trust; /* Trust the given keys even if there is no
valid certification chain */
int skip_verify; /* do not check signatures on data */
diff --git a/sm/sign.c b/sm/sign.c
index d617e7239..d8e8451bf 100644
--- a/sm/sign.c
+++ b/sm/sign.c
@@ -491,7 +491,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
unsigned char *digest;
size_t digest_len;
/* Fixme do this for all signers and get the algo to use from
- the signer's certificate - does not make mich sense, but we
+ the signer's certificate - does not make much sense, but we
should do this consistent as we have already done it above. */
algo = GCRY_MD_SHA1;
hash_data (data_fd, data_md);
@@ -530,7 +530,7 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist,
}
/* We need to write at least a minimal list of our capabilities to
- try to convince some MUAs to use 3DEs and not the crippled
+ try to convince some MUAs to use 3DES and not the crippled
RC2. Our list is:
aes128-CBC
diff --git a/sm/verify.c b/sm/verify.c
index 2a455a5ce..1071d9086 100644
--- a/sm/verify.c
+++ b/sm/verify.c
@@ -203,10 +203,20 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
}
else
{
+ if (DBG_X509)
+ log_debug ("enabling hash algorithm %d (%s)\n",
+ algo, algoid? algoid:"");
gcry_md_enable (data_md, algo);
audit_log_i (ctrl->audit, AUDIT_DATA_HASH_ALGO, algo);
}
}
+ if (opt.extra_digest_algo)
+ {
+ if (DBG_X509)
+ log_debug ("enabling extra hash algorithm %d\n",
+ opt.extra_digest_algo);
+ gcry_md_enable (data_md, opt.extra_digest_algo);
+ }
if (is_detached)
{
if (data_fd == -1)
@@ -271,6 +281,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
char *msgdigest = NULL;
size_t msgdigestlen;
char *ctattr;
+ int sigval_hash_algo;
int info_pkalgo;
unsigned int verifyflags;
@@ -331,7 +342,8 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
&algo, &is_enabled)
|| !is_enabled)
{
- log_error ("digest algo %d has not been enabled\n", algo);
+ log_error ("digest algo %d (%s) has not been enabled\n",
+ algo, algoid?algoid:"");
audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "unsupported");
goto next_signer;
}
@@ -389,8 +401,16 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "bad");
goto next_signer;
}
+ sigval_hash_algo = hash_algo_from_sigval (sigval);
if (DBG_X509)
- log_debug ("signer %d - signature available", signer);
+ {
+ log_debug ("signer %d - signature available (sigval hash=%d)",
+ signer, sigval_hash_algo);
+/* log_printhex ("sigval ", sigval, */
+/* gcry_sexp_canon_len (sigval, 0, NULL, NULL)); */
+ }
+ if (!sigval_hash_algo)
+ sigval_hash_algo = algo; /* Fallback used e.g. with old libksba. */
/* Find the certificate of the signer */
keydb_search_reset (kh);
@@ -438,8 +458,8 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
gcry_md_hd_t md;
unsigned char *s;
- /* check that the message digest in the signed attributes
- matches the one we calculated on the data */
+ /* Check that the message digest in the signed attributes
+ matches the one we calculated on the data. */
s = gcry_md_read (data_md, algo);
if ( !s || !msgdigestlen
|| gcry_md_get_algo_dlen (algo) != msgdigestlen
@@ -456,7 +476,7 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
goto next_signer;
}
- rc = gcry_md_open (&md, algo, 0);
+ rc = gcry_md_open (&md, sigval_hash_algo, 0);
if (rc)
{
log_error ("md_open failed: %s\n", gpg_strerror (rc));
@@ -476,14 +496,14 @@ gpgsm_verify (ctrl_t ctrl, int in_fd, int data_fd, FILE *out_fp)
audit_log_s (ctrl->audit, AUDIT_SIG_STATUS, "error");
goto next_signer;
}
- rc = gpgsm_check_cms_signature (cert, sigval, md, algo,
- &info_pkalgo);
+ rc = gpgsm_check_cms_signature (cert, sigval, md,
+ sigval_hash_algo, &info_pkalgo);
gcry_md_close (md);
}
else
{
- rc = gpgsm_check_cms_signature (cert, sigval, data_md, algo,
- &info_pkalgo);
+ rc = gpgsm_check_cms_signature (cert, sigval, data_md,
+ algo, &info_pkalgo);
}
if (rc)