diff options
author | Werner Koch <wk@gnupg.org> | 2007-12-13 16:45:40 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2007-12-13 16:45:40 +0100 |
commit | 9d66580cff83d5b6cb6dc52ecc2fcfbfe1e94315 (patch) | |
tree | 7373ba64496d9695d194ed16c54abee7f5f887ba /sm | |
parent | Allow type 20 keys only with option --rfc2440. (diff) | |
download | gnupg2-9d66580cff83d5b6cb6dc52ecc2fcfbfe1e94315.tar.xz gnupg2-9d66580cff83d5b6cb6dc52ecc2fcfbfe1e94315.zip |
Allow verification of some broken S-TRUST generated signatures.
Diffstat (limited to 'sm')
-rw-r--r-- | sm/ChangeLog | 7 | ||||
-rw-r--r-- | sm/gpgsm.c | 13 | ||||
-rw-r--r-- | sm/gpgsm.h | 3 | ||||
-rw-r--r-- | sm/sign.c | 4 | ||||
-rw-r--r-- | sm/verify.c | 38 |
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 */ @@ -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) |