[tor-commits] [bridgedb/develop] Move HMAC and HMACfunction creators to bridgedb.crypto module.

isis at torproject.org isis at torproject.org
Sun Mar 16 16:38:45 UTC 2014


commit 437f816fea14565a34cb9377e665c599d01b4a53
Author: Isis Lovecruft <isis at torproject.org>
Date:   Tue Mar 11 20:18:25 2014 +0000

    Move HMAC and HMACfunction creators to bridgedb.crypto module.
    
     * MOVE bridgedb.Bridges.get_hmac()    → bridgedb.crypto.getHMAC()
     * MOVE bridgedb.Bridges.get_hmac_fn() → bridgedb.crypto.getHMACFunc()
     * CHANGE all other modules which use these functions to use the newer
       ones.
---
 lib/bridgedb/Bridges.py |   37 ++++++-------------------------------
 lib/bridgedb/Dist.py    |   45 +++++++++++++++++++++------------------------
 lib/bridgedb/Main.py    |    6 +++---
 lib/bridgedb/crypto.py  |   27 +++++++++++++++++++++++++++
 4 files changed, 57 insertions(+), 58 deletions(-)

diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py
index cd77911..2293c78 100644
--- a/lib/bridgedb/Bridges.py
+++ b/lib/bridgedb/Bridges.py
@@ -7,7 +7,6 @@ them in rings.
 
 import binascii
 import bisect
-import hmac
 import logging
 import re
 import hashlib
@@ -15,12 +14,12 @@ import socket
 import time
 import ipaddr
 import random
-import hashlib
 
 import bridgedb.Storage
 import bridgedb.Bucket
 import bridgedb.Util as Util
 
+from bridgedb.crypto import getHMACFunc
 from bridgedb.parse import addr
 from bridgedb.parse import networkstatus
 
@@ -32,8 +31,6 @@ except ImportError:
 
 HEX_FP_LEN = 40
 ID_LEN = 20
-
-DIGESTMOD = hashlib.sha1
 HEX_DIGEST_LEN = 40
 DIGEST_LEN = 20
 PORTSPEC_LEN = 16
@@ -87,28 +84,6 @@ def is_valid_fingerprint(fp):
 toHex = binascii.b2a_hex
 fromHex = binascii.a2b_hex
 
-def get_hmac(key, value):
-    """Return the hmac of **value** using the **key**."""
-    h = hmac.new(key, value, digestmod=DIGESTMOD)
-    return h.digest()
-
-def get_hmac_fn(key, hex=True):
-    """Return a function that computes the hmac of its input using the key k.
-
-    :param bool hex: If True, the output of the function will be hex-encoded.
-    :rtype: callable
-    :returns: A function which can be uses to generate HMACs.
-    """
-    h = hmac.new(key, digestmod=DIGESTMOD)
-    def hmac_fn(value):
-        h_tmp = h.copy()
-        h_tmp.update(value)
-        if hex:
-            return h_tmp.hexdigest()
-        else:
-            return h_tmp.digest()
-    return hmac_fn
-
 def chopString(s, size):
     """Generator. Given a string and a length, divide the string into pieces
        of no more than that length.
@@ -216,7 +191,7 @@ class Bridge(object):
         """
 
         if not request: request = 'default'
-        digest = get_hmac_fn('Order-Or-Addresses')(request)
+        digest = getHMACFunc('Order-Or-Addresses')(request)
         pos = long(digest[:8], 16) # lower 8 bytes -> long
 
         # default address type
@@ -847,7 +822,7 @@ class BridgeRing(BridgeHolder):
         """
         self.bridges = {}
         self.bridgesByID = {}
-        self.hmac = get_hmac_fn(key, hex=False)
+        self.hmac = getHMACFunc(key, hex=False)
         self.isSorted = False
         self.sortedKeys = []
         if answerParameters is None:
@@ -1045,7 +1020,7 @@ class FixedBridgeSplitter(BridgeHolder):
        them to several sub-bridgeholders with equal probability.
     """
     def __init__(self, key, rings):
-        self.hmac = get_hmac_fn(key, hex=True)
+        self.hmac = getHMACFunc(key, hex=True)
         self.rings = rings[:]
         for r in self.rings:
             assert(isinstance(r, BridgeHolder))
@@ -1123,7 +1098,7 @@ class BridgeSplitter(BridgeHolder):
        Bridge-to-bridgeholder associations are recorded in a store.
     """
     def __init__(self, key):
-        self.hmac = get_hmac_fn(key, hex=True)
+        self.hmac = getHMACFunc(key, hex=True)
         self.ringsByName = {}
         self.totalP = 0
         self.pValues = []
@@ -1230,7 +1205,7 @@ class FilteredBridgeSplitter(BridgeHolder):
         """
         self.key = key
         self.filterRings = {}
