예제 #1
0
    def test_safe_os_crypt(self):
        "test safe_os_crypt() wrapper"
        if not safe_os_crypt:
            raise self.skipTest("stdlib crypt module not available")

        #NOTE: this is assuming EVERY crypt will support des_crypt.
        #      if this fails on some platform, this test will need modifying.

        #test normal case
        ok, hash = safe_os_crypt(u'test', u'aa')
        self.assertTrue(ok)
        self.assertIsInstance(hash, unicode)
        self.assertEqual(hash, u'aaqPiZY5xR5l.')

        #test hash-as-bytes
        self.assertRaises(TypeError, safe_os_crypt, u'test', b('aa'))

        #test password as ascii
        ret = safe_os_crypt(b('test'), u'aa')
        self.assertEqual(ret, (True, u'aaqPiZY5xR5l.'))

        #test unicode password w/ high char
        ret = safe_os_crypt(u'test\u1234', u'aa')
        self.assertEqual(ret, (True, u'aahWwbrUsKZk.'))

        #test utf-8 password w/ high char
        ret = safe_os_crypt(b('test\xe1\x88\xb4'), u'aa')
        self.assertEqual(ret, (True, u'aahWwbrUsKZk.'))

        #test latin-1 password
        ret = safe_os_crypt(b('test\xff'), u'aa')
        # Py2k #
        self.assertEqual(ret, (True, u'aaOx.5nbTU/.M'))
예제 #2
0
    def test_05_load(self):
        "test load()"
        if gae_env:
            return self.skipTest(
                "GAE doesn't offer read/write filesystem access")

        #setup empty file
        path = mktemp()
        set_file(path, "")
        backdate_file_mtime(path, 5)
        ha = apache.HtdigestFile(path)
        self.assertEqual(ha.to_string(), b(""))

        #make changes, check force=False does nothing
        ha.update("user1", "realm", "pass1")
        ha.load(force=False)
        self.assertEqual(ha.to_string(),
                         b('user1:realm:2a6cf53e7d8f8cf39d946dc880b14128\n'))

        #change file
        set_file(path, self.sample_01)
        ha.load(force=False)
        self.assertEqual(ha.to_string(), self.sample_01)

        #make changes, check force=True overwrites them
        ha.update("user5", "realm", "pass5")
        ha.load()
        self.assertEqual(ha.to_string(), self.sample_01)

        #test load w/ no path
        hb = apache.HtdigestFile()
        self.assertRaises(RuntimeError, hb.load)
        self.assertRaises(RuntimeError, hb.load, force=False)
예제 #3
0
    def test_safe_os_crypt(self):
        "test safe_os_crypt() wrapper"
        if not safe_os_crypt:
            raise self.skipTest("stdlib crypt module not available")

        #NOTE: this is assuming EVERY crypt will support des_crypt.
        #      if this fails on some platform, this test will need modifying.

        #test normal case
        ok, hash = safe_os_crypt(u'test', u'aa')
        self.assertTrue(ok)
        self.assertIsInstance(hash, unicode)
        self.assertEqual(hash, u'aaqPiZY5xR5l.')

        #test hash-as-bytes
        self.assertRaises(TypeError, safe_os_crypt, u'test', b('aa'))

        #test password as ascii
        ret = safe_os_crypt(b('test'), u'aa')
        self.assertEqual(ret, (True, u'aaqPiZY5xR5l.'))

        #test unicode password w/ high char
        ret = safe_os_crypt(u'test\u1234', u'aa')
        self.assertEqual(ret, (True, u'aahWwbrUsKZk.'))

        #test utf-8 password w/ high char
        ret = safe_os_crypt(b('test\xe1\x88\xb4'), u'aa')
        self.assertEqual(ret, (True, u'aahWwbrUsKZk.'))

        #test latin-1 password
        ret = safe_os_crypt(b('test\xff'), u'aa')
        # Py2k #
        self.assertEqual(ret, (True, u'aaOx.5nbTU/.M'))
예제 #4
0
    def test_getrandstr(self):
        "test getrandstr()"

        def f(*a, **k):
            return utils.getrandstr(utils.rng, *a, **k)

        #count 0
        self.assertEqual(f('abc', 0), '')

        #count <0
        self.assertRaises(ValueError, f, 'abc', -1)

        #letters 0
        self.assertRaises(ValueError, f, '', 0)

        #letters 1
        self.assertEqual(f('a', 5), 'aaaaa')

        #letters
        x = f(u'abc', 16)
        y = f(u'abc', 16)
        self.assertIsInstance(x, unicode)
        self.assertNotEqual(x, y)
        self.assertEqual(sorted(set(x)), [u'a', u'b', u'c'])

        #bytes
        x = f(b('abc'), 16)
        y = f(b('abc'), 16)
        self.assertIsInstance(x, bytes)
        self.assertNotEqual(x, y)
        #NOTE: decoding this due to py3 bytes
        self.assertEqual(sorted(set(x.decode("ascii"))), [u'a', u'b', u'c'])

        #generate_password
        self.assertEqual(len(utils.generate_password(15)), 15)
