/************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Nokia Corporation (info@qt.nokia.com) ** ** ** GNU Lesser General Public License Usage ** ** This file may be used under the terms of the GNU Lesser General Public ** License version 2.1 as published by the Free Software Foundation and ** appearing in the file LICENSE.LGPL included in the packaging of this file. ** Please review the following information to ensure the GNU Lesser General ** Public License version 2.1 requirements will be met: ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** Other Usage ** ** Alternatively, this file may be used in accordance with the terms and ** conditions contained in a signed written agreement between you and Nokia. ** ** If you have questions regarding the use of this file, please contact ** Nokia at info@qt.nokia.com. ** **************************************************************************/ #include "sshkeygenerator.h" #include "sshbotanconversions_p.h" #include "sshcapabilities_p.h" #include "sshpacket_p.h" #include #include #include #include #include #include #include #include #include namespace Utils { using namespace Botan; using namespace Internal; SshKeyGenerator::SshKeyGenerator() : m_type(Rsa) { } bool SshKeyGenerator::generateKeys(KeyType type, PrivateKeyFormat format, int keySize) { m_type = type; try { AutoSeeded_RNG rng; KeyPtr key; if (m_type == Rsa) key = KeyPtr(new RSA_PrivateKey(rng, keySize)); else key = KeyPtr(new DSA_PrivateKey(rng, DL_Group(rng, DL_Group::DSA_Kosherizer, keySize))); switch (format) { case Pkcs8: generatePkcs8KeyStrings(key); break; case OpenSsl: generateOpenSslKeyStrings(key); break; case Mixed: default: generatePkcs8KeyString(key, true); generateOpenSslPublicKeyString(key); } return true; } catch (Botan::Exception &e) { m_error = tr("Error generating key: %1").arg(e.what()); return false; } } void SshKeyGenerator::generatePkcs8KeyStrings(const KeyPtr &key) { generatePkcs8KeyString(key, false); generatePkcs8KeyString(key, true); } void SshKeyGenerator::generatePkcs8KeyString(const KeyPtr &key, bool privateKey) { Pipe pipe; pipe.start_msg(); QByteArray *keyData; if (privateKey) { PKCS8::encode(*key, pipe); keyData = &m_privateKey; } else { X509::encode(*key, pipe); keyData = &m_publicKey; } pipe.end_msg(); keyData->resize(pipe.remaining(pipe.message_count() - 1)); pipe.read(convertByteArray(*keyData), keyData->size(), pipe.message_count() - 1); } void SshKeyGenerator::generateOpenSslKeyStrings(const KeyPtr &key) { generateOpenSslPublicKeyString(key); generateOpenSslPrivateKeyString(key); } void SshKeyGenerator::generateOpenSslPublicKeyString(const KeyPtr &key) { QList params; QByteArray keyId; if (m_type == Rsa) { const QSharedPointer rsaKey = key.dynamicCast(); params << rsaKey->get_e() << rsaKey->get_n(); keyId = SshCapabilities::PubKeyRsa; } else { const QSharedPointer dsaKey = key.dynamicCast(); params << dsaKey->group_p() << dsaKey->group_q() << dsaKey->group_g() << dsaKey->get_y(); keyId = SshCapabilities::PubKeyDss; } QByteArray publicKeyBlob = AbstractSshPacket::encodeString(keyId); foreach (const BigInt &b, params) publicKeyBlob += AbstractSshPacket::encodeMpInt(b); publicKeyBlob = publicKeyBlob.toBase64(); const QByteArray id = "QtCreator/" + QDateTime::currentDateTime().toString(Qt::ISODate).toUtf8(); m_publicKey = keyId + ' ' + publicKeyBlob + ' ' + id; } void SshKeyGenerator::generateOpenSslPrivateKeyString(const KeyPtr &key) { QList params; QByteArray keyId; const char *label; if (m_type == Rsa) { const QSharedPointer rsaKey = key.dynamicCast(); params << rsaKey->get_n() << rsaKey->get_e() << rsaKey->get_d() << rsaKey->get_p() << rsaKey->get_q(); keyId = SshCapabilities::PubKeyRsa; label = "RSA PRIVATE KEY"; } else { const QSharedPointer dsaKey = key.dynamicCast(); params << dsaKey->group_p() << dsaKey->group_q() << dsaKey->group_g() << dsaKey->get_y() << dsaKey->get_x(); keyId = SshCapabilities::PubKeyDss; label = "DSA PRIVATE KEY"; } DER_Encoder encoder; encoder.start_cons(SEQUENCE).encode(0U); foreach (const BigInt &b, params) encoder.encode(b); encoder.end_cons(); m_privateKey = QByteArray(PEM_Code::encode (encoder.get_contents(), label).c_str()); } } // namespace Utils