2d7e35d37082e9481963aad703fdebe08d78b3d3
[monkeysphere.git] / patches / gnutls / 22_functional_s2k_with_GNU_dummy.diff
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
4 @@ -214,7 +214,11 @@
5  enum cdk_s2k_type_t {
6      CDK_S2K_SIMPLE     = 0,
7      CDK_S2K_SALTED     = 1,
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
13 + */
14  };
15  
16  
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
20 @@ -78,10 +78,35 @@
21  }
22  
23  
24 -static int
25 +/* read about S2K at http://tools.ietf.org/html/rfc4880#section-3.7.1 */
26 +static cdk_error_t
27  read_s2k (cdk_stream_t inp, cdk_s2k_t s2k)
28  {
29 -  return CDK_Not_Implemented;
30 +  size_t nread;
31 +
32 +  s2k->mode = cdk_stream_getc (inp);
33 +  s2k->hash_algo = cdk_stream_getc (inp);
34 +  if (s2k->mode == CDK_S2K_SIMPLE) 
35 +      return 0;
36 +  else if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED)
37 +    {
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;
42 +      
43 +      if (s2k->mode == CDK_S2K_ITERSALTED)
44 +       s2k->count = cdk_stream_getc (inp);
45 +    }
46 +  else if (s2k->mode == CDK_S2K_GNU_EXT)
47 +    {
48 +      /* GNU extensions to the S2K : read DETAILS from gnupg */
49 +      return 0;
50 +    }
51 +  else
52 +    return CDK_Not_Implemented;
53 +
54 +  return 0;
55  }
56  
57  
58 @@ -194,6 +219,7 @@
59  static cdk_error_t
60  read_symkey_enc (cdk_stream_t inp, size_t pktlen, cdk_pkt_symkey_enc_t ske)
61  {
62 +  cdk_error_t ret;
63    cdk_s2k_t s2k;
64    size_t minlen;
65    size_t nread, nleft;
66 @@ -213,7 +239,9 @@
67      return CDK_Out_Of_Core;
68    
69    ske->cipher_algo = cdk_stream_getc (inp);
70 -  s2k->mode = cdk_stream_getc (inp);
71 +  ret = read_s2k(inp, s2k);
72 +  if (ret != 0)
73 +    return ret;
74    switch (s2k->mode)
75      {
76      case CDK_S2K_SIMPLE    : minlen = 0; break;
77 @@ -225,18 +253,6 @@
78        return CDK_Inv_Packet;
79      }
80    
81 -  s2k->hash_algo = cdk_stream_getc (inp);
82 -  if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED)
83 -    {
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;
88 -      
89 -      if (s2k->mode == CDK_S2K_ITERSALTED)
90 -       s2k->count = cdk_stream_getc (inp);
91 -    }
92 -  
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. */
96 @@ -421,14 +437,19 @@
97        rc = read_s2k (inp, sk->protect.s2k);
98        if (rc) 
99         return rc;
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);
104 -      if (rc)
105 -       return rc;
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;
111 +      else {
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);
116 +       if (rc)
117 +         return rc;
118 +       if (nread != sk->protect.ivlen)
119 +         return CDK_Inv_Packet;
120 +      }
121      }
122    else
123      sk->protect.algo = sk->s2k_usage;
124 @@ -476,6 +497,22 @@
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.
137 +       */
138 +       if (gnumode != 1)
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;
143 +      }
144        nskey = cdk_pk_get_nskey (sk->pk->pubkey_algo);
145        if (!nskey)
146         return CDK_Inv_Algo;