diff --git a/src/libs/3rdparty/botan/botan.cpp b/src/libs/3rdparty/botan/botan.cpp index 000c3ea823cc032ad08bbcecbb7f566d320b31eb..4431ce17fbd2420b5a72f90c997cb70f91c87b36 100644 --- a/src/libs/3rdparty/botan/botan.cpp +++ b/src/libs/3rdparty/botan/botan.cpp @@ -47182,3 +47182,44 @@ u32bit version_minor() { return BOTAN_VERSION_MINOR; } u32bit version_patch() { return BOTAN_VERSION_PATCH; } } + +namespace Botan { +PublicKeyPtr createRsaPublicKey(const BigInt &e, const BigInt &n) +{ + return PublicKeyPtr(new RSA_PublicKey(e, n)); +} + +PublicKeyPtr createDsaPublicKey(const DL_Group &group, const BigInt &y) +{ + return PublicKeyPtr(new DSA_PublicKey(group, y)); +} + +PrivateKeyPtr createRsaPrivateKey(RandomNumberGenerator &rng, const BigInt &p, const BigInt &q, + const BigInt &e, const BigInt &d, const BigInt &n) +{ + return PrivateKeyPtr(new RSA_PrivateKey(rng, p, q, e, d, n)); +} + +PrivateKeyPtr createRsaPrivateKey(RandomNumberGenerator &rng, size_t bits, size_t exp) +{ + return PrivateKeyPtr(new RSA_PrivateKey(rng, bits, exp)); +} + +PrivateKeyPtr createDsaPrivateKey(RandomNumberGenerator &rng, const DL_Group &group, + const BigInt &private_key) +{ + return PrivateKeyPtr(new DSA_PrivateKey(rng, group, private_key)); +} + +PrivateKeyPtr loadPkcs8PrivateKey(DataSource& source, RandomNumberGenerator& rng, + const User_Interface& ui) +{ + return PrivateKeyPtr(PKCS8::load_key(source, rng, ui)); +} + +DhPrivateKeyPtr createDhPrivateKey(RandomNumberGenerator &rng, const DL_Group &grp, const BigInt &x) +{ + return DhPrivateKeyPtr(new DH_PrivateKey(rng, grp, x)); +} + +} diff --git a/src/libs/3rdparty/botan/botan.h b/src/libs/3rdparty/botan/botan.h index a073890986c4d626b2f0f7b582a7582d5a88e347..13ec9fd00b603d7ebcca4b39e25d2513917dfd8d 100644 --- a/src/libs/3rdparty/botan/botan.h +++ b/src/libs/3rdparty/botan/botan.h @@ -9,6 +9,7 @@ #define BOTAN_AMALGAMATION_H__ #include <QtGlobal> +#include <QSharedPointer> #include <iosfwd> #include <map> @@ -16181,7 +16182,26 @@ class BOTAN_DLL ANSI_X919_MAC : public MessageAuthenticationCode SecureVector<byte> state; size_t position; }; +} + +namespace Botan { +typedef QSharedPointer<Public_Key> PublicKeyPtr; +BOTAN_DLL PublicKeyPtr createRsaPublicKey(const BigInt &e, const BigInt &n); +BOTAN_DLL PublicKeyPtr createDsaPublicKey(const DL_Group& group, const BigInt& y); + +typedef QSharedPointer<Private_Key> PrivateKeyPtr; +BOTAN_DLL PrivateKeyPtr createRsaPrivateKey(RandomNumberGenerator& rng, const BigInt& p, + const BigInt& q, const BigInt& e, const BigInt& d = 0, const BigInt& n = 0); +BOTAN_DLL PrivateKeyPtr createRsaPrivateKey(RandomNumberGenerator& rng, size_t bits, + size_t exp = 65537); +BOTAN_DLL PrivateKeyPtr createDsaPrivateKey(RandomNumberGenerator& rng, const DL_Group& group, + const BigInt& private_key = 0); +BOTAN_DLL PrivateKeyPtr loadPkcs8PrivateKey(DataSource& source, RandomNumberGenerator& rng, + const User_Interface& ui); +typedef QSharedPointer<DH_PrivateKey> DhPrivateKeyPtr; +BOTAN_DLL DhPrivateKeyPtr createDhPrivateKey(RandomNumberGenerator& rng, const DL_Group& grp, + const BigInt& x = 0); } diff --git a/src/libs/ssh/sshcryptofacility.cpp b/src/libs/ssh/sshcryptofacility.cpp index 3e1b6970154ccfd47eed235896a7f40b5928c3ff..868a64b4b94a1acae4dbc64b02f725f0cdc5ee21 100644 --- a/src/libs/ssh/sshcryptofacility.cpp +++ b/src/libs/ssh/sshcryptofacility.cpp @@ -218,16 +218,14 @@ bool SshEncryptionFacility::createAuthenticationKeyFromPKCS8(const QByteArray &p try { Pipe pipe; pipe.process_msg(convertByteArray(privKeyFileContents), privKeyFileContents.size()); - Private_Key * const key = PKCS8::load_key(pipe, m_rng, SshKeyPasswordRetriever()); - if (DSA_PrivateKey * const dsaKey = dynamic_cast<DSA_PrivateKey *>(key)) { + const PrivateKeyPtr authKey = loadPkcs8PrivateKey(pipe, m_rng, SshKeyPasswordRetriever()); + if (DSA_PrivateKey * const dsaKey = dynamic_cast<DSA_PrivateKey *>(authKey.data())) { m_authKeyAlgoName = SshCapabilities::PubKeyDss; - m_authKey.reset(dsaKey); pubKeyParams << dsaKey->group_p() << dsaKey->group_q() << dsaKey->group_g() << dsaKey->get_y(); allKeyParams << pubKeyParams << dsaKey->get_x(); - } else if (RSA_PrivateKey * const rsaKey = dynamic_cast<RSA_PrivateKey *>(key)) { + } else if (RSA_PrivateKey * const rsaKey = dynamic_cast<RSA_PrivateKey *>(authKey.data())) { m_authKeyAlgoName = SshCapabilities::PubKeyRsa; - m_authKey.reset(rsaKey); pubKeyParams << rsaKey->get_e() << rsaKey->get_n(); allKeyParams << pubKeyParams << rsaKey->get_p() << rsaKey->get_q() << rsaKey->get_d(); @@ -235,6 +233,7 @@ bool SshEncryptionFacility::createAuthenticationKeyFromPKCS8(const QByteArray &p qWarning("%s: Unexpected code flow, expected success or exception.", Q_FUNC_INFO); return false; } + m_authKey = authKey; } catch (const Botan::Exception &ex) { error = QLatin1String(ex.what()); return false; @@ -291,15 +290,13 @@ bool SshEncryptionFacility::createAuthenticationKeyFromOpenSSL(const QByteArray if (m_authKeyAlgoName == SshCapabilities::PubKeyDss) { BigInt p, q, g, y, x; sequence.decode (p).decode (q).decode (g).decode (y).decode (x); - DSA_PrivateKey * const dsaKey = new DSA_PrivateKey(m_rng, DL_Group(p, q, g), x); - m_authKey.reset(dsaKey); + m_authKey = createDsaPrivateKey(m_rng, DL_Group(p, q, g), x); pubKeyParams << p << q << g << y; allKeyParams << pubKeyParams << x; } else { BigInt p, q, e, d, n; sequence.decode(n).decode(e).decode(d).decode(p).decode(q); - RSA_PrivateKey * const rsaKey = new RSA_PrivateKey(m_rng, p, q, e, d, n); - m_authKey.reset(rsaKey); + m_authKey = createRsaPrivateKey(m_rng, p, q, e, d, n); pubKeyParams << e << n; allKeyParams << pubKeyParams << p << q << d; } diff --git a/src/libs/ssh/sshcryptofacility_p.h b/src/libs/ssh/sshcryptofacility_p.h index 5b22429fe4ba138396388f752d5446a0cf89fd87..afd85fbcd03a019305fbb7fcd1182f1902387024 100644 --- a/src/libs/ssh/sshcryptofacility_p.h +++ b/src/libs/ssh/sshcryptofacility_p.h @@ -117,7 +117,7 @@ private: QByteArray m_authKeyAlgoName; QByteArray m_authPubKeyBlob; QByteArray m_cachedPrivKeyContents; - QScopedPointer<Botan::Private_Key> m_authKey; + QSharedPointer<Botan::Private_Key> m_authKey; mutable Botan::AutoSeeded_RNG m_rng; }; diff --git a/src/libs/ssh/sshkeyexchange.cpp b/src/libs/ssh/sshkeyexchange.cpp index c11201c47c3eace0fc525613b61e086057f22354..0c0fea6215888ba4bce8017e0574a12f1e681977 100644 --- a/src/libs/ssh/sshkeyexchange.cpp +++ b/src/libs/ssh/sshkeyexchange.cpp @@ -136,8 +136,7 @@ bool SshKeyExchange::sendDhInitPacket(const SshIncomingPacket &serverKexInit) kexInitParams.compressionAlgorithmsServerToClient.names); AutoSeeded_RNG rng; - m_dhKey.reset(new DH_PrivateKey(rng, - DL_Group(botanKeyExchangeAlgoName(keyAlgo)))); + m_dhKey = createDhPrivateKey(rng, DL_Group(botanKeyExchangeAlgoName(keyAlgo))); m_serverKexInitPayload = serverKexInit.payLoad(); m_sendFacility.sendKeyDhInitPacket(m_dhKey->get_y()); @@ -184,28 +183,24 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply, printData("H", m_h); #endif // CREATOR_SSH_DEBUG - QScopedPointer<Public_Key> sigKey; - QScopedPointer<PK_Verifier> verifier; + QSharedPointer<Public_Key> publicKey; + QByteArray algorithm; 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))); + publicKey = createDsaPublicKey(group, reply.parameters.at(3)); + algorithm = 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))); + publicKey = createRsaPublicKey(reply.parameters.at(1), reply.parameters.at(0)); + algorithm = 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, - reply.signatureBlob.size())) { + if (!PK_Verifier(*publicKey, botanEmsaAlgoName(algorithm)).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."); } diff --git a/src/libs/ssh/sshkeyexchange_p.h b/src/libs/ssh/sshkeyexchange_p.h index ea3e599a9ee58f4f475e538a2dd738383bdc267c..e8d27b662b2c1840027be0eac82b89330d754312 100644 --- a/src/libs/ssh/sshkeyexchange_p.h +++ b/src/libs/ssh/sshkeyexchange_p.h @@ -33,6 +33,7 @@ #include <QByteArray> #include <QScopedPointer> +#include <QSharedPointer> namespace Botan { class DH_PrivateKey; @@ -71,7 +72,7 @@ private: QByteArray m_serverId; QByteArray m_clientKexInitPayload; QByteArray m_serverKexInitPayload; - QScopedPointer<Botan::DH_PrivateKey> m_dhKey; + QSharedPointer<Botan::DH_PrivateKey> m_dhKey; QByteArray m_k; QByteArray m_h; QByteArray m_serverHostKeyAlgo; diff --git a/src/libs/ssh/sshkeygenerator.cpp b/src/libs/ssh/sshkeygenerator.cpp index ef28c05eebd1b873cd213a8a0204204f8b13c183..5aefdd9b3405616f4e51ca64740b419cbd07b071 100644 --- a/src/libs/ssh/sshkeygenerator.cpp +++ b/src/libs/ssh/sshkeygenerator.cpp @@ -60,9 +60,9 @@ bool SshKeyGenerator::generateKeys(KeyType type, PrivateKeyFormat format, int ke AutoSeeded_RNG rng; KeyPtr key; if (m_type == Rsa) - key = KeyPtr(new RSA_PrivateKey(rng, keySize)); + key = createRsaPrivateKey(rng, keySize); else - key = KeyPtr(new DSA_PrivateKey(rng, DL_Group(rng, DL_Group::DSA_Kosherizer, keySize))); + key = createDsaPrivateKey(rng, DL_Group(rng, DL_Group::DSA_Kosherizer, keySize)); switch (format) { case Pkcs8: generatePkcs8KeyStrings(key, rng);