Пример #1
0
    def test_ignoring_spaces_in_secret(self):
        """
        Check if spaces are skipped during generation of the token
        """
        def chunks(original, size):
            """
            Split original string into chunks sized as requested in ``size``
            parameter. Returns iterator yielding single chunks.
            Similar to: http://stackoverflow.com/a/312464/548696
            :param original: original string (almost any iterable really)
            :type original: str or unicode
            :param size: requested size of chunks
            :type size: int
            """
            for i in six.moves.range(0, len(original), size):
                yield original[i:i + size]

        # Simple generation without spaces:
        secret = 'MFRGGZDFMZTWQ2LK'
        # Simple generation with spaces:
        secret_with_spaces = ' '.join(chunks(secret, 3))
        # Check if was properly sliced:
        self.assertEqual(5, secret_with_spaces.count(' '))

        # Both spaceless secret and secret with spaces should give the same
        self.assertEqual(
            get_hotp(secret, 1),
            get_hotp(secret_with_spaces, 1),
        )
Пример #2
0
    def test_ignoring_spaces_in_secret(self):
        """
        Check if spaces are skipped during generation of the token
        """
        def chunks(original, size):
            """
            Split original string into chunks sized as requested in ``size``
            parameter. Returns iterator yielding single chunks.
            Similar to: http://stackoverflow.com/a/312464/548696
            :param original: original string (almost any iterable really)
            :type original: str or unicode
            :param size: requested size of chunks
            :type size: int
            """
            for i in six.moves.range(0, len(original), size):
                yield original[i:i+size]

        # Simple generation without spaces:
        secret = 'MFRGGZDFMZTWQ2LK'
        # Simple generation with spaces:
        secret_with_spaces = ' '.join(chunks(secret, 3))
        # Check if was properly sliced:
        self.assertEqual(5, secret_with_spaces.count(' '))

        # Both spaceless secret and secret with spaces should give the same
        self.assertEqual(
            get_hotp(secret, 1),
            get_hotp(secret_with_spaces, 1),
        )
Пример #3
0
    def test_generation_for_different_intervals(self):
        """
        Check if the HOTP changes with different intervals properly
        """
        secret = b'MFRGGZDFMZTWQ2LK'
        self.assertEqual(get_hotp(secret, intervals_no=1), 765705)
        self.assertEqual(get_hotp(secret, intervals_no=2), 816065)

        self.assertEqual(
            get_hotp(secret, intervals_no=2, as_string=True),
            b'816065',
        )
Пример #4
0
    def test_generation_for_different_intervals(self):
        """
        Check if the HOTP changes with different intervals properly
        """
        secret = b'MFRGGZDFMZTWQ2LK'
        self.assertEqual(get_hotp(secret, intervals_no=1), 765705)
        self.assertEqual(get_hotp(secret, intervals_no=2), 816065)

        self.assertEqual(
            get_hotp(secret, intervals_no=2, as_string=True),
            b'816065',
        )
