aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/ssh
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/ssh')
-rw-r--r--src/libs/ssh/ssh.pro14
-rw-r--r--src/libs/ssh/ssh.qbs76
-rw-r--r--src/libs/ssh/sshbotanconversions_p.h16
-rw-r--r--src/libs/ssh/sshchannel.cpp2
-rw-r--r--src/libs/ssh/sshconnection.cpp14
-rw-r--r--src/libs/ssh/sshcryptofacility.cpp44
-rw-r--r--src/libs/ssh/sshcryptofacility_p.h8
-rw-r--r--src/libs/ssh/sshinit.cpp49
-rw-r--r--src/libs/ssh/sshinit_p.h32
-rw-r--r--src/libs/ssh/sshkeyexchange.cpp30
-rw-r--r--src/libs/ssh/sshkeyexchange_p.h6
-rw-r--r--src/libs/ssh/sshkeygenerator.cpp22
-rw-r--r--src/libs/ssh/sshkeypasswordretriever.cpp8
-rw-r--r--src/libs/ssh/sshkeypasswordretriever_p.h9
-rw-r--r--src/libs/ssh/sshpacketparser_p.h2
-rw-r--r--src/libs/ssh/sshremoteprocess.cpp2
16 files changed, 117 insertions, 217 deletions
diff --git a/src/libs/ssh/ssh.pro b/src/libs/ssh/ssh.pro
index 499540ac72e..40efcaf96b5 100644
--- a/src/libs/ssh/ssh.pro
+++ b/src/libs/ssh/ssh.pro
@@ -27,7 +27,6 @@ SOURCES = $$PWD/sshsendfacility.cpp \
$$PWD/sshkeypasswordretriever.cpp \
$$PWD/sftpfilesystemmodel.cpp \
$$PWD/sshkeycreationdialog.cpp \
- $$PWD/sshinit.cpp \
$$PWD/sshdirecttcpiptunnel.cpp \
$$PWD/sshlogging.cpp \
$$PWD/sshhostkeydatabase.cpp \
@@ -69,7 +68,6 @@ HEADERS = $$PWD/sshsendfacility_p.h \
$$PWD/sshkeycreationdialog.h \
$$PWD/ssh_global.h \
$$PWD/sshdirecttcpiptunnel_p.h \
- $$PWD/sshinit_p.h \
$$PWD/sshdirecttcpiptunnel.h \
$$PWD/sshlogging_p.h \
$$PWD/sshhostkeydatabase.h \
@@ -84,4 +82,14 @@ FORMS = $$PWD/sshkeycreationdialog.ui
RESOURCES += $$PWD/ssh.qrc
-include(../3rdparty/botan/botan.pri)
+include(../botan/botan.pri)
+use_system_botan {
+ CONFIG += link_pkgconfig
+ PKGCONFIG += botan-2
+} else {
+ BOTAN_BUILD_DIR = $$OUT_PWD/../botan/$$BOTAN_BUILD_DIR
+ INCLUDEPATH += $$BOTAN_BUILD_DIR/build/include
+ LIBS += $$BOTAN_BUILD_DIR/$$BOTAN_FULL_NAME
+ win32: LIBS += -ladvapi32 -luser32 -lws2_32
+}
+msvc:QMAKE_CXXFLAGS += /wd4250
diff --git a/src/libs/ssh/ssh.qbs b/src/libs/ssh/ssh.qbs
index 3aa95a16d53..b635b7037f0 100644
--- a/src/libs/ssh/ssh.qbs
+++ b/src/libs/ssh/ssh.qbs
@@ -7,12 +7,18 @@ Project {
QtcDevHeaders { }
QtcLibrary {
- cpp.defines: base.concat(["QTCSSH_LIBRARY"]).concat(botanDefines)
+ cpp.defines: base.concat("QTCSSH_LIBRARY")
cpp.includePaths: botanIncludes
cpp.dynamicLibraries: botanLibs
cpp.enableExceptions: true
+ Properties {
+ condition: qbs.toolchain.contains("msvc")
+ cpp.cxxFlags: base.concat("/wd4250");
+ }
+
Depends { name: "Qt"; submodules: ["widgets", "network" ] }
+ Depends { name: "Botan"; condition: !qtc.useSystemBotan }
files: [
"sftpchannel.h", "sftpchannel_p.h", "sftpchannel.cpp",
@@ -38,7 +44,6 @@ Project {
"sshhostkeydatabase.cpp",
"sshhostkeydatabase.h",
"sshincomingpacket_p.h", "sshincomingpacket.cpp",
- "sshinit_p.h", "sshinit.cpp",
"sshkeycreationdialog.cpp", "sshkeycreationdialog.h", "sshkeycreationdialog.ui",
"sshkeyexchange.cpp", "sshkeyexchange_p.h",
"sshkeygenerator.cpp", "sshkeygenerator.h",
@@ -54,21 +59,15 @@ Project {
"sshsendfacility.cpp", "sshsendfacility_p.h",
"sshtcpipforwardserver.cpp", "sshtcpipforwardserver.h", "sshtcpipforwardserver_p.h",
"sshtcpiptunnel.cpp", "sshtcpiptunnel_p.h",
- ].concat(botanFiles)
+ ]
- property var useSystemBotan: Environment.getEnv("USE_SYSTEM_BOTAN") === "1"
- property var botanIncludes: {
- var result = ["../3rdparty"];
- if (useSystemBotan)
- result.push("/usr/include/botan-1.10")
- return result
- }
+ property var botanIncludes: qtc.useSystemBotan ? ["/usr/include/botan-2"] : []
property var botanLibs: {
var result = [];
- if (useSystemBotan)
- result.push("botan-1.10")
+ if (qtc.useSystemBotan)
+ result.push("botan-2")
if (qbs.targetOS.contains("windows"))
- result.push("advapi32", "user32")
+ result.push("advapi32", "user32", "ws2_32")
else if (qbs.targetOS.contains("linux"))
result.push("rt", "dl");
else if (qbs.targetOS.contains("macos"))
@@ -77,57 +76,6 @@ Project {
result.push("rt");
return result
}
- property var botanDefines: {
- var result = [];
- if (useSystemBotan) {
- result.push("USE_SYSTEM_BOTAN")
- } else {
- result.push("BOTAN_DLL=")
- if (qbs.toolchain.contains("msvc"))
- result.push("BOTAN_BUILD_COMPILER_IS_MSVC",
- "BOTAN_TARGET_OS_HAS_GMTIME_S",
- "_SCL_SECURE_NO_WARNINGS")
- if (qbs.toolchain.contains("gcc") || qbs.toolchain.contains("mingw"))
- result.push("BOTAN_BUILD_COMPILER_IS_GCC")
- if (qbs.targetOS.contains("linux"))
- result.push("BOTAN_TARGET_OS_IS_LINUX", "BOTAN_TARGET_OS_HAS_CLOCK_GETTIME",
- "BOTAN_TARGET_OS_HAS_DLOPEN", " BOTAN_TARGET_OS_HAS_GMTIME_R",
- "BOTAN_TARGET_OS_HAS_POSIX_MLOCK", "BOTAN_HAS_DYNAMICALLY_LOADED_ENGINE",
- "BOTAN_HAS_DYNAMIC_LOADER", "BOTAN_TARGET_OS_HAS_GETTIMEOFDAY",
- "BOTAN_HAS_ALLOC_MMAP", "BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM",
- "BOTAN_HAS_ENTROPY_SRC_EGD", "BOTAN_HAS_ENTROPY_SRC_FTW",
- "BOTAN_HAS_ENTROPY_SRC_UNIX", "BOTAN_HAS_MUTEX_PTHREAD", "BOTAN_HAS_PIPE_UNIXFD_IO")
- if (qbs.targetOS.contains("macos"))
- result.push("BOTAN_TARGET_OS_IS_DARWIN", "BOTAN_TARGET_OS_HAS_GETTIMEOFDAY",
- "BOTAN_HAS_ALLOC_MMAP", "BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM",
- "BOTAN_HAS_ENTROPY_SRC_EGD", "BOTAN_HAS_ENTROPY_SRC_FTW",
- "BOTAN_HAS_ENTROPY_SRC_UNIX", "BOTAN_HAS_MUTEX_PTHREAD", "BOTAN_HAS_PIPE_UNIXFD_IO")
- if (qbs.targetOS.contains("windows"))
- result.push("BOTAN_TARGET_OS_IS_WINDOWS",
- "BOTAN_TARGET_OS_HAS_LOADLIBRARY", "BOTAN_TARGET_OS_HAS_WIN32_GET_SYSTEMTIME",
- "BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK", "BOTAN_HAS_DYNAMICALLY_LOADED_ENGINE",
- "BOTAN_HAS_DYNAMIC_LOADER", "BOTAN_HAS_ENTROPY_SRC_CAPI",
- "BOTAN_HAS_ENTROPY_SRC_WIN32", "BOTAN_HAS_MUTEX_WIN32")
- }
- return result
- }
- property var botanFiles: {
- var result = ["../3rdparty/botan/botan.h"];
- if (!useSystemBotan)
- result.push("../3rdparty/botan/botan.cpp")
- return result
- }
-
- // For Botan.
- Properties {
- condition: qbs.toolchain.contains("mingw")
- cpp.cxxFlags: base.concat([
- "-fpermissive",
- "-finline-functions",
- "-Wno-long-long"
- ])
- }
- cpp.cxxFlags: base
Export {
Depends { name: "Qt"; submodules: ["widgets", "network"] }
diff --git a/src/libs/ssh/sshbotanconversions_p.h b/src/libs/ssh/sshbotanconversions_p.h
index f54ca843a2c..335a02323c9 100644
--- a/src/libs/ssh/sshbotanconversions_p.h
+++ b/src/libs/ssh/sshbotanconversions_p.h
@@ -28,7 +28,8 @@
#include "sshcapabilities_p.h"
#include "sshexception_p.h"
-#include <botan/botan.h>
+#include <botan/secmem.h>
+#include <botan/types.h>
namespace QSsh {
namespace Internal {
@@ -45,7 +46,12 @@ inline Botan::byte *convertByteArray(QByteArray &a)
inline QByteArray convertByteArray(const Botan::SecureVector<Botan::byte> &v)
{
- return QByteArray(reinterpret_cast<const char *>(v.begin()), static_cast<int>(v.size()));
+ return QByteArray(reinterpret_cast<const char *>(&v.front()), static_cast<int>(v.size()));
+}
+
+inline QByteArray convertByteArray(const std::vector<std::uint8_t> &v)
+{
+ return QByteArray(reinterpret_cast<const char *>(&v.front()), static_cast<int>(v.size()));
}
inline const char *botanKeyExchangeAlgoName(const QByteArray &rfcAlgoName)
@@ -91,11 +97,11 @@ inline const char *botanEmsaAlgoName(const QByteArray &rfcAlgoName)
if (rfcAlgoName == SshCapabilities::PubKeyRsa)
return "EMSA3(SHA-1)";
if (rfcAlgoName == SshCapabilities::PubKeyEcdsa256)
- return "EMSA1_BSI(SHA-256)";
+ return "EMSA1(SHA-256)";
if (rfcAlgoName == SshCapabilities::PubKeyEcdsa384)
- return "EMSA1_BSI(SHA-384)";
+ return "EMSA1(SHA-384)";
if (rfcAlgoName == SshCapabilities::PubKeyEcdsa521)
- return "EMSA1_BSI(SHA-512)";
+ return "EMSA1(SHA-512)";
throw SshClientException(SshInternalError, SSH_TR("Unexpected host key algorithm \"%1\"")
.arg(QString::fromLatin1(rfcAlgoName)));
}
diff --git a/src/libs/ssh/sshchannel.cpp b/src/libs/ssh/sshchannel.cpp
index d48622b36f1..5a3d5e4d42f 100644
--- a/src/libs/ssh/sshchannel.cpp
+++ b/src/libs/ssh/sshchannel.cpp
@@ -29,8 +29,6 @@
#include "sshlogging_p.h"
#include "sshsendfacility_p.h"
-#include <botan/botan.h>
-
#include <QTimer>
namespace QSsh {
diff --git a/src/libs/ssh/sshconnection.cpp b/src/libs/ssh/sshconnection.cpp
index e1f98da06dc..7981a65cb94 100644
--- a/src/libs/ssh/sshconnection.cpp
+++ b/src/libs/ssh/sshconnection.cpp
@@ -34,13 +34,10 @@
#include "sshdirecttcpiptunnel.h"
#include "sshtcpipforwardserver.h"
#include "sshexception_p.h"
-#include "sshinit_p.h"
#include "sshkeyexchange_p.h"
#include "sshlogging_p.h"
#include "sshremoteprocess.h"
-#include <botan/botan.h>
-
#include <QFile>
#include <QMutex>
#include <QMutexLocker>
@@ -94,7 +91,6 @@ bool operator!=(const SshConnectionParameters &p1, const SshConnectionParameters
SshConnection::SshConnection(const SshConnectionParameters &serverInfo, QObject *parent)
: QObject(parent)
{
- Internal::initSsh();
qRegisterMetaType<QSsh::SshError>("QSsh::SshError");
qRegisterMetaType<QSsh::SftpJobId>("QSsh::SftpJobId");
qRegisterMetaType<QSsh::SftpFileInfo>("QSsh::SftpFileInfo");
@@ -947,10 +943,12 @@ void SshConnectionPrivate::closeConnection(SshErrorCode sshError,
disconnect(&m_timeoutTimer, 0, this, 0);
m_keepAliveTimer.stop();
disconnect(&m_keepAliveTimer, 0, this, 0);
- try {
- m_channelManager->closeAllChannels(SshChannelManager::CloseAllAndReset);
- m_sendFacility.sendDisconnectPacket(sshError, serverErrorString);
- } catch (...) {} // Nothing sensible to be done here.
+ if (m_state != SocketConnected) {
+ try {
+ m_channelManager->closeAllChannels(SshChannelManager::CloseAllAndReset);
+ m_sendFacility.sendDisconnectPacket(sshError, serverErrorString);
+ } catch (...) {} // Nothing sensible to be done here.
+ }
if (m_error != SshNoError)
emit error(userError);
if (m_state == ConnectionEstablished)
diff --git a/src/libs/ssh/sshcryptofacility.cpp b/src/libs/ssh/sshcryptofacility.cpp
index 7156fd801ad..83a2490caa7 100644
--- a/src/libs/ssh/sshcryptofacility.cpp
+++ b/src/libs/ssh/sshcryptofacility.cpp
@@ -33,7 +33,16 @@
#include "sshlogging_p.h"
#include "sshpacket_p.h"
-#include <botan/botan.h>
+#include <botan/ber_dec.h>
+#include <botan/ctr.h>
+#include <botan/dsa.h>
+#include <botan/ec_group.h>
+#include <botan/ecdsa.h>
+#include <botan/filters.h>
+#include <botan/pkcs8.h>
+#include <botan/point_gfp.h>
+#include <botan/pubkey.h>
+#include <botan/rsa.h>
#include <QDebug>
#include <QList>
@@ -77,11 +86,9 @@ void SshAbstractCryptoFacility::recreateKeys(const SshKeyExchange &kex)
if (m_sessionId.isEmpty())
m_sessionId = kex.h();
- Algorithm_Factory &af = global_state().algorithm_factory();
const QByteArray &rfcCryptAlgoName = cryptAlgoName(kex);
- BlockCipher * const cipher
- = af.prototype_block_cipher(botanCryptAlgoName(rfcCryptAlgoName))->clone();
-
+ std::unique_ptr<BlockCipher> cipher
+ = BlockCipher::create_or_throw(botanCryptAlgoName(rfcCryptAlgoName));
m_cipherBlockSize = static_cast<quint32>(cipher->block_size());
const QByteArray ivData = generateHash(kex, ivChar(), m_cipherBlockSize);
const InitializationVector iv(convertByteArray(ivData), m_cipherBlockSize);
@@ -90,15 +97,15 @@ void SshAbstractCryptoFacility::recreateKeys(const SshKeyExchange &kex)
const QByteArray cryptKeyData = generateHash(kex, keyChar(), keySize);
SymmetricKey cryptKey(convertByteArray(cryptKeyData), keySize);
Keyed_Filter * const cipherMode
- = makeCipherMode(cipher, getMode(rfcCryptAlgoName), iv, cryptKey);
+ = makeCipherMode(cipher.release(), getMode(rfcCryptAlgoName), iv, cryptKey);
m_pipe.reset(new Pipe(cipherMode));
m_macLength = botanHMacKeyLen(hMacAlgoName(kex));
const QByteArray hMacKeyData = generateHash(kex, macChar(), macLength());
SymmetricKey hMacKey(convertByteArray(hMacKeyData), macLength());
- const HashFunction * const hMacProto
- = af.prototype_hash_function(botanHMacAlgoName(hMacAlgoName(kex)));
- m_hMac.reset(new HMAC(hMacProto->clone()));
+ std::unique_ptr<HashFunction> hashFunc
+ = HashFunction::create_or_throw(botanHMacAlgoName(hMacAlgoName(kex)));
+ m_hMac.reset(new HMAC(hashFunc.release()));
m_hMac->set_key(hMacKey);
}
@@ -156,12 +163,12 @@ QByteArray SshAbstractCryptoFacility::generateHash(const SshKeyExchange &kex,
= kex.hash()->process(convertByteArray(data), data.size());
while (key.size() < length) {
SecureVector<byte> tmpKey;
- tmpKey += SecureVector<byte>(convertByteArray(k), k.size());
- tmpKey += SecureVector<byte>(convertByteArray(h), h.size());
+ tmpKey.insert(tmpKey.end(), k.cbegin(), k.cend());
+ tmpKey.insert(tmpKey.end(), h.cbegin(), h.cend());
tmpKey += key;
key += kex.hash()->process(tmpKey);
}
- return QByteArray(reinterpret_cast<const char *>(key.begin()), length);
+ return QByteArray(reinterpret_cast<const char *>(&key.front()), length);
}
void SshAbstractCryptoFacility::checkInvariant() const
@@ -192,7 +199,7 @@ Keyed_Filter *SshEncryptionFacility::makeCipherMode(BlockCipher *cipher, Mode mo
{
switch (mode) {
case CbcMode:
- return new CBC_Encryption(cipher, new Null_Padding, key, iv);
+ return get_cipher(cipher->name() + "/CBC/NoPadding", key, iv, ENCRYPTION);
case CtrMode:
return makeCtrCipherMode(cipher, iv, key);
}
@@ -235,7 +242,7 @@ void SshEncryptionFacility::createAuthenticationKey(const QByteArray &privKeyFil
if (ecdsaKey) {
m_authPubKeyBlob += AbstractSshPacket::encodeString(m_authKeyAlgoName.mid(11)); // Without "ecdsa-sha2-" prefix.
m_authPubKeyBlob += AbstractSshPacket::encodeString(
- convertByteArray(EC2OSP(ecdsaKey->public_point(), PointGFp::UNCOMPRESSED)));
+ convertByteArray(ecdsaKey->public_point().encode(PointGFp::UNCOMPRESSED)));
} else {
foreach (const BigInt &b, pubKeyParams)
m_authPubKeyBlob += AbstractSshPacket::encodeMpInt(b);
@@ -249,7 +256,7 @@ bool SshEncryptionFacility::createAuthenticationKeyFromPKCS8(const QByteArray &p
try {
Pipe pipe;
pipe.process_msg(convertByteArray(privKeyFileContents), privKeyFileContents.size());
- m_authKey.reset(PKCS8::load_key(pipe, m_rng, SshKeyPasswordRetriever()));
+ m_authKey.reset(PKCS8::load_key(pipe, m_rng, &get_passphrase));
if (auto * const dsaKey = dynamic_cast<DSA_PrivateKey *>(m_authKey.data())) {
m_authKeyAlgoName = SshCapabilities::PubKeyDss;
pubKeyParams << dsaKey->group_p() << dsaKey->group_q()
@@ -338,8 +345,7 @@ bool SshEncryptionFacility::createAuthenticationKeyFromOpenSSL(const QByteArray
} else if (m_authKeyAlgoName == SshCapabilities::PubKeyRsa) {
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.reset(new RSA_PrivateKey(p, q, e, d, n));
pubKeyParams << e << n;
allKeyParams << pubKeyParams << p << q << d;
} else {
@@ -374,7 +380,7 @@ QByteArray SshEncryptionFacility::authenticationKeySignature(const QByteArray &d
{
Q_ASSERT(m_authKey);
- QScopedPointer<PK_Signer> signer(new PK_Signer(*m_authKey,
+ QScopedPointer<PK_Signer> signer(new PK_Signer(*m_authKey, m_rng,
botanEmsaAlgoName(m_authKeyAlgoName)));
QByteArray dataToSign = AbstractSshPacket::encodeString(sessionId()) + data;
QByteArray signature
@@ -417,7 +423,7 @@ Keyed_Filter *SshDecryptionFacility::makeCipherMode(BlockCipher *cipher, Mode mo
{
switch (mode) {
case CbcMode:
- return new CBC_Decryption(cipher, new Null_Padding, key, iv);
+ return get_cipher(cipher->name() + "/CBC/NoPadding", iv, key, DECRYPTION);
case CtrMode:
return makeCtrCipherMode(cipher, iv, key);
}
diff --git a/src/libs/ssh/sshcryptofacility_p.h b/src/libs/ssh/sshcryptofacility_p.h
index 2f9b64c44c2..86df75764d8 100644
--- a/src/libs/ssh/sshcryptofacility_p.h
+++ b/src/libs/ssh/sshcryptofacility_p.h
@@ -25,7 +25,13 @@
#pragma once
-#include <botan/botan.h>
+#include <botan/auto_rng.h>
+#include <botan/bigint.h>
+#include <botan/block_cipher.h>
+#include <botan/hmac.h>
+#include <botan/key_filt.h>
+#include <botan/pipe.h>
+#include <botan/pk_keys.h>
#include <QByteArray>
#include <QScopedPointer>
diff --git a/src/libs/ssh/sshinit.cpp b/src/libs/ssh/sshinit.cpp
deleted file mode 100644
index a76724e5519..00000000000
--- a/src/libs/ssh/sshinit.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "sshinit_p.h"
-
-#include <botan/botan.h>
-
-#include <QMutex>
-#include <QMutexLocker>
-
-namespace QSsh {
-namespace Internal {
-
-static bool initialized = false;
-static QMutex initMutex;
-
-void initSsh()
-{
- QMutexLocker locker(&initMutex);
- if (!initialized) {
- Botan::LibraryInitializer::initialize("thread_safe=true");
- initialized = true;
- }
-}
-
-} // namespace Internal
-} // namespace QSsh
diff --git a/src/libs/ssh/sshinit_p.h b/src/libs/ssh/sshinit_p.h
deleted file mode 100644
index 8fb84e27b11..00000000000
--- a/src/libs/ssh/sshinit_p.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-namespace QSsh {
-namespace Internal {
-
-void initSsh();
-
-} // namespace Internal
-} // namespace QSsh
diff --git a/src/libs/ssh/sshkeyexchange.cpp b/src/libs/ssh/sshkeyexchange.cpp
index f513454d456..3eb013f282a 100644
--- a/src/libs/ssh/sshkeyexchange.cpp
+++ b/src/libs/ssh/sshkeyexchange.cpp
@@ -33,7 +33,18 @@
#include "sshexception_p.h"
#include "sshincomingpacket_p.h"
-#include <botan/botan.h>
+#include <botan/auto_rng.h>
+#include <botan/dh.h>
+#include <botan/dl_group.h>
+#include <botan/dsa.h>
+#include <botan/ec_group.h>
+#include <botan/ecdh.h>
+#include <botan/ecdsa.h>
+#include <botan/lookup.h>
+#include <botan/point_gfp.h>
+#include <botan/pubkey.h>
+#include <botan/rsa.h>
+#include <botan/types.h>
#include <string>
@@ -148,12 +159,13 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply,
printData("K_S", reply.k_s);
SecureVector<byte> encodedK;
+ Botan::AutoSeeded_RNG rng;
if (m_dhKey) {
concatenatedData += AbstractSshPacket::encodeMpInt(m_dhKey->get_y());
concatenatedData += AbstractSshPacket::encodeMpInt(reply.f);
- DH_KA_Operation dhOp(*m_dhKey);
- SecureVector<byte> encodedF = BigInt::encode(reply.f);
- encodedK = dhOp.agree(encodedF, encodedF.size());
+ Botan::PK_Key_Agreement dhOp(*m_dhKey, rng, "Raw");
+ const std::vector<std::uint8_t> encodedF = BigInt::encode(reply.f);
+ encodedK = dhOp.derive_key(m_dhKey->group_p().bytes(), encodedF).bits_of();
printData("y", AbstractSshPacket::encodeMpInt(m_dhKey->get_y()));
printData("f", AbstractSshPacket::encodeMpInt(reply.f));
m_dhKey.reset(nullptr);
@@ -162,8 +174,9 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply,
concatenatedData // Q_C.
+= AbstractSshPacket::encodeString(convertByteArray(m_ecdhKey->public_value()));
concatenatedData += AbstractSshPacket::encodeString(reply.q_s);
- ECDH_KA_Operation ecdhOp(*m_ecdhKey);
- encodedK = ecdhOp.agree(convertByteArray(reply.q_s), reply.q_s.count());
+ Botan::PK_Key_Agreement ecdhOp(*m_ecdhKey, rng, "Raw");
+ encodedK = ecdhOp.derive_key(m_ecdhKey->domain().get_p().bytes(),
+ convertByteArray(reply.q_s), reply.q_s.count()).bits_of();
m_ecdhKey.reset(nullptr);
}
@@ -173,7 +186,7 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply,
concatenatedData += m_k;
printData("Concatenated data", concatenatedData);
- m_hash.reset(get_hash(botanHMacAlgoName(hashAlgoForKexAlgo())));
+ m_hash = HashFunction::create_or_throw(botanHMacAlgoName(hashAlgoForKexAlgo()));
const SecureVector<byte> &hashResult = m_hash->process(convertByteArray(concatenatedData),
concatenatedData.size());
m_h = convertByteArray(hashResult);
@@ -193,8 +206,7 @@ void SshKeyExchange::sendNewKeysPacket(const SshIncomingPacket &dhReply,
} else {
QSSH_ASSERT_AND_RETURN(m_serverHostKeyAlgo.startsWith(SshCapabilities::PubKeyEcdsaPrefix));
const EC_Group domain(SshCapabilities::oid(m_serverHostKeyAlgo));
- const PointGFp point = OS2ECP(convertByteArray(reply.q), reply.q.count(),
- domain.get_curve());
+ const PointGFp point = domain.OS2ECP(convertByteArray(reply.q), reply.q.count());
ECDSA_PublicKey * const ecdsaKey = new ECDSA_PublicKey(domain, point);
sigKey.reset(ecdsaKey);
}
diff --git a/src/libs/ssh/sshkeyexchange_p.h b/src/libs/ssh/sshkeyexchange_p.h
index b56597b6df3..de5828292e2 100644
--- a/src/libs/ssh/sshkeyexchange_p.h
+++ b/src/libs/ssh/sshkeyexchange_p.h
@@ -30,6 +30,8 @@
#include <QByteArray>
#include <QScopedPointer>
+#include <memory>
+
namespace Botan {
class DH_PrivateKey;
class ECDH_PrivateKey;
@@ -59,7 +61,7 @@ public:
QByteArray k() const { return m_k; }
QByteArray h() const { return m_h; }
- Botan::HashFunction *hash() const { return m_hash.data(); }
+ Botan::HashFunction *hash() const { return m_hash.get(); }
QByteArray encryptionAlgo() const { return m_encryptionAlgo; }
QByteArray decryptionAlgo() const { return m_decryptionAlgo; }
QByteArray hMacAlgoClientToServer() const { return m_c2sHMacAlgo; }
@@ -84,7 +86,7 @@ private:
QByteArray m_decryptionAlgo;
QByteArray m_c2sHMacAlgo;
QByteArray m_s2cHMacAlgo;
- QScopedPointer<Botan::HashFunction> m_hash;
+ std::unique_ptr<Botan::HashFunction> m_hash;
const SshConnectionParameters m_connParams;
SshSendFacility &m_sendFacility;
};
diff --git a/src/libs/ssh/sshkeygenerator.cpp b/src/libs/ssh/sshkeygenerator.cpp
index eb85c1aa66f..38828ee97f4 100644
--- a/src/libs/ssh/sshkeygenerator.cpp
+++ b/src/libs/ssh/sshkeygenerator.cpp
@@ -27,11 +27,20 @@
#include "sshbotanconversions_p.h"
#include "sshcapabilities_p.h"
+#include "sshlogging_p.h"
#include "ssh_global.h"
-#include "sshinit_p.h"
#include "sshpacket_p.h"
-#include <botan/botan.h>
+#include <botan/auto_rng.h>
+#include <botan/der_enc.h>
+#include <botan/dsa.h>
+#include <botan/ecdsa.h>
+#include <botan/numthry.h>
+#include <botan/pem.h>
+#include <botan/pipe.h>
+#include <botan/pkcs8.h>
+#include <botan/rsa.h>
+#include <botan/x509_key.h>
#include <QDateTime>
#include <QInputDialog>
@@ -45,7 +54,6 @@ using namespace Internal;
SshKeyGenerator::SshKeyGenerator() : m_type(Rsa)
{
- initSsh();
}
bool SshKeyGenerator::generateKeys(KeyType type, PrivateKeyFormat format, int keySize,
@@ -116,8 +124,10 @@ void SshKeyGenerator::generatePkcs8KeyString(const KeyPtr &key, bool privateKey,
}
pipe.end_msg();
keyData->resize(static_cast<int>(pipe.remaining(pipe.message_count() - 1)));
- pipe.read(convertByteArray(*keyData), keyData->size(),
- pipe.message_count() - 1);
+ if (pipe.read(convertByteArray(*keyData), keyData->size(), pipe.message_count() - 1)
+ != std::size_t(keyData->size())) {
+ qCWarning(sshLog) << "short read from botan pipe";
+ }
}
void SshKeyGenerator::generateOpenSslKeyStrings(const KeyPtr &key)
@@ -146,7 +156,7 @@ void SshKeyGenerator::generateOpenSslPublicKeyString(const KeyPtr &key)
}
case Ecdsa: {
const auto ecdsaKey = key.dynamicCast<ECDSA_PrivateKey>();
- q = convertByteArray(EC2OSP(ecdsaKey->public_point(), PointGFp::UNCOMPRESSED));
+ q = convertByteArray(ecdsaKey->public_point().encode(PointGFp::UNCOMPRESSED));
keyId = SshCapabilities::ecdsaPubKeyAlgoForKeyWidth(
static_cast<int>(ecdsaKey->private_value().bytes()));
break;
diff --git a/src/libs/ssh/sshkeypasswordretriever.cpp b/src/libs/ssh/sshkeypasswordretriever.cpp
index 8f133623636..6631404a038 100644
--- a/src/libs/ssh/sshkeypasswordretriever.cpp
+++ b/src/libs/ssh/sshkeypasswordretriever.cpp
@@ -34,20 +34,16 @@
namespace QSsh {
namespace Internal {
-std::string SshKeyPasswordRetriever::get_passphrase(const std::string &, const std::string &,
- UI_Result &result) const
+std::string get_passphrase()
{
const bool hasGui = dynamic_cast<QApplication *>(QApplication::instance());
if (hasGui) {
- bool ok;
const QString &password = QInputDialog::getText(0,
QCoreApplication::translate("QSsh::Ssh", "Password Required"),
QCoreApplication::translate("QSsh::Ssh", "Please enter the password for your private key."),
- QLineEdit::Password, QString(), &ok);
- result = ok ? OK : CANCEL_ACTION;
+ QLineEdit::Password, QString());
return std::string(password.toLocal8Bit().data());
} else {
- result = OK;
std::string password;
std::cout << "Please enter the password for your private key (set echo off beforehand!): " << std::flush;
std::cin >> password;
diff --git a/src/libs/ssh/sshkeypasswordretriever_p.h b/src/libs/ssh/sshkeypasswordretriever_p.h
index 15301feb67b..7d7bc76e698 100644
--- a/src/libs/ssh/sshkeypasswordretriever_p.h
+++ b/src/libs/ssh/sshkeypasswordretriever_p.h
@@ -25,19 +25,12 @@
#pragma once
-#include <botan/botan.h>
-
#include <string>
namespace QSsh {
namespace Internal {
-class SshKeyPasswordRetriever : public Botan::User_Interface
-{
-public:
- std::string get_passphrase(const std::string &what, const std::string &source,
- UI_Result &result) const;
-};
+std::string get_passphrase();
} // namespace Internal
} // namespace QSsh
diff --git a/src/libs/ssh/sshpacketparser_p.h b/src/libs/ssh/sshpacketparser_p.h
index b57f22f0846..db63f0a1b9c 100644
--- a/src/libs/ssh/sshpacketparser_p.h
+++ b/src/libs/ssh/sshpacketparser_p.h
@@ -25,7 +25,7 @@
#pragma once
-#include <botan/botan.h>
+#include <botan/bigint.h>
#include <QByteArray>
#include <QList>
diff --git a/src/libs/ssh/sshremoteprocess.cpp b/src/libs/ssh/sshremoteprocess.cpp
index 5a875d1f105..3b81e0409ce 100644
--- a/src/libs/ssh/sshremoteprocess.cpp
+++ b/src/libs/ssh/sshremoteprocess.cpp
@@ -31,8 +31,6 @@
#include "sshlogging_p.h"
#include "sshsendfacility_p.h"
-#include <botan/botan.h>
-
#include <QTimer>
#include <cstring>