-        self.hmac = get_hmac_fn(key, hex=True)
+        self.hmac = getHMACFunc(key, hex=True)
         self.bridges = []
         self.distributorName = ''
 
diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py
index 6e9c436..9d3b06e 100644
--- a/lib/bridgedb/Dist.py
+++ b/lib/bridgedb/Dist.py
@@ -15,11 +15,14 @@ import re
 import time
 from ipaddr import IPv6Address, IPAddress
 
+from bridgedb.crypto import getHMAC
+from bridgedb.crypto import getHMACFunc
 from bridgedb.Filters import filterAssignBridgesToRing
 from bridgedb.Filters import filterBridgesByRules
 from bridgedb.Filters import filterBridgesByIP4
 from bridgedb.Filters import filterBridgesByIP6
 
+
 def uniformMap(ip):
     """Map an IP to an arbitrary 'area' string, such that any two /24 addresses
     get the same string.
@@ -137,11 +140,11 @@ class IPBasedDistributor(Distributor):
         for c in ipCategories:
             self.categories.append(c)
 
-        key2 = bridgedb.Bridges.get_hmac(key, "Assign-Bridges-To-Rings")
-        key3 = bridgedb.Bridges.get_hmac(key, "Order-Areas-In-Rings")
-        self.areaOrderHmac = bridgedb.Bridges.get_hmac_fn(key3, hex=False)
-        key4 = bridgedb.Bridges.get_hmac(key, "Assign-Areas-To-Rings")
-        self.areaClusterHmac = bridgedb.Bridges.get_hmac_fn(key4, hex=True)
+        key2 = getHMAC(key, "Assign-Bridges-To-Rings")
+        key3 = getHMAC(key, "Order-Areas-In-Rings")
+        self.areaOrderHmac = getHMACFunc(key3, hex=False)
+        key4 = getHMAC(key, "Assign-Areas-To-Rings")
+        self.areaClusterHmac = getHMACFunc(key4, hex=True)
 
         # add splitter and cache the default rings
         # plus leave room for dynamic filters
@@ -170,9 +173,8 @@ class IPBasedDistributor(Distributor):
                 if filterFn:
                     bridgeFilterRules.append(filterFn)
                 ruleset = frozenset(bridgeFilterRules)
-                key1 = bridgedb.Bridges.get_hmac(self.splitter.key,
-                                                 "Order-Bridges-In-Ring-%d"
-                                                 % n)
+                key1 = getHMAC(self.splitter.key,
+                               "Order-Bridges-In-Ring-%d" % n)
                 n += 1
                 ring = bridgedb.Bridges.BridgeRing(key1, self.answerParameters)
                 ring.setName('{0} Ring'.format(self.name))
@@ -192,9 +194,8 @@ class IPBasedDistributor(Distributor):
                 if filterFn:
                     bridgeFilterRules.append(filterFn)
                 ruleset = frozenset(bridgeFilterRules)
-                key1 = bridgedb.Bridges.get_hmac(self.splitter.key,
-                                                 "Order-Bridges-In-Ring-%d"
-                                                 % clusterNum)
+                key1 = getHMAC(self.splitter.key,
+                               "Order-Bridges-In-Ring-%d" % clusterNum)
                 ring = bridgedb.Bridges.BridgeRing(key1, self.answerParameters)
                 self.splitter.addRing(ring,
                                       ruleset,
@@ -262,9 +263,8 @@ class IPBasedDistributor(Distributor):
                 bridgeFilterRules.append(g)
                 logging.info("category<%s>%s", epoch, Util.logSafely(area))
                 pos = self.areaOrderHmac("category<%s>%s" % (epoch, area))
-                key1 = bridgedb.Bridges.get_hmac(self.splitter.key,
-                                                 "Order-Bridges-In-Ring-%d"
-                                                 % n)
+                key1 = getHMAC(self.splitter.key,
+                               "Order-Bridges-In-Ring-%d" % n)
                 break
             n += 1
 
@@ -281,9 +281,8 @@ class IPBasedDistributor(Distributor):
                                           clusterNum)
             bridgeFilterRules.append(g)
             pos = self.areaOrderHmac("<%s>%s" % (epoch, area))
-            key1 = bridgedb.Bridges.get_hmac(self.splitter.key,
-                                             "Order-Bridges-In-Ring-%d"
-                                             % clusterNum)
+            key1 = getHMAC(self.splitter.key,
+                           "Order-Bridges-In-Ring-%d" % clusterNum)
 
         # try to find a cached copy
         ruleset = frozenset(bridgeFilterRules)
@@ -425,10 +424,10 @@ class EmailBasedDistributor(Distributor):
     ##       to their canonical forms.
     def __init__(self, key, domainmap, domainrules,
                  answerParameters=None):
-        key1 = bridgedb.Bridges.get_hmac(key, "Map-Addresses-To-Ring")
-        self.emailHmac = bridgedb.Bridges.get_hmac_fn(key1, hex=False)
+        key1 = getHMAC(key, "Map-Addresses-To-Ring")
+        self.emailHmac = getHMACFunc(key1, hex=False)
 
-        key2 = bridgedb.Bridges.get_hmac(key, "Order-Bridges-In-Ring")
+        key2 = getHMAC(key, "Order-Bridges-In-Ring")
         # XXXX clear the store when the period rolls over!
         self.domainmap = domainmap
         self.domainrules = domainrules
@@ -506,8 +505,7 @@ class EmailBasedDistributor(Distributor):
             logging.debug("Cache miss %s" % ruleset)
 
             # add new ring
-            key1 = bridgedb.Bridges.get_hmac(self.splitter.key,
-                                             "Order-Bridges-In-Ring")
+            key1 = getHMAC(self.splitter.key, "Order-Bridges-In-Ring")
             ring = bridgedb.Bridges.BridgeRing(key1, self.answerParameters)
             # debug log: cache miss
             self.splitter.addRing(ring, ruleset,
@@ -544,8 +542,7 @@ class EmailBasedDistributor(Distributor):
         # populate all rings (for dumping assignments and testing)
         for filterFn in [filterBridgesByIP4, filterBridgesByIP6]:
             ruleset = frozenset([filterFn])
-            key1 = bridgedb.Bridges.get_hmac(self.splitter.key,
-                                             "Order-Bridges-In-Ring")
+            key1 = getHMAC(self.splitter.key, "Order-Bridges-In-Ring")
             ring = bridgedb.Bridges.BridgeRing(key1, self.answerParameters)
             self.splitter.addRing(ring, ruleset,
                                   filterBridgesByRules([filterFn]),
diff --git a/lib/bridgedb/Main.py b/lib/bridgedb/Main.py
index be8b1b0..e7dc153 100644
--- a/lib/bridgedb/Main.py
+++ b/lib/bridgedb/Main.py
@@ -410,7 +410,7 @@ def startup(options):
 
     # Create a BridgeSplitter to assign the bridges to the different
     # distributors.
-    splitter = Bridges.BridgeSplitter(Bridges.get_hmac(key, "Splitter-Key"))
+    splitter = Bridges.BridgeSplitter(crypto.getHMAC(key, "Splitter-Key"))
     logging.debug("Created splitter: %r" % splitter)
 
     # Create ring parameters.
@@ -431,7 +431,7 @@ def startup(options):
         ipDistributor = Dist.IPBasedDistributor(
             Dist.uniformMap,
             config.N_IP_CLUSTERS,
-            Bridges.get_hmac(key, "HTTPS-IP-Dist-Key"),
+            crypto.getHMAC(key, "HTTPS-IP-Dist-Key"),
             categories,
             answerParameters=ringParams)
         splitter.addRing(ipDistributor, "https", config.HTTPS_SHARE)
@@ -442,7 +442,7 @@ def startup(options):
     if config.EMAIL_DIST and config.EMAIL_SHARE:
         logging.debug("Setting up Email Distributor...")
         emailDistributor = Dist.EmailBasedDistributor(
-            Bridges.get_hmac(key, "Email-Dist-Key"),
+            crypto.getHMAC(key, "Email-Dist-Key"),
             config.EMAIL_DOMAIN_MAP.copy(),
             config.EMAIL_DOMAIN_RULES.copy(),
             answerParameters=ringParams)
diff --git a/lib/bridgedb/crypto.py b/lib/bridgedb/crypto.py
index d615489..054ec11 100644
--- a/lib/bridgedb/crypto.py
+++ b/lib/bridgedb/crypto.py
@@ -29,12 +29,17 @@
 from __future__ import absolute_import
 from __future__ import unicode_literals
 
+import hashlib
+import hmac
 import logging
 import os
 
 import OpenSSL.rand
 
 
+#: The hash digest to use for HMACs.
+DIGESTMOD = hashlib.sha1
+
 def getKey(filename):
     """Load the key stored in ``filename``, or create a new key.
 
@@ -74,3 +79,25 @@ def getKey(filename):
         key = fh.read()
         fh.close()
     return key
+
+def getHMAC(key, value):
+    """Return the HMAC of **value** using the **key**."""
+    h = hmac.new(key, value, digestmod=DIGESTMOD)
+    return h.digest()
+
+def getHMACFunc(key, hex=True):
+    """Return a function that computes the HMAC of its input using the **key**.
+
+    :param bool hex: If True, the output of the function will be hex-encoded.
+    :rtype: callable
+    :returns: A function which can be uses to generate HMACs.
+    """
+    h = hmac.new(key, digestmod=DIGESTMOD)
+    def hmac_fn(value):
+        h_tmp = h.copy()
+        h_tmp.update(value)
+        if hex:
+            return h_tmp.hexdigest()
+        else:
+            return h_tmp.digest()
+    return hmac_fn





More information about the tor-commits mailing list