diff --git a/gnupg-2.0.25-file-is-digest.patch b/gnupg-2.0.25-file-is-digest.patch new file mode 100644 index 0000000..dda2635 --- /dev/null +++ b/gnupg-2.0.25-file-is-digest.patch @@ -0,0 +1,173 @@ +diff -up gnupg-2.0.25/g10/gpg.c.file-is-digest gnupg-2.0.25/g10/gpg.c +--- gnupg-2.0.25/g10/gpg.c.file-is-digest 2014-08-05 16:46:28.865869320 +0200 ++++ gnupg-2.0.25/g10/gpg.c 2014-08-05 16:49:27.520063937 +0200 +@@ -345,6 +345,7 @@ enum cmd_and_opt_values + oTTYtype, + oLCctype, + oLCmessages, ++ oFileIsDigest, + oXauthority, + oGroup, + oUnGroup, +@@ -711,6 +712,7 @@ static ARGPARSE_OPTS opts[] = { + ARGPARSE_s_s (oPersonalDigestPreferences, "personal-digest-preferences","@"), + ARGPARSE_s_s (oPersonalCompressPreferences, + "personal-compress-preferences", "@"), ++ ARGPARSE_s_n (oFileIsDigest, "file-is-digest", "@"), + + /* Aliases. I constantly mistype these, and assume other people do + as well. */ +@@ -2003,6 +2005,7 @@ main (int argc, char **argv) + set_homedir ( default_homedir () ); + opt.passphrase_repeat=1; + opt.emit_version = 1; /* Limit to the major number. */ ++ opt.file_is_digest=0; + + opt.list_options |= LIST_SHOW_UID_VALIDITY; + opt.verify_options |= LIST_SHOW_UID_VALIDITY; +@@ -2493,6 +2496,7 @@ main (int argc, char **argv) + case oPhotoViewer: opt.photo_viewer = pargs.r.ret_str; break; + case oForceV3Sigs: opt.force_v3_sigs = 1; break; + case oNoForceV3Sigs: opt.force_v3_sigs = 0; break; ++ case oFileIsDigest: opt.file_is_digest = 1; break; + case oForceV4Certs: opt.force_v4_certs = 1; break; + case oNoForceV4Certs: opt.force_v4_certs = 0; break; + case oForceMDC: opt.force_mdc = 1; break; +diff -up gnupg-2.0.25/g10/options.h.file-is-digest gnupg-2.0.25/g10/options.h +--- gnupg-2.0.25/g10/options.h.file-is-digest 2014-06-30 17:28:52.000000000 +0200 ++++ gnupg-2.0.25/g10/options.h 2014-08-05 16:46:28.869869414 +0200 +@@ -198,6 +198,7 @@ struct + int no_auto_check_trustdb; + int preserve_permissions; + int no_homedir_creation; ++ int file_is_digest; + struct groupitem *grouplist; + int mangle_dos_filenames; + int enable_progress_filter; +diff -up gnupg-2.0.25/g10/sign.c.file-is-digest gnupg-2.0.25/g10/sign.c +--- gnupg-2.0.25/g10/sign.c.file-is-digest 2014-06-30 17:28:52.000000000 +0200 ++++ gnupg-2.0.25/g10/sign.c 2014-08-05 16:46:28.870869438 +0200 +@@ -665,8 +665,12 @@ write_signature_packets (SK_LIST sk_list + mk_notation_policy_etc (sig, NULL, sk); + } + ++ if (!opt.file_is_digest) { + hash_sigversion_to_magic (md, sig); + gcry_md_final (md); ++ } else if (sig->version >= 4) { ++ log_bug("file-is-digest doesn't work with v4 sigs\n"); ++ } + + rc = do_sign( sk, sig, md, hash_for (sk) ); + gcry_md_close (md); +@@ -723,6 +727,8 @@ sign_file( strlist_t filenames, int deta + SK_LIST sk_rover = NULL; + int multifile = 0; + u32 duration=0; ++ int sigclass = 0x00; ++ u32 timestamp = 0; + + pfx = new_progress_context (); + afx = new_armor_context (); +@@ -739,7 +745,16 @@ sign_file( strlist_t filenames, int deta + fname = NULL; + + if( fname && filenames->next && (!detached || encryptflag) ) +- log_bug("multiple files can only be detached signed"); ++ log_bug("multiple files can only be detached signed\n"); ++ ++ if (opt.file_is_digest && (multifile || !fname)) ++ log_bug("file-is-digest only works with one file\n"); ++ if (opt.file_is_digest && !detached) ++ log_bug("file-is-digest can only write detached signatures\n"); ++ if (opt.file_is_digest && !opt.def_digest_algo) ++ log_bug("file-is-digest needs --digest-algo\n"); ++ if (opt.file_is_digest && opt.textmode) ++ log_bug("file-is-digest doesn't work with --textmode\n"); + + if(encryptflag==2 + && (rc=setup_symkey(&efx.symkey_s2k,&efx.symkey_dek))) +@@ -767,7 +782,7 @@ sign_file( strlist_t filenames, int deta + goto leave; + + /* prepare iobufs */ +- if( multifile ) /* have list of filenames */ ++ if( multifile || opt.file_is_digest) /* have list of filenames */ + inp = NULL; /* we do it later */ + else { + inp = iobuf_open(fname); +@@ -900,7 +915,7 @@ sign_file( strlist_t filenames, int deta + gcry_md_enable (mfx.md, hash_for(sk)); + } + +- if( !multifile ) ++ if( !multifile && !opt.file_is_digest ) + iobuf_push_filter( inp, md_filter, &mfx ); + + if( detached && !encryptflag && !RFC1991 ) +@@ -955,6 +970,8 @@ sign_file( strlist_t filenames, int deta + + write_status_begin_signing (mfx.md); + ++ sigclass = opt.textmode && !outfile? 0x01 : 0x00; ++ + /* Setup the inner packet. */ + if( detached ) { + if( multifile ) { +@@ -995,6 +1012,45 @@ sign_file( strlist_t filenames, int deta + if( opt.verbose ) + putc( '\n', stderr ); + } ++ else if (opt.file_is_digest) { ++ byte *mdb, ts[5]; ++ size_t mdlen; ++ const char *fp; ++ int c, d; ++ ++ gcry_md_final(mfx.md); ++ /* this assumes gcry_md_read returns the same buffer */ ++ mdb = gcry_md_read(mfx.md, opt.def_digest_algo); ++ mdlen = gcry_md_get_algo_dlen(opt.def_digest_algo); ++ if (strlen(fname) != mdlen * 2 + 11) ++ log_bug("digests must be %zu + @ + 5 bytes\n", mdlen); ++ d = -1; ++ for (fp = fname ; *fp; ) { ++ c = *fp++; ++ if (c >= '0' && c <= '9') ++ c -= '0'; ++ else if (c >= 'a' && c <= 'f') ++ c -= 'a' - 10; ++ else if (c >= 'A' && c <= 'F') ++ c -= 'A' - 10; ++ else ++ log_bug("filename is not hex\n"); ++ if (d >= 0) { ++ *mdb++ = d << 4 | c; ++ c = -1; ++ if (--mdlen == 0) { ++ mdb = ts; ++ if (*fp++ != '@') ++ log_bug("missing time separator\n"); ++ } ++ } ++ d = c; ++ } ++ sigclass = ts[0]; ++ if (sigclass != 0x00 && sigclass != 0x01) ++ log_bug("bad cipher class\n"); ++ timestamp = buffer_to_u32(ts + 1); ++ } + else { + /* read, so that the filter can calculate the digest */ + while( iobuf_get(inp) != -1 ) +@@ -1012,8 +1068,8 @@ sign_file( strlist_t filenames, int deta + + /* write the signatures */ + rc = write_signature_packets (sk_list, out, mfx.md, +- opt.textmode && !outfile? 0x01 : 0x00, +- 0, duration, detached ? 'D':'S'); ++ sigclass, ++ timestamp, duration, detached ? 'D':'S'); + if( rc ) + goto leave; + diff --git a/gnupg2.spec b/gnupg2.spec index 544d248..d84da8f 100644 --- a/gnupg2.spec +++ b/gnupg2.spec @@ -11,6 +11,8 @@ Source1: ftp://ftp.gnupg.org/gcrypt/%{?pre:alpha/}gnupg/gnupg-%{version}%{?pre}. #Source0: gnupg2-20090809svn.tar.bz2 Patch1: gnupg-2.0.20-insttools.patch Patch3: gnupg-2.0.20-secmem.patch +# non-upstreamable patch adding file-is-digest option needed for Copr +Patch4: gnupg-2.0.25-file-is-digest.patch Patch5: gnupg-2.0.20-ocsp-keyusage.patch Patch6: gnupg-2.0.19-fips-algo.patch @@ -76,6 +78,7 @@ to the base GnuPG package %patch1 -p1 -b .insttools %endif %patch3 -p1 -b .secmem +%patch4 -p1 -b .file-is-digest %patch5 -p1 -b .keyusage %patch6 -p1 -b .fips @@ -193,6 +196,7 @@ fi %changelog * Tue Aug 5 2014 Tomáš Mráz - 2.0.25-1 - new upstream release fixing a minor regression introduced by the previous one +- add --file-is-digest option needed for copr * Wed Jun 25 2014 Tomáš Mráz - 2.0.24-1 - new upstream release fixing CVE-2014-4617