forked from qt-creator/qt-creator
		
	SSH: Minor refactorings in key exchange code.
Change-Id: I107a61831ca7824c30dcc83b3a13f5765dd2da52 Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com> Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
This commit is contained in:
		| @@ -89,14 +89,18 @@ const QList<QByteArray> SshCapabilities::CompressionAlgorithms | ||||
|  | ||||
| const QByteArray SshCapabilities::SshConnectionService("ssh-connection"); | ||||
|  | ||||
| QByteArray SshCapabilities::findBestMatch(const QList<QByteArray> &myCapabilities, | ||||
|     const QList<QByteArray> &serverCapabilities) | ||||
| QList<QByteArray> SshCapabilities::commonCapabilities(const QList<QByteArray> &myCapabilities, | ||||
|                                                const QList<QByteArray> &serverCapabilities) | ||||
| { | ||||
|     QList<QByteArray> capabilities; | ||||
|     foreach (const QByteArray &myCapability, myCapabilities) { | ||||
|         if (serverCapabilities.contains(myCapability)) | ||||
|             return myCapability; | ||||
|             capabilities << myCapability; | ||||
|     } | ||||
|  | ||||
|     if (!capabilities.isEmpty()) | ||||
|         return capabilities; | ||||
|  | ||||
|     throw SshServerException(SSH_DISCONNECT_KEY_EXCHANGE_FAILED, | ||||
|         "Server and client capabilities do not match.", | ||||
|         QCoreApplication::translate("SshConnection", | ||||
| @@ -104,6 +108,13 @@ QByteArray SshCapabilities::findBestMatch(const QList<QByteArray> &myCapabilitie | ||||
|             "Client list was: %1.\nServer list was %2.") | ||||
|             .arg(QString::fromLocal8Bit(listAsByteArray(myCapabilities).data())) | ||||
|             .arg(QString::fromLocal8Bit(listAsByteArray(serverCapabilities).data()))); | ||||
|  | ||||
| } | ||||
|  | ||||
| QByteArray SshCapabilities::findBestMatch(const QList<QByteArray> &myCapabilities, | ||||
|     const QList<QByteArray> &serverCapabilities) | ||||
| { | ||||
|     return commonCapabilities(myCapabilities, serverCapabilities).first(); | ||||
| } | ||||
|  | ||||
| } // namespace Internal | ||||
|   | ||||
| @@ -65,6 +65,8 @@ public: | ||||
|  | ||||
|     static const QByteArray SshConnectionService; | ||||
|  | ||||
|     static QList<QByteArray> commonCapabilities(const QList<QByteArray> &myCapabilities, | ||||
|                                                 const QList<QByteArray> &serverCapabilities); | ||||
|     static QByteArray findBestMatch(const QList<QByteArray> &myCapabilities, | ||||
|         const QList<QByteArray> &serverCapabilities); | ||||
| }; | ||||
|   | ||||
| @@ -162,8 +162,11 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, | ||||
|     concatenatedData += reply.k_s; | ||||
|     concatenatedData += AbstractSshPacket::encodeMpInt(m_dhKey->get_y()); | ||||
|     concatenatedData += AbstractSshPacket::encodeMpInt(reply.f); | ||||
|     const BigInt k = power_mod(reply.f, m_dhKey->get_x(), m_dhKey->get_domain().get_p()); | ||||
|     m_k = AbstractSshPacket::encodeMpInt(k); | ||||
|     DH_KA_Operation dhOp(*m_dhKey); | ||||
|     SecureVector<byte> encodedF = BigInt::encode(reply.f); | ||||
|     SecureVector<byte> encodedK = dhOp.agree(encodedF, encodedF.size()); | ||||
|     const BigInt k = BigInt::decode(encodedK); | ||||
|     m_k = AbstractSshPacket::encodeMpInt(k); // Roundtrip, as Botan encodes BigInts somewhat differently. | ||||
|     concatenatedData += m_k; | ||||
|  | ||||
|     m_hash.reset(get_hash(botanSha1Name())); | ||||
| @@ -186,26 +189,24 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, | ||||
| #endif // CREATOR_SSH_DEBUG | ||||
|  | ||||
|     QScopedPointer<Public_Key> sigKey; | ||||
|     QScopedPointer<PK_Verifier> verifier; | ||||
|     if (m_serverHostKeyAlgo == SshCapabilities::PubKeyDss) { | ||||
|         const DL_Group group(reply.parameters.at(0), reply.parameters.at(1), | ||||
|             reply.parameters.at(2)); | ||||
|         DSA_PublicKey * const dsaKey | ||||
|             = new DSA_PublicKey(group, reply.parameters.at(3)); | ||||
|         sigKey.reset(dsaKey); | ||||
|         verifier.reset(new PK_Verifier(*dsaKey, botanEmsaAlgoName(SshCapabilities::PubKeyDss))); | ||||
|     } else if (m_serverHostKeyAlgo == SshCapabilities::PubKeyRsa) { | ||||
|         RSA_PublicKey * const rsaKey | ||||
|             = new RSA_PublicKey(reply.parameters.at(1), reply.parameters.at(0)); | ||||
|         sigKey.reset(rsaKey); | ||||
|         verifier.reset(new PK_Verifier(*rsaKey, botanEmsaAlgoName(SshCapabilities::PubKeyRsa))); | ||||
|     } else { | ||||
|         Q_ASSERT(!"Impossible: Neither DSS nor RSA!"); | ||||
|     } | ||||
|     const byte * const botanH = convertByteArray(m_h); | ||||
|     const Botan::byte * const botanSig | ||||
|         = convertByteArray(reply.signatureBlob); | ||||
|     if (!verifier->verify_message(botanH, m_h.size(), botanSig, | ||||
|     PK_Verifier verifier(*sigKey, botanEmsaAlgoName(m_serverHostKeyAlgo)); | ||||
|     if (!verifier.verify_message(botanH, m_h.size(), botanSig, | ||||
|         reply.signatureBlob.size())) { | ||||
|         throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_KEY_EXCHANGE_FAILED, | ||||
|             "Invalid signature in SSH_MSG_KEXDH_REPLY packet."); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user