[Pkg-privacy-commits] [obfsproxy] 127/353: Add shared secret support to obfs2.

Ximin Luo infinity0 at moszumanska.debian.org
Sat Aug 22 13:01:49 UTC 2015


This is an automated email from the git hooks/post-receive script.

infinity0 pushed a commit to branch master
in repository obfsproxy.

commit d414b20dc46bf149f9f29d779efe9907b3e5c55f
Author: George Kadianakis <desnacked at riseup.net>
Date:   Thu Feb 28 15:33:35 2013 +0200

    Add shared secret support to obfs2.
---
 ChangeLog                          |  1 +
 obfsproxy/pyobfsproxy.py           |  4 +--
 obfsproxy/transports/base.py       |  2 +-
 obfsproxy/transports/obfs2.py      | 52 +++++++++++++++++++++++++++++++-------
 obfsproxy/transports/transports.py |  8 +++---
 5 files changed, 51 insertions(+), 16 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 63a006c..b4e6df2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
 Changes in version 0.0.3 - ??
  - Add support for logging exceptions to logfiles.
+ - Add shared secret support to obfs2.
 
 Changes in version 0.0.2 - 2013-02-17
  - Add some more files to the MANIFEST.in.
diff --git a/obfsproxy/pyobfsproxy.py b/obfsproxy/pyobfsproxy.py
index 8a742fb..acde5ed 100755
--- a/obfsproxy/pyobfsproxy.py
+++ b/obfsproxy/pyobfsproxy.py
@@ -52,8 +52,8 @@ def set_up_cli_parsing():
     # arguments.
     for transport, transport_class in transports.transports.items():
         subparser = subparsers.add_parser(transport, help='%s help' % transport)
-        transport_class['client'].register_external_mode_cli(subparser)
-        subparser.set_defaults(validation_function=transport_class['client'].validate_external_mode_cli)
+        transport_class['base'].register_external_mode_cli(subparser)
+        subparser.set_defaults(validation_function=transport_class['base'].validate_external_mode_cli)
 
     return parser
 
diff --git a/obfsproxy/transports/base.py b/obfsproxy/transports/base.py
index acb6598..5b2c8a4 100644
--- a/obfsproxy/transports/base.py
+++ b/obfsproxy/transports/base.py
@@ -23,7 +23,7 @@ def addrport(string):
     except ValueError, err:
         raise argparse.ArgumentTypeError(err)
 
-class BaseTransport:
+class BaseTransport(object):
     """
     The BaseTransport class is a skeleton class for pluggable transports.
     It contains callbacks that your pluggable transports should
diff --git a/obfsproxy/transports/obfs2.py b/obfsproxy/transports/obfs2.py
index 33c49d5..379dbda 100644
--- a/obfsproxy/transports/obfs2.py
+++ b/obfsproxy/transports/obfs2.py
@@ -37,18 +37,29 @@ def h(x):
     hasher.update(x)
     return hasher.digest()
 
-
 def hn(x, n):
     """ H^n(x) is H(x) called iteratively n times. """
 
+    data = x
     for _ in xrange(n):
-        data = h(x)
+        data = h(data)
     return data
 
-def mac(s, x):
-    """ # MAC(s, x) = H(s | x | s) """
+def mac(s, x, secret):
+    """
+    obfs2 regular MAC: MAC(s, x) = H(s | x | s)
 
-    return h(s + x + s)
+    Optionally, if the client and server share a secret value SECRET,
+    they can replace the MAC function with:
+    MAC(s,x) = H^n(s | x | H(SECRET) | s)
+
+    where n = HASH_ITERATIONS.
+    """
+    if secret:
+        secret_hash = h(secret)
+        return hn(s + x + secret_hash + s, HASH_ITERATIONS)
+    else:
+        return h(s + x + s)
 
 class Obfs2Transport(base.BaseTransport):
     """
@@ -58,6 +69,9 @@ class Obfs2Transport(base.BaseTransport):
     def __init__(self):
         """Initialize the obfs2 pluggable transport."""
 
+        if self.shared_secret:
+            log.debug("Starting obfs2 with shared secret: %s" % self.shared_secret)
+
         # Our state.
         self.state = ST_WAIT_FOR_KEY
 
@@ -76,7 +90,7 @@ class Obfs2Transport(base.BaseTransport):
         # Crypto to encrypt outgoing padding. Generate it now.
         self.send_padding_crypto = \
             self._derive_padding_crypto(self.initiator_seed if self.we_are_initiator else self.responder_seed,
-                                     self.send_pad_keytype)
+                                        self.send_pad_keytype)
         # Crypto to decrypt incoming data.
         self.recv_crypto = None
         # Crypto to decrypt incoming padding.
@@ -91,6 +105,20 @@ class Obfs2Transport(base.BaseTransport):
         # must remember to push the cached upstream data downstream.
         self.pending_data_to_send = False
 
+    @classmethod
+    def register_external_mode_cli(cls, subparser):
+        subparser.add_argument('--shared-secret', type=str, help='Shared secret')
+        super(Obfs2Transport, cls).register_external_mode_cli(subparser)
+
+    @classmethod
+    def validate_external_mode_cli(cls, args):
+        if args.shared_secret:
+            cls.shared_secret = args.shared_secret
+        else:
+            cls.shared_secret = None
+
+        super(Obfs2Transport, cls).validate_external_mode_cli(args)
+
     def handshake(self, circuit):
         """
         Do the obfs2 handshake:
