SSH Agent: Fix handling of encrypted RSA keys

Also fix multiple UI issues caused by said keys.

Fixes #1560
This commit is contained in:
Toni Spets 2018-03-01 18:27:53 +02:00 committed by Janek Bevendorff
parent 97a890e8a0
commit b0a61f437a
4 changed files with 52 additions and 26 deletions

View file

@ -346,24 +346,32 @@ void EditEntryWidget::updateSSHAgentKeyInfo()
return; return;
} }
if (!key.fingerprint().isEmpty()) {
m_sshAgentUi->fingerprintTextLabel->setText(key.fingerprint()); m_sshAgentUi->fingerprintTextLabel->setText(key.fingerprint());
if (key.encrypted()) {
m_sshAgentUi->commentTextLabel->setText(tr("(encrypted)"));
m_sshAgentUi->decryptButton->setEnabled(true);
} else { } else {
m_sshAgentUi->commentTextLabel->setText(key.comment()); m_sshAgentUi->fingerprintTextLabel->setText(tr("(encrypted)"));
} }
if (!key.comment().isEmpty() || !key.encrypted()) {
m_sshAgentUi->commentTextLabel->setText(key.comment());
} else {
m_sshAgentUi->commentTextLabel->setText(tr("(encrypted)"));
m_sshAgentUi->decryptButton->setEnabled(true);
}
if (!key.publicKey().isEmpty()) {
m_sshAgentUi->publicKeyEdit->document()->setPlainText(key.publicKey()); m_sshAgentUi->publicKeyEdit->document()->setPlainText(key.publicKey());
m_sshAgentUi->copyToClipboardButton->setEnabled(true);
} else {
m_sshAgentUi->publicKeyEdit->document()->setPlainText(tr("(encrypted)"));
m_sshAgentUi->copyToClipboardButton->setDisabled(true);
}
// enable agent buttons only if we have an agent running // enable agent buttons only if we have an agent running
if (SSHAgent::instance()->isAgentRunning()) { if (SSHAgent::instance()->isAgentRunning()) {
m_sshAgentUi->addToAgentButton->setEnabled(true); m_sshAgentUi->addToAgentButton->setEnabled(true);
m_sshAgentUi->removeFromAgentButton->setEnabled(true); m_sshAgentUi->removeFromAgentButton->setEnabled(true);
} }
m_sshAgentUi->copyToClipboardButton->setEnabled(true);
} }
void EditEntryWidget::saveSSHAgentConfig() void EditEntryWidget::saveSSHAgentConfig()
@ -410,7 +418,7 @@ void EditEntryWidget::browsePrivateKey()
} }
} }
bool EditEntryWidget::getOpenSSHKey(OpenSSHKey& key) bool EditEntryWidget::getOpenSSHKey(OpenSSHKey& key, bool decrypt)
{ {
QByteArray privateKeyData; QByteArray privateKeyData;
@ -436,7 +444,7 @@ bool EditEntryWidget::getOpenSSHKey(OpenSSHKey& key)
privateKeyData = localFile.readAll(); privateKeyData = localFile.readAll();
} }
if (privateKeyData.length() == 0) { if (privateKeyData.isEmpty()) {
return false; return false;
} }
@ -445,6 +453,13 @@ bool EditEntryWidget::getOpenSSHKey(OpenSSHKey& key)
return false; return false;
} }
if (key.encrypted() && (decrypt || key.publicKey().isEmpty())) {
if (!key.openPrivateKey(m_entry->password())) {
showMessage(key.errorString(), MessageWidget::Error);
return false;
}
}
if (key.comment().isEmpty()) { if (key.comment().isEmpty()) {
key.setComment(m_entry->username()); key.setComment(m_entry->username());
} }
@ -456,16 +471,12 @@ void EditEntryWidget::addKeyToAgent()
{ {
OpenSSHKey key; OpenSSHKey key;
if (!getOpenSSHKey(key)) { if (!getOpenSSHKey(key, true)) {
return; return;
} }
if (!key.openPrivateKey(m_entry->password())) {
showMessage(key.errorString(), MessageWidget::Error);
} else {
m_sshAgentUi->commentTextLabel->setText(key.comment()); m_sshAgentUi->commentTextLabel->setText(key.comment());
m_sshAgentUi->publicKeyEdit->document()->setPlainText(key.publicKey()); m_sshAgentUi->publicKeyEdit->document()->setPlainText(key.publicKey());
}
quint32 lifetime = 0; quint32 lifetime = 0;
bool confirm = m_sshAgentUi->requireUserConfirmationCheckBox->isChecked(); bool confirm = m_sshAgentUi->requireUserConfirmationCheckBox->isChecked();
@ -494,16 +505,19 @@ void EditEntryWidget::decryptPrivateKey()
{ {
OpenSSHKey key; OpenSSHKey key;
if (!getOpenSSHKey(key)) { if (!getOpenSSHKey(key, true)) {
return; return;
} }
if (!key.openPrivateKey(m_entry->password())) { if (!key.comment().isEmpty()) {
showMessage(key.errorString(), MessageWidget::Error);
} else {
m_sshAgentUi->commentTextLabel->setText(key.comment()); m_sshAgentUi->commentTextLabel->setText(key.comment());
m_sshAgentUi->publicKeyEdit->document()->setPlainText(key.publicKey()); } else {
m_sshAgentUi->commentTextLabel->setText(tr("n/a"));
} }
m_sshAgentUi->fingerprintTextLabel->setText(key.fingerprint());
m_sshAgentUi->publicKeyEdit->document()->setPlainText(key.publicKey());
m_sshAgentUi->copyToClipboardButton->setEnabled(true);
} }
void EditEntryWidget::copyPublicKey() void EditEntryWidget::copyPublicKey()

View file

@ -128,7 +128,7 @@ private:
QMenu* createPresetsMenu(); QMenu* createPresetsMenu();
void updateEntryData(Entry* entry) const; void updateEntryData(Entry* entry) const;
#ifdef WITH_XC_SSHAGENT #ifdef WITH_XC_SSHAGENT
bool getOpenSSHKey(OpenSSHKey& key); bool getOpenSSHKey(OpenSSHKey& key, bool decrypt = false);
void saveSSHAgentConfig(); void saveSSHAgentConfig();
#endif #endif

View file

@ -94,6 +94,10 @@ int OpenSSHKey::keyLength() const
const QString OpenSSHKey::fingerprint() const const QString OpenSSHKey::fingerprint() const
{ {
if (m_publicData.isEmpty()) {
return {};
}
QByteArray publicKey; QByteArray publicKey;
BinaryStream stream(&publicKey); BinaryStream stream(&publicKey);
@ -115,6 +119,10 @@ const QString OpenSSHKey::comment() const
const QString OpenSSHKey::publicKey() const const QString OpenSSHKey::publicKey() const
{ {
if (m_publicData.isEmpty()) {
return {};
}
QByteArray publicKey; QByteArray publicKey;
BinaryStream stream(&publicKey); BinaryStream stream(&publicKey);
@ -326,7 +334,7 @@ bool OpenSSHKey::openPrivateKey(const QString& passphrase)
return false; return false;
} }
if (passphrase.length() == 0) { if (passphrase.isEmpty()) {
m_error = tr("Passphrase is required to decrypt this key"); m_error = tr("Passphrase is required to decrypt this key");
return false; return false;
} }

View file

@ -260,6 +260,10 @@ void SSHAgent::databaseModeChanged(DatabaseWidget::Mode mode)
continue; continue;
} }
if (!key.openPrivateKey(e->password())) {
continue;
}
if (key.comment().isEmpty()) { if (key.comment().isEmpty()) {
key.setComment(e->username()); key.setComment(e->username());
} }
@ -268,7 +272,7 @@ void SSHAgent::databaseModeChanged(DatabaseWidget::Mode mode)
removeIdentityAtLock(key, uuid); removeIdentityAtLock(key, uuid);
} }
if (settings.addAtDatabaseOpen() && key.openPrivateKey(e->password())) { if (settings.addAtDatabaseOpen()) {
int lifetime = 0; int lifetime = 0;
if (settings.useLifetimeConstraintWhenAdding()) { if (settings.useLifetimeConstraintWhenAdding()) {