예제 #5
0
def _get_hmac_prf(digest):
    "helper to return HMAC prf for specific digest"
    #check if m2crypto is present and supports requested digest
    if _EVP:
        try:
            result = _EVP.hmac(b('x'), b('y'), digest)
        except ValueError:
            pass
        else:
            #it does. so use M2Crypto's hmac & digest code
            hmac_const = _EVP.hmac
            def prf(key, msg):
                "prf(key,msg)->digest; generated by passlib.utils.pbkdf2.get_prf()"
                return hmac_const(key, msg, digest)
            prf.__name__ = "hmac_" + digest
            digest_size = len(result)
            return prf, digest_size

    #fall back to stdlib implementation
    digest_const = getattr(hashlib, digest, None)
    if not digest_const:
        raise ValueError("unknown hash algorithm: %r" % (digest,))
    digest_size = digest_const().digest_size
    hmac_const = hmac.new
    def prf(key, msg):
        "prf(key,msg)->digest; generated by passlib.utils.pbkdf2.get_prf()"
        return hmac_const(key, msg, digest_const).digest()
    prf.__name__ = "hmac_" + digest
    return prf, digest_size
예제 #6
0
    def test_getrandstr(self):
        "test getrandstr()"
        def f(*a,**k):
            return utils.getrandstr(utils.rng, *a, **k)

        #count 0
        self.assertEqual(f('abc',0), '')

        #count <0
        self.assertRaises(ValueError, f, 'abc', -1)

        #letters 0
        self.assertRaises(ValueError, f, '', 0)

        #letters 1
        self.assertEqual(f('a',5), 'aaaaa')

        #letters
        x = f(u'abc', 16)
        y = f(u'abc', 16)
        self.assertIsInstance(x, unicode)
        self.assertNotEqual(x,y)
        self.assertEqual(sorted(set(x)), [u'a',u'b',u'c'])

        #bytes
        x = f(b('abc'), 16)
        y = f(b('abc'), 16)
        self.assertIsInstance(x, bytes)
        self.assertNotEqual(x,y)
        #NOTE: decoding this due to py3 bytes
        self.assertEqual(sorted(set(x.decode("ascii"))), [u'a',u'b',u'c'])

        #generate_password
        self.assertEqual(len(utils.generate_password(15)), 15)
예제 #7
0
def _get_hmac_prf(digest):
    "helper to return HMAC prf for specific digest"
    #check if m2crypto is present and supports requested digest
    if _EVP:
        try:
            result = _EVP.hmac(b('x'), b('y'), digest)
        except ValueError:
            pass
        else:
            #it does. so use M2Crypto's hmac & digest code
            hmac_const = _EVP.hmac

            def prf(key, msg):
                "prf(key,msg)->digest; generated by passlib.utils.pbkdf2.get_prf()"
                return hmac_const(key, msg, digest)

            prf.__name__ = "hmac_" + digest
            digest_size = len(result)
            return prf, digest_size

    #fall back to stdlib implementation
    digest_const = getattr(hashlib, digest, None)
    if not digest_const:
        raise ValueError("unknown hash algorithm: %r" % (digest, ))
    digest_size = digest_const().digest_size
    hmac_const = hmac.new

    def prf(key, msg):
        "prf(key,msg)->digest; generated by passlib.utils.pbkdf2.get_prf()"
        return hmac_const(key, msg, digest_const).digest()

    prf.__name__ = "hmac_" + digest
    return prf, digest_size
예제 #8
0
    def test_05_load(self):
        "test load()"
        if gae_env:
            return self.skipTest("GAE doesn't offer read/write filesystem access")

        #setup empty file
        path = mktemp()
        set_file(path, "")
        backdate_file_mtime(path, 5)
        ha = apache.HtdigestFile(path)
        self.assertEqual(ha.to_string(), b(""))

        #make changes, check force=False does nothing
        ha.update("user1", "realm", "pass1")
        ha.load(force=False)
        self.assertEqual(ha.to_string(), b('user1:realm:2a6cf53e7d8f8cf39d946dc880b14128\n'))

        #change file
        set_file(path, self.sample_01)
        ha.load(force=False)
        self.assertEqual(ha.to_string(), self.sample_01)

        #make changes, check force=True overwrites them
        ha.update("user5", "realm", "pass5")
        ha.load()
        self.assertEqual(ha.to_string(), self.sample_01)

        #test load w/ no path
        hb = apache.HtdigestFile()
        self.assertRaises(RuntimeError, hb.load)
        self.assertRaises(RuntimeError, hb.load, force=False)
예제 #9
0
def get_prf(name):
    """lookup pseudo-random family (prf) by name.

    :arg name:
        this must be the name of a recognized prf.
        currently this only recognizes names with the format
        :samp:`hmac-{digest}`, where :samp:`{digest}`
        is the name of a hash function such as
        ``md5``, ``sha256``, etc.

        this can also be a callable with the signature
        ``prf(secret, message) -> digest``,
        in which case it will be returned unchanged.

    :raises ValueError: if the name is not known
    :raises TypeError: if the name is not a callable or string

    :returns:
        a tuple of :samp:`({func}, {digest_size})`.

        * :samp:`{func}` is a function implementing
          the specified prf, and has the signature
          ``func(secret, message) -> digest``.

        * :samp:`{digest_size}` is an integer indicating
          the number of bytes the function returns.

    usage example::

        >>> from passlib.utils.pbkdf2 import get_prf
        >>> hmac_sha256, dsize = get_prf("hmac-sha256")
        >>> hmac_sha256
        <function hmac_sha256 at 0x1e37c80>
        >>> dsize
        32
        >>> digest = hmac_sha256('password', 'message')

    this function will attempt to return the fastest implementation
    it can find; if M2Crypto is present, and supports the specified prf,
    :func:`M2Crypto.EVP.hmac` will be used behind the scenes.
    """
    global _prf_cache
    if name in _prf_cache:
        return _prf_cache[name]
    if isinstance(name, native_str):
        if name.startswith("hmac-") or name.startswith("hmac_"):
            retval = _get_hmac_prf(name[5:])
        else:
            raise ValueError("unknown prf algorithm: %r" % (name,))
    elif callable(name):
        #assume it's a callable, use it directly
        digest_size = len(name(b('x'),b('y')))
        retval = (name, digest_size)
    else:
        raise TypeError("prf must be string or callable")
    _prf_cache[name] = retval
    return retval
