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
This commit is contained in:
Simon Howard 2012-08-04 23:32:17 +00:00
parent 6f54a0d8c1
commit 2cc103e783
2 changed files with 29 additions and 10 deletions

View File

@ -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)

View File

@ -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__":