mirror of
https://github.com/openpgpjs/openpgpjs.git
synced 2025-11-26 07:25:51 +00:00
Add support for parsing transferable private keys with a primary public key and public subkeys
This commit is contained in:
parent
ada794cab6
commit
1f574e0df7
@ -51,15 +51,18 @@ const allowedKeyPackets = /*#__PURE__*/ util.constructAllowedPackets([
|
||||
* @throws if no key packet was found
|
||||
*/
|
||||
function createKey(packetlist) {
|
||||
for (const packet of packetlist) {
|
||||
switch (packet.constructor.tag) {
|
||||
case enums.packet.secretKey:
|
||||
return new PrivateKey(packetlist);
|
||||
case enums.packet.publicKey:
|
||||
return new PublicKey(packetlist);
|
||||
if (packetlist[0]?.constructor.tag === enums.packet.secretKey) {
|
||||
return new PrivateKey(packetlist);
|
||||
} else if (packetlist[0]?.constructor.tag === enums.packet.publicKey) {
|
||||
if (packetlist.findPacket(enums.packet.secretSubkey)) {
|
||||
return new PrivateKey(packetlist);
|
||||
} else {
|
||||
return new PublicKey(packetlist);
|
||||
}
|
||||
} else {
|
||||
throw new Error('No primary key packet found');
|
||||
}
|
||||
throw new Error('No key packet found');
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -384,10 +387,10 @@ export async function readPrivateKey({ armoredKey, binaryKey, config, ...rest })
|
||||
const packetlist = await PacketList.fromBinary(input, allowedKeyPackets, config);
|
||||
const keyIndex = packetlist.indexOfTag(enums.packet.publicKey, enums.packet.secretKey);
|
||||
for (let i = 0; i < keyIndex.length; i++) {
|
||||
if (packetlist[keyIndex[i]].constructor.tag === enums.packet.publicKey) {
|
||||
const firstPrivateKeyList = packetlist.slice(keyIndex[i], keyIndex[i + 1]);
|
||||
if (packetlist[keyIndex[i]].constructor.tag === enums.packet.publicKey && !firstPrivateKeyList.findPacket(enums.packet.secretSubkey)) {
|
||||
continue;
|
||||
}
|
||||
const firstPrivateKeyList = packetlist.slice(keyIndex[i], keyIndex[i + 1]);
|
||||
return new PrivateKey(firstPrivateKeyList);
|
||||
}
|
||||
throw new Error('No secret key packet found');
|
||||
@ -471,10 +474,10 @@ export async function readPrivateKeys({ armoredKeys, binaryKeys, config }) {
|
||||
const packetlist = await PacketList.fromBinary(input, allowedKeyPackets, config);
|
||||
const keyIndex = packetlist.indexOfTag(enums.packet.publicKey, enums.packet.secretKey);
|
||||
for (let i = 0; i < keyIndex.length; i++) {
|
||||
if (packetlist[keyIndex[i]].constructor.tag === enums.packet.publicKey) {
|
||||
const oneKeyList = packetlist.slice(keyIndex[i], keyIndex[i + 1]);
|
||||
if (packetlist[keyIndex[i]].constructor.tag === enums.packet.publicKey && !oneKeyList.findPacket(enums.packet.secretSubkey)) {
|
||||
continue;
|
||||
}
|
||||
const oneKeyList = packetlist.slice(keyIndex[i], keyIndex[i + 1]);
|
||||
const newKey = new PrivateKey(oneKeyList);
|
||||
keys.push(newKey);
|
||||
}
|
||||
|
||||
@ -49,13 +49,14 @@ class Key {
|
||||
/**
|
||||
* Transforms packetlist to structured key data
|
||||
* @param {PacketList} packetlist - The packets that form a key
|
||||
* @param {Set<enums.packet>} disallowedPackets - disallowed packet tags
|
||||
* @param {Boolean} expectPrivateKey - if a private key is expected, a SecretKeyPacket or SecretKeySubpacket must be present.
|
||||
*/
|
||||
packetListToStructure(packetlist, disallowedPackets = new Set()) {
|
||||
packetListToStructure(packetlist, expectPrivateKey) {
|
||||
let user;
|
||||
let primaryKeyID;
|
||||
let subkey;
|
||||
let ignoreUntil;
|
||||
let isPrivateKey;
|
||||
|
||||
for (const packet of packetlist) {
|
||||
|
||||
@ -78,7 +79,8 @@ class Key {
|
||||
if (!ignoreUntil.has(tag)) continue;
|
||||
ignoreUntil = null;
|
||||
}
|
||||
if (disallowedPackets.has(tag)) {
|
||||
isPrivateKey = isPrivateKey || tag === enums.packet.secretKey || tag === enums.packet.secretSubkey;
|
||||
if (!expectPrivateKey && isPrivateKey) {
|
||||
throw new Error(`Unexpected packet type: ${tag}`);
|
||||
}
|
||||
switch (tag) {
|
||||
@ -151,6 +153,13 @@ class Key {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.keyPacket) {
|
||||
throw new Error('Invalid key: missing primary key packet');
|
||||
}
|
||||
if (expectPrivateKey && !isPrivateKey) {
|
||||
throw new Error('No secret key packet found');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -18,10 +18,7 @@ class PrivateKey extends PublicKey {
|
||||
*/
|
||||
constructor(packetlist) {
|
||||
super();
|
||||
this.packetListToStructure(packetlist, new Set([enums.packet.publicKey, enums.packet.publicSubkey]));
|
||||
if (!this.keyPacket) {
|
||||
throw new Error('Invalid key: missing private-key packet');
|
||||
}
|
||||
this.packetListToStructure(packetlist, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -32,10 +32,7 @@ class PublicKey extends Key {
|
||||
this.users = [];
|
||||
this.subkeys = [];
|
||||
if (packetlist) {
|
||||
this.packetListToStructure(packetlist, new Set([enums.packet.secretKey, enums.packet.secretSubkey]));
|
||||
if (!this.keyPacket) {
|
||||
throw new Error('Invalid key: missing public-key packet');
|
||||
}
|
||||
this.packetListToStructure(packetlist, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user