gnutls-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

GNU extensions to read_s2k for GnuTLS 2.4.x [was: Re: GNU extensions to


From: Daniel Kahn Gillmor
Subject: GNU extensions to read_s2k for GnuTLS 2.4.x [was: Re: GNU extensions to read_s2k for 2.5.x]
Date: Fri, 22 Aug 2008 02:36:45 -0400
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.2 (gnu/linux)

On Fri 2008-08-22 01:14:11 -0400, Daniel Kahn Gillmor wrote:

> In particular, it treats S2K mode 101 as GNU-Dummy, when in fact it
> should be "GNU Extensions", and it should just test the data after
> the hash to find out whether it's the gnu-dummy extension or not.

Attached is the revised patch against the GnuTLS 2.4.x series that
adopts the same semantic clarification.  This applies against 2.4.1 as
shipped in debian lenny, if anyone is interested.  

I've prepared patched .debs, which are available from the monkeysphere
repository:

  http://monkeysphere.info/news/modified-gnutls-2.4.x-available/

They're working for me nicely at the moment.

For anyone interested in testing, below is a public key with the
primary key stripped (using GNU-Dummy S2K), and an
authentication-capable subkey with unencrypted secret material.

I think this would be a reasonable method to provide private keys to a
typical TLS-capable service (such as HTTPS or SMTP).

-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1.4.9 (GNU/Linux)

lQCVBEO3YdABBACRqqEnucag4+vyZny2M67Pai5+5suIRRvY+Ly8Ms5MvgCi3EVV
xT05O/+0ShiRaf+QicCOFrhbU9PZzzU+seEvkeW2UCu4dQfILkmj+HBEIltGnHr3
G0yegHj5pnqrcezERURf2e17gGFWX91cXB9Cm721FPXczuKraphKwCA9PwARAQAB
/gNlAkdOVQG0OURlbW9uc3RyYXRpb24gS2V5IGZvciBTMksgR05VIGV4dGVuc2lv
biAxMDAxIC0tIGdudS1kdW1teYi8BBMBAgAmBQJDt2HQAhsDBQkB4TOABgsJCAcD
AgQVAggDBBYCAwECHgECF4AACgkQQZUwSa4UDezTOQP/TMQXUVrWzHYZGopoPZ2+
ZS3qddiznBHsgb7MGYg1KlTiVJSroDUBCHIUJvdQKZV9zrzrFl47D07x6hGyUPHV
aZXvuITW8t1o5MMHkCy3pmJ2KgfDvdUxrBvLfgPMICA4c6zA0mWquee43syEW9NY
g3q61iPlQwD1J1kX1wlimLCdAdgEQ7dh0AEEANAwa63zlQbuy1Meliy8otwiOa+a
mH6pxxUgUNggjyjO5qx+rl25mMjvGIRX4/L1QwIBXJBVi3SgvJW1COZxZqBYqj9U
8HVT07mWKFEDf0rZLeUE2jTm16cF9fcW4DQhW+sfYm+hi2sY3HeMuwlUBK9KHfW2
+bGeDzVZ4pqfUEudABEBAAEAA/0bemib+wxub9IyVFUp7nPobjQC83qxLSNzrGI/
RHzgu/5CQi4tfLOnwbcQsLELfker2hYnjsLrT9PURqK4F7udrWEoZ1I1LymOtLG/
4tNZ7Mnul3wRC2tCn7FKx8sGJwGh/3li8vZ6ALVJAyOia5TZ/buX0+QZzt6+hPKk
7MU1WQIA4bUBjtrsqDwro94DvPj3/jBnMZbXr6WZIItLNeVDUcM8oHL807Am97K1
ueO/f6v1sGAHG6lVPTmtekqPSTWBfwIA7CGFvEyvSALfB8NUa6jtk27NCiw0csql
kuhCmwXGMVOiryKEfegkIahf2bAd/gnWHPrpWp7bUE20v8YoW22I4wIAhnm5Wr5Q
Sy7EHDUxmJm5TzadFp9gq08qNzHBpXSYXXJ3JuWcL1/awUqp3tE1I6zZ0hZ38Ia6
SdBMN88idnhDPqPoiKUEGAECAA8FAkO3YdACGyAFCQHhM4AACgkQQZUwSa4UDezm
vQP/ZhK+2ly9oI2z7ZcNC/BJRch0/ybQ3haahII8pXXmOThpZohr/LUgoWgCZdXg
vP6yiszNk2tIs8KphCAw7Lw/qzDC2hEORjWO4f46qk73RAgSqG/GyzI4ltWiDhqn
vnQCFl3+QFSe4zinqykHnLwGPMXv428d/ZjkIc2ju8dRsn4=
=CR5w
-----END PGP PRIVATE KEY BLOCK-----

As always, feedback is appreciated.

Regards,

        --dkg

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;

Attachment: pgplY65dhvhwa.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]