예제 #10
0
def get_prf(name):
    """lookup pseudo-random family (prf) by name.

    :arg name:
        this must be the name of a recognized prf.
        currently this only recognizes names with the format
        :samp:`hmac-{digest}`, where :samp:`{digest}`
        is the name of a hash function such as
        ``md5``, ``sha256``, etc.

        this can also be a callable with the signature
        ``prf(secret, message) -> digest``,
        in which case it will be returned unchanged.

    :raises ValueError: if the name is not known
    :raises TypeError: if the name is not a callable or string

    :returns:
        a tuple of :samp:`({func}, {digest_size})`.

        * :samp:`{func}` is a function implementing
          the specified prf, and has the signature
          ``func(secret, message) -> digest``.

        * :samp:`{digest_size}` is an integer indicating
          the number of bytes the function returns.

    usage example::

        >>> from passlib.utils.pbkdf2 import get_prf
        >>> hmac_sha256, dsize = get_prf("hmac-sha256")
        >>> hmac_sha256
        <function hmac_sha256 at 0x1e37c80>
        >>> dsize
        32
        >>> digest = hmac_sha256('password', 'message')

    this function will attempt to return the fastest implementation
    it can find; if M2Crypto is present, and supports the specified prf,
    :func:`M2Crypto.EVP.hmac` will be used behind the scenes.
    """
    global _prf_cache
    if name in _prf_cache:
        return _prf_cache[name]
    if isinstance(name, native_str):
        if name.startswith("hmac-") or name.startswith("hmac_"):
            retval = _get_hmac_prf(name[5:])
        else:
            raise ValueError("unknown prf algorithm: %r" % (name, ))
    elif callable(name):
        #assume it's a callable, use it directly
        digest_size = len(name(b('x'), b('y')))
        retval = (name, digest_size)
    else:
        raise TypeError("prf must be string or callable")
    _prf_cache[name] = retval
    return retval
예제 #11
0
 def test_24_verify_none(self):
     "test verify() throws error against hash=None/empty string"
     #find valid hash so that doesn't mask error
     self.assertRaises(ValueError, self.do_verify, 'stub', None, __msg__="hash=None:")
     if self.accepts_empty_hash:
         self.do_verify("stub", u"")
         self.do_verify("stub", b(""))
     else:
         self.assertRaises(ValueError, self.do_verify, 'stub', u'', __msg__="hash='':")
         self.assertRaises(ValueError, self.do_verify, 'stub', b(''), __msg__="hash='':")
예제 #12
0
    def test_md4_copy(self):
        "test md4 copy()"
        md4 = self.hash
        h = md4(b('abc'))

        h2 = h.copy()
        h2.update(b('def'))
        self.assertEqual(h2.hexdigest(), '804e7f1c2586e50b49ac65db5b645131')

        h.update(b('ghi'))
        self.assertEqual(h.hexdigest(), 'c5225580bfe176f6deeee33dee98732c')
예제 #13
0
    def test_md4_copy(self):
        "test md4 copy()"
        md4 = self.hash
        h = md4(b('abc'))

        h2 = h.copy()
        h2.update(b('def'))
        self.assertEqual(h2.hexdigest(), '804e7f1c2586e50b49ac65db5b645131')

        h.update(b('ghi'))
        self.assertEqual(h.hexdigest(), 'c5225580bfe176f6deeee33dee98732c')
예제 #14
0
    def test_decode_int(self):
        self.assertEqual(h64.decode_int64(b('...........')), 0)

        self.assertRaises(ValueError, h64.decode_int12, b('a?'))
        self.assertRaises(ValueError, h64.decode_int24, b('aaa?'))
        self.assertRaises(ValueError, h64.decode_int64, b('aaa?aaa?aaa'))
        self.assertRaises(ValueError, h64.decode_dc_int64, b('aaa?aaa?aaa'))

        self.assertRaises(TypeError, h64.decode_int12, u'a'*2)
        self.assertRaises(TypeError, h64.decode_int24, u'a'*4)
        self.assertRaises(TypeError, h64.decode_int64, u'a'*11)
        self.assertRaises(TypeError, h64.decode_dc_int64, u'a'*11)
예제 #15
0
    def test_decode_int(self):
        self.assertEqual(h64.decode_int64(b('...........')), 0)

        self.assertRaises(ValueError, h64.decode_int12, b('a?'))
        self.assertRaises(ValueError, h64.decode_int24, b('aaa?'))
        self.assertRaises(ValueError, h64.decode_int64, b('aaa?aaa?aaa'))
        self.assertRaises(ValueError, h64.decode_dc_int64, b('aaa?aaa?aaa'))

        self.assertRaises(TypeError, h64.decode_int12, u'a' * 2)
        self.assertRaises(TypeError, h64.decode_int24, u'a' * 4)
        self.assertRaises(TypeError, h64.decode_int64, u'a' * 11)
        self.assertRaises(TypeError, h64.decode_dc_int64, u'a' * 11)
