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