SSH Agent: Template reading key parts

This is a prerequisite for security key backed keys.
This commit is contained in:
Toni Spets 2021-02-23 18:49:55 +02:00 committed by Jonathan White
parent 6ded326de7
commit c07a57d141
2 changed files with 70 additions and 41 deletions

View File

@ -428,8 +428,54 @@ bool OpenSSHKey::openKey(const QString& passphrase)
return false; return false;
} }
bool OpenSSHKey::readKeyParts(BinaryStream& in, const QList<KeyPart> parts, BinaryStream& out)
{
for (auto part : parts) {
switch (part) {
case STR_PART: {
QByteArray t;
if (!in.readString(t)) {
m_error = tr("Unexpected EOF while reading key");
return false;
}
out.writeString(t);
break;
}
case UINT8_PART: {
quint8 i;
if (!in.read(i)) {
m_error = tr("Unexpected EOF while reading key");
return false;
}
out.write(i);
break;
}
default:
m_error = tr("Unsupported key part");
return false;
}
}
return true;
}
bool OpenSSHKey::readPublic(BinaryStream& stream) bool OpenSSHKey::readPublic(BinaryStream& stream)
{ {
// clang-format off
static const QMap<QString, QList<KeyPart>> keyTemplates {
{ "ssh-dss", {STR_PART, STR_PART, STR_PART, STR_PART} },
{ "ssh-rsa", {STR_PART, STR_PART} },
{ "ecdsa-sha2-nistp256", {STR_PART, STR_PART} },
{ "ecdsa-sha2-nistp384", {STR_PART, STR_PART} },
{ "ecdsa-sha2-nistp521", {STR_PART, STR_PART} },
{ "ssh-ed25519", {STR_PART} },
};
// clang-format on
m_rawPublicData.clear(); m_rawPublicData.clear();
BinaryStream rawPublicDataStream(&m_rawPublicData); BinaryStream rawPublicDataStream(&m_rawPublicData);
@ -438,36 +484,27 @@ bool OpenSSHKey::readPublic(BinaryStream& stream)
return false; return false;
} }
int keyParts; if (!keyTemplates.contains(m_type)) {
if (m_type == "ssh-dss") {
keyParts = 4;
} else if (m_type == "ssh-rsa") {
keyParts = 2;
} else if (m_type.startsWith("ecdsa-sha2-")) {
keyParts = 2;
} else if (m_type == "ssh-ed25519") {
keyParts = 1;
} else {
m_error = tr("Unknown key type: %1").arg(m_type); m_error = tr("Unknown key type: %1").arg(m_type);
return false; return false;
} }
for (int i = 0; i < keyParts; ++i) { return readKeyParts(stream, keyTemplates[m_type], rawPublicDataStream);
QByteArray t;
if (!stream.readString(t)) {
m_error = tr("Unexpected EOF while reading public key");
return false;
}
rawPublicDataStream.writeString(t);
}
return true;
} }
bool OpenSSHKey::readPrivate(BinaryStream& stream) bool OpenSSHKey::readPrivate(BinaryStream& stream)
{ {
// clang-format off
static const QMap<QString, QList<KeyPart>> keyTemplates {
{ "ssh-dss", {STR_PART, STR_PART, STR_PART, STR_PART, STR_PART} },
{ "ssh-rsa", {STR_PART, STR_PART, STR_PART, STR_PART, STR_PART, STR_PART} },
{ "ecdsa-sha2-nistp256", {STR_PART, STR_PART, STR_PART} },
{ "ecdsa-sha2-nistp384", {STR_PART, STR_PART, STR_PART} },
{ "ecdsa-sha2-nistp521", {STR_PART, STR_PART, STR_PART} },
{ "ssh-ed25519", {STR_PART, STR_PART} },
};
// clang-format on
m_rawPrivateData.clear(); m_rawPrivateData.clear();
BinaryStream rawPrivateDataStream(&m_rawPrivateData); BinaryStream rawPrivateDataStream(&m_rawPrivateData);
@ -476,31 +513,16 @@ bool OpenSSHKey::readPrivate(BinaryStream& stream)
return false; return false;
} }
int keyParts; if (!keyTemplates.contains(m_type)) {
if (m_type == "ssh-dss") {
keyParts = 5;
} else if (m_type == "ssh-rsa") {
keyParts = 6;
} else if (m_type.startsWith("ecdsa-sha2-")) {
keyParts = 3;
} else if (m_type == "ssh-ed25519") {
keyParts = 2;
} else {
m_error = tr("Unknown key type: %1").arg(m_type); m_error = tr("Unknown key type: %1").arg(m_type);
return false; return false;
} }
for (int i = 0; i < keyParts; ++i) { if (!readKeyParts(stream, keyTemplates[m_type], rawPrivateDataStream)) {
QByteArray t;
if (!stream.readString(t)) {
m_error = tr("Unexpected EOF while reading private key"); m_error = tr("Unexpected EOF while reading private key");
return false; return false;
} }
rawPrivateDataStream.writeString(t);
}
if (!stream.readString(m_comment)) { if (!stream.readString(m_comment)) {
m_error = tr("Unexpected EOF while reading private key"); m_error = tr("Unexpected EOF while reading private key");
return false; return false;

View File

@ -60,6 +60,13 @@ public:
static const QString TYPE_OPENSSH_PRIVATE; static const QString TYPE_OPENSSH_PRIVATE;
private: private:
enum KeyPart
{
STR_PART,
UINT8_PART
};
bool readKeyParts(BinaryStream& in, const QList<KeyPart> parts, BinaryStream& out);
bool extractPEM(const QByteArray& in, QByteArray& out); bool extractPEM(const QByteArray& in, QByteArray& out);
QString m_type; QString m_type;