From 2cc103e7835b151cf32de851bcc81d9e94d96009 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 4 Aug 2012 23:32:17 +0000 Subject: [PATCH] Include a Message-Type: field so that end messages can only be generated from start messages. Include millisecond precision in the time fields of the messages for extra accuracy. Log nonce values and demo hashes. Subversion-branch: /master Subversion-revision: 2519 --- chocolate-master | 9 +++++++-- secure_demo.py | 30 ++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/chocolate-master b/chocolate-master index 62340f3..ca5e942 100755 --- a/chocolate-master +++ b/chocolate-master @@ -322,6 +322,8 @@ class MasterServer: packet = nonce + signature self.send_message(addr, NET_MASTER_PACKET_TYPE_SIGN_START_RESPONSE, packet) + self.log_output(addr, "Generated nonce: %s" % + secure_demo.bin_to_hex(nonce)) def sign_end_message(self, data, addr): """ Generate a signed end message and return to the client. """ @@ -336,6 +338,9 @@ class MasterServer: demo_hash = data[0:20] start_message = data[20:] + self.log_output(addr, "End demo hash: %s" % + secure_demo.bin_to_hex(demo_hash)) + # Parse the start message and verify the signature, then use it # to generate an end message along with the hash of the demo. signature = self.signer.sign_end_message(start_message, demo_hash) @@ -364,7 +369,7 @@ class MasterServer: def rx_packet(self): """ Invoked when a packet is received. """ - data, addr = self.sock.recvfrom(1024) + data, addr = self.sock.recvfrom(1400) try: self.process_packet(data, addr) @@ -374,7 +379,7 @@ class MasterServer: def rx_packet_query_sock(self): """ Invoked when a packet is received on the query socket. """ - data, addr = self.query_sock.recvfrom(1024) + data, addr = self.query_sock.recvfrom(1400) try: self.process_query_response(data, addr) diff --git a/secure_demo.py b/secure_demo.py index 49fafa6..eea4c93 100755 --- a/secure_demo.py +++ b/secure_demo.py @@ -37,9 +37,15 @@ except ImportError: available = False def now_string(): - """Generate an ISO8601 string for the current time.""" + """Generate a string representing the current time. + + The time is roughly ISO8601 UTC format, but also includes + milliseconds for additional accuracy. + """ now = time.time() - return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(now)) + ms = int(now * 1000) % 1000 + datetime_base = time.strftime('%Y-%m-%dT%H:%M:%S', time.gmtime(now)) + return "%s.%03iZ" % (datetime_base, ms) def bin_to_hex(data): """Convert a string of binary data into a hex representation.""" @@ -56,6 +62,7 @@ class SecureSigner(object): def _generate_start_message(self, nonce): """Generate the plaintext used for a start message.""" return "\n".join([ + "Message-Type: Start", "Start-Time: %s" % now_string(), "Nonce: %s" % bin_to_hex(nonce), ]) @@ -115,15 +122,22 @@ class SecureSigner(object): if plaintext is None: return None - # We assume the plaintext message ends with a newline. - if plaintext[-1] != "\n": - plaintext = plaintext + "\n" + # Split plain-text of start message into lines, and verify + # message type: + plaintext = plaintext.rstrip("\n") + plaintext_lines = plaintext.split("\n") - # Add extra fields to the plaintext, to create the end message. - message = plaintext + "\n".join([ + if plaintext_lines[0] != "Message-Type: Start": + return None + + # Construct the end message: + message_lines = [ "Message-Type: Signature" ] + message_lines += plaintext_lines[1:] + message_lines += [ "End-Time: %s" % now_string(), "Demo-Checksum: %s" % bin_to_hex(demo_hash), - ]) + ] + message = "\n".join(message_lines) return self._sign_plaintext_message(message) if __name__ == "__main__":