def _start_handshake_xx(self, stream, client_payload, s): """ :param stream: :type stream: SegmentedStream :param client_payload: :type client_payload: :param s: :type s: KeyPair :return: :rtype: """ self._handshakestate.initialize(handshake_pattern=XXHandshakePattern(), initiator=True, prologue=self._prologue, s=s) ephemeral_public = bytearray() self._handshakestate.write_message(b'', ephemeral_public) handshakemessage = wa20_pb2.HandshakeMessage() client_hello = wa20_pb2.HandshakeMessage.ClientHello() client_hello.ephemeral = bytes(ephemeral_public) handshakemessage.client_hello.MergeFrom(client_hello) stream.write_segment(handshakemessage.SerializeToString()) incoming_handshakemessage = wa20_pb2.HandshakeMessage() incoming_handshakemessage.ParseFromString(stream.read_segment()) if not incoming_handshakemessage.HasField("server_hello"): raise ValueError( "Handshake message does not contain server hello!") server_hello = incoming_handshakemessage.server_hello payload_buffer = bytearray() self._handshakestate.read_message( server_hello.ephemeral + server_hello.static + server_hello.payload, payload_buffer) certman = CertMan() if certman.is_valid(self._handshakestate.rs, bytes(payload_buffer)): logger.debug("cert is valid") else: logger.error("cert is not valid") message_buffer = bytearray() cipherpair = self._handshakestate.write_message( client_payload.SerializeToString(), message_buffer) static, payload = ByteUtil.split(bytes(message_buffer), 48, len(message_buffer) - 48) client_finish = wa20_pb2.HandshakeMessage.ClientFinish() client_finish.static = static client_finish.payload = payload outgoing_handshakemessage = wa20_pb2.HandshakeMessage() outgoing_handshakemessage.client_finish.MergeFrom(client_finish) stream.write_segment(outgoing_handshakemessage.SerializeToString()) return cipherpair
def _switch_handshake_xxfallback(self, stream, s, client_payload, server_hello): """ :param handshake_pattern: :type handshake_pattern: HandshakePattern :param stream: :type stream: SegmentedStream :param s: :type s: KeyPair :param e: :type e: KeyPair :param client_payload: :type client_payload: :param server_hello: :type server_hello: :return: :rtype: tuple(CipherState,CipherState) """ self._handshakestate.switch( handshake_pattern=FallbackPatternModifier().modify( XXHandshakePattern()), initiator=True, prologue=self._prologue, s=s) payload_buffer = bytearray() self._handshakestate.read_message( server_hello.ephemeral + server_hello.static + server_hello.payload, payload_buffer) certman = CertMan() if certman.is_valid(self._handshakestate.rs, bytes(payload_buffer)): logger.debug("cert is valid") else: logger.error("cert is not valid") message_buffer = bytearray() cipherpair = self._handshakestate.write_message( client_payload.SerializeToString(), message_buffer) static, payload = ByteUtil.split(bytes(message_buffer), 48, len(message_buffer) - 48) client_finish = wa20_pb2.HandshakeMessage.ClientFinish() client_finish.static = static client_finish.payload = payload outgoing_handshakemessage = wa20_pb2.HandshakeMessage() outgoing_handshakemessage.client_finish.MergeFrom(client_finish) stream.write_segment(outgoing_handshakemessage.SerializeToString()) return cipherpair
from dissononce.hash.sha256 import SHA256Hash import dissononce, logging if __name__ == "__main__": dissononce.logger.setLevel(logging.DEBUG) # setup initiator and responder variables alice_s = X25519DH().generate_keypair() bob_s = X25519DH().generate_keypair() # prepare handshakestate objects for initiator and responder alice_handshakestate = HandshakeState( SymmetricState(CipherState(AESGCMCipher()), SHA256Hash()), X25519DH()) bob_handshakestate = HandshakeState( SymmetricState(CipherState(AESGCMCipher()), SHA256Hash()), X25519DH()) # initialize handshakestate objects alice_handshakestate.initialize(XXHandshakePattern(), True, b'', s=alice_s) bob_handshakestate.initialize(XXHandshakePattern(), False, b'', s=bob_s) # -> e message_buffer = bytearray() alice_handshakestate.write_message(b'', message_buffer) bob_handshakestate.read_message(bytes(message_buffer), bytearray()) # <- e, ee, s, es message_buffer = bytearray() bob_handshakestate.write_message(b'', message_buffer) alice_handshakestate.read_message(bytes(message_buffer), bytearray()) # -> s, se message_buffer = bytearray() alice_cipherstates = alice_handshakestate.write_message(
True, b'', s=alice_s, rs=alice_rs) bob_handshakestate.initialize(IKHandshakePattern(), False, b'', s=bob_s) # -> e, es, s, ss message_buffer = bytearray() alice_handshakestate.write_message(b'', message_buffer) try: bob_handshakestate.read_message(bytes(message_buffer), bytearray()) except DecryptFailedException: # bob failed to read alice's message, possibly because alice used wrong static keys for bob, will now fallback # to XX bob_handshakestate.initialize(FallbackPatternModifier().modify( XXHandshakePattern()), False, b'', s=bob_s, re=bob_handshakestate.re) # <- e, ee, s, es message_buffer = bytearray() bob_handshakestate.write_message(b'', message_buffer) try: # alice doesn't yet know about the XX fallback switch and still expects IK's (e, ee, se) pattern alice_handshakestate.read_message(bytes(message_buffer), bytearray()) except DecryptFailedException: # alice failed to read bob's message. but alice and bob had a pre-agreement that if will happen if bob for # whatever reason descides to fall back to XX, an therefore so must alice