diff options
author | Christian Kandeler <[email protected]> | 2015-06-23 12:53:30 +0200 |
---|---|---|
committer | Christian Kandeler <[email protected]> | 2015-06-24 10:34:31 +0000 |
commit | f8a8c6cac3f7e1955025e72dde451e00c10a1077 (patch) | |
tree | 23e4271cd7ab80a81bc1762f93a5df58b02d3381 /src/libs/ssh/sshkeyexchange.cpp | |
parent | 3c1b1496d43d41e6a628b14abe0172f34a866151 (diff) |
SSH: Do not tie key exchange methods to specific host key algorithms.
Contrary to what I believed, all key exchange methods are compatible
with all types of host key (at least for everything we support).
Task-number: QTCREATORBUG-14621
Change-Id: Iacae3d36170b9841cceb3705780a64aeb15e10b9
Reviewed-by: Benjamin Zeller <[email protected]>
Reviewed-by: Christian Kandeler <[email protected]>
Diffstat (limited to 'src/libs/ssh/sshkeyexchange.cpp')
-rw-r--r-- | src/libs/ssh/sshkeyexchange.cpp | 44 |
1 files changed, 13 insertions, 31 deletions
diff --git a/src/libs/ssh/sshkeyexchange.cpp b/src/libs/ssh/sshkeyexchange.cpp index c553ecc8b22..62071e4fc70 100644 --- a/src/libs/ssh/sshkeyexchange.cpp +++ b/src/libs/ssh/sshkeyexchange.cpp @@ -30,6 +30,7 @@ #include "sshkeyexchange_p.h" +#include "ssh_global.h" #include "sshbotanconversions_p.h" #include "sshcapabilities_p.h" #include "sshsendfacility_p.h" @@ -115,28 +116,8 @@ bool SshKeyExchange::sendDhInitPacket(const SshIncomingPacket &serverKexInit) m_kexAlgoName = SshCapabilities::findBestMatch(SshCapabilities::KeyExchangeMethods, kexInitParams.keyAlgorithms.names); - const QList<QByteArray> &commonHostKeyAlgos - = SshCapabilities::commonCapabilities(SshCapabilities::PublicKeyAlgorithms, - kexInitParams.serverHostKeyAlgorithms.names); - const bool ecdh = m_kexAlgoName.startsWith(SshCapabilities::EcdhKexNamePrefix); - foreach (const QByteArray &possibleHostKeyAlgo, commonHostKeyAlgos) { - if (ecdh && possibleHostKeyAlgo == SshCapabilities::PubKeyEcdsa) { - m_serverHostKeyAlgo = possibleHostKeyAlgo; - break; - } - if (!ecdh && (possibleHostKeyAlgo == SshCapabilities::PubKeyDss - || possibleHostKeyAlgo == SshCapabilities::PubKeyRsa)) { - m_serverHostKeyAlgo = possibleHostKeyAlgo; - break; - } - } - if (m_serverHostKeyAlgo.isEmpty()) { - throw SshServerException(SSH_DISCONNECT_KEY_EXCHANGE_FAILED, - "Invalid combination of key exchange and host key algorithms.", - QCoreApplication::translate("SshConnection", - "No matching host key algorithm available for key exchange algorithm \"%1\".") - .arg(QString::fromLatin1(m_kexAlgoName))); - } + m_serverHostKeyAlgo = SshCapabilities::findBestMatch(SshCapabilities::PublicKeyAlgorithms, + kexInitParams.serverHostKeyAlgorithms.names); determineHashingAlgorithm(kexInitParams, true); determineHashingAlgorithm(kexInitParams, false); @@ -152,7 +133,7 @@ bool SshKeyExchange::sendDhInitPacket(const SshIncomingPacket &serverKexInit) kexInitParams.compressionAlgorithmsServerToClient.names); AutoSeeded_RNG rng; - if (ecdh) { + if (m_kexAlgoName.startsWith(SshCapabilities::EcdhKexNamePrefix)) { m_ecdhKey.reset(new ECDH_PrivateKey(rng, EC_Group(botanKeyExchangeAlgoName(m_kexAlgoName)))); m_sendFacility.sendKeyEcdhInitPacket(convertByteArray(m_ecdhKey->public_value())); } else { @@ -169,7 +150,7 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, { const SshKeyExchangeReply &reply - = dhReply.extractKeyExchangeReply(m_serverHostKeyAlgo); + = dhReply.extractKeyExchangeReply(m_kexAlgoName, m_serverHostKeyAlgo); if (m_dhKey && (reply.f <= 0 || reply.f >= m_dhKey->group_p())) { throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_KEY_EXCHANGE_FAILED, "Server sent invalid f."); @@ -187,6 +168,7 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, DH_KA_Operation dhOp(*m_dhKey); SecureVector<byte> encodedF = BigInt::encode(reply.f); encodedK = dhOp.agree(encodedF, encodedF.size()); + m_dhKey.reset(nullptr); } else { Q_ASSERT(m_ecdhKey); concatenatedData // Q_C. @@ -194,7 +176,9 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, concatenatedData += AbstractSshPacket::encodeString(reply.q_s); ECDH_KA_Operation ecdhOp(*m_ecdhKey); encodedK = ecdhOp.agree(convertByteArray(reply.q_s), reply.q_s.count()); + m_ecdhKey.reset(nullptr); } + const BigInt k = BigInt::decode(encodedK); m_k = AbstractSshPacket::encodeMpInt(k); // Roundtrip, as Botan encodes BigInts somewhat differently. concatenatedData += m_k; @@ -228,13 +212,13 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, RSA_PublicKey * const rsaKey = new RSA_PublicKey(reply.parameters.at(1), reply.parameters.at(0)); sigKey.reset(rsaKey); - } else if (m_serverHostKeyAlgo == SshCapabilities::PubKeyEcdsa) { + } else { + QSSH_ASSERT_AND_RETURN(m_serverHostKeyAlgo == SshCapabilities::PubKeyEcdsa); + const EC_Group domain("secp256r1"); const PointGFp point = OS2ECP(convertByteArray(reply.q), reply.q.count(), - m_ecdhKey->domain().get_curve()); - ECDSA_PublicKey * const ecdsaKey = new ECDSA_PublicKey(m_ecdhKey->domain(), point); + domain.get_curve()); + ECDSA_PublicKey * const ecdsaKey = new ECDSA_PublicKey(domain, point); sigKey.reset(ecdsaKey); - } else { - Q_ASSERT(!"Impossible: Neither DSS nor RSA nor ECDSA!"); } const byte * const botanH = convertByteArray(m_h); @@ -248,8 +232,6 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, checkHostKey(reply.k_s); m_sendFacility.sendNewKeysPacket(); - m_dhKey.reset(nullptr); - m_ecdhKey.reset(nullptr); } QByteArray SshKeyExchange::hashAlgoForKexAlgo() const |