예제 #16
0
    def test_bytes(self):
        "test b() helper, bytes and native_str types"
        # Py2k #
        self.assertIs(bytes, type(''))
        self.assertIs(native_str, bytes)
        # Py3k #
        #self.assertIs(bytes, type(b''))
        #self.assertIs(native_str, unicode)
        # end Py3k #

        self.assertIsInstance(b(''), bytes)
        self.assertIsInstance(b('\x00\xff'), bytes)
        # Py2k #
        self.assertEqual(b('\x00\xff'), "\x00\xff")
예제 #17
0
    def test_bytes(self):
        "test b() helper, bytes and native_str types"
        # Py2k #
        self.assertIs(bytes, type(''))
        self.assertIs(native_str, bytes)
        # Py3k #
        #self.assertIs(bytes, type(b''))
        #self.assertIs(native_str, unicode)
        # end Py3k #

        self.assertIsInstance(b(''), bytes)
        self.assertIsInstance(b('\x00\xff'), bytes)
        # Py2k #
        self.assertEqual(b('\x00\xff'), "\x00\xff")
예제 #18
0
    def test_rfc6070(self):
        "rfc6070 test vectors"
        self.assertFunctionResults(
            pbkdf2.pbkdf2,
            [
                (
                    hb("0c60c80f961f0e71f3a9b524af6012062fe037a6"),
                    b("password"),
                    b("salt"),
                    1,
                    20,
                ),
                (
                    hb("ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"),
                    b("password"),
                    b("salt"),
                    2,
                    20,
                ),
                (
                    hb("4b007901b765489abead49d926f721d065a429c1"),
                    b("password"),
                    b("salt"),
                    4096,
                    20,
                ),

                #just runs too long - could enable if ALL option is set
                ##(
                ##
                ##    unhexlify("eefe3d61cd4da4e4e9945b3d6ba2158c2634e984"),
                ##    "password", "salt", 16777216, 20,
                ##),
                (
                    hb("3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"),
                    b("passwordPASSWORDpassword"),
                    b("saltSALTsaltSALTsaltSALTsaltSALTsalt"),
                    4096,
                    25,
                ),
                (
                    hb("56fa6aa75548099dcc37d7f03425e0c3"),
                    b("pass\00word"),
                    b("sa\00lt"),
                    4096,
                    16,
                ),
            ])
예제 #19
0
def raw_ext_crypt(secret, rounds, salt):
    "ext_crypt() helper which returns checksum only"

    #decode salt
    try:
        salt_value = h64.decode_int24(salt)
    except ValueError: #pragma: no cover - always caught by class
        raise ValueError("invalid salt")

    #validate secret
    if b('\x00') in secret: #pragma: no cover - always caught by class
        #builtin linux crypt doesn't like this, so we don't either
        #XXX: would make more sense to raise ValueError, but want to be compatible w/ stdlib crypt
        raise ValueError("secret must be string without null bytes")

    #convert secret string into an integer
    key_value = _crypt_secret_to_key(secret)
    idx = 8
    end = len(secret)
    while idx < end:
        next = idx+8
        key_value = mdes_encrypt_int_block(key_value, key_value) ^ \
                                        _crypt_secret_to_key(secret[idx:next])
        idx = next

    #run data through des using input of 0
    result = mdes_encrypt_int_block(key_value, 0, salt_value, rounds)

    #run h64 encode on result
    return h64.encode_dc_int64(result)
예제 #20
0
 def identify(cls, hash):
     if not hash:
         return False
     if isinstance(hash, bytes):
         return hash == b("!")
     else:
         return hash == u"!"
예제 #21
0
 def identify(cls, hash):
     if not hash:
         return False
     if isinstance(hash, bytes):
         return hash == b("!")
     else:
         return hash == u"!"
 def genhash(cls, secret, hash):
     if not cls.identify(hash):
         raise ValueError("not a unsalted-example hash")
     if isinstance(secret, unicode):
         secret = secret.encode("utf-8")
     data = b("boblious") + secret
     return to_hash_str(hashlib.sha1(data).hexdigest())
예제 #23
0
    def test_09_encodings(self):
        "test encoding parameter"
        #test bad encodings cause failure in constructor
        self.assertRaises(ValueError, apache.HtdigestFile, encoding="utf-16")

        #check users() returns native string by default
        ht = apache.HtdigestFile._from_string(self.sample_01)
        self.assertIsInstance(ht.realms()[0], native_str)
        self.assertIsInstance(ht.users("realm")[0], native_str)

        #check returns unicode if encoding explicitly set
        ht = apache.HtdigestFile._from_string(self.sample_01, encoding="utf-8")
        self.assertIsInstance(ht.realms()[0], unicode)
        self.assertIsInstance(ht.users(u"realm")[0], unicode)

        #check returns bytes if encoding explicitly disabled
        ht = apache.HtdigestFile._from_string(self.sample_01, encoding=None)
        self.assertIsInstance(ht.realms()[0], bytes)
        self.assertIsInstance(ht.users(b("realm"))[0], bytes)

        #check sample utf-8
        ht = apache.HtdigestFile._from_string(self.sample_04_utf8,
                                              encoding="utf-8")
        self.assertEqual(ht.realms(), [u"realm\u00e6"])
        self.assertEqual(ht.users(u"realm\u00e6"), [u"user\u00e6"])

        #check sample latin-1
        ht = apache.HtdigestFile._from_string(self.sample_04_latin1,
                                              encoding="latin-1")
        self.assertEqual(ht.realms(), [u"realm\u00e6"])
        self.assertEqual(ht.users(u"realm\u00e6"), [u"user\u00e6"])
