From 4f2abba493a35709d0d28a70f9856c6c349d50bd Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Fri, 22 Aug 2008 00:31:56 -0400 Subject: [PATCH] added patch to enable GnuTLS 2.4.x to read gnu-dummy S2K extensions, along with build script to make updated .deb packages. --- .../22_functional_s2k_with_GNU_dummy.diff | 146 ++++++++++++++++++ patches/gnutls/build | 26 ++++ 2 files changed, 172 insertions(+) create mode 100644 patches/gnutls/22_functional_s2k_with_GNU_dummy.diff create mode 100755 patches/gnutls/build diff --git a/patches/gnutls/22_functional_s2k_with_GNU_dummy.diff b/patches/gnutls/22_functional_s2k_with_GNU_dummy.diff new file mode 100644 index 0000000..2d7e35d --- /dev/null +++ b/patches/gnutls/22_functional_s2k_with_GNU_dummy.diff @@ -0,0 +1,146 @@ +diff -ruN gnutls26-2.4.1.orig/lib/opencdk/opencdk.h gnutls26-2.4.1/lib/opencdk/opencdk.h +--- gnutls26-2.4.1.orig/lib/opencdk/opencdk.h 2008-06-30 16:45:51.000000000 -0400 ++++ gnutls26-2.4.1/lib/opencdk/opencdk.h 2008-08-21 19:23:44.000000000 -0400 +@@ -214,7 +214,11 @@ + enum cdk_s2k_type_t { + CDK_S2K_SIMPLE = 0, + CDK_S2K_SALTED = 1, +- CDK_S2K_ITERSALTED = 3 ++ CDK_S2K_ITERSALTED = 3, ++ CDK_S2K_GNU_EXT = 101 ++ /* GNU S2K extensions: refer to DETAILS from GnuPG: ++ http://cvs.gnupg.org/cgi-bin/viewcvs.cgi/trunk/doc/DETAILS?root=GnuPG ++ */ + }; + + +diff -ruN gnutls26-2.4.1.orig/lib/opencdk/read-packet.c gnutls26-2.4.1/lib/opencdk/read-packet.c +--- gnutls26-2.4.1.orig/lib/opencdk/read-packet.c 2008-06-30 16:45:51.000000000 -0400 ++++ gnutls26-2.4.1/lib/opencdk/read-packet.c 2008-08-21 19:30:09.000000000 -0400 +@@ -78,10 +78,35 @@ + } + + +-static int ++/* read about S2K at http://tools.ietf.org/html/rfc4880#section-3.7.1 */ ++static cdk_error_t + read_s2k (cdk_stream_t inp, cdk_s2k_t s2k) + { +- return CDK_Not_Implemented; ++ size_t nread; ++ ++ s2k->mode = cdk_stream_getc (inp); ++ s2k->hash_algo = cdk_stream_getc (inp); ++ if (s2k->mode == CDK_S2K_SIMPLE) ++ return 0; ++ else if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED) ++ { ++ if (stream_read (inp, s2k->salt, DIM (s2k->salt), &nread)) ++ return CDK_Inv_Packet; ++ if (nread != DIM (s2k->salt)) ++ return CDK_Inv_Packet; ++ ++ if (s2k->mode == CDK_S2K_ITERSALTED) ++ s2k->count = cdk_stream_getc (inp); ++ } ++ else if (s2k->mode == CDK_S2K_GNU_EXT) ++ { ++ /* GNU extensions to the S2K : read DETAILS from gnupg */ ++ return 0; ++ } ++ else ++ return CDK_Not_Implemented; ++ ++ return 0; + } + + +@@ -194,6 +219,7 @@ + static cdk_error_t + read_symkey_enc (cdk_stream_t inp, size_t pktlen, cdk_pkt_symkey_enc_t ske) + { ++ cdk_error_t ret; + cdk_s2k_t s2k; + size_t minlen; + size_t nread, nleft; +@@ -213,7 +239,9 @@ + return CDK_Out_Of_Core; + + ske->cipher_algo = cdk_stream_getc (inp); +- s2k->mode = cdk_stream_getc (inp); ++ ret = read_s2k(inp, s2k); ++ if (ret != 0) ++ return ret; + switch (s2k->mode) + { + case CDK_S2K_SIMPLE : minlen = 0; break; +@@ -225,18 +253,6 @@ + return CDK_Inv_Packet; + } + +- s2k->hash_algo = cdk_stream_getc (inp); +- if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED) +- { +- if (stream_read (inp, s2k->salt, DIM (s2k->salt), &nread)) +- return CDK_Inv_Packet; +- if (nread != DIM (s2k->salt)) +- return CDK_Inv_Packet; +- +- if (s2k->mode == CDK_S2K_ITERSALTED) +- s2k->count = cdk_stream_getc (inp); +- } +- + ske->seskeylen = pktlen - 4 - minlen; + /* We check if there is an encrypted session key and if it fits into + the buffer. The maximal key length is 256-bit. */ +@@ -421,14 +437,19 @@ + rc = read_s2k (inp, sk->protect.s2k); + if (rc) + return rc; +- sk->protect.ivlen = gcry_cipher_get_algo_blklen (sk->protect.algo); +- if (!sk->protect.ivlen) +- return CDK_Inv_Packet; +- rc = stream_read (inp, sk->protect.iv, sk->protect.ivlen, &nread); +- if (rc) +- return rc; +- if (nread != sk->protect.ivlen) +- return CDK_Inv_Packet; ++ /* refer to --export-secret-subkeys in gpg(1) */ ++ if (sk->protect.s2k->mode == CDK_S2K_GNU_EXT) ++ sk->protect.ivlen = 0; ++ else { ++ sk->protect.ivlen = gcry_cipher_get_algo_blklen (sk->protect.algo); ++ if (!sk->protect.ivlen) ++ return CDK_Inv_Packet; ++ rc = stream_read (inp, sk->protect.iv, sk->protect.ivlen, &nread); ++ if (rc) ++ return rc; ++ if (nread != sk->protect.ivlen) ++ return CDK_Inv_Packet; ++ } + } + else + sk->protect.algo = sk->s2k_usage; +@@ -476,6 +497,22 @@ + return CDK_Out_Of_Core; + if (stream_read (inp, sk->encdata, sk->enclen, &nread)) + return CDK_Inv_Packet; ++ /* Handle the GNU S2K extensions we know (just gnu-dummy right now): */ ++ if (sk->protect.s2k->mode == CDK_S2K_GNU_EXT) { ++ unsigned char gnumode; ++ if ((sk->enclen < strlen("GNU") + 1) || ++ (0 != memcmp("GNU", sk->encdata, strlen("GNU")))) ++ return CDK_Inv_Packet; ++ gnumode = sk->encdata[strlen("GNU")]; ++ /* we only handle gnu-dummy (mode 1). ++ mode 2 should refer to external smart cards. ++ */ ++ if (gnumode != 1) ++ return CDK_Inv_Packet; ++ /* gnu-dummy should have no more data */ ++ if (sk->enclen != strlen("GNU") + 1) ++ return CDK_Inv_Packet; ++ } + nskey = cdk_pk_get_nskey (sk->pk->pubkey_algo); + if (!nskey) + return CDK_Inv_Algo; diff --git a/patches/gnutls/build b/patches/gnutls/build new file mode 100755 index 0000000..0037431 --- /dev/null +++ b/patches/gnutls/build @@ -0,0 +1,26 @@ +#!/bin/sh -e + +# build a patched version of GnuTLS version 2.4.x, including the +# ability to parse and accept the GNU S2K extension known as +# "gnu-dummy" (which doesn't have any secret key data at all) + +# Note: you probably want + +# Author: Daniel Kahn Gillmor +# Date: 2008-08-22 00:11:05-0400 + +# Note: please run this from the current directory, so it can find and +# transfer the patch it needs. + +workingdir=$(mktemp -d) + +(cd "$workingdir" && apt-get source libgnutls26) + +cp ./*.diff "$workingdir/gnutls26-2.4".*/debian/patches/ + +(cd "$workingdir/gnutls26-2.4".* && \ + dch --local .s2kext1 --distribution experimental 'added patch to handle GNU extensions to S2K' && \ + debuild -uc -us -sa) + +echo now you should: +echo reprepro -C gnutls include experimental "$workingdir/"*.changes -- 2.26.2