mirror of
https://github.com/openpgpjs/openpgpjs.git
synced 2025-11-24 14:35:51 +00:00
PrivateKey.getDecryptionKeys: do not return public key packets
This commit is contained in:
parent
36308615ad
commit
84d7d12c83
5
openpgp.d.ts
vendored
5
openpgp.d.ts
vendored
@ -383,7 +383,7 @@ declare abstract class BasePublicKeyPacket extends BasePacket {
|
|||||||
public hasSameFingerprintAs(other: BasePublicKeyPacket): boolean;
|
public hasSameFingerprintAs(other: BasePublicKeyPacket): boolean;
|
||||||
public getCreationTime(): Date;
|
public getCreationTime(): Date;
|
||||||
public getKeyID(): KeyID;
|
public getKeyID(): KeyID;
|
||||||
public isDecrypted(): boolean;
|
public isDecrypted(): boolean | null;
|
||||||
public publicParams: object;
|
public publicParams: object;
|
||||||
// `isSubkey` is a dummy method to ensure that Subkey packets are not accepted as Key one, and vice versa.
|
// `isSubkey` is a dummy method to ensure that Subkey packets are not accepted as Key one, and vice versa.
|
||||||
// The key class hierarchy is already modelled to cover this, but the concrete key packet classes
|
// The key class hierarchy is already modelled to cover this, but the concrete key packet classes
|
||||||
@ -394,11 +394,13 @@ declare abstract class BasePublicKeyPacket extends BasePacket {
|
|||||||
export class PublicKeyPacket extends BasePublicKeyPacket {
|
export class PublicKeyPacket extends BasePublicKeyPacket {
|
||||||
static readonly tag: enums.packet.publicKey;
|
static readonly tag: enums.packet.publicKey;
|
||||||
protected isSubkey(): false;
|
protected isSubkey(): false;
|
||||||
|
public isDecrypted(): null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class PublicSubkeyPacket extends BasePublicKeyPacket {
|
export class PublicSubkeyPacket extends BasePublicKeyPacket {
|
||||||
static readonly tag: enums.packet.publicSubkey;
|
static readonly tag: enums.packet.publicSubkey;
|
||||||
protected isSubkey(): true;
|
protected isSubkey(): true;
|
||||||
|
public isDecrypted(): null;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare abstract class BaseSecretKeyPacket extends BasePublicKeyPacket {
|
declare abstract class BaseSecretKeyPacket extends BasePublicKeyPacket {
|
||||||
@ -406,6 +408,7 @@ declare abstract class BaseSecretKeyPacket extends BasePublicKeyPacket {
|
|||||||
public encrypt(passphrase: string, config?: Config): Promise<void>; // throws on error
|
public encrypt(passphrase: string, config?: Config): Promise<void>; // throws on error
|
||||||
public decrypt(passphrase: string): Promise<void>; // throws on error
|
public decrypt(passphrase: string): Promise<void>; // throws on error
|
||||||
public validate(): Promise<void>; // throws on error
|
public validate(): Promise<void>; // throws on error
|
||||||
|
public isDecrypted(): boolean;
|
||||||
public isDummy(): boolean;
|
public isDummy(): boolean;
|
||||||
public isMissingSecretKeyMaterial(): boolean;
|
public isMissingSecretKeyMaterial(): boolean;
|
||||||
public makeDummy(config?: Config): void;
|
public makeDummy(config?: Config): void;
|
||||||
|
|||||||
@ -469,3 +469,5 @@ export function checkKeyRequirements(keyPacket, config) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const isPublicOrDummyKeyPacket = keyPacket => keyPacket.isDecrypted() === null || keyPacket.isDummy();
|
||||||
|
|||||||
@ -274,8 +274,8 @@ class Key {
|
|||||||
throw util.wrapError('Could not verify primary key', err);
|
throw util.wrapError('Could not verify primary key', err);
|
||||||
}
|
}
|
||||||
const subkeys = this.subkeys.slice().sort((a, b) => {
|
const subkeys = this.subkeys.slice().sort((a, b) => {
|
||||||
const aIsPrivate = a.isDecrypted() !== null && !a.isDummy();
|
const aIsPrivate = !helper.isPublicOrDummyKeyPacket(a.keyPacket);
|
||||||
const bIsPrivate = b.isDecrypted() !== null && !b.isDummy();
|
const bIsPrivate = !helper.isPublicOrDummyKeyPacket(b.keyPacket);
|
||||||
const diffIsPrivate = bIsPrivate - aIsPrivate;
|
const diffIsPrivate = bIsPrivate - aIsPrivate;
|
||||||
// return non-dummy private (sub)keys first
|
// return non-dummy private (sub)keys first
|
||||||
return diffIsPrivate !== 0 ? diffIsPrivate : b.keyPacket.created - a.keyPacket.created;
|
return diffIsPrivate !== 0 ? diffIsPrivate : b.keyPacket.created - a.keyPacket.created;
|
||||||
|
|||||||
@ -83,8 +83,8 @@ class PrivateKey extends PublicKey {
|
|||||||
let exception = null;
|
let exception = null;
|
||||||
for (let i = 0; i < this.subkeys.length; i++) {
|
for (let i = 0; i < this.subkeys.length; i++) {
|
||||||
if (!keyID || this.subkeys[i].getKeyID().equals(keyID, true)) {
|
if (!keyID || this.subkeys[i].getKeyID().equals(keyID, true)) {
|
||||||
if (this.subkeys[i].keyPacket.isDummy()) {
|
if (helper.isPublicOrDummyKeyPacket(this.subkeys[i].keyPacket)) {
|
||||||
exception = exception || new Error('Gnu-dummy key packets cannot be used for decryption');
|
exception = exception || new Error('Public or gnu-dummy key packets cannot be used for decryption');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,8 +103,8 @@ class PrivateKey extends PublicKey {
|
|||||||
// evaluate primary key
|
// evaluate primary key
|
||||||
const selfCertification = await this.getPrimarySelfSignature(date, userID, config);
|
const selfCertification = await this.getPrimarySelfSignature(date, userID, config);
|
||||||
if ((!keyID || primaryKey.getKeyID().equals(keyID, true)) && helper.validateDecryptionKeyPacket(primaryKey, selfCertification, config)) {
|
if ((!keyID || primaryKey.getKeyID().equals(keyID, true)) && helper.validateDecryptionKeyPacket(primaryKey, selfCertification, config)) {
|
||||||
if (primaryKey.isDummy()) {
|
if (helper.isPublicOrDummyKeyPacket(primaryKey)) {
|
||||||
exception = exception || new Error('Gnu-dummy key packets cannot be used for decryption');
|
exception = exception || new Error('Public or gnu-dummy key packets cannot be used for decryption');
|
||||||
} else {
|
} else {
|
||||||
keys.push(this);
|
keys.push(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3019,6 +3019,64 @@ export default () => describe('Key', function() {
|
|||||||
expect(key.write()).to.deep.equal(expectedSerializedKey.data);
|
expect(key.write()).to.deep.equal(expectedSerializedKey.data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Parsing armored key with public primary key and private subkeys', async function() {
|
||||||
|
// public primary key with:
|
||||||
|
// - one signing private subkey
|
||||||
|
// - one signing public subkey
|
||||||
|
// - one encryption private subkey
|
||||||
|
// - one encryption public subkey
|
||||||
|
const privateKeyWithPublicKeyPackets = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||||
|
|
||||||
|
xjMEZr9cyxYJKwYBBAHaRw8BAQdAlC7g7Q4UZmN5zNhFynWuEXYn1KV8Jfp4
|
||||||
|
DMiKf8ZQ5oDNDzx0ZXN0QHRlc3QuY29tPsLAEwQTFgoAhQWCZr9cywMLCQcJ
|
||||||
|
kPhnPZ0LDe1wRRQAAAAAABwAIHNhbHRAbm90YXRpb25zLm9wZW5wZ3Bqcy5v
|
||||||
|
cmeWobLLkXmgpg9Pet9xOLiKvUAGKchlrMxBubhvTpBGygUVCAoMDgQWAAIB
|
||||||
|
AhkBApsDAh4BFiEEYmvn2jb9uzAG41Ql+Gc9nQsN7XAAAHGyAP9URiF2uq/O
|
||||||
|
8PJkjoehixMx9h9a8L+lPd56ymbdxUb/swEA0tNWA9alk/m3rml0aTPNucuG
|
||||||
|
Aj/FLBixvbva+SWEkgrOMwRmv1zLFgkrBgEEAdpHDwEBB0DdyjGHiVCA0Cbr
|
||||||
|
5u5pcuZmYZylLDURujjhEWYcLKIg0MLAuwQYFgoBLQWCZr9cywmQ+Gc9nQsN
|
||||||
|
7XBFFAAAAAAAHAAgc2FsdEBub3RhdGlvbnMub3BlbnBncGpzLm9yZ5UtjGIA
|
||||||
|
N+2fOlsIv9vwi5MaTUxoXXc+Mw6ETjRvW3fUApsCvKAEGRYKAG0Fgma/XMsJ
|
||||||
|
kHC3NLlxFk7wRRQAAAAAABwAIHNhbHRAbm90YXRpb25zLm9wZW5wZ3Bqcy5v
|
||||||
|
cme74M+JTJ/Clb0bApLqL/QGKOZbaXdL3Y/p02QX2o6AgRYhBFFraL50hRm3
|
||||||
|
RC4PZHC3NLlxFk7wAABAgwEAhQ+EgvirBcabNlmHV6nEbqyTz85oBj8SKNM2
|
||||||
|
d+tDQ3YBAN3jXoPGx22sVoy5rAMerwq1lhnlgCh4xfdTw1jtr2QEFiEEYmvn
|
||||||
|
2jb9uzAG41Ql+Gc9nQsN7XAAALGsAQCCDkhWJRgiCoHIvjWwRqVWU1BsVaj5
|
||||||
|
dr6fxkK9yaOv6QEA+JjqAgPcRo/LGHpO0dZS9qi1Zpy4u5bT2FunXqvNDQ7O
|
||||||
|
MwRmv1zLFgkrBgEEAdpHDwEBB0A4CyxR5ZSvF8FrEhjzFO8W6paAtqm92p7k
|
||||||
|
+HQC7TRhKcLAuwQYFgoBLQWCZr9cywmQ+Gc9nQsN7XBFFAAAAAAAHAAgc2Fs
|
||||||
|
dEBub3RhdGlvbnMub3BlbnBncGpzLm9yZ8eA420LE1oqZm9UQ2mAl0VpYysv
|
||||||
|
9w9FhamakpSbum0jApsCvKAEGRYKAG0Fgma/XMsJkMrApZFFMT1MRRQAAAAA
|
||||||
|
ABwAIHNhbHRAbm90YXRpb25zLm9wZW5wZ3Bqcy5vcmcyU0rvMw4GVCasfsGO
|
||||||
|
ke8VBnf9DX73KF4Fuw5HRwy65BYhBPmjv8j7/15Fu3bvL8rApZFFMT1MAADv
|
||||||
|
OgEAp2P/olg/8frAKhZNhBNNcnZ3mBPgw+jnVB2q3lJR3G4A/Az8kxPmyhmf
|
||||||
|
vaorTRswb2d7xes3ubunWLvHBcU+LSAIFiEEYmvn2jb9uzAG41Ql+Gc9nQsN
|
||||||
|
7XAAAO9CAP4y3wh7tKf5QkWhz18Lo2Zjqv4S+rCVJZWe9SDRFJq4rwD/eJTb
|
||||||
|
wFTiP1x1KHQY+bnZQUll10A9c/G9yMrOC0qR8gHHXQRmv1zLEgorBgEEAZdV
|
||||||
|
AQUBAQdAdWmLtTwhcOH7tlr+2FEysYY3Z6gPpP6EalQnbXEHKRsDAQgHAAD/
|
||||||
|
ROS5zCtNP0O2t9U7T/Cs2+n1snTVW+RBTbESM+hjWfgTIcK+BBgWCgBwBYJm
|
||||||
|
v1zLCZD4Zz2dCw3tcEUUAAAAAAAcACBzYWx0QG5vdGF0aW9ucy5vcGVucGdw
|
||||||
|
anMub3JniqUd+21Sxr5oHb+ctdQKLEpRYCSR1I0Ap/Z5o3XfqRACmwwWIQRi
|
||||||
|
a+faNv27MAbjVCX4Zz2dCw3tcAAABPQBAK7S2Izm3D4dEkoJb869wOqtK4be
|
||||||
|
zdP4cdQMfO/4hsLRAPwMxCX51Okaj/SvwEzjI/RCPmfv9l441PmzQheQ4Gqr
|
||||||
|
BM44BGa/XMsSCisGAQQBl1UBBQEBB0CqHCGPBZg8ioGvjV4nKteCFs4hAzLn
|
||||||
|
nFHyv2RF+YdFJgMBCAfCvgQYFgoAcAWCZr9cywmQ+Gc9nQsN7XBFFAAAAAAA
|
||||||
|
HAAgc2FsdEBub3RhdGlvbnMub3BlbnBncGpzLm9yZw1hBEkI2dXfJXMVH/ha
|
||||||
|
uCz6Opp4tu616/VBZWGParIfApsMFiEEYmvn2jb9uzAG41Ql+Gc9nQsN7XAA
|
||||||
|
ABWvAQDZznAKuYpaWKklOVw2z8fgLP6sL9ai+zBjlWogKoswNgEAoXTZ1SOJ
|
||||||
|
bWGFbTrrvSBYui/idHvj8Tax0EDVVw6W1Qc=
|
||||||
|
=OKHa
|
||||||
|
-----END PGP PRIVATE KEY BLOCK-----` });
|
||||||
|
|
||||||
|
expect(privateKeyWithPublicKeyPackets.isDecrypted()).to.be.true;
|
||||||
|
expect(privateKeyWithPublicKeyPackets.isPrivate()).to.be.true;
|
||||||
|
const signingKey = await privateKeyWithPublicKeyPackets.getSigningKey();
|
||||||
|
expect(signingKey.getKeyID().equals(privateKeyWithPublicKeyPackets.subkeys[0].getKeyID())).to.be.true;
|
||||||
|
const decryptedKeys = await privateKeyWithPublicKeyPackets.getDecryptionKeys();
|
||||||
|
expect(decryptedKeys.length).to.equal(1);
|
||||||
|
expect(decryptedKeys[0].getKeyID().equals(privateKeyWithPublicKeyPackets.subkeys[2].getKeyID())).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
it('Parses V5 sample key', async function() {
|
it('Parses V5 sample key', async function() {
|
||||||
// sec ed25519 2019-03-20 [SC]
|
// sec ed25519 2019-03-20 [SC]
|
||||||
// 19347BC9872464025F99DF3EC2E0000ED9884892E1F7B3EA4C94009159569B54
|
// 19347BC9872464025F99DF3EC2E0000ED9884892E1F7B3EA4C94009159569B54
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user