Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#5032 Show clearer error message why key is not usable #5894

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion extension/chrome/elements/pgp_pubkey.htm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<div id="pgp_block" class="pgp_pubkey" data-test="container-pgp-pubkey">
<div class="line error_container hidden">
<div class="error_info">
<span data-test="error-introduce-label">This OpenPGP key is not usable.</span>
<span class="error_introduce_label" data-test="error-introduce-label">This OpenPGP key is not usable.</span>
<input class="input_error_email" disabled data-test="error-email-input" />
</div>

Expand Down
28 changes: 25 additions & 3 deletions extension/chrome/elements/pgp_pubkey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { Url } from '../../js/common/core/common.js';
import { View } from '../../js/common/view.js';
import { Xss } from '../../js/common/platform/xss.js';
import { ContactStore } from '../../js/common/platform/store/contact-store.js';
import { Buf } from '../../js/common/core/buf.js';
import { OpenPGPKey } from '../../js/common/core/crypto/pgp/openpgp-key.js';

// todo - this should use KeyImportUI for consistency.
View.run(
Expand Down Expand Up @@ -71,7 +73,7 @@ View.run(
!this.firstParsedPublicKey.usableForEncryption &&
!this.firstParsedPublicKey.usableForSigning
) {
this.showKeyNotUsableError();
await this.showKeyNotUsableError();
} else {
let emailText = '';
if (this.parsedPublicKeys.length === 1) {
Expand Down Expand Up @@ -116,7 +118,7 @@ View.run(
frameId: this.frameId,
});
} else {
this.showKeyNotUsableError();
await this.showKeyNotUsableError();
}
}
this.sendResizeMsg();
Expand All @@ -137,6 +139,25 @@ View.run(
);
};

private getErrorText = async () => {
let errorStr = '';
const { keys, errs } = await KeyUtil.readMany(Buf.fromUtfStr(this.armoredPubkey));
errorStr = errs.join('\n');
for (const key of keys) {
const errorMessage = await OpenPGPKey.checkPublicKeyError(key);
if (errorMessage) {
const match = new RegExp(/Error encrypting message: (.+)$/).exec(errorMessage);
// remove `error: error encrypting message: part`, so error message will begin directly from error reason
if (match) {
errorStr += match[1];
} else {
errorStr += errorMessage;
}
}
}
return errorStr;
};

private sendResizeMsg = () => {
const origHeight = $('#pgp_block').height();
if (!origHeight) {
Expand Down Expand Up @@ -167,8 +188,9 @@ View.run(
}
};

private showKeyNotUsableError = () => {
private showKeyNotUsableError = async () => {
$('.error_container').removeClass('hidden');
$('.error_introduce_label').html(`This OpenPGP key is not usable.<br/><small>(${await this.getErrorText()})</small>`); // xss-escaped
$('.hide_if_error').hide();
$('.fingerprints, .add_contact, #manual_import_warning').remove();
const email = this.firstParsedPublicKey?.emails[0];
Expand Down
8 changes: 8 additions & 0 deletions extension/css/cryptup.css
Original file line number Diff line number Diff line change
Expand Up @@ -1446,6 +1446,10 @@ td {
align-items: flex-start;
}

.pgp_neutral .error_container .error_info .error_introduce_label {
white-space: pre-line;
}

.pgp_neutral .error_container .error_info span {
color: #a44;
font-size: 14px;
Expand Down Expand Up @@ -1625,6 +1629,10 @@ td {
display: none;
}

#pgp_block.pgp_pubkey .action_show_full {
width: 118px;
}

#pgp_block .three_dots {
text-align: center;
width: 25px;
Expand Down
13 changes: 13 additions & 0 deletions extension/js/common/core/crypto/pgp/openpgp-key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,19 @@ export class OpenPGPKey {
return nonDummyPrvPackets.every(p => p.isDecrypted());
}

public static async checkPublicKeyError(pubkey: Key): Promise<string | undefined> {
try {
const key = await OpenPGPKey.extractExternalLibraryObjFromKey(pubkey);
await opgp.encrypt({
message: await opgp.createMessage({ text: OpenPGPKey.encryptionText }),
encryptionKeys: key.toPublic(),
format: 'armored',
});
return undefined;
} catch (err) {
return String(err);
}
}
public static isFullyEncrypted(key: OpenPGP.PrivateKey): boolean {
const nonDummyPrvPackets = OpenPGPKey.getPrvPackets(key);
return nonDummyPrvPackets.every(p => !p.isDecrypted());
Expand Down
1 change: 1 addition & 0 deletions test/source/tests/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ export const defineSettingsTests = (testVariant: TestVariant, testWithBrowser: T
const firstFrameId = /frameId=.*?&/s.exec(framesUrls[0])![0];
const errorFrame = await contactsFrame.getFrame(['pgp_pubkey.htm', firstFrameId]);
await errorFrame.waitForContent('@error-introduce-label', 'This OpenPGP key is not usable.');
await errorFrame.waitForContent('@error-introduce-label', 'Could not verify primary key: dsa keys are considered too weak');
await errorFrame.waitForInputValue('@error-email-input', '[email protected]');
})
);
Expand Down
Loading