예제 #24
0
 def genhash(cls, secret, hash):
     if not cls.identify(hash):
         raise ValueError("not a unsalted-example hash")
     if isinstance(secret, unicode):
         secret = secret.encode("utf-8")
     data = b("boblious") + secret
     return to_hash_str(hashlib.sha1(data).hexdigest())
예제 #25
0
    def test_des_encrypt_block(self):
        for k,p,c in self.test_des_vectors:
            k = unhexlify(k)
            p = unhexlify(p)
            c = unhexlify(c)
            result = des.des_encrypt_block(k,p)
            self.assertEqual(result, c, "key=%r p=%r:" % (k,p))

        #test 7 byte key
        #FIXME: use a better key
        k,p,c = b('00000000000000'), b('FFFFFFFFFFFFFFFF'), b('355550B2150E2451')
        k = unhexlify(k)
        p = unhexlify(p)
        c = unhexlify(c)
        result = des.des_encrypt_block(k,p)
        self.assertEqual(result, c, "key=%r p=%r:" % (k,p))
예제 #26
0
    def test_09_encodings(self):
        "test encoding parameter"
        #test bad encodings cause failure in constructor
        self.assertRaises(ValueError, apache.HtdigestFile, encoding="utf-16")

        #check users() returns native string by default
        ht = apache.HtdigestFile._from_string(self.sample_01)
        self.assertIsInstance(ht.realms()[0], native_str)
        self.assertIsInstance(ht.users("realm")[0], native_str)

        #check returns unicode if encoding explicitly set
        ht = apache.HtdigestFile._from_string(self.sample_01, encoding="utf-8")
        self.assertIsInstance(ht.realms()[0], unicode)
        self.assertIsInstance(ht.users(u"realm")[0], unicode)

        #check returns bytes if encoding explicitly disabled
        ht = apache.HtdigestFile._from_string(self.sample_01, encoding=None)
        self.assertIsInstance(ht.realms()[0], bytes)
        self.assertIsInstance(ht.users(b("realm"))[0], bytes)

        #check sample utf-8
        ht = apache.HtdigestFile._from_string(self.sample_04_utf8, encoding="utf-8")
        self.assertEqual(ht.realms(), [ u"realm\u00e6" ])
        self.assertEqual(ht.users(u"realm\u00e6"), [ u"user\u00e6" ])

        #check sample latin-1
        ht = apache.HtdigestFile._from_string(self.sample_04_latin1, encoding="latin-1")
        self.assertEqual(ht.realms(), [ u"realm\u00e6" ])
        self.assertEqual(ht.users(u"realm\u00e6"), [ u"user\u00e6" ])
예제 #27
0
 def to_string(self):
     chk = self.checksum
     if not chk: #fill in stub checksum
         chk = b('\x00') * self._info[1]
     salt = self.salt
     data = b64encode(salt+chk).decode("ascii")
     hash = u"{FSHP%d|%d|%d}%s" % (self.variant, len(salt), self.rounds, data)
     return to_hash_str(hash)
예제 #28
0
 def create_mismatch(self, secret):
     "return other secret which won't match"
     #NOTE: this is subclassable mainly for some algorithms
     #which accept non-strings in secret
     if isinstance(secret, unicode):
         return u'x' + secret
     else:
         return b('x') + secret
예제 #29
0
    def test_md4_update(self):
        "test md4 update"
        md4 = self.hash        
        h = md4(b(''))
        self.assertEqual(h.hexdigest(), "31d6cfe0d16ae931b73c59d7e0c089c0")

        #NOTE: under py2, hashlib methods try to encode to ascii,
        #      though shouldn't rely on that.
        # Py3k #
        #self.assertRaises(TypeError, h.update, u'x')
        # end Py3k #

        h.update(b('a'))
        self.assertEqual(h.hexdigest(), "bde52cb31de33e46245e05fbdbd6fb24")

        h.update(b('bcdefghijklmnopqrstuvwxyz'))
        self.assertEqual(h.hexdigest(), "d79e1c308aa5bbcdeea8ed63df412da9")
예제 #30
0
 def _calc_checksum_builtin(self, secret):
     #gotta do something - no official policy since des-crypt predates unicode
     if isinstance(secret, unicode):
         secret = secret.encode("utf-8")
     #forbidding nul chars because linux crypt (and most C implementations) won't accept it either.
     if b('\x00') in secret:
         raise ValueError("null char in secret")
     return raw_crypt(secret, self.salt.encode("ascii")).decode("ascii")
예제 #31
0
    def test_md4_update(self):
        "test md4 update"
        md4 = self.hash
        h = md4(b(''))
        self.assertEqual(h.hexdigest(), "31d6cfe0d16ae931b73c59d7e0c089c0")

        #NOTE: under py2, hashlib methods try to encode to ascii,
        #      though shouldn't rely on that.
        # Py3k #
        #self.assertRaises(TypeError, h.update, u'x')
        # end Py3k #

        h.update(b('a'))
        self.assertEqual(h.hexdigest(), "bde52cb31de33e46245e05fbdbd6fb24")

        h.update(b('bcdefghijklmnopqrstuvwxyz'))
        self.assertEqual(h.hexdigest(), "d79e1c308aa5bbcdeea8ed63df412da9")
