modified:   base_node.py
	modified:   controller.py
	new file:   hmac_helper.py
diff --git a/hmac_helper.py b/hmac_helper.py
new file mode 100644
index 0000000..15d8c47
--- /dev/null
+++ b/hmac_helper.py
@@ -0,0 +1,129 @@
+# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
+#
+# Copyright (C) 2014 Regents of the University of California.
+# Author: Adeola Bannis <thecodemaiden@gmail.com>
+# 
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# A copy of the GNU General Public License is in the file COPYING.
+from pyndn.encoding import WireFormat
+from pyndn.util import Blob
+from pyndn.digest_sha256_signature import DigestSha256Signature
+from pyndn import Data, KeyLocatorType, Interest, Name
+from hashlib import sha256
+from random import SystemRandom
+from time import time as timestamp
+
+import hmac
+
+class HmacHelper(object):
+    def __init__(self, raw_key, wireFormat=None):
+        super(HmacHelper, self).__init__()
+        self.key = sha256(raw_key).digest()
+        self.random = SystemRandom()
+        if wireFormat is None:
+            self.wireFormat = WireFormat.getDefaultWireFormat()
+        else:
+            self.wireFormat = wireFormat
+
+    @classmethod
+    def generatePin(cls):
+        """
+        Generate a pin to be entered into another device.
+        Restricting this to 8 bytes (16 hex chars) for now.
+        """
+        pin = bytearray(8)
+        random = SystemRandom()
+        for i in range(8):
+            pin[i] = random.randint(0,0xff)
+        return str(pin).encode('hex')
+    
+    @classmethod
+    def extractInterestSignature(cls, interest, wireFormat=None):
+        if wireFormat is None:
+            wireFormat = WireFormat.getDefaultWireFormat()
+
+        try:
+            signature = wireFormat.decodeSignatureInfoAndValue(
+                            interest.getName().get(-2).getValue().buf(),
+                            interest.getName().get(-1).getValue().buf())
+        except:
+            signature = None
+
+        return signature
+
+    def signData(self, data, keyName=None, wireFormat=None):
+        data.setSignature(DigestSha256Signature())
+        s = data.getSignature()
+
+        #s.getKeyLocator().setType(KeyLocatorType.KEYNAME)
+        #s.getKeyLocator().setKeyName(keyName)
+
+        if wireFormat is None:
+            wireFormat = WireFormat.getDefaultWireFormat()
+        encoded = data.wireEncode(wireFormat)
+        signer = hmac.new(self.key, bytearray(encoded.toSignedBuffer()), sha256)
+        s.setSignature(Blob(signer.digest()))
+        data.wireEncode(wireFormat)
+     
+    def verifyData(self, data, wireFormat=None):
+        # clear out old signature so encoding does not include it
+        if wireFormat is None:
+            wireFormat = WireFormat.getDefaultWireFormat()
+        encoded = data.wireEncode(wireFormat)
+        hasher = hmac.new(self.key, bytearray(encoded.toSignedBuffer()), sha256)
+        sigBytes = data.getSignature().getSignature()
+        return sigBytes.toRawStr() == hasher.digest()
+
+    def signInterest(self, interest, keyName=None, wireFormat=None):
+        # Adds the nonce and timestamp here, because there is no
+        # 'makeCommandInterest' call for this yet
+        nonceValue = bytearray(8)
+        for i in range(8):
+            nonceValue[i] = self.random.randint(0,0xff)
+        timestampValue = bytearray(8)
+        ts = int(timestamp()*1000)
+        for i in range(8):
+            byte = ts & 0xff
+            timestampValue[-(i+1)] = byte
+            ts = ts >> 8
+
+        if wireFormat is None:
+            wireFormat = WireFormat.getDefaultWireFormat()
+
+        s = DigestSha256Signature()
+        #s.getKeyLocator().setType(KeyLocatorType.KEYNAME)
+        #s.getKeyLocator().setKeyName(keyName)
+
+        interestName = interest.getName()
+        interestName.append(nonceValue).append(timestampValue)
+        interestName.append(wireFormat.encodeSignatureInfo(s))
+        interestName.append(Name.Component())
+
+        encoding = interest.wireEncode(wireFormat)
+        signer = hmac.new(self.key, encoding.toSignedBuffer(), sha256)
+
+        s.setSignature(Blob(signer.digest()))
+        interest.setName(interestName.getPrefix(-1).append(
+            wireFormat.encodeSignatureValue(s)))
+
+
+    def verifyInterest(self, interest, wireFormat=None):
+        if wireFormat is None:
+            wireFormat = WireFormat.getDefaultWireFormat()
+
+        signature = self.extractInterestSignature(interest, wireFormat)
+        encoding = interest.wireEncode(wireFormat)
+        hasher = hmac.new(self.key, encoding.toSignedBuffer(), sha256)
+        return signature.getSignature().toRawStr() == hasher.digest()
+