예제 #1
0
    def test_ecdh(self):
        # pylint: disable=too-many-locals
        a_rng = botan2.RandomNumberGenerator('user')
        b_rng = botan2.RandomNumberGenerator('user')

        kdf = 'KDF2(SHA-384)'

        for grp in ['secp256r1', 'secp384r1', 'brainpool256r1']:
            a_priv = botan2.PrivateKey.create('ECDH', grp, a_rng)
            b_priv = botan2.PrivateKey.create('ECDH', grp, b_rng)

            a_op = botan2.PKKeyAgreement(a_priv, kdf)
            b_op = botan2.PKKeyAgreement(b_priv, kdf)

            a_pub = a_op.public_value()
            b_pub = b_op.public_value()

            salt = a_rng.get(8) + b_rng.get(8)

            a_key = a_op.agree(b_pub, 32, salt)
            b_key = b_op.agree(a_pub, 32, salt)

            self.assertEqual(a_key, b_key)

            a_pem = a_priv.to_pem()

            a_priv_x = a_priv.get_field('x')

            new_a = botan2.PrivateKey.load_ecdh(grp, a_priv_x)

            self.assertEqual(a_pem, new_a.to_pem())
예제 #2
0
    def test_rsa(self):
        # pylint: disable=too-many-locals
        rng = botan2.RandomNumberGenerator()
        rsapriv = botan2.PrivateKey.create('RSA', '1024', rng)
        self.assertEqual(rsapriv.algo_name(), 'RSA')

        priv_pem = rsapriv.to_pem()
        priv_der = rsapriv.to_der()

        self.assertEqual(priv_pem[0:28], "-----BEGIN PRIVATE KEY-----\n")
        self.assertGreater(len(priv_pem), len(priv_der))

        rsapub = rsapriv.get_public_key()
        self.assertEqual(rsapub.algo_name(), 'RSA')
        self.assertEqual(rsapub.estimated_strength(), 80)

        pub_pem = rsapub.to_pem()
        pub_der = rsapub.to_der()

        self.assertEqual(pub_pem[0:27], "-----BEGIN PUBLIC KEY-----\n")
        self.assertGreater(len(pub_pem), len(pub_der))

        enc = botan2.PKEncrypt(rsapub, "OAEP(SHA-256)")
        dec = botan2.PKDecrypt(rsapriv, "OAEP(SHA-256)")

        symkey = rng.get(32)
        ctext = enc.encrypt(symkey, rng)

        ptext = dec.decrypt(ctext)

        self.assertEqual(ptext, symkey)

        signer = botan2.PKSign(rsapriv, 'EMSA4(SHA-384)')

        signer.update('messa')
        signer.update('ge')
        sig = signer.finish(botan2.RandomNumberGenerator())

        verify = botan2.PKVerify(rsapub, 'EMSA4(SHA-384)')

        verify.update('mess')
        verify.update('age')
        self.assertTrue(verify.check_signature(sig))

        verify.update('mess of things')
        verify.update('age')
        self.assertFalse(verify.check_signature(sig))

        verify.update('message')
        self.assertTrue(verify.check_signature(sig))
예제 #3
0
    def test_key_crypto(self):
        rng = botan2.RandomNumberGenerator()
        priv = botan2.PrivateKey.create('RSA', '1024', rng)
        passphrase = "super secret tell noone"

        for is_pem in [True, False]:
            ref_val = priv.export(is_pem)

            enc1 = priv.export_encrypted(passphrase, rng, True, msec=10)
            dec1 = botan2.PrivateKey.load(enc1, passphrase)
            self.assertEqual(dec1.export(is_pem), ref_val)

            pem2 = priv.export_encrypted(passphrase,
                                         rng,
                                         True,
                                         msec=10,
                                         cipher="AES-128/SIV")
            dec2 = botan2.PrivateKey.load(pem2, passphrase)
            self.assertEqual(dec2.export(is_pem), ref_val)

            pem3 = priv.export_encrypted(passphrase,
                                         rng,
                                         True,
                                         msec=10,
                                         cipher="AES-128/GCM",
                                         pbkdf="Scrypt")
            dec3 = botan2.PrivateKey.load(pem3, passphrase)
            self.assertEqual(dec3.export(is_pem), ref_val)
