1 diff -ruN gnutls26-2.4.1.orig/lib/opencdk/opencdk.h gnutls26-2.4.1/lib/opencdk/opencdk.h
2 --- gnutls26-2.4.1.orig/lib/opencdk/opencdk.h 2008-06-30 16:45:51.000000000 -0400
3 +++ gnutls26-2.4.1/lib/opencdk/opencdk.h 2008-08-21 19:23:44.000000000 -0400
8 - CDK_S2K_ITERSALTED = 3
9 + CDK_S2K_ITERSALTED = 3,
10 + CDK_S2K_GNU_EXT = 101
11 + /* GNU S2K extensions: refer to DETAILS from GnuPG:
12 + http://cvs.gnupg.org/cgi-bin/viewcvs.cgi/trunk/doc/DETAILS?root=GnuPG
17 diff -ruN gnutls26-2.4.1.orig/lib/opencdk/read-packet.c gnutls26-2.4.1/lib/opencdk/read-packet.c
18 --- gnutls26-2.4.1.orig/lib/opencdk/read-packet.c 2008-06-30 16:45:51.000000000 -0400
19 +++ gnutls26-2.4.1/lib/opencdk/read-packet.c 2008-08-21 19:30:09.000000000 -0400
25 +/* read about S2K at http://tools.ietf.org/html/rfc4880#section-3.7.1 */
27 read_s2k (cdk_stream_t inp, cdk_s2k_t s2k)
29 - return CDK_Not_Implemented;
32 + s2k->mode = cdk_stream_getc (inp);
33 + s2k->hash_algo = cdk_stream_getc (inp);
34 + if (s2k->mode == CDK_S2K_SIMPLE)
36 + else if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED)
38 + if (stream_read (inp, s2k->salt, DIM (s2k->salt), &nread))
39 + return CDK_Inv_Packet;
40 + if (nread != DIM (s2k->salt))
41 + return CDK_Inv_Packet;
43 + if (s2k->mode == CDK_S2K_ITERSALTED)
44 + s2k->count = cdk_stream_getc (inp);
46 + else if (s2k->mode == CDK_S2K_GNU_EXT)
48 + /* GNU extensions to the S2K : read DETAILS from gnupg */
52 + return CDK_Not_Implemented;
60 read_symkey_enc (cdk_stream_t inp, size_t pktlen, cdk_pkt_symkey_enc_t ske)
67 return CDK_Out_Of_Core;
69 ske->cipher_algo = cdk_stream_getc (inp);
70 - s2k->mode = cdk_stream_getc (inp);
71 + ret = read_s2k(inp, s2k);
76 case CDK_S2K_SIMPLE : minlen = 0; break;
78 return CDK_Inv_Packet;
81 - s2k->hash_algo = cdk_stream_getc (inp);
82 - if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED)
84 - if (stream_read (inp, s2k->salt, DIM (s2k->salt), &nread))
85 - return CDK_Inv_Packet;
86 - if (nread != DIM (s2k->salt))
87 - return CDK_Inv_Packet;
89 - if (s2k->mode == CDK_S2K_ITERSALTED)
90 - s2k->count = cdk_stream_getc (inp);
93 ske->seskeylen = pktlen - 4 - minlen;
94 /* We check if there is an encrypted session key and if it fits into
95 the buffer. The maximal key length is 256-bit. */
97 rc = read_s2k (inp, sk->protect.s2k);
100 - sk->protect.ivlen = gcry_cipher_get_algo_blklen (sk->protect.algo);
101 - if (!sk->protect.ivlen)
102 - return CDK_Inv_Packet;
103 - rc = stream_read (inp, sk->protect.iv, sk->protect.ivlen, &nread);
106 - if (nread != sk->protect.ivlen)
107 - return CDK_Inv_Packet;
108 + /* refer to --export-secret-subkeys in gpg(1) */
109 + if (sk->protect.s2k->mode == CDK_S2K_GNU_EXT)
110 + sk->protect.ivlen = 0;
112 + sk->protect.ivlen = gcry_cipher_get_algo_blklen (sk->protect.algo);
113 + if (!sk->protect.ivlen)
114 + return CDK_Inv_Packet;
115 + rc = stream_read (inp, sk->protect.iv, sk->protect.ivlen, &nread);
118 + if (nread != sk->protect.ivlen)
119 + return CDK_Inv_Packet;
123 sk->protect.algo = sk->s2k_usage;
125 return CDK_Out_Of_Core;
126 if (stream_read (inp, sk->encdata, sk->enclen, &nread))
127 return CDK_Inv_Packet;
128 + /* Handle the GNU S2K extensions we know (just gnu-dummy right now): */
129 + if (sk->protect.s2k->mode == CDK_S2K_GNU_EXT) {
130 + unsigned char gnumode;
131 + if ((sk->enclen < strlen("GNU") + 1) ||
132 + (0 != memcmp("GNU", sk->encdata, strlen("GNU"))))
133 + return CDK_Inv_Packet;
134 + gnumode = sk->encdata[strlen("GNU")];
135 + /* we only handle gnu-dummy (mode 1).
136 + mode 2 should refer to external smart cards.
139 + return CDK_Inv_Packet;
140 + /* gnu-dummy should have no more data */
141 + if (sk->enclen != strlen("GNU") + 1)
142 + return CDK_Inv_Packet;
144 nskey = cdk_pk_get_nskey (sk->pk->pubkey_algo);