Remove yaml from scramblesuit module

This commit is contained in:
Oleksii Shevchuk 2017-04-20 23:18:08 +03:00
parent b4c7ff8e89
commit 933c4b6dff
4 changed files with 8 additions and 139 deletions

View File

@ -20,7 +20,7 @@ all_dependencies=set(
x.split('.')[0] for x,m in sys_modules \
if not '(built-in)' in str(m) and x != '__main__'
] + [
'Crypto', 'yaml', 'rpyc', 'pyasn1', 'rsa',
'Crypto', 'rpyc', 'rsa',
'encodings.idna', 'stringprep',
]
)

View File

@ -103,9 +103,6 @@ ST_WAIT_FOR_AUTH = 0
ST_AUTH_FAILED = 1
ST_CONNECTED = 2
# File which holds the client's session tickets.
CLIENT_TICKET_FILE = "session_ticket.yaml"
# Static validation string embedded in all tickets. Must be a multiple of 16
# bytes due to AES' block size.
TICKET_IDENTIFIER = "ScrambleSuitTicket"

View File

@ -14,7 +14,6 @@ import logging
import random
import base64
import yaml
import argparse
import probdist
@ -23,11 +22,10 @@ import message
import const
import util
import packetmorpher
import ticket
import uniformdh
import state
import fifobuf
import ticket
log = logging
@ -221,31 +219,14 @@ class ScrambleSuitTransport( base.BaseTransport ):
# The preferred authentication mechanism is a session ticket.
bridge = self.circuit.downstream.transport.getPeer()
storedTicket = ticket.findStoredTicket(bridge)
if storedTicket is not None:
#log.debug("Redeeming stored session ticket.")
(masterKey, rawTicket) = storedTicket
self.deriveSecrets(masterKey)
self.circuit.downstream.write(ticket.createTicketMessage(rawTicket,
self.sendHMAC))
# We switch to ST_CONNECTED opportunistically since we don't know
# yet whether the server accepted the ticket.
#log.debug("Switching to state ST_CONNECTED.")
self.protoState = const.ST_CONNECTED
self.flushSendBuffer()
# Conduct an authenticated UniformDH handshake if there's no ticket.
else:
if self.uniformDHSecret is None:
if self.uniformDHSecret is None:
#log.warning("A UniformDH password is not set, most likely " \
# "a missing 'password' argument.")
self.circuit.close()
return
self.circuit.close()
return
#log.debug("No session ticket to redeem. Running UniformDH.")
self.circuit.downstream.write(self.uniformdh.createHandshake())
self.circuit.downstream.write(self.uniformdh.createHandshake())
def sendRemote( self, data, flags=const.FLAG_PAYLOAD ):
"""
@ -336,10 +317,6 @@ class ScrambleSuitTransport( base.BaseTransport ):
assert len(msg.payload) == (const.TICKET_LENGTH +
const.MASTER_KEY_LENGTH)
peer = self.circuit.downstream.transport.getPeer()
ticket.storeNewTicket(msg.payload[0:const.MASTER_KEY_LENGTH],
msg.payload[const.MASTER_KEY_LENGTH:
const.MASTER_KEY_LENGTH +
const.TICKET_LENGTH], peer)
# Use the PRNG seed to generate the same probability distributions
# as the server. That's where the polymorphism comes from.
@ -704,7 +681,7 @@ class ScrambleSuitServer( ScrambleSuitTransport ):
"""
Initialise a ScrambleSuitServer object.
"""
self.weAreServer=True
self.weAreClient=False
self.weAreExternal=True

View File

@ -20,7 +20,6 @@ The 64-byte encrypted state contains:
import os
import time
import const
import yaml
import struct
import random
import datetime
@ -81,78 +80,6 @@ def issueTicketAndKey( srvState ):
return masterKey + newTicket
def storeNewTicket( masterKey, ticket, bridge ):
"""
Store a new session ticket and the according master key for future use.
This method is only called by clients. The given data, `masterKey',
`ticket' and `bridge', is YAMLed and stored in the global ticket
dictionary. If there already is a ticket for the given `bridge', it is
overwritten.
"""
assert len(masterKey) == const.MASTER_KEY_LENGTH
assert len(ticket) == const.TICKET_LENGTH
ticketFile = const.STATE_LOCATION + const.CLIENT_TICKET_FILE
log.debug("Storing newly received ticket in `%s'." % ticketFile)
# Add a new (key, ticket) tuple with the given bridge as hash key.
tickets = dict()
content = util.readFromFile(ticketFile)
if (content is not None) and (len(content) > 0):
tickets = yaml.safe_load(content)
# We also store a timestamp so we later know if our ticket already expired.
tickets[str(bridge)] = [int(time.time()), masterKey, ticket]
util.writeToFile(yaml.dump(tickets), ticketFile)
def findStoredTicket( bridge ):
"""
Retrieve a previously stored ticket from the ticket dictionary.
The global ticket dictionary is loaded and the given `bridge' is used to
look up the ticket and the master key. If the ticket dictionary does not
exist (yet) or the ticket data could not be found, `None' is returned.
"""
assert bridge
ticketFile = const.STATE_LOCATION + const.CLIENT_TICKET_FILE
log.debug("Attempting to read master key and ticket from file `%s'." %
ticketFile)
# Load the ticket hash table from file.
yamlBlurb = util.readFromFile(ticketFile)
if (yamlBlurb is None) or (len(yamlBlurb) == 0):
return None
tickets = yaml.safe_load(yamlBlurb)
try:
timestamp, masterKey, ticket = tickets[str(bridge)]
except KeyError:
log.info("Found no ticket for bridge `%s'." % str(bridge))
return None
# We can remove the ticket now since we are about to redeem it.
log.debug("Deleting ticket since it is about to be redeemed.")
del tickets[str(bridge)]
util.writeToFile(yaml.dump(tickets), ticketFile)
# If our ticket is expired, we can't redeem it.
ticketAge = int(time.time()) - timestamp
if ticketAge > const.SESSION_TICKET_LIFETIME:
log.warning("We did have a ticket but it already expired %s ago." %
str(datetime.timedelta(seconds=
(ticketAge - const.SESSION_TICKET_LIFETIME))))
return None
return (masterKey, ticket)
def checkKeys( srvState ):
"""
Check whether the key material for session tickets must be rotated.
@ -357,35 +284,3 @@ class SessionTicket( object ):
# Alias class name in order to provide a more intuitive API.
new = SessionTicket
# Give ScrambleSuit server operators a way to manually issue new session
# tickets for out-of-band distribution.
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("ip_addr", type=str, help="The IPv4 address of the "
"%s server." % const.TRANSPORT_NAME)
parser.add_argument("tcp_port", type=int, help="The TCP port of the %s "
"server." % const.TRANSPORT_NAME)
parser.add_argument("ticket_file", type=str, help="The file, the newly "
"issued ticket is written to.")
args = parser.parse_args()
print "[+] Loading server state file."
serverState = state.load()
print "[+] Generating new session ticket."
masterKey = mycrypto.strongRandom(const.MASTER_KEY_LENGTH)
ticket = SessionTicket(masterKey, serverState).issue()
print "[+] Writing new session ticket to `%s'." % args.ticket_file
tickets = dict()
server = IPv4Address('TCP', args.ip_addr, args.tcp_port)
tickets[str(server)] = [int(time.time()), masterKey, ticket]
util.writeToFile(yaml.dump(tickets), args.ticket_file)
print "[+] Success."