예제 #4
0
    def test_sm2(self):
        rng = botan2.RandomNumberGenerator()

        hash_fn = 'EMSA1(SM3)'
        group = 'sm2p256v1'
        msg = 'test message'

        priv = botan2.PrivateKey.create('SM2', group, rng)
        pub = priv.get_public_key()
        self.assertEqual(pub.get_field('public_x'), priv.get_field('public_x'))
        self.assertEqual(pub.get_field('public_y'), priv.get_field('public_y'))

        signer = botan2.PKSign(priv, hash_fn)
        signer.update(msg)
        signature = signer.finish(rng)

        verifier = botan2.PKVerify(pub, hash_fn)
        verifier.update(msg)
        self.assertTrue(verifier.check_signature(signature))

        pub_x = pub.get_field('public_x')
        pub_y = priv.get_field('public_y')
        pub2 = botan2.PublicKey.load_sm2(group, pub_x, pub_y)
        verifier = botan2.PKVerify(pub2, hash_fn)
        verifier.update(msg)
        self.assertTrue(verifier.check_signature(signature))

        priv2 = botan2.PrivateKey.load_sm2(group, priv.get_field('x'))
        signer = botan2.PKSign(priv2, hash_fn)
        # sign empty message
        signature = signer.finish(rng)

        # verify empty message
        self.assertTrue(verifier.check_signature(signature))
예제 #5
0
    def test_cipher(self):
        for mode in ['AES-128/CTR-BE', 'Serpent/GCM', 'ChaCha20Poly1305']:
            enc = botan2.SymmetricCipher(mode, encrypt=True)

            if mode == 'AES-128/CTR-BE':
                self.assertEqual(enc.algo_name(), 'CTR-BE(AES-128)')
            elif mode == 'Serpent/GCM':
                self.assertEqual(enc.algo_name(), 'Serpent/GCM(16)')
            else:
                self.assertEqual(enc.algo_name(), mode)

            (kmin, kmax) = enc.key_length()

            self.assertLessEqual(kmin, kmax)

            rng = botan2.RandomNumberGenerator()
            iv = rng.get(enc.default_nonce_length())
            key = rng.get(kmax)
            pt = rng.get(21)

            enc.set_key(key)
            enc.start(iv)

            update_result = enc.update('')
            assert not update_result

            ct = enc.finish(pt)

            dec = botan2.SymmetricCipher(mode, encrypt=False)
            dec.set_key(key)
            dec.start(iv)
            decrypted = dec.finish(ct)

            self.assertEqual(decrypted, pt)
예제 #6
0
def encrypt(key, ptxt):
    iv = botan.RandomNumberGenerator().get(16)
    cipher = botan.SymmetricCipher('AES-256/GCM')
    cipher.set_key(key)
    cipher.start(iv)
    ctxt = cipher.finish(ptxt.encode('utf-8'))
    cipher.clear()
    return (iv, ctxt)
예제 #7
0
    def test_rng(self):
        user_rng = botan2.RandomNumberGenerator("user")

        output1 = user_rng.get(32)
        output2 = user_rng.get(32)

        self.assertEqual(len(output1), 32)
        self.assertEqual(len(output2), 32)
        self.assertNotEqual(output1, output2)

        output3 = user_rng.get(1021)
        self.assertEqual(len(output3), 1021)

        system_rng = botan2.RandomNumberGenerator('system')

        user_rng.reseed_from_rng(system_rng, 256)

        user_rng.add_entropy('seed material...')
예제 #8
0
    def test_bcrypt(self):
        r = botan2.RandomNumberGenerator()
        phash = botan2.bcrypt('testing', r)
        self.assertTrue(isinstance(phash, str))
        self.assertTrue(phash.startswith("$2a$"))

        self.assertTrue(botan2.check_bcrypt('testing', phash))
        self.assertFalse(botan2.check_bcrypt('live fire', phash))

        self.assertTrue(botan2.check_bcrypt('test', '$2a$04$wjen1fAA.UW6UxthpKK.huyOoxvCR7ATRCVC4CBIEGVDOCtr8Oj1C'))
예제 #9
0
    def test_dh(self):
        a_rng = botan2.RandomNumberGenerator('user')
        b_rng = botan2.RandomNumberGenerator('user')

        for dh_grp in ['secp256r1', 'curve25519']:
            dh_kdf = 'KDF2(SHA-384)'.encode('utf-8')
            a_dh_priv = botan2.PrivateKey.create('ecdh', dh_grp, a_rng)
            b_dh_priv = botan2.PrivateKey.create('ecdh', dh_grp, b_rng)

            a_dh = botan2.PKKeyAgreement(a_dh_priv, dh_kdf)
            b_dh = botan2.PKKeyAgreement(b_dh_priv, dh_kdf)

            a_dh_pub = a_dh.public_value()
            b_dh_pub = b_dh.public_value()

            salt = a_rng.get(8) + b_rng.get(8)

            a_key = a_dh.agree(b_dh_pub, 32, salt)
            b_key = b_dh.agree(a_dh_pub, 32, salt)

            self.assertEqual(a_key, b_key)