Пример #5
0
    def test_generating_totp_at_specific_clock(self):
        """
        check if the totp can be generated for a specific clock
        which is basically the same as hotp
        """
        secret = b'MFRGGZDFMZTWQ2LK'
        hotp = get_hotp(secret=secret, intervals_no=int(time.time())//30,)
        totp = get_totp(secret=secret, clock=None)
        self.assertEqual(hotp, totp)

        # hotp intervals minus 1
        hotp = get_hotp(secret=secret, intervals_no=int(time.time())//30-1,)
        #totp 30 seconds in the past
        totp = get_totp(secret=secret, clock=(int(time.time())-30))
        self.assertEqual(hotp, totp)
Пример #6
0
 def test_validating_correct_hotp_after_exhaustion(self):
     """
     Validating token created for old interval number should fail
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     # Act as if the given token was created for previous interval
     self.assertFalse(valid_hotp(get_hotp(secret, 123), secret, last=123))
Пример #7
0
 def test_checking_hotp_validity_for_unicode_secret(self):
     """
     Validity check should also work if secret passed to valid_hotp is
     unicode.
     """
     secret = six.u('MFRGGZDFMZTWQ2LK')
     self.assertTrue(valid_hotp(get_hotp(secret, 123), secret))
Пример #8
0
 def test_checking_hotp_validity_for_unicode_secret(self):
     """
     Validity check should also work if secret passed to valid_hotp is
     unicode.
     """
     secret = six.u('MFRGGZDFMZTWQ2LK')
     self.assertTrue(valid_hotp(get_hotp(secret, 123), secret))
Пример #9
0
 def test_validating_correct_hotp_after_exhaustion(self):
     """
     Validating token created for old interval number should fail
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     # Act as if the given token was created for previous interval
     self.assertFalse(valid_hotp(get_hotp(secret, 123), secret, last=123))
Пример #10
0
 def test_hotp_generation_from_bytes_secret(self):
     """
     Test simple generation of HOTP token
     """
     # Simple generation from bytes
     secret = b'MFRGGZDFMZTWQ2LK'
     self.assertEqual(get_hotp(secret, 1), 765705)
Пример #11
0
 def test_hotp_generation_from_unicode_secret(self):
     """
     Check if HOTP is properly generated for unicode secrets
     """
     # Simple generation from unicode
     secret = six.u('MFRGGZDFMZTWQ2LK')
     self.assertEqual(get_hotp(secret, 1), 765705)
Пример #12
0
 def test_validating_correct_hotp_as_totp(self):
     """
     Check if valid TOTP will work as HOTP - should not work, unless for
     very big interval number (matching Unix epoch timestamp)
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     self.assertFalse(valid_totp(get_hotp(secret, 1), secret))
Пример #13
0
 def test_hotp_generation_from_bytes_secret(self):
     """
     Test simple generation of HOTP token
     """
     # Simple generation from bytes
     secret = b'MFRGGZDFMZTWQ2LK'
     self.assertEqual(get_hotp(secret, 1), 765705)
Пример #14
0
 def test_hotp_generation_from_unicode_secret(self):
     """
     Check if HOTP is properly generated for unicode secrets
     """
     # Simple generation from unicode
     secret = six.u('MFRGGZDFMZTWQ2LK')
     self.assertEqual(get_hotp(secret, 1), 765705)
Пример #15
0
def generateOTP(user):
    secKey = base64.b32encode(os.urandom(10)).decode('utf-8')
    user.secKey = secKey
    db.session.commit()
    token = otp.get_hotp(secKey, intervals_no=3)
    html = render_template('frontpage/otp.html', token=token)
    subject = "OTP Verification for Updating Password"
    send_email(user.email, subject, html)
Пример #16
0
 def test_validating_correct_hotp_as_totp(self):
     """
     Check if valid TOTP will work as HOTP - should not work, unless for
     very big interval number (matching Unix epoch timestamp)
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     with timecop.freeze(time.time()):
         self.assertFalse(valid_totp(get_hotp(secret, 1), secret))
Пример #17
0
 def test_generating_current_totp_and_validating(self):
     """
     Check if TOTP generated for current time is the same as manually
     created HOTP for proper interval
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     hotp = get_hotp(secret=secret, intervals_no=int(time.time())//30,)
     totp = get_totp(secret=secret)
     self.assertEqual(hotp, totp)
Пример #18
0
 def test_retrieving_proper_interval_from_validator(self):
     """
     Check, if returns valid interval when checking the valid HOTP
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     totp = 713385
     result = valid_hotp(totp, secret, last=1, trials=5)
     # Should be 4, as HOTP is valid for 4th interval
     self.assertEqual(result, 4)
     # Re-generate HOTP for this specific interval and check again
     self.assertEqual(get_hotp(secret, intervals_no=4), totp)
Пример #19
0
 def test_retrieving_proper_interval_from_validator(self):
     """
     Check, if returns valid interval when checking the valid HOTP
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     totp = 713385
     result = valid_hotp(totp, secret, last=1, trials=5)
     # Should be 4, as HOTP is valid for 4th interval
     self.assertEqual(result, 4)
     # Re-generate HOTP for this specific interval and check again
     self.assertEqual(get_hotp(secret, intervals_no=4), totp)
Пример #20
0
 def test_generating_current_totp_as_string(self):
     """
     Check if the TOTP also works seamlessly when generated as string
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     hotp = get_hotp(
         secret=secret,
         intervals_no=int(time.time())//30,
         as_string=True,
     )
     totp = get_totp(secret=secret, as_string=True)
     self.assertEqual(hotp, totp)
Пример #21
0
    def test_generating_totp_at_specific_clock(self):
        """
        check if the totp can be generated for a specific clock
        which is basically the same as hotp
        """
        secret = b'MFRGGZDFMZTWQ2LK'
        with timecop.freeze(time.time()):
            hotp = get_hotp(
                secret=secret,
                intervals_no=int(time.time()) // 30,
            )
            totp = get_totp(secret=secret, clock=None)
            self.assertEqual(hotp, totp)

            # hotp intervals minus 1
            hotp = get_hotp(
                secret=secret,
                intervals_no=int(time.time()) // 30 - 1,
            )
            # totp 30 seconds in the past
            totp = get_totp(secret=secret, clock=(int(time.time()) - 30))
            self.assertEqual(hotp, totp)
Пример #22
0
 def test_generating_current_totp_as_string(self):
     """
     Check if the TOTP also works seamlessly when generated as string
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     with timecop.freeze(time.time()):
         hotp = get_hotp(
             secret=secret,
             intervals_no=int(time.time()) // 30,
             as_string=True,
         )
         totp = get_totp(secret=secret, as_string=True)
         self.assertEqual(hotp, totp)
Пример #23
0
 def test_generating_current_totp_and_validating(self):
     """
     Check if TOTP generated for current time is the same as manually
     created HOTP for proper interval
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     with timecop.freeze(time.time()):
         hotp = get_hotp(
             secret=secret,
             intervals_no=int(time.time()) // 30,
         )
         totp = get_totp(secret=secret)
         self.assertEqual(hotp, totp)
Пример #24
0
        def __call__(self, username, garbage=False, do_replay=False):
            # calc right values!
            from base64 import b32decode

            mode, secret, _ = TEST_USERS[username]

            if garbage:
                pw = b'\x12' * 32 if mode == USER_AUTH_HMAC else b'123x23'
                cnt = (self.tt if mode == USER_AUTH_TOTP else 0)
            elif mode == USER_AUTH_HMAC:
                assert len(self.psbt_hash) == 32
                assert username == 'pw'
                cnt = 0

                from hmac import HMAC

                key = calc_hmac_key(dev.serial)
                pw = HMAC(key, self.psbt_hash, sha256).digest()

                #print("\n  pw=%s\n key=%s\npsbt=%s\nsalt=%s\n" % (
                #    b2a_hex(pw),
                #    b2a_hex(key),
                #    b2a_hex(self.psbt_hash),
                #    b2a_hex(salt)))

                assert not do_replay
            else:
                if do_replay:
                    if mode == USER_AUTH_TOTP:
                        cnt = self.tt - 1
                    elif mode == USER_AUTH_HOTP:
                        cnt = self.ht - 1
                else:
                    if mode == USER_AUTH_TOTP:
                        cnt = self.tt
                        self.tt += 1
                    elif mode == USER_AUTH_HOTP:
                        cnt = self.ht
                        self.ht += 1

                pw = b'%06d' % get_hotp(secret, cnt)

            assert len(pw) in {6, 32}

            # no feedback from device at this point.
            dev.send_recv(
                CCProtocolPacker.user_auth(username.encode('ascii'),
                                           pw,
                                           totp_time=cnt))
Пример #25
0
    def get(self, username, items=[]):
        if not username:
            return logger.error('a username was not passed in')
        try:
            document = db.collection.find({'username':username}, limit=1)[0]
        except IndexError:
            return logger.warning('could not find any matching users to delete')

        key = document['key']
        step = int(document['step'])
        b32 = document['b32']

        pin = otp.get_hotp(b32, intervals_no=step)
        password = "******" % (document['secret'], pin)
        if 'pin' in items:
            pyperclip.copy(pin)
            logger.info('pin copied to the clipboard')
        else:
            pyperclip.copy(password)
            logger.info('secret with generated pin has been copied to the clipboard')
        document['step'] = step + 1
        db.collection.update(document)
Пример #26
0
    parser.description = "Prints the TOTP auth code for the given secret. Can be either the raw secret string or a otpauth:// URI; the script will attempt to auto-detect which is given."
    parser.usage = "%prog [options] secret OR %prog [options] --stdin < secret.txt"
    parser.epilog = "Copyright (c) Mark Embling 2013"

    parser.add_option("--stdin", dest="stdin", 
                      action="store_true", default=False,
                      help="Read the secret (raw secret or otpauth:// URI) from stdin [default: %default]")
    parser.add_option("--type", dest="type", 
                      choices=["TOTP", "HOTP"], default="TOTP", 
                      help="Token type (HOTP or TOTP). If a URI is provided, the type will be determined from there. [default: %default]")
    parser.add_option("--count", dest="count", 
                      type="int", default=1,
                      help="Counter for HOTP [default: %default]")
    # parser.add_option("-d", "--digits", dest="digits", 
    #                   choices=['6','8'], default='6',
    #                   help="Number of digits to display (6 or 8) [default: %default]")

    (options, args) = parser.parse_args()

    # Get the secret and type
    data = _get_data(options, args)
    (secret, type_) = _get_secret(data)
    if type_ is None:
        type_ = options.type

    # Get the token and print
    if type_.upper() == "HOTP":
        print(otp.get_hotp(secret, intervals_no=options.count, as_string=True))
    else:
        print(otp.get_totp(secret, as_string=True))
Пример #27
0
 def test_returning_hotp_as_string(self):
     """
     Check if properly returns string when asked
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     self.assertEqual(get_hotp(secret, 1, as_string=True), b'765705')
Пример #28
0
def valid_guess_xy(secret, coord, guess):
    "test if correct answer given"
    num = xy_to_num(coord)
    return get_hotp(secret, num) == int(guess)
Пример #29
0
 def test_checking_hotp_validity_without_range(self):
     """
     Check if validating HOTP without giving any interval works properly
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     self.assertTrue(valid_hotp(get_hotp(secret, 123), secret))
Пример #30
0
 def test_checking_hotp_validity_without_range(self):
     """
     Check if validating HOTP without giving any interval works properly
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     self.assertTrue(valid_hotp(get_hotp(secret, 123), secret))
Пример #31
0
def calc_values(secret):
    "Calculate all the tokens for a single page"
    return [get_hotp(secret, i, as_string=True) for i in range(NUM_CODES)]
Пример #32
0
 def test_returning_hotp_as_string(self):
     """
     Check if properly returns string when asked
     """
     secret = b'MFRGGZDFMZTWQ2LK'
     self.assertEqual(get_hotp(secret, 1, as_string=True), b'765705')