@@ -100,7 +128,9 @@ class Obfs2Transport(base.BaseTransport):
         padding_length = random.randint(0, MAX_PADDING)
         seed = self.initiator_seed if self.we_are_initiator else self.responder_seed
 
-        handshake_message = seed + self.send_padding_crypto.crypt(srlz.htonl(MAGIC_VALUE) + srlz.htonl(padding_length) + rand.random_bytes(padding_length))
+        handshake_message = seed + self.send_padding_crypto.crypt(srlz.htonl(MAGIC_VALUE) +
+                                                                  srlz.htonl(padding_length) +
+                                                                  rand.random_bytes(padding_length))
 
         log.debug("obfs2 handshake: %s queued %d bytes (padding_length: %d).",
                   "initiator" if self.we_are_initiator else "responder",
@@ -188,14 +218,18 @@ class Obfs2Transport(base.BaseTransport):
         """
         Derive and return an obfs2 key using the pad string in 'pad_string'.
         """
-        secret = mac(pad_string, self.initiator_seed + self.responder_seed)
+        secret = mac(pad_string,
+                     self.initiator_seed + self.responder_seed,
+                     self.shared_secret)
         return aes.AES_CTR_128(secret[:KEYLEN], secret[KEYLEN:])
 
     def _derive_padding_crypto(self, seed, pad_string): # XXX consider secret_seed
         """
         Derive and return an obfs2 padding key using the pad string in 'pad_string'.
         """
-        secret = mac(pad_string, seed)
+        secret = mac(pad_string,
+                     seed,
+                     self.shared_secret)
         return aes.AES_CTR_128(secret[:KEYLEN], secret[KEYLEN:])
 
 class Obfs2Client(Obfs2Transport):
diff --git a/obfsproxy/transports/transports.py b/obfsproxy/transports/transports.py
index 77aca7c..485269b 100644
--- a/obfsproxy/transports/transports.py
+++ b/obfsproxy/transports/transports.py
@@ -4,10 +4,10 @@ import obfsproxy.transports.b64 as b64
 import obfsproxy.transports.obfs2 as obfs2
 import obfsproxy.transports.obfs3 as obfs3
 
-transports = { 'dummy' : {'client' : dummy.DummyClient, 'server' : dummy.DummyServer },
-               'b64' : {'client' : b64.B64Client, 'server' : b64.B64Server },
-               'obfs2' : {'client' : obfs2.Obfs2Client, 'server' : obfs2.Obfs2Server },
-               'obfs3' : {'client' : obfs3.Obfs3Client, 'server' : obfs3.Obfs3Server } }
+transports = { 'dummy' : {'base': dummy.DummyTransport, 'client' : dummy.DummyClient, 'server' : dummy.DummyServer },
+               'b64'   : {'base': b64.B64Transport, 'client' : b64.B64Client, 'server' : b64.B64Server },
+               'obfs2' : {'base': obfs2.Obfs2Transport, 'client' : obfs2.Obfs2Client, 'server' : obfs2.Obfs2Server },
+               'obfs3' : {'base': obfs3.Obfs3Transport, 'client' : obfs3.Obfs3Client, 'server' : obfs3.Obfs3Server } }
 
 def get_transport_class(name, role):
     # Rewrite equivalent roles.

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/obfsproxy.git



More information about the Pkg-privacy-commits mailing list