예제 #10
0
    def test_srp6(self):
        identity = 'alice'
        password = '******'
        rng = botan2.RandomNumberGenerator()

        # Test successful authentication
        server = botan2.Srp6ServerSession()
        salt = rng.get(24)
        verifier = botan2.generate_srp6_verifier(identity, password, salt,
                                                 'modp/srp/1024', 'SHA-512')
        b = server.step1(verifier, 'modp/srp/1024', 'SHA-512', rng)
        (a, key_c) = botan2.srp6_client_agree(identity, password,
                                              'modp/srp/1024', 'SHA-512', salt,
                                              b, rng)
        key_s = server.step2(a)
        self.assertEqual(key_c, key_s)

        # Test wrong server ephemeral
        try:
            salt = rng.get(24)
            b = b'BD0C6151 2C692C0C B6D041FA 01BB152D 4916A1E7 7AF46AE1 05393011 \
            BAF38964 DC46A067 0DD125B9 5A981652 236F99D9 B681CBF8 7837EC99 \
            6C6DA044 53728610 D0C6DDB5 8B318885 D7D82C7F 8DEB75CE 7BD4FBAA \
            37089E6F 9C6059F3 88838E7A 00030B33 1EB76840 910440B1 B27AAEAE \
            EB4012B7 D7665238 A8E3FB00 4B117B58'

            botan2.srp6_client_agree(identity, password, 'modp/srp/1024',
                                     'SHA-512', salt, b, rng)
        except botan2.BotanException as e:
            self.assertEqual(
                str(e),
                "botan_srp6_client_agree failed: -1 (Invalid input): Invalid SRP parameter from server"
            )

        # Test wrong client ephemeral
        try:
            salt = rng.get(24)
            verifier = botan2.generate_srp6_verifier(identity, password, salt,
                                                     'modp/srp/1024',
                                                     'SHA-512')
            server.step1(verifier, 'modp/srp/1024', 'SHA-512', rng)
            a = b'61D5E490 F6F1B795 47B0704C 436F523D D0E560F0 C64115BB 72557EC4 \
            4352E890 3211C046 92272D8B 2D1A5358 A2CF1B6E 0BFCF99F 921530EC \
            8E393561 79EAE45E 42BA92AE ACED8251 71E1E8B9 AF6D9C03 E1327F44 \
            BE087EF0 6530E69F 66615261 EEF54073 CA11CF58 58F0EDFD FE15EFEA \
            B349EF5D 76988A36 72FAC47B 0769447B'

            server.step2(a)
        except botan2.BotanException as e:
            self.assertEqual(
                str(e),
                "botan_srp6_server_session_step2 failed: -32 (Bad parameter)")
예제 #11
0
    def test_check_key(self):
        # valid (if rather small) RSA key
        n = 273279220906618527352827457840955116141
        e = 0x10001

        rng = botan2.RandomNumberGenerator()

        rsapub = botan2.PublicKey.load_rsa(n, e)
        self.assertTrue(rsapub.check_key(rng))

        # invalid
        rsapub = botan2.PublicKey.load_rsa(n - 1, e)
        self.assertFalse(rsapub.check_key(rng))
예제 #12
0
    def test_mpi_random(self):
        rng = botan2.RandomNumberGenerator()

        u = botan2.MPI.random(rng, 512)
        self.assertEqual(u.bit_count(), 512)

        l = u >> 32
        self.assertEqual(l.bit_count(), 512 - 32)

        for _i in range(10):
            x = botan2.MPI.random_range(rng, l, u)
            self.assertLess(x, u)
            self.assertGreater(x, l)
예제 #13
0
    def test_check_key(self):
        # valid (if rather small) RSA key
        n = 273279220906618527352827457840955116141
        e = 0x10001

        rng = botan2.RandomNumberGenerator()

        rsapub = botan2.PublicKey.load_rsa(n, e)
        self.assertTrue(rsapub.check_key(rng))

        # invalid
        try:
            rsapub = botan2.PublicKey.load_rsa(n - 1, e)
        except botan2.BotanException as e:
            self.assertEqual(str(e), "botan_pubkey_load_rsa failed: -1 (Invalid input)")
예제 #14
0
    def test_mceliece(self):
        rng = botan2.RandomNumberGenerator()
        mce_priv = botan2.PrivateKey.create('McEliece', '2960,57', rng)
        mce_pub = mce_priv.get_public_key()
        self.assertEqual(mce_pub.estimated_strength(), 128)

        mce_plaintext = rng.get(16)
        mce_ad = rng.get(48)
        mce_ciphertext = botan2.mceies_encrypt(mce_pub, rng,
                                               'ChaCha20Poly1305',
                                               mce_plaintext, mce_ad)

        mce_decrypt = botan2.mceies_decrypt(mce_priv, 'ChaCha20Poly1305',
                                            mce_ciphertext, mce_ad)

        self.assertEqual(mce_plaintext, mce_decrypt)
