Пример #1
0
bool AbstractSshPacket::isComplete() const
{
    if (currentDataSize() < minPacketSize())
        return false;
    Q_ASSERT(4 + length() + macLength() >= currentDataSize());
    return 4 + length() + macLength() == currentDataSize();
}
Пример #2
0
void SshIncomingPacket::consumeData(QByteArray &newData)
{
#ifdef CREATOR_SSH_DEBUG
    qDebug("%s: current data size = %d, new data size = %d",
        Q_FUNC_INFO, m_data.size(), newData.size());
#endif

    if (isComplete() || newData.isEmpty())
        return;

    /*
     * Until we have reached the minimum packet size, we cannot decrypt the
     * length field.
     */
    const quint32 minSize = minPacketSize();
    if (currentDataSize() < minSize) {
        const int bytesToTake
            = qMin<quint32>(minSize - currentDataSize(), newData.size());
        moveFirstBytes(m_data, newData, bytesToTake);
#ifdef CREATOR_SSH_DEBUG
        qDebug("Took %d bytes from new data", bytesToTake);
#endif
        if (currentDataSize() < minSize)
            return;
    }

    if (4 + length() + macLength() < currentDataSize())
        throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR, "Server sent invalid packet.");

    const int bytesToTake
        = qMin<quint32>(length() + 4 + macLength() - currentDataSize(),
              newData.size());
    moveFirstBytes(m_data, newData, bytesToTake);
#ifdef CREATOR_SSH_DEBUG
    qDebug("Took %d bytes from new data", bytesToTake);
#endif
    if (isComplete()) {
#ifdef CREATOR_SSH_DEBUG
        qDebug("Message complete. Overall size: %u, payload size: %u",
            m_data.size(), m_length - paddingLength() - 1);
#endif
        decrypt();
        ++m_serverSeqNr;
    }
}
Пример #3
0
void SshIncomingPacket::calculateLength() const
{
    Q_ASSERT(currentDataSize() >= minPacketSize());
#ifdef CREATOR_SSH_DEBUG
    qDebug("Length field before decryption: %d-%d-%d-%d", m_data.at(0) & 0xff,
        m_data.at(1) & 0xff, m_data.at(2) & 0xff, m_data.at(3) & 0xff);
#endif
    m_decrypter.decrypt(m_data, 0, cipherBlockSize());
#ifdef CREATOR_SSH_DEBUG
    qDebug("Length field after decryption: %d-%d-%d-%d", m_data.at(0) & 0xff, m_data.at(1) & 0xff, m_data.at(2) & 0xff, m_data.at(3) & 0xff);
    qDebug("message type = %d", m_data.at(TypeOffset));
#endif
    m_length = SshPacketParser::asUint32(m_data, static_cast<quint32>(0));
#ifdef CREATOR_SSH_DEBUG
    qDebug("decrypted length is %u", m_length);
#endif
}
Пример #4
0
SshKeyExchangeReply SshIncomingPacket::extractKeyExchangeReply(const QByteArray &pubKeyAlgo) const
{
    Q_ASSERT(isComplete());
    Q_ASSERT(type() == SSH_MSG_KEXDH_REPLY);

    try {
        SshKeyExchangeReply replyData;
        quint32 offset = TypeOffset + 1;
        const quint32 k_sLength
            = SshPacketParser::asUint32(m_data, &offset);
        if (offset + k_sLength > currentDataSize())
            throw SshPacketParseException();
        replyData.k_s = m_data.mid(offset - 4, k_sLength + 4);
        if (SshPacketParser::asString(m_data, &offset) != pubKeyAlgo)
            throw SshPacketParseException();

        // DSS: p and q, RSA: e and n
        replyData.parameters << SshPacketParser::asBigInt(m_data, &offset);
        replyData.parameters << SshPacketParser::asBigInt(m_data, &offset);

        // g and y
        if (pubKeyAlgo == SshCapabilities::PubKeyDss) {
            replyData.parameters << SshPacketParser::asBigInt(m_data, &offset);
            replyData.parameters << SshPacketParser::asBigInt(m_data, &offset);
        }

        replyData.f = SshPacketParser::asBigInt(m_data, &offset);
        offset += 4;
        if (SshPacketParser::asString(m_data, &offset) != pubKeyAlgo)
            throw SshPacketParseException();
        replyData.signatureBlob = SshPacketParser::asString(m_data, &offset);
        return replyData;
    } catch (SshPacketParseException &) {
        throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_KEY_EXCHANGE_FAILED,
            "Key exchange failed: "
            "Server sent invalid SSH_MSG_KEXDH_REPLY packet.");
    }
}