Commit fd4a9119 authored by Philipp Winter's avatar Philipp Winter Committed by George Kadianakis
Browse files

When authenticating, also test epoch boundaries.

On occasion, a client's or a server's epoch might already have increased
whereas the epoch of the other party didn't.  This is a benign event and there
is no reason to fail authentication because of this.  As a result, as a server,
we now also test boundary values, i.e., epoch - 1, epoch, epoch + 1.
parent 37fb7903
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -388,14 +388,20 @@ class ScrambleSuitTransport( base.BaseTransport ):
        existingHMAC = potentialTicket[index + const.MARK_LENGTH:
                                       index + const.MARK_LENGTH +
                                       const.HMAC_SHA256_128_LENGTH]
        authenticated = False
        for epoch in util.expandedEpoch():
            myHMAC = mycrypto.HMAC_SHA256_128(self.recvHMAC,
                                          potentialTicket[0:
                                          index + const.MARK_LENGTH] +
                                          util.getEpoch())
                                              potentialTicket[0:index + \
                                              const.MARK_LENGTH] + epoch)

        if not util.isValidHMAC(myHMAC, existingHMAC, self.recvHMAC):
            log.warning("The HMAC is invalid: `%s' vs. `%s'." %
                        (myHMAC.encode('hex'), existingHMAC.encode('hex')))
            if util.isValidHMAC(myHMAC, existingHMAC, self.recvHMAC):
                authenticated = True
                break

            log.debug("HMAC invalid.  Trying next epoch value.")

        if not authenticated:
            log.warning("Could not verify the authentication message's HMAC.")
            return False

        # Do nothing if the ticket is replayed.  Immediately closing the
+14 −8
Original line number Diff line number Diff line
@@ -120,19 +120,25 @@ class UniformDH( object ):
        if not index:
            return False

        self.echoEpoch = util.getEpoch()

        # Now that we know where the authenticating HMAC is: verify it.
        hmacStart = index + const.MARK_LENGTH
        existingHMAC = handshake[hmacStart:
                                 (hmacStart + const.HMAC_SHA256_128_LENGTH)]

        authenticated = False
        for epoch in util.expandedEpoch():
            myHMAC = mycrypto.HMAC_SHA256_128(self.sharedSecret,
                                          handshake[0 : hmacStart] +
                                          self.echoEpoch)
                                              handshake[0 : hmacStart] + epoch)

            if util.isValidHMAC(myHMAC, existingHMAC, self.sharedSecret):
                self.echoEpoch = epoch
                authenticated = True
                break

            log.debug("HMAC invalid.  Trying next epoch value.")

        if not util.isValidHMAC(myHMAC, existingHMAC, self.sharedSecret):
            log.warning("The HMAC is invalid: `%s' vs. `%s'." %
                        (myHMAC.encode('hex'), existingHMAC.encode('hex')))
        if not authenticated:
            log.warning("Could not verify the authentication message's HMAC.")
            return False

        # Do nothing if the ticket is replayed.  Immediately closing the
+10 −0
Original line number Diff line number Diff line
@@ -106,6 +106,16 @@ def getEpoch( ):
    return str(int(time.time()) / const.EPOCH_GRANULARITY)


def expandedEpoch( ):
    """
    Return [epoch, epoch-1, epoch+1].
    """

    epoch = int(getEpoch())

    return [str(epoch), str(epoch - 1), str(epoch + 1)]


def writeToFile( data, fileName ):
    """
    Writes the given `data' to the file specified by `fileName'.