예제 #15
0
    def test_ecdsa(self):
        rng = botan2.RandomNumberGenerator()

        hash_fn = 'EMSA1(SHA-256)'
        group = 'secp256r1'
        msg = 'test message'

        priv = botan2.PrivateKey.create('ECDSA', group, rng)
        pub = priv.get_public_key()
        self.assertEqual(pub.get_field('public_x'), priv.get_field('public_x'))
        self.assertEqual(pub.get_field('public_y'), priv.get_field('public_y'))

        signer = botan2.PKSign(priv, hash_fn, True)
        signer.update(msg)
        signature = signer.finish(rng)

        verifier = botan2.PKVerify(pub, hash_fn)
        verifier.update(msg)
        #fails because DER/not-DER mismatch
        self.assertFalse(verifier.check_signature(signature))

        verifier = botan2.PKVerify(pub, hash_fn, True)
        verifier.update(msg)
        self.assertTrue(verifier.check_signature(signature))

        pub_x = pub.get_field('public_x')
        pub_y = priv.get_field('public_y')
        pub2 = botan2.PublicKey.load_ecdsa(group, pub_x, pub_y)
        verifier = botan2.PKVerify(pub2, hash_fn, True)
        verifier.update(msg)
        self.assertTrue(verifier.check_signature(signature))

        priv2 = botan2.PrivateKey.load_ecdsa(group, priv.get_field('x'))
        signer = botan2.PKSign(priv2, hash_fn, True)
        # sign empty message
        signature = signer.finish(rng)

        # verify empty message
        self.assertTrue(verifier.check_signature(signature))
예제 #16
0
    def test_mpi(self):
        # pylint: disable=too-many-statements
        z = botan2.MPI()
        self.assertEqual(z.bit_count(), 0)
        five = botan2.MPI('5')
        self.assertEqual(five.bit_count(), 3)
        big = botan2.MPI('0x85839682368923476892367235')
        self.assertEqual(big.bit_count(), 104)
        small = botan2.MPI(0xDEADBEEF)

        self.assertEqual(hex_encode(small.to_bytes()), "deadbeef")
        self.assertEqual(hex_encode(big.to_bytes()),
                         "85839682368923476892367235")

        self.assertEqual(int(small), 0xDEADBEEF)

        self.assertEqual(int(small >> 16), 0xDEAD)

        small >>= 15

        self.assertEqual(int(small), 0x1BD5B)

        small <<= 15

        self.assertEqual(int(small), 0xDEAD8000)

        ten = botan2.MPI(10)

        self.assertEqual(ten, five + five)
        self.assertNotEqual(ten, five)
        self.assertLess(five, ten)
        self.assertLessEqual(five, ten)

        x = botan2.MPI(five)

        self.assertEqual(x, five)

        x += botan2.MPI(1)
        self.assertNotEqual(x, five)

        self.assertEqual(int(x * five), 30)

        x *= five
        x *= five
        self.assertEqual(int(x), 150)

        self.assertTrue(not x.is_negative())

        x.flip_sign()
        self.assertTrue(x.is_negative())
        self.assertEqual(int(x), -150)

        x.flip_sign()

        x.set_bit(0)
        self.assertTrue(int(x), 151)
        self.assertTrue(x.get_bit(0))
        self.assertTrue(x.get_bit(4))
        self.assertFalse(x.get_bit(6))

        x.clear_bit(4)
        self.assertEqual(int(x), 135)

        rng = botan2.RandomNumberGenerator()
        self.assertFalse(x.is_prime(rng))

        two = botan2.MPI(2)

        x += two
        self.assertTrue(x.is_prime(rng))

        mod = x + two

        inv = x.inverse_mod(mod)
        self.assertEqual(int(inv), 69)
        self.assertEqual(int((inv * x) % mod), 1)

        p = inv.pow_mod(botan2.MPI(46), mod)
        self.assertEqual(int(p), 42)
예제 #17
0
def gen_key(bytes):
    return botan.RandomNumberGenerator().get(bytes)
예제 #18
0
def tag(pwd):
    return botan.bcrypt(pwd, botan.RandomNumberGenerator(), 11)
예제 #19
0
 def test_mceliece(self):
     rng = botan2.RandomNumberGenerator()
     mce_priv = botan2.PrivateKey.create('McEliece', '2960,57', rng)
     mce_pub = mce_priv.get_public_key()
     self.assertEqual(mce_pub.estimated_strength(), 128)