From 6ded326de74e6d1434efb9cfb7ab1a120a788007 Mon Sep 17 00:00:00 2001 From: Toni Spets Date: Sun, 21 Feb 2021 11:22:12 +0200 Subject: [PATCH] SSH Agent: Store raw key data as complete blobs This is a prerequisite for security key backed keys. --- src/sshagent/ASN1Key.cpp | 46 ++++++++++++++++++++----------------- src/sshagent/OpenSSHKey.cpp | 40 +++++++++++++------------------- src/sshagent/OpenSSHKey.h | 8 +++---- 3 files changed, 45 insertions(+), 49 deletions(-) diff --git a/src/sshagent/ASN1Key.cpp b/src/sshagent/ASN1Key.cpp index b91caab1b..abd28a31b 100644 --- a/src/sshagent/ASN1Key.cpp +++ b/src/sshagent/ASN1Key.cpp @@ -109,18 +109,20 @@ bool ASN1Key::parseDSA(QByteArray& ba, OpenSSHKey& key) readInt(stream, y); readInt(stream, x); - QList publicData; - publicData.append(p); - publicData.append(q); - publicData.append(g); - publicData.append(y); + QByteArray publicData; + BinaryStream publicDataStream(&publicData); + publicDataStream.writeString(p); + publicDataStream.writeString(q); + publicDataStream.writeString(g); + publicDataStream.writeString(y); - QList privateData; - privateData.append(p); - privateData.append(q); - privateData.append(g); - privateData.append(y); - privateData.append(x); + QByteArray privateData; + BinaryStream privateDataStream(&privateData); + privateDataStream.writeString(p); + privateDataStream.writeString(q); + privateDataStream.writeString(g); + privateDataStream.writeString(y); + privateDataStream.writeString(x); key.setType("ssh-dss"); key.setPublicData(publicData); @@ -148,17 +150,19 @@ bool ASN1Key::parseRSA(QByteArray& ba, OpenSSHKey& key) readInt(stream, qinv); // Note: To properly calculate the key fingerprint, e and n are reversed per RFC 4253 - QList publicData; - publicData.append(e); - publicData.append(n); + QByteArray publicData; + BinaryStream publicDataStream(&publicData); + publicDataStream.writeString(e); + publicDataStream.writeString(n); - QList privateData; - privateData.append(n); - privateData.append(e); - privateData.append(d); - privateData.append(qinv); - privateData.append(p); - privateData.append(q); + QByteArray privateData; + BinaryStream privateDataStream(&privateData); + privateDataStream.writeString(n); + privateDataStream.writeString(e); + privateDataStream.writeString(d); + privateDataStream.writeString(qinv); + privateDataStream.writeString(p); + privateDataStream.writeString(q); key.setType("ssh-rsa"); key.setPublicData(publicData); diff --git a/src/sshagent/OpenSSHKey.cpp b/src/sshagent/OpenSSHKey.cpp index 84f154906..12e91f155 100644 --- a/src/sshagent/OpenSSHKey.cpp +++ b/src/sshagent/OpenSSHKey.cpp @@ -39,8 +39,8 @@ OpenSSHKey::OpenSSHKey(QObject* parent) , m_kdfOptions(QByteArray()) , m_rawType(QString()) , m_rawData(QByteArray()) - , m_rawPublicData(QList()) - , m_rawPrivateData(QList()) + , m_rawPublicData(QByteArray()) + , m_rawPrivateData(QByteArray()) , m_comment(QString()) , m_error(QString()) { @@ -87,10 +87,7 @@ const QString OpenSSHKey::fingerprint(QCryptographicHash::Algorithm algo) const BinaryStream stream(&publicKey); stream.writeString(m_type); - - for (const QByteArray& ba : m_rawPublicData) { - stream.writeString(ba); - } + stream.write(m_rawPublicData); QByteArray rawHash = QCryptographicHash::hash(publicKey, algo); @@ -123,10 +120,7 @@ const QString OpenSSHKey::publicKey() const BinaryStream stream(&publicKey); stream.writeString(m_type); - - for (QByteArray ba : m_rawPublicData) { - stream.writeString(ba); - } + stream.write(m_rawPublicData); return m_type + " " + QString::fromLatin1(publicKey.toBase64()) + " " + m_comment; } @@ -141,12 +135,12 @@ void OpenSSHKey::setType(const QString& type) m_type = type; } -void OpenSSHKey::setPublicData(const QList& data) +void OpenSSHKey::setPublicData(const QByteArray& data) { m_rawPublicData = data; } -void OpenSSHKey::setPrivateData(const QList& data) +void OpenSSHKey::setPrivateData(const QByteArray& data) { m_rawPrivateData = data; } @@ -437,6 +431,7 @@ bool OpenSSHKey::openKey(const QString& passphrase) bool OpenSSHKey::readPublic(BinaryStream& stream) { m_rawPublicData.clear(); + BinaryStream rawPublicDataStream(&m_rawPublicData); if (!stream.readString(m_type)) { m_error = tr("Unexpected EOF while reading public key"); @@ -465,7 +460,7 @@ bool OpenSSHKey::readPublic(BinaryStream& stream) return false; } - m_rawPublicData.append(t); + rawPublicDataStream.writeString(t); } return true; @@ -474,6 +469,7 @@ bool OpenSSHKey::readPublic(BinaryStream& stream) bool OpenSSHKey::readPrivate(BinaryStream& stream) { m_rawPrivateData.clear(); + BinaryStream rawPrivateDataStream(&m_rawPrivateData); if (!stream.readString(m_type)) { m_error = tr("Unexpected EOF while reading private key"); @@ -502,7 +498,7 @@ bool OpenSSHKey::readPrivate(BinaryStream& stream) return false; } - m_rawPrivateData.append(t); + rawPrivateDataStream.writeString(t); } if (!stream.readString(m_comment)) { @@ -525,11 +521,9 @@ bool OpenSSHKey::writePublic(BinaryStream& stream) return false; } - for (QByteArray t : m_rawPublicData) { - if (!stream.writeString(t)) { - m_error = tr("Unexpected EOF when writing public key"); - return false; - } + if (!stream.write(m_rawPublicData)) { + m_error = tr("Unexpected EOF when writing public key"); + return false; } return true; @@ -547,11 +541,9 @@ bool OpenSSHKey::writePrivate(BinaryStream& stream) return false; } - for (QByteArray t : m_rawPrivateData) { - if (!stream.writeString(t)) { - m_error = tr("Unexpected EOF when writing private key"); - return false; - } + if (!stream.write(m_rawPrivateData)) { + m_error = tr("Unexpected EOF when writing private key"); + return false; } if (!stream.writeString(m_comment)) { diff --git a/src/sshagent/OpenSSHKey.h b/src/sshagent/OpenSSHKey.h index 99689da5b..8c7242e74 100644 --- a/src/sshagent/OpenSSHKey.h +++ b/src/sshagent/OpenSSHKey.h @@ -44,8 +44,8 @@ public: const QString errorString() const; void setType(const QString& type); - void setPublicData(const QList& data); - void setPrivateData(const QList& data); + void setPublicData(const QByteArray& data); + void setPrivateData(const QByteArray& data); void setComment(const QString& comment); void clearPrivate(); @@ -70,8 +70,8 @@ private: QString m_rawType; QByteArray m_rawData; - QList m_rawPublicData; - QList m_rawPrivateData; + QByteArray m_rawPublicData; + QByteArray m_rawPrivateData; QString m_comment; QString m_error; };