def receivedDownstream( self, data, circuit ):
        """
        Receives and processes data coming from the remote machine.

        The incoming `data' is dispatched depending on the current protocol
        state and whether we are the client or the server.  The data is either
        payload or authentication data.
        """

        if self.weAreServer and (self.protoState == const.ST_WAIT_FOR_AUTH):

            # First, try to interpret the incoming data as session ticket.
            if self.receiveTicket(data):
                log.debug("Ticket authentication succeeded.")
                self.flushSendBuffer(circuit)
                self.sendRemote(circuit,
                                ticket.issueTicketAndKey(self.srvState),
                                flags=const.FLAG_NEW_TICKET)
                self.sendRemote(circuit, self.srvState.prngSeed,
                                flags=const.FLAG_PRNG_SEED)

            # Second, interpret the data as a UniformDH handshake.
            elif self.uniformdh.receivePublicKey(data, self.deriveSecrets,
                    self.srvState):
                # Now send the server's UniformDH public key to the client.
                handshakeMsg = self.uniformdh.createHandshake()
                newTicket = ticket.issueTicketAndKey(self.srvState)

                log.debug("Sending %d bytes of UniformDH handshake and "
                          "session ticket." % len(handshakeMsg))

                circuit.downstream.write(handshakeMsg)

                log.debug("UniformDH authentication succeeded.")
                self.sendRemote(circuit, newTicket,
                                flags=const.FLAG_NEW_TICKET)
                self.sendRemote(circuit, self.srvState.prngSeed,
                                flags=const.FLAG_PRNG_SEED)

                log.debug("Switching to state ST_CONNECTED.")
                self.protoState = const.ST_CONNECTED
                self.flushSendBuffer(circuit)

            else:
                log.debug("Authentication unsuccessful so far.  "
                          "Waiting for more data.")
                return

        if self.weAreClient and (self.protoState == const.ST_WAIT_FOR_AUTH):

            if not self.uniformdh.receivePublicKey(data, self.deriveSecrets):
                log.debug("Unable to finish UniformDH handshake just yet.")
                return
            log.debug("Switching to state ST_CONNECTED.")
            self.protoState = const.ST_CONNECTED
            self.flushSendBuffer(circuit)

        if self.protoState == const.ST_CONNECTED:

            self.processMessages(circuit, data.read())
Example #2
0
    def test1_authentication( self ):
        srvState = state.State()
        srvState.genState()

        ss = scramblesuit.ScrambleSuitTransport()
        ss.srvState = srvState

        realEpoch = util.getEpoch

        # Try three valid and one invalid epoch value.
        for epoch in util.expandedEpoch() + ["000000"]:

            util.getEpoch = lambda: epoch

            # Prepare ticket message.
            blurb = ticket.issueTicketAndKey(srvState)
            rawTicket = blurb[const.MASTER_KEY_LENGTH:]
            masterKey = blurb[:const.MASTER_KEY_LENGTH]
            ss.deriveSecrets(masterKey)
            ticketMsg = ticket.createTicketMessage(rawTicket, ss.recvHMAC)

            util.getEpoch = realEpoch

            buf = obfs_buf.Buffer()
            buf.write(ticketMsg)

            if epoch == "000000":
                self.assertFalse(ss.receiveTicket(buf))
            else:
                self.assertTrue(ss.receiveTicket(buf))
Example #3
0
    def sendTicketAndSeed(self):
        """
        Send a session ticket and the PRNG seed to the client.

        This method is only called by the server after successful
        authentication.  Finally, the server's send buffer is flushed.
        """

        log.debug("Sending a new session ticket and the PRNG seed to the " "client.")

        self.sendRemote(ticket.issueTicketAndKey(self.srvState), flags=const.FLAG_NEW_TICKET)
        self.sendRemote(self.srvState.prngSeed, flags=const.FLAG_PRNG_SEED)
        self.flushSendBuffer()
Example #4
0
    def sendTicketAndSeed(self):
        """
        Send a session ticket and the PRNG seed to the client.

        This method is only called by the server after successful
        authentication.  Finally, the server's send buffer is flushed.
        """

        log.debug("Sending a new session ticket and the PRNG seed to the " \
                  "client.")

        self.sendRemote(ticket.issueTicketAndKey(self.srvState),
                        flags=const.FLAG_NEW_TICKET)
        self.sendRemote(self.srvState.prngSeed, flags=const.FLAG_PRNG_SEED)
        self.flushSendBuffer()