Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 53
Show warnings on unusable keys#3198
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
31805dd4b5a769834630f58484ca18d4c2450115ce1fdd960bb53a8a5f04d4fbbf23162c7337e114aee6File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -13,6 +13,9 @@ export class OpenPGPKey { | ||
| private static readonly encryptionText = 'This is the text we are encrypting!'; | ||
| // mapping of algo names to required param count, lazy initialized | ||
| private static paramCountByAlgo: { [key: string]: number }; | ||
| public static parse = async (text: string): Promise<Key> => { | ||
| // TODO: Should we throw if more keys are in the armor? | ||
| return (await OpenPGPKey.parseMany(text))[0]; | ||
| @@ -192,13 +195,26 @@ export class OpenPGPKey { | ||
| } | ||
| const algoInfo = opgpKey.primaryKey.getAlgorithmInfo(); | ||
| const key = keyToUpdate || {} as Key; // if no key to update, use empty object, will get props assigned below | ||
| const encryptionKey = await Catch.undefinedOnException(opgpKey.getEncryptionKey()); | ||
| const getEncryptionKey = (keyid?: OpenPGP.Keyid | null, date?: Date, userId?: OpenPGP.UserId | null) => | ||
| opgpKey.getEncryptionKey(keyid, date, userId); | ||
| const encryptionKeyIgnoringExpiration = encryptionKey ? encryptionKey : await OpenPGPKey.getKeyIgnoringExpiration(getEncryptionKey, exp, expired); | ||
Collaborator There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can use a ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just forgot about this operator 😊 | ||
| const signingKey = await Catch.undefinedOnException(opgpKey.getSigningKey()); | ||
| const getSigningKey = (keyid?: OpenPGP.Keyid | null, date?: Date, userId?: OpenPGP.UserId | null) => | ||
| opgpKey.getSigningKey(keyid, date, userId); | ||
| const signingKeyIgnoringExpiration = signingKey ? signingKey : await OpenPGPKey.getKeyIgnoringExpiration(getSigningKey, exp, expired); | ||
| const missingPrivateKeyForSigning = signingKeyIgnoringExpiration?.keyPacket ? OpenPGPKey.arePrivateParamsMissing(signingKeyIgnoringExpiration.keyPacket) : false; | ||
| const missingPrivateKeyForDecryption = encryptionKeyIgnoringExpiration?.keyPacket ? OpenPGPKey.arePrivateParamsMissing(encryptionKeyIgnoringExpiration.keyPacket) : false; | ||
| Object.assign(key, { | ||
| type: 'openpgp', | ||
| id: fingerprint.toUpperCase(), | ||
| allIds: opgpKey.getKeys().map(k => k.getFingerprint().toUpperCase()), | ||
| usableForEncryption: ! await Catch.doesReject(opgpKey.getEncryptionKey()), | ||
| usableButExpired: await OpenPGPKey.usableButExpired(opgpKey, exp, expired), | ||
| usableForSigning: ! await Catch.doesReject(opgpKey.getSigningKey()), | ||
| usableForEncryption: encryptionKey ? true : false, | ||
| usableForEncryptionButExpired: !encryptionKey && !!encryptionKeyIgnoringExpiration, | ||
| usableForSigning: signingKey ? true : false, | ||
| usableForSigningButExpired: !signingKey && !!signingKeyIgnoringExpiration, | ||
| missingPrivateKeyForSigning, | ||
| missingPrivateKeyForDecryption, | ||
| // valid emails extracted from uids | ||
| emails, | ||
| // full uids that have valid emails in them | ||
| @@ -421,27 +437,43 @@ export class OpenPGPKey { | ||
| return raw; | ||
| } | ||
| private static usableButExpired = async (key: OpenPGP.key.Key, exp: Date | number | null, expired: () => boolean): Promise<boolean> => { | ||
| if (!key) { | ||
| return false; | ||
| } | ||
| if (! await Catch.doesReject(key.getEncryptionKey())) { | ||
| return false; | ||
| private static getKeyIgnoringExpiration = async ( | ||
| getter: (keyid?: OpenPGP.Keyid | null, date?: Date, userId?: OpenPGP.UserId | null) => Promise<OpenPGP.key.Key | OpenPGP.key.SubKey | null>, | ||
| exp: Date | number | null, | ||
| expired: () => boolean): Promise<OpenPGP.key.Key | OpenPGP.key.SubKey | null> => { | ||
| const firstTry = await Catch.undefinedOnException(getter()); | ||
| if (firstTry) { | ||
| return firstTry; | ||
| } | ||
| if (exp === null || typeof exp === 'number') { | ||
| // If key does not expire (exp == Infinity) the encryption key should be available. | ||
| return false; | ||
| return null; // tslint:disable-line:no-null-keyword | ||
| } | ||
| const oneSecondBeforeExpiration = exp && expired() ? new Date(exp.getTime() - 1000) : undefined; | ||
| if (typeof oneSecondBeforeExpiration === 'undefined') { | ||
| return false; | ||
| } | ||
| try { | ||
| await key.getEncryptionKey(undefined, oneSecondBeforeExpiration); | ||
| return true; | ||
| } catch (e) { | ||
| return false; | ||
| return null; // tslint:disable-line:no-null-keyword | ||
| } | ||
| const secondTry = await Catch.undefinedOnException(getter(undefined, oneSecondBeforeExpiration)); | ||
| return secondTry ? secondTry : null; // tslint:disable-line:no-null-keyword | ||
| } | ||
| private static arePrivateParamsMissing = (packet: OpenPGP.packet.BaseKeyPacket): boolean => { | ||
rrrooommmaaa marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| // detection of missing private params to solve #2887 | ||
| if (!OpenPGPKey.paramCountByAlgo) { | ||
| OpenPGPKey.paramCountByAlgo = { | ||
| [opgp.enums.read(opgp.enums.publicKey, opgp.enums.publicKey.rsa_encrypt)]: 6, | ||
| [opgp.enums.read(opgp.enums.publicKey, opgp.enums.publicKey.rsa_encrypt_sign)]: 6, | ||
| [opgp.enums.read(opgp.enums.publicKey, opgp.enums.publicKey.rsa_sign)]: 6, | ||
| [opgp.enums.read(opgp.enums.publicKey, opgp.enums.publicKey.dsa)]: 5, | ||
| [opgp.enums.read(opgp.enums.publicKey, opgp.enums.publicKey.elgamal)]: 4, | ||
| [opgp.enums.read(opgp.enums.publicKey, opgp.enums.publicKey.ecdsa)]: 2, | ||
| [opgp.enums.read(opgp.enums.publicKey, opgp.enums.publicKey.ecdh)]: 3, | ||
| [opgp.enums.read(opgp.enums.publicKey, opgp.enums.publicKey.eddsa)]: 3, | ||
| }; | ||
| } | ||
| return packet.algorithm | ||
| && !packet.isEncrypted // isDecrypted() returns false when isEncrypted is null | ||
| && OpenPGPKey.paramCountByAlgo[packet.algorithm] > packet.params?.length; | ||
| } | ||
| private static testEncryptDecrypt = async (key: OpenPGP.key.Key): Promise<string[]> => { | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much better! (for me)