def test_ecdh(tmpdir): """ Test and ECDH key exchange :param tmpdir: :return: """ alicedir = os.path.join(tmpdir.strpath, "alice") os.makedirs(alicedir) identity.first_run(alicedir) alicepriv = identity.get_priv_keyfilename(alicedir) aliceprivkey = identity.load(alicepriv) bobdir = os.path.join(tmpdir.strpath, "bob") os.makedirs(bobdir) identity.first_run(bobdir) bobpriv = identity.get_priv_keyfilename(bobdir) bobprivkey = identity.load(bobpriv) alicepub = identity.loadpub(identity.get_pub_keyfilename(alicedir)) bobpub = identity.loadpub(identity.get_pub_keyfilename(bobdir)) shared_bob = identity.ecdh(bobprivkey, alicepub) shared_alice = identity.ecdh(aliceprivkey, bobpub) assert shared_alice == shared_bob
def server_handshake_begin(server_priv, message): """ Receive the handshake :param server_priv: server private key :param message: message data (decoded) :return: secret aes key, client's pubkey, handshake response to send """ assert server_priv.curve.openssl_name == message["keytype"] signature = message["signature"] client_pub = identity.loadpubstr(message["pub"]) # client long term key session_pub = identity.loadpubstr(message["session"]) # client session ecc key verify_msg = message["session"] + message["kdf"] + message["keytype"] assert identity.verify_string(client_pub, signature, verify_msg) is True shared = identity.ecdh(server_priv, session_pub) secret = derive_key(message["kdf"], shared) challenge_plain = str(uuid.uuid4()) challenge, iv = aes_encrypt_str(secret, challenge_plain) response = {"challenge": challenge, "iv": iv} return secret, client_pub, response, challenge_plain
def client_handshake_begin(ecdsa_priv, ecdh_priv, server_pub, curve=identity.DEFAULT_KEYTYPE, kdf=DEFAULT_KDF): """ Start the handshake :param ecdsa_priv: long term signing privkey :param ecdh_priv: temporary session ecc privkey :param server_pub: server long term pub key :param curve: EC Curve name :param kdf: Key derivation mechanism :return: secret aes key, handshake message to send """ session_pub_str = ecdh_priv.get_verifying_key().to_pem() # sign our session key signature = identity.sign_string(ecdsa_priv, session_pub_str + kdf + curve.openssl_name) message = { "pub": ecdsa_priv.get_verifying_key().to_pem(), "session": session_pub_str, "signature": signature, "keytype": curve.openssl_name, "kdf": kdf, } shared = identity.ecdh(ecdh_priv, server_pub) secret = derive_key(kdf, shared) return secret, message