예제 #32
0
    def test_des_encrypt_block(self):
        for k, p, c in self.test_des_vectors:
            k = unhexlify(k)
            p = unhexlify(p)
            c = unhexlify(c)
            result = des.des_encrypt_block(k, p)
            self.assertEqual(result, c, "key=%r p=%r:" % (k, p))

        #test 7 byte key
        #FIXME: use a better key
        k, p, c = b('00000000000000'), b('FFFFFFFFFFFFFFFF'), b(
            '355550B2150E2451')
        k = unhexlify(k)
        p = unhexlify(p)
        c = unhexlify(c)
        result = des.des_encrypt_block(k, p)
        self.assertEqual(result, c, "key=%r p=%r:" % (k, p))
예제 #33
0
    def test_decode_bytes(self):
        for result, source in self.encoded_bytes:
            out = h64.decode_bytes(source)
            self.assertEqual(out, result)

        #wrong size (1 % 4)
        self.assertRaises(ValueError, h64.decode_bytes, b('abcde'))

        self.assertRaises(TypeError, h64.decode_bytes, u'abcd')
예제 #34
0
 def test_pbkdf1(self):
     "test pbkdf1"
     for secret, salt, rounds, klen, hash, correct in [
         #http://www.di-mgt.com.au/cryptoKDFs.html
         (b('password'), hb('78578E5A5D63CB06'), 1000, 16, 'sha1',
             hb('dc19847e05c64d2faf10ebfb4a3d2a20')),
     ]:
         result = pbkdf2.pbkdf1(secret, salt, rounds, klen, hash)
         self.assertEqual(result, correct)
예제 #35
0
 def test_pbkdf1(self):
     "test pbkdf1"
     for secret, salt, rounds, klen, hash, correct in [
             #http://www.di-mgt.com.au/cryptoKDFs.html
         (b('password'), hb('78578E5A5D63CB06'), 1000, 16, 'sha1',
          hb('dc19847e05c64d2faf10ebfb4a3d2a20')),
     ]:
         result = pbkdf2.pbkdf1(secret, salt, rounds, klen, hash)
         self.assertEqual(result, correct)
예제 #36
0
    def test_decode_bytes(self):
        for result, source in self.encoded_bytes:
            out = h64.decode_bytes(source)
            self.assertEqual(out, result)

        #wrong size (1 % 4)
        self.assertRaises(ValueError, h64.decode_bytes, b('abcde'))

        self.assertRaises(TypeError, h64.decode_bytes, u'abcd')
예제 #37
0
    def test_10_to_string(self):
        "test to_string()"

        #check sample
        ht = apache.HtdigestFile._from_string(self.sample_01)
        self.assertEqual(ht.to_string(), self.sample_01)

        #check blank
        ht = apache.HtdigestFile()
        self.assertEqual(ht.to_string(), b(""))
예제 #38
0
    def test_08_to_string(self):
        "test to_string"

        #check with known sample
        ht = apache.HtpasswdFile._from_string(self.sample_01)
        self.assertEqual(ht.to_string(), self.sample_01)

        #test blank
        ht = apache.HtpasswdFile()
        self.assertEqual(ht.to_string(), b(""))
예제 #39
0
    def test_07_realms(self):
        "test realms() & delete_realm()"
        ht = apache.HtdigestFile._from_string(self.sample_01)

        self.assertEqual(ht.delete_realm("x"), 0)
        self.assertEqual(ht.realms(), ['realm'])

        self.assertEqual(ht.delete_realm("realm"), 4)
        self.assertEqual(ht.realms(), [])
        self.assertEqual(ht.to_string(), b(""))
예제 #40
0
    def test_10_to_string(self):
        "test to_string()"

        #check sample
        ht = apache.HtdigestFile._from_string(self.sample_01)
        self.assertEqual(ht.to_string(), self.sample_01)

        #check blank
        ht = apache.HtdigestFile()
        self.assertEqual(ht.to_string(), b(""))
예제 #41
0
    def test_08_to_string(self):
        "test to_string"

        #check with known sample
        ht = apache.HtpasswdFile._from_string(self.sample_01)
        self.assertEqual(ht.to_string(), self.sample_01)

        #test blank
        ht = apache.HtpasswdFile()
        self.assertEqual(ht.to_string(), b(""))
예제 #42
0
    def test_07_realms(self):
        "test realms() & delete_realm()"
        ht = apache.HtdigestFile._from_string(self.sample_01)

        self.assertEqual(ht.delete_realm("x"), 0)
        self.assertEqual(ht.realms(), ['realm'])

        self.assertEqual(ht.delete_realm("realm"), 4)
        self.assertEqual(ht.realms(), [])
        self.assertEqual(ht.to_string(), b(""))
예제 #43
0
    def test_to_unicode(self):
        "test to_unicode()"

        #check unicode inputs
        self.assertEqual(to_unicode(u'abc'), u'abc')
        self.assertEqual(to_unicode(u'\x00\xff'), u'\x00\xff')

        #check unicode input ignores encoding
        self.assertEqual(to_unicode(u'\x00\xff', None), u'\x00\xff')
        self.assertEqual(to_unicode(u'\x00\xff', "ascii"), u'\x00\xff')

        #check bytes input
        self.assertEqual(to_unicode(b('abc')), u'abc')
        self.assertEqual(to_unicode(b('\x00\xc3\xbf')), u'\x00\xff')
        self.assertEqual(to_unicode(b('\x00\xff'), 'latin-1'), u'\x00\xff')
        self.assertRaises(ValueError, to_unicode, b('\x00\xff'))
        self.assertRaises(TypeError, to_unicode, b('\x00\xff'), None)

        #check other
        self.assertRaises(TypeError, to_unicode, None)
    def test_00_static_handler(self):
        "test StaticHandler helper class"

        class d1(uh.StaticHandler):
            name = "d1"
            context_kwds = ("flag",)

            @classmethod
            def genhash(cls, secret, hash, flag=False):
                if isinstance(hash, bytes):
                    hash = hash.decode("ascii")
                if hash not in (u"a", u"b"):
                    raise ValueError
                return to_hash_str(u"b" if flag else u"a")

        # check default identify method
        self.assertTrue(d1.identify(u"a"))
        self.assertTrue(d1.identify(b("a")))
        self.assertTrue(d1.identify(u"b"))
        self.assertFalse(d1.identify(u"c"))
        self.assertFalse(d1.identify(b("c")))
        self.assertFalse(d1.identify(u""))
        self.assertFalse(d1.identify(None))

        # check default genconfig method
        self.assertIs(d1.genconfig(), None)
        d1._stub_config = u"b"
        self.assertEqual(d1.genconfig(), to_hash_str("b"))

        # check default verify method
        self.assertTrue(d1.verify("s", "a"))
        self.assertTrue(d1.verify("s", u"a"))
        self.assertFalse(d1.verify("s", "b"))
        self.assertFalse(d1.verify("s", u"b"))
        self.assertTrue(d1.verify("s", "b", flag=True))
        self.assertRaises(ValueError, d1.verify, "s", "c")

        # check default encrypt method
        self.assertEqual(d1.encrypt("s"), to_hash_str("a"))
        self.assertEqual(d1.encrypt("s"), to_hash_str("a"))
        self.assertEqual(d1.encrypt("s", flag=True), to_hash_str("b"))
예제 #45
0
    def test_00_static_handler(self):
        "test StaticHandler helper class"

        class d1(uh.StaticHandler):
            name = "d1"
            context_kwds = ("flag",)

            @classmethod
            def genhash(cls, secret, hash, flag=False):
                if isinstance(hash, bytes):
                    hash = hash.decode("ascii")
                if hash not in (u'a',u'b'):
                    raise ValueError
                return to_hash_str(u'b' if flag else u'a')

        #check default identify method
        self.assertTrue(d1.identify(u'a'))
        self.assertTrue(d1.identify(b('a')))
        self.assertTrue(d1.identify(u'b'))
        self.assertFalse(d1.identify(u'c'))
        self.assertFalse(d1.identify(b('c')))
        self.assertFalse(d1.identify(u''))
        self.assertFalse(d1.identify(None))

        #check default genconfig method
        self.assertIs(d1.genconfig(), None)
        d1._stub_config = u'b'
        self.assertEqual(d1.genconfig(), to_hash_str('b'))

        #check default verify method
        self.assertTrue(d1.verify('s','a'))
        self.assertTrue(d1.verify('s',u'a'))
        self.assertFalse(d1.verify('s','b'))
        self.assertFalse(d1.verify('s',u'b'))
        self.assertTrue(d1.verify('s', 'b', flag=True))
        self.assertRaises(ValueError, d1.verify, 's', 'c')

        #check default encrypt method
        self.assertEqual(d1.encrypt('s'), to_hash_str('a'))
        self.assertEqual(d1.encrypt('s'), to_hash_str('a'))
        self.assertEqual(d1.encrypt('s', flag=True), to_hash_str('b'))
예제 #46
0
    def test_to_unicode(self):
        "test to_unicode()"

        #check unicode inputs
        self.assertEqual(to_unicode(u'abc'),                u'abc')
        self.assertEqual(to_unicode(u'\x00\xff'),           u'\x00\xff')

        #check unicode input ignores encoding
        self.assertEqual(to_unicode(u'\x00\xff', None),     u'\x00\xff')
        self.assertEqual(to_unicode(u'\x00\xff', "ascii"),  u'\x00\xff')

        #check bytes input
        self.assertEqual(to_unicode(b('abc')),              u'abc')
        self.assertEqual(to_unicode(b('\x00\xc3\xbf')),     u'\x00\xff')
        self.assertEqual(to_unicode(b('\x00\xff'), 'latin-1'),
                                                            u'\x00\xff')
        self.assertRaises(ValueError, to_unicode, b('\x00\xff'))
        self.assertRaises(TypeError, to_unicode, b('\x00\xff'), None)

        #check other
        self.assertRaises(TypeError, to_unicode, None)
예제 #47
0
def raw_lmhash(secret, encoding="ascii", hex=False):
    "encode password using des-based LMHASH algorithm; returns string of raw bytes, or unicode hex"
    # NOTE: various references say LMHASH uses the OEM codepage of the host
    #      for it's encoding. until a clear reference is found,
    #      as well as a path for getting the encoding,
    #      letting this default to "ascii" to prevent incorrect hashes
    #      from being made w/o user explicitly choosing an encoding.
    if isinstance(secret, unicode):
        secret = secret.encode(encoding)
    ns = secret.upper()[:14] + b("\x00") * (14 - len(secret))
    out = des_encrypt_block(ns[:7], LM_MAGIC) + des_encrypt_block(ns[7:], LM_MAGIC)
    return hexlify(out).decode("ascii") if hex else out
예제 #48
0
    def test_sha512_string(self):
        "test alternate digest string (sha512)"
        self.assertFunctionResults(pbkdf2.pbkdf2, [
            # result, secret, salt, rounds, keylen, digest="sha1"

            #case taken from example in http://grub.enbug.org/Authentication
            (
               hb("887CFF169EA8335235D8004242AA7D6187A41E3187DF0CE14E256D85ED97A97357AAA8FF0A3871AB9EEFF458392F462F495487387F685B7472FC6C29E293F0A0"),
               b("hello"),
               hb("9290F727ED06C38BA4549EF7DE25CF5642659211B7FC076F2D28FEFD71784BB8D8F6FB244A8CC5C06240631B97008565A120764C0EE9C2CB0073994D79080136"),
               10000, 64, "hmac-sha512"
            ),
        ])
예제 #49
0
    def test_sha512_string(self):
        "test alternate digest string (sha512)"
        self.assertFunctionResults(
            pbkdf2.pbkdf2,
            [
                # result, secret, salt, rounds, keylen, digest="sha1"

                #case taken from example in http://grub.enbug.org/Authentication
                (hb("887CFF169EA8335235D8004242AA7D6187A41E3187DF0CE14E256D85ED97A97357AAA8FF0A3871AB9EEFF458392F462F495487387F685B7472FC6C29E293F0A0"
                    ), b("hello"),
                 hb("9290F727ED06C38BA4549EF7DE25CF5642659211B7FC076F2D28FEFD71784BB8D8F6FB244A8CC5C06240631B97008565A120764C0EE9C2CB0073994D79080136"
                    ), 10000, 64, "hmac-sha512"),
            ])
예제 #50
0
def des_cbc_encrypt(key, value, iv=b('\x00') * 8, pad=b('\x00')):
    """performs des-cbc encryption, returns only last block.

    this performs a specific DES-CBC encryption implementation
    as needed by the Oracle10 hash. it probably won't be useful for
    other purposes as-is.

    input value is null-padded to multiple of 8 bytes.

    :arg key: des key as bytes
    :arg value: value to encrypt, as bytes.
    :param iv: optional IV
    :param pad: optional pad byte

    :returns: last block of DES-CBC encryption of all ``value``'s byte blocks.
    """
    value += pad * (-len(value) % 8) #null pad to multiple of 8
    hash = iv #start things off
    for offset in xrange(0,len(value),8):
        chunk = xor_bytes(hash, value[offset:offset+8])
        hash = des_encrypt_block(key, chunk)
    return hash
예제 #51
0
    def _calc_checksum_os_crypt(self, secret):
        #os_crypt() would raise less useful error
        null = u'\x00' if isinstance(secret, unicode) else b('\x00')
        if null in secret:
            raise ValueError("null char in secret")

        #NOTE: safe_os_crypt encodes unicode secret -> utf8
        #no official policy since des-crypt predates unicode
        ok, hash = safe_os_crypt(secret, self.salt)
        if ok:
            return hash[2:]
        else:
            return self._calc_checksum_builtin(secret)
예제 #52
0
def raw_lmhash(secret, encoding="ascii", hex=False):
    "encode password using des-based LMHASH algorithm; returns string of raw bytes, or unicode hex"
    #NOTE: various references say LMHASH uses the OEM codepage of the host
    #      for it's encoding. until a clear reference is found,
    #      as well as a path for getting the encoding,
    #      letting this default to "ascii" to prevent incorrect hashes
    #      from being made w/o user explicitly choosing an encoding.
    if isinstance(secret, unicode):
        secret = secret.encode(encoding)
    ns = secret.upper()[:14] + b("\x00") * (14 - len(secret))
    out = des_encrypt_block(ns[:7], LM_MAGIC) + des_encrypt_block(
        ns[7:], LM_MAGIC)
    return hexlify(out).decode("ascii") if hex else out
예제 #53
0
    def test_rfc6070(self):
        "rfc6070 test vectors"
        self.assertFunctionResults(pbkdf2.pbkdf2, [

            (
                hb("0c60c80f961f0e71f3a9b524af6012062fe037a6"),
                b("password"), b("salt"), 1, 20,
            ),

            (
                hb("ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"),
                b("password"), b("salt"), 2, 20,
            ),

            (
                hb("4b007901b765489abead49d926f721d065a429c1"),
                b("password"), b("salt"), 4096, 20,
            ),

            #just runs too long - could enable if ALL option is set
            ##(
            ##
            ##    unhexlify("eefe3d61cd4da4e4e9945b3d6ba2158c2634e984"),
            ##    "password", "salt", 16777216, 20,
            ##),

            (
                hb("3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"),
                b("passwordPASSWORDpassword"),
                b("saltSALTsaltSALTsaltSALTsaltSALTsalt"),
                4096, 25,
            ),

            (
                hb("56fa6aa75548099dcc37d7f03425e0c3"),
                b("pass\00word"), b("sa\00lt"), 4096, 16,
            ),
        ])
예제 #54
0
    def digest(self):
        #NOTE: backing up state so we can restore it after _process is called,
        #in case object is updated again (this is only attr altered by this method)
        orig = list(self._state)

        #final block: buf + 0x80,
        # then 0x00 padding until congruent w/ 56 mod 64 bytes
        # then last 8 bytes = msg length in bits
        buf = self._buf
        msglen = self._count * 512 + len(buf) * 8
        block = buf + b('\x80') + b('\x00') * ((119-len(buf)) % 64) + \
            struct.pack("<2I", msglen & MASK_32, (msglen>>32) & MASK_32)
        if len(block) == 128:
            self._process(block[:64])
            self._process(block[64:])
        else:
            assert len(block) == 64
            self._process(block)

        #render digest & restore un-finalized state
        out = struct.pack("<4I", *self._state)
        self._state = orig
        return out