- --- ./lib/opencdk/opencdk.h.orig 2008-06-30 16:45:51.000000000 -0400
- +++ ./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
- + */
- };
-
-
- --- ./lib/opencdk/read-packet.c.orig 2008-06-30 16:45:51.000000000 -0400
- +++ ./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;
|