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

[minion-cvs] Fix 3 outstanding MMTP issues: cert confusion, self-to-...



Update of /home/minion/cvsroot/src/minion/lib/mixminion
In directory moria.mit.edu:/tmp/cvs-serv20486/src/minion/lib/mixminion

Modified Files:
	MMTPClient.py test.py 
Log Message:
Fix 3 outstanding MMTP issues: cert confusion, self-to-self connections, avoid multiple connections to same server.

Index: MMTPClient.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/MMTPClient.py,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- MMTPClient.py	20 Feb 2003 16:57:39 -0000	1.24
+++ MMTPClient.py	28 Mar 2003 15:36:22 -0000	1.25
@@ -56,6 +56,7 @@
         self.context = _ml.TLSContext_new()
         self.tls = None
         self.sock = None
+        self.certCache = PeerCertificateCache()
 
     def connect(self, connectTimeout=None):
         """Connect to the server, perform the TLS handshake, check the server
@@ -119,11 +120,8 @@
 
         # Check the public key of the server to prevent man-in-the-middle
         # attacks.
-        peer_pk = self.tls.get_peer_cert_pk()
-        keyID = sha1(peer_pk.encode_key(public=1))
-        if self.targetKeyID is not None and (keyID != self.targetKeyID):
-            raise MixProtocolError("Bad Key ID: Expected %r but got %r" % (
-                self.targetKeyID, keyID))
+        self.certCache.check(self.tls, self.targetKeyID,
+                             "%s:%s"%(self.targetIP,self.targetPort))
 
         ####
         # Protocol negotiation
@@ -253,3 +251,42 @@
                 callback(idx)
     finally:
         con.shutdown()
+
+class PeerCertificateCache:
+    #XXXX004 use this properly; flush it to disk.
+    "DOCDOC"
+    def __init__(self):
+        self.cache = {} # hashed peer pk -> identity keyid that it is valid for
+
+    def check(self, tls, targetKeyID, address):
+        "DOCDOC"
+        if targetKeyID is None:
+            return
+
+        peer_pk = tls.get_peer_cert_pk()
+        hashed_peer_pk = sha1(peer_pk.encode_key(public=1))
+        #XXXX Remove this option
+        if targetKeyID == hashed_peer_pk:
+            LOG.warn("Non-rotatable keyid from server at %s", address)
+            return # raise MixProtocolError
+
+        try:
+            if self.cache[hashed_peer_pk] == targetKeyID:
+                return # All is well.
+            else:
+                raise MixProtocolError("Mismatch between expected and actual key id")
+        except KeyError:
+            # We haven't found an identity for this pk yet.
+            pass
+
+        try:
+            identity = tls.verify_cert_and_get_identity_pk()
+        except _ml.TLSError, e:
+            raise MixProtocolError("Invalid KeyID from server at %s: %s"
+                                   %(address, e))
+
+        hashed_identity = sha1(peer_pk.encode_key(public=1))
+        self.cache[hashed_peer_pk] = hashed_identity
+        if hashed_identity != targetKeyID:
+            raise MixProtocolError("Invalid KeyID for server at %s", address)
+

Index: test.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/test.py,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -d -r1.96 -r1.97
--- test.py	27 Mar 2003 10:30:59 -0000	1.96
+++ test.py	28 Mar 2003 15:36:22 -0000	1.97
@@ -62,7 +62,8 @@
 from mixminion.server.Modules import *
 from mixminion.server.PacketHandler import *
 from mixminion.server.ServerQueue import *
-from mixminion.server.ServerKeys import generateServerDescriptorAndKeys
+from mixminion.server.ServerKeys import generateServerDescriptorAndKeys, \
+     generateCertChain
 
 # Set this flag to 1 in order to have all RSA keys and diffie-hellman params
 # generated independently.  Otherwise, we cache diffie-hellman parameters
@@ -2879,8 +2880,10 @@
                 sys.stdout.flush()
             pk = getRSAKey(3,1024)
             pk.PEM_write_key(open(pkfile, 'w'), 0)
-            _ml.generate_cert(certfile, pk, "Testing certificate",
+            ident = getRSAKey(0,2048)
+            generateCertChain(certfile, pk, ident, "<testing>",
                               time.time(), time.time()+365*24*60*60)
+            
 
         pk = _ml.rsa_PEM_read_key(open(pkfile, 'r'), 0)
         return _ml.TLSContext_new(certfile, pk, dhfile)
@@ -3624,7 +3627,7 @@
            info['Server']['Packet-Key'].get_public_key())
         mmtpKey = Crypto.pk_PEM_load(
             os.path.join(keydir, "mmtp.key"))
-        eq(Crypto.sha1(mmtpKey.encode_key(1)),
+        eq(Crypto.sha1(identity.encode_key(1)),
            info['Incoming/MMTP']['Key-Digest'])
 
         # Now check the digest and signature
@@ -5428,7 +5431,8 @@
     tc = loader.loadTestsFromTestCase
 
     if 0:
-        suite.addTest(tc(MiscTests))
+        suite.addTest(tc(MMTPTests))
+        #suite.addTest(tc(MiscTests))
         return suite
 
     suite.addTest(tc(MiscTests))