Drop inconsistent boolean returns and fix type definitions (#1191)

- Remove the boolean return value of various internal functions that throw on
  error (the returned value was unused in most cases)
- Update and fix type definitions
This commit is contained in:
larabr 2020-12-22 18:36:23 +01:00 committed by Daniel Huigens
parent 89f738da45
commit 2ee36c2984
15 changed files with 205 additions and 180 deletions

202
openpgp.d.ts vendored
View File

@ -16,33 +16,33 @@ export function readKeys(data: Uint8Array): Promise<Key[]>;
export function generateKey(options: KeyOptions): Promise<KeyPair>;
export function generateSessionKey(options: { publicKeys: Key[], date?: Date, toUserIds?: UserId[] }): Promise<SessionKey>;
export function decryptKey(options: { privateKey: Key; passphrase?: string | string[]; }): Promise<Key>;
export function encryptKey(options: { privateKey: Key; passphrase?: string }): Promise<Key>;
export function encryptKey(options: { privateKey: Key; passphrase?: string | string[] }): Promise<Key>;
export function reformatKey(options: { privateKey: Key; userIds?: (string | UserId)[]; passphrase?: string; keyExpirationTime?: number; }): Promise<KeyPair>;
export class Key {
constructor(packetlist: PacketList<AnyPacket>);
public primaryKey: PublicKeyPacket | SecretKeyPacket;
public subKeys: SubKey[];
public users: User[];
public revocationSignatures: SignaturePacket[];
public keyPacket: PublicKeyPacket | SecretKeyPacket;
constructor(packetlist: PacketList<AnyPacket>);
public armor(): string;
public decrypt(passphrase: string | string[], keyId?: Keyid): Promise<boolean>;
public encrypt(passphrase: string | string[]): Promise<void>;
public getExpirationTime(capability?: 'encrypt' | 'encrypt_sign' | 'sign' | null, keyId?: Keyid | null, userId?: UserId | null): Promise<Date | typeof Infinity | null>; // Returns null if `capabilities` is passed and the key does not have the specified capabilities or is revoked or invalid.
public decrypt(passphrase: string | string[], keyId?: Keyid): Promise<void>; // throws on error
public encrypt(passphrase: string | string[]): Promise<void>; // throws on error
public getExpirationTime(capability?: 'encrypt' | 'encrypt_sign' | 'sign', keyId?: Keyid, userId?: UserId): Promise<Date | typeof Infinity | null>; // Returns null if `capabilities` is passed and the key does not have the specified capabilities or is revoked or invalid.
public getKeyIds(): Keyid[];
public getPrimaryUser(): Promise<PrimaryUser>; // throws on err
public getPrimaryUser(): Promise<PrimaryUser>; // throws on error
public getUserIds(): string[];
public isPrivate(): boolean;
public isPublic(): boolean;
public toPublic(): Key;
public update(key: Key): void;
public verifyPrimaryKey(): Promise<void>; // throws on err
public verifyPrimaryKey(): Promise<void>; // throws on error
public isRevoked(): Promise<boolean>;
public revoke(reason: { flag?: enums.reasonForRevocation; string?: string; }, date?: Date): Promise<Key>;
public getRevocationCertificate(): Promise<Stream<string> | string | undefined>;
public getEncryptionKey(keyid?: Keyid | null, date?: Date, userId?: UserId | null): Promise<Key | SubKey | null>;
public getSigningKey(keyid?: Keyid | null, date?: Date, userId?: UserId | null): Promise<Key | SubKey | null>;
public getEncryptionKey(keyid?: Keyid, date?: Date | null, userId?: UserId): Promise<Key | SubKey>;
public getSigningKey(keyid?: Keyid, date?: Date | null, userId?: UserId): Promise<Key | SubKey>;
public getKeys(keyId?: Keyid): (Key | SubKey)[];
public isDecrypted(): boolean;
public getFingerprint(): string;
@ -52,11 +52,10 @@ export class Key {
}
export class SubKey {
public subKey: SecretSubkeyPacket | PublicSubkeyPacket;
public keyPacket: SecretKeyPacket;
constructor(subKeyPacket: SecretSubkeyPacket | PublicSubkeyPacket);
public keyPacket: SecretSubkeyPacket | PublicSubkeyPacket;
public bindingSignatures: SignaturePacket[];
public revocationSignatures: SignaturePacket[];
constructor(subKeyPacket: SecretSubkeyPacket | PublicSubkeyPacket);
public verify(primaryKey: PublicKeyPacket | SecretKeyPacket): Promise<enums.keyStatus>;
public isDecrypted(): boolean;
public getFingerprint(): string;
@ -80,7 +79,8 @@ export interface PrimaryUser {
type AlgorithmInfo = {
algorithm: enums.publicKeyNames;
bits: number;
bits?: number;
curve?: EllipticCurveName;
};
/* ############## v5 SIG #################### */
@ -94,7 +94,7 @@ export class Signature {
public armor(): string;
}
export interface VerificationResult {
interface VerificationResult {
keyid: Keyid;
verified: Promise<null | boolean>;
signature: Promise<Signature>;
@ -113,7 +113,7 @@ export class CleartextMessage {
/** Returns the key IDs of the keys that signed the cleartext message
*/
getSigningKeyIds(): Array<Keyid>;
getSigningKeyIds(): Keyid[];
/** Get cleartext
*/
@ -123,7 +123,7 @@ export class CleartextMessage {
*
* @param privateKeys private keys with decrypted secret key data for signing
*/
sign(privateKeys: Array<Key>): void;
sign(privateKeys: Key[]): void;
/** Verify signatures of cleartext signed message
* @param keys array of keys to verify signatures
@ -258,7 +258,7 @@ export class Message<T extends MaybeStream<Data>> {
/** Get literal data that is the body of the message
*/
public getLiteralData(): Uint8Array | null | Stream<Uint8Array>;
public getLiteralData(): Uint8Array | Stream<Uint8Array> | null;
/** Returns the key IDs of the keys that signed the message
*/
@ -266,7 +266,7 @@ export class Message<T extends MaybeStream<Data>> {
/** Get literal data as text
*/
public getText(): string | null | Stream<string>;
public getText(): string | Stream<string> | null;
public getFilename(): string | null;
@ -324,32 +324,54 @@ export namespace config {
/* ############## v5 PACKET #################### */
declare class BasePacket {
declare abstract class BasePacket {
public tag: enums.packet;
public read(bytes: Uint8Array): void;
public write(): Uint8Array;
}
declare class BaseKeyPacket extends BasePacket {
// fingerprint: Uint8Array|null; - not included because not recommended to use. Use getFingerprint() or getFingerprintBytes()
/**
* The relationship between the KeyPacket classes is modeled by considering the following:
* - A Secret (Sub)Key Packet can always be used when a Public one is expected.
* - A Subkey Packet cannot always be used when a Primary Key Packet is expected (and vice versa).
*/
declare abstract class BasePublicKeyPacket extends BasePacket {
public algorithm: enums.publicKey;
public created: Date;
public version: number;
public expirationTimeV3: number | null;
public keyExpirationTime: number | null;
public getBitSize(): number;
public getAlgorithmInfo(): AlgorithmInfo;
public getFingerprint(): string;
public getFingerprintBytes(): Uint8Array | null;
public hasSameFingerprintAs(other: BasePublicKeyPacket): boolean;
public getCreationTime(): Date;
public getKeyId(): Keyid;
public params: object[];
public isDecrypted(): boolean;
public isEncrypted: boolean; // may be null, false or true
public publicParams: object;
}
declare class BasePrimaryKeyPacket extends BaseKeyPacket {
export class PublicKeyPacket extends BasePublicKeyPacket {
public tag: enums.packet.publicKey;
}
export class PublicSubkeyPacket extends BasePublicKeyPacket {
public tag: enums.packet.publicSubkey;
}
declare abstract class BaseSecretKeyPacket extends BasePublicKeyPacket {
public privateParams: object | null;
public encrypt(passphrase: string): Promise<void>; // throws on error
public decrypt(passphrase: string): Promise<void>; // throws on error
public validate(): Promise<void>; // throws on error
public isDummy(): boolean;
public makeDummy(): void;
}
export class SecretKeyPacket extends BaseSecretKeyPacket {
public tag: enums.packet.secretKey;
}
export class SecretSubkeyPacket extends BaseSecretKeyPacket {
public tag: enums.packet.secretSubkey;
}
export class CompressedDataPacket extends BasePacket {
@ -376,10 +398,6 @@ export class LiteralDataPacket extends BasePacket {
public tag: enums.packet.literalData;
}
export class PublicKeyPacket extends BasePrimaryKeyPacket {
public tag: enums.packet.publicKey;
}
export class SymmetricallyEncryptedDataPacket extends BasePacket {
public tag: enums.packet.symmetricallyEncryptedData;
}
@ -388,10 +406,6 @@ export class MarkerPacket extends BasePacket {
public tag: enums.packet.marker;
}
export class PublicSubkeyPacket extends BaseKeyPacket {
public tag: enums.packet.publicSubkey;
}
export class UserAttributePacket extends BasePacket {
public tag: enums.packet.userAttribute;
}
@ -401,33 +415,17 @@ export class OnePassSignaturePacket extends BasePacket {
public correspondingSig?: Promise<SignaturePacket>;
}
export class SecretKeyPacket extends BasePrimaryKeyPacket {
public tag: enums.packet.secretKey;
// encrypted: null | unknown[]; // Encrypted secret-key data, not meant for public use
public s2k: { type: string } | null;
public encrypt(passphrase: string): Promise<boolean>;
public decrypt(passphrase: string): Promise<true>;
}
export class UserIDPacket extends BasePacket {
public tag: enums.packet.userID;
public userid: string;
}
export class SecretSubkeyPacket extends BaseKeyPacket {
public tag: enums.packet.secretSubkey;
// encrypted: null | unknown[]; // Encrypted secret-key data, not meant for public use
public s2k: { type: string } | null;
public encrypt(passphrase: string): Promise<boolean>;
public decrypt(passphrase: string): Promise<true>;
}
export class SignaturePacket extends BasePacket {
public tag: enums.packet.signature;
public version: number;
public signatureType: null | number;
public hashAlgorithm: null | number;
public publicKeyAlgorithm: null | number;
public signatureType: enums.signature | null;
public hashAlgorithm: enums.hash | null;
public publicKeyAlgorithm: enums.publicKey | null;
public signatureData: null | Uint8Array;
public unhashedSubpackets: null | Uint8Array;
public signedHashValue: null | Uint8Array;
@ -441,33 +439,34 @@ export class SignaturePacket extends BasePacket {
public revocable: null | boolean;
public keyExpirationTime: null | number;
public keyNeverExpires: null | boolean;
public preferredSymmetricAlgorithms: null | number[];
public preferredSymmetricAlgorithms: enums.symmetric[] | null;
public revocationKeyClass: null | number;
public revocationKeyAlgorithm: null | number;
public revocationKeyAlgorithm: null | enums.publicKey;
public revocationKeyFingerprint: null | Uint8Array;
public issuerKeyId: Keyid;
public notation: null | { [name: string]: string };
public preferredHashAlgorithms: null | number[];
public preferredCompressionAlgorithms: null | number[];
public preferredHashAlgorithms: enums.hash[] | null;
public preferredCompressionAlgorithms: enums.compression[] | null;
public keyServerPreferences: null | number[];
public preferredKeyServer: null | string;
public isPrimaryUserID: null | boolean;
public policyURI: null | string;
public keyFlags: null | number[];
public keyFlags: Uint8Array | null;
public signersUserId: null | string;
public reasonForRevocationFlag: null | number;
public reasonForRevocationFlag: null | enums.reasonForRevocation;
public reasonForRevocationString: null | string;
public features: null | number[];
public signatureTargetPublicKeyAlgorithm: null | number;
public signatureTargetHashAlgorithm: null | number;
public features: Uint8Array | null;
public signatureTargetPublicKeyAlgorithm: enums.publicKey | null;
public signatureTargetHashAlgorithm: enums.hash | null;
public signatureTargetHash: null | string;
public embeddedSignature: null | SignaturePacket;
public issuerKeyVersion: null | number;
public issuerFingerprint: null | Uint8Array;
public preferredAeadAlgorithms: null | Uint8Array;
public preferredAeadAlgorithms: enums.aead[] | null;
public verified: null | boolean;
public revoked: null | boolean;
public sign(key: SecretKeyPacket | SecretSubkeyPacket, data: Uint8Array): true;
public sign(key: AnySecretKeyPacket, data: Uint8Array, detached?: boolean, streaming?: boolean): Promise<void>;
public verify(key: AnyKeyPacket, signatureType: enums.signature, data: Uint8Array, detached?: boolean, streaming?: boolean): Promise<void>; // throws on error
public isExpired(date?: Date): boolean;
public getExpirationTime(): Date | typeof Infinity;
}
@ -476,10 +475,9 @@ export class TrustPacket extends BasePacket {
public tag: enums.packet.trust;
}
export type AnyPacket = CompressedDataPacket | SymEncryptedIntegrityProtectedDataPacket | AEADEncryptedDataPacket | PublicKeyEncryptedSessionKeyPaclet | SymEncryptedSessionKey | LiteralDataPacket
| PublicKeyPacket | SymmetricallyEncryptedDataPacket | MarkerPacket | PublicSubkeyPacket | UserAttributePacket | OnePassSignaturePacket | SecretKeyPacket | UserIDPacket | SecretSubkeyPacket | SignaturePacket | TrustPacket;
export type AnySecretPacket = SecretKeyPacket | SecretSubkeyPacket;
export type AnyKeyPacket = PublicKeyPacket | SecretKeyPacket | PublicSubkeyPacket | SecretSubkeyPacket;
export type AnyPacket = BasePacket;
export type AnySecretKeyPacket = SecretKeyPacket | SecretSubkeyPacket;
export type AnyKeyPacket = BasePublicKeyPacket;
type DataPacketType = 'utf8' | 'binary' | 'text' | 'mime';
@ -531,7 +529,7 @@ export namespace stream {
/* ############## v5 GENERAL #################### */
export interface UserId { name?: string; email?: string; }
export interface UserId { name?: string; email?: string; comment?: string; }
export interface SessionKey { data: Uint8Array; algorithm: string; }
@ -564,7 +562,7 @@ interface EncryptOptions {
toUserId?: UserId;
}
export interface DecryptOptions {
interface DecryptOptions {
/** the message object with the encrypted data */
message: Message<MaybeStream<Data>>;
/** (optional) private keys with decrypted secret key data or session key */
@ -585,7 +583,7 @@ export interface DecryptOptions {
date?: Date;
}
export interface SignOptions {
interface SignOptions {
message: CleartextMessage | Message<MaybeStream<Data>>;
privateKeys?: Key | Key[];
armor?: boolean;
@ -596,7 +594,7 @@ export interface SignOptions {
fromUserId?: UserId;
}
export interface VerifyOptions {
interface VerifyOptions {
/** array of publicKeys or single key, to verify signatures */
publicKeys: Key | Key[];
/** (cleartext) message object with signatures */
@ -611,15 +609,16 @@ export interface VerifyOptions {
date?: Date;
}
export interface KeyPair {
interface KeyPair {
key: Key;
privateKeyArmored: string;
publicKeyArmored: string;
revocationCertificate: string;
}
export type EllipticCurveName = 'curve25519' | 'p256' | 'p384' | 'p521' | 'secp256k1' | 'brainpoolP256r1' | 'brainpoolP384r1' | 'brainpoolP512r1';
export type EllipticCurveName = 'ed25519' | 'curve25519' | 'p256' | 'p384' | 'p521' | 'secp256k1' | 'brainpoolP256r1' | 'brainpoolP384r1' | 'brainpoolP512r1';
export interface KeyOptions {
interface KeyOptions {
userIds: UserId[]; // generating a key with no user defined results in error
passphrase?: string;
numBits?: number;
@ -629,17 +628,19 @@ export interface KeyOptions {
subkeys?: KeyOptions[];
}
export interface Keyid {
declare class Keyid {
bytes: string;
equals(keyid: Keyid, matchWildcard?: boolean): boolean;
toHex(): string;
}
export interface DecryptMessageResult {
interface DecryptMessageResult {
data: MaybeStream<Data>;
signatures: VerificationResult[];
filename: string;
}
export interface VerifyMessageResult {
interface VerifyMessageResult {
data: MaybeStream<Data>;
signatures: VerificationResult[];
}
@ -664,14 +665,14 @@ export class HKP {
export namespace enums {
function read(type: typeof armor, e: armor): armorNames | string | any;
function read(type: typeof compression, e: compression): compressionNames | string | any;
function read(type: typeof hash, e: hash): hashNames | string | any;
function read(type: typeof packet, e: packet): packetNames | string | any;
function read(type: typeof publicKey, e: publicKey): publicKeyNames | string | any;
function read(type: typeof symmetric, e: symmetric): symmetricNames | string | any;
function read(type: typeof keyStatus, e: keyStatus): keyStatusNames | string | any;
function read(type: typeof keyFlags, e: keyFlags): keyFlagsNames | string | any;
function read(type: typeof armor, e: armor): armorNames;
function read(type: typeof compression, e: compression): compressionNames;
function read(type: typeof hash, e: hash): hashNames;
function read(type: typeof packet, e: packet): packetNames;
function read(type: typeof publicKey, e: publicKey): publicKeyNames;
function read(type: typeof symmetric, e: symmetric): symmetricNames;
function read(type: typeof keyStatus, e: keyStatus): keyStatusNames;
function read(type: typeof keyFlags, e: keyFlags): keyFlagsNames;
export type armorNames = 'multipartSection' | 'multipartLast' | 'signed' | 'message' | 'publicKey' | 'privateKey';
enum armor {
@ -783,11 +784,34 @@ export namespace enums {
sharedPrivateKey = 128,
}
enum signature {
binary = 0,
text = 1,
standalone = 2,
certGeneric = 16,
certPersona = 17,
certCasual = 18,
certPositive = 19,
certRevocation = 48,
subkeyBinding = 24,
keyBinding = 25,
key = 31,
keyRevocation = 32,
subkeyRevocation = 40,
timestamp = 64,
thirdParty = 80
}
enum aead {
eax = 1,
ocb = 2,
experimentalGcm = 100 // Private algorithm
}
}
/* ############## v5 UTIL #################### */
export namespace util {
declare namespace util {
/** Convert a string of utf8 bytes to a native javascript string
@param utf8 A valid squence of utf8 bytes
*/

View File

@ -62,10 +62,10 @@ export async function getLatestValidSignature(signatures, primaryKey, signatureT
if (
(!signature || signatures[i].created >= signature.created) &&
// check binding signature is not expired (ie, check for V4 expiration time)
!signatures[i].isExpired(date) &&
// check binding signature is verified
(signatures[i].verified || await signatures[i].verify(primaryKey, signatureType, dataToVerify))
!signatures[i].isExpired(date)
) {
// check binding signature is verified
signatures[i].verified || await signatures[i].verify(primaryKey, signatureType, dataToVerify);
signature = signatures[i];
}
} catch (e) {
@ -278,9 +278,10 @@ export async function isDataRevoked(primaryKey, signatureType, dataToVerify, rev
// third-party key certification, which should only affect
// `verifyAllCertifications`.)
(!signature || revocationSignature.issuerKeyId.equals(signature.issuerKeyId)) &&
!(config.revocationsExpire && revocationSignature.isExpired(normDate)) &&
(revocationSignature.verified || await revocationSignature.verify(key, signatureType, dataToVerify))
!(config.revocationsExpire && revocationSignature.isExpired(normDate))
) {
revocationSignature.verified || await revocationSignature.verify(key, signatureType, dataToVerify);
// TODO get an identifier of the revoked object instead
revocationKeyIds.push(revocationSignature.issuerKeyId);
}

View File

@ -398,7 +398,7 @@ class Key {
* Encrypts all secret key and subkey packets matching keyId
* @param {String|Array<String>} passphrases - if multiple passphrases, then should be in same order as packets each should encrypt
* @param {module:type/keyid} keyId
* @returns {Promise<Array<SecretKeyPacket|SecretSubkeyPacket>>}
* @throws {Error} if encryption failed for any key or subkey
* @async
*/
async encrypt(passphrases, keyId = null) {
@ -412,11 +412,10 @@ class Key {
throw new Error("Invalid number of passphrases for key");
}
return Promise.all(keys.map(async function(key, i) {
await Promise.all(keys.map(async function(key, i) {
const { keyPacket } = key;
await keyPacket.encrypt(passphrases[i]);
keyPacket.clearPrivateParams();
return keyPacket;
}));
}
@ -449,7 +448,6 @@ class Key {
if (!decrypted) {
throw error;
}
return decrypted;
}));
if (!keyId) {
@ -536,7 +534,7 @@ class Key {
* and valid self signature. Throws if the primary key is invalid.
* @param {Date} date (optional) use the given date for verification instead of the current time
* @param {Object} userId (optional) user ID
* @returns {Promise<true>} The status of the primary key
* @throws {Error} If key verification failed
* @async
*/
async verifyPrimaryKey(date = new Date(), userId = {}) {

View File

@ -64,11 +64,11 @@ class SubKey {
/**
* Verify subkey. Checks for revocation signatures, expiration time
* and valid binding signature. Throws if the subkey is invalid.
* and valid binding signature.
* @param {SecretKeyPacket|
* PublicKeyPacket} primaryKey The primary key packet
* @param {Date} date Use the given date instead of the current time
* @returns {Promise<undefined>}
* @throws {Error} if the subkey is invalid.
* @async
*/
async verify(primaryKey, date = new Date()) {
@ -112,7 +112,7 @@ class SubKey {
* @param {module:key~SubKey} subKey Source subkey to merge
* @param {SecretKeyPacket|
SecretSubkeyPacket} primaryKey primary key used for validation
* @returns {Promise<undefined>}
* @throws {Error} if update failed
* @async
*/
async update(subKey, primaryKey) {
@ -137,7 +137,8 @@ class SubKey {
}
}
try {
return srcBindSig.verified || await srcBindSig.verify(primaryKey, enums.signature.subkeyBinding, dataToVerify);
srcBindSig.verified || await srcBindSig.verify(primaryKey, enums.signature.subkeyBinding, dataToVerify);
return true;
} catch (e) {
return false;
}

View File

@ -102,7 +102,7 @@ class User {
* @param {SignaturePacket} certificate A certificate of this user
* @param {Array<module:key.Key>} keys Array of keys to verify certificate signatures
* @param {Date} date Use the given date instead of the current time
* @returns {Promise<true>} status of the certificate
* @returns {Promise<true|null>} status of the certificate
* @async
*/
async verifyCertificate(primaryKey, certificate, keys, date = new Date()) {
@ -157,11 +157,12 @@ class User {
/**
* Verify User. Checks for existence of self signatures, revocation signatures
* and validity of self signature. Throws when there are no valid self signatures.
* and validity of self signature.
* @param {SecretKeyPacket|
* PublicKeyPacket} primaryKey The primary key packet
* @param {Date} date Use the given date instead of the current time
* @returns {Promise<true>} Status of user
* @throws {Error} if there are no valid self signatures.
* @async
*/
async verify(primaryKey, date = new Date()) {
@ -215,7 +216,8 @@ class User {
// self signatures
await mergeSignatures(user, this, 'selfCertifications', async function(srcSelfSig) {
try {
return srcSelfSig.verified || srcSelfSig.verify(primaryKey, enums.signature.certGeneric, dataToVerify);
srcSelfSig.verified || await srcSelfSig.verify(primaryKey, enums.signature.certGeneric, dataToVerify);
return true;
} catch (e) {
return false;
}

View File

@ -730,7 +730,7 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig
* i.e. check signature creation time < date < expiration time
* @param {Boolean} detached (optional) whether to verify detached signature packets
* @returns {Promise<Array<{keyid: module:type/keyid,
* valid: Boolean}>>} list of signer's keyid and validity of signature
* valid: Boolean|null}>>} list of signer's keyid and validity of signature
* @async
*/
async function createVerificationObject(signature, literalDataList, keys, date = new Date(), detached = false, streaming = false) {
@ -751,7 +751,7 @@ async function createVerificationObject(signature, literalDataList, keys, date =
if (!signingKey) {
return null;
}
const verified = await signature.verify(signingKey.keyPacket, signature.signatureType, literalDataList[0], detached, streaming);
await signature.verify(signingKey.keyPacket, signature.signatureType, literalDataList[0], detached, streaming);
const sig = await signaturePacket;
if (sig.isExpired(date) || !(
sig.created >= signingKey.getCreationTime() &&
@ -762,7 +762,7 @@ async function createVerificationObject(signature, literalDataList, keys, date =
)) {
throw new Error('Signature is expired');
}
return verified;
return true;
})(),
signature: (async () => {
const sig = await signaturePacket;

View File

@ -90,7 +90,7 @@ class AEADEncryptedDataPacket {
* @param {String} sessionKeyAlgorithm The session key's cipher algorithm e.g. 'aes128'
* @param {Uint8Array} key The session key used to encrypt the payload
* @param {Boolean} streaming Whether the top-level function will return a stream
* @returns {Boolean}
* @throws {Error} if decryption was not successful
* @async
*/
async decrypt(sessionKeyAlgorithm, key, streaming) {
@ -100,7 +100,6 @@ class AEADEncryptedDataPacket {
OnePassSignaturePacket,
SignaturePacket
}, streaming);
return true;
}
/**
@ -108,6 +107,7 @@ class AEADEncryptedDataPacket {
* @param {String} sessionKeyAlgorithm The session key's cipher algorithm e.g. 'aes128'
* @param {Uint8Array} key The session key used to encrypt the payload
* @param {Boolean} streaming Whether the top-level function will return a stream
* @throws {Error} if encryption was not successful
* @async
*/
async encrypt(sessionKeyAlgorithm, key, streaming) {

View File

@ -272,12 +272,12 @@ class SecretKeyPacket extends PublicKeyPacket {
* and the passphrase is empty or undefined, the key will be set as not encrypted.
* This can be used to remove passphrase protection after calling decrypt().
* @param {String} passphrase
* @returns {Promise<Boolean>}
* @throws {Error} if encryption was not successful
* @async
*/
async encrypt(passphrase) {
if (this.isDummy()) {
return false;
return;
}
if (!this.isDecrypted()) {
@ -286,7 +286,7 @@ class SecretKeyPacket extends PublicKeyPacket {
if (this.isDecrypted() && !passphrase) {
this.s2k_usage = 0;
return false;
return;
} else if (!passphrase) {
throw new Error('The key must be decrypted before removing passphrase protection.');
}
@ -313,7 +313,6 @@ class SecretKeyPacket extends PublicKeyPacket {
await crypto.hash.sha1(cleartext)
]), this.iv);
}
return true;
}
/**
@ -321,13 +320,13 @@ class SecretKeyPacket extends PublicKeyPacket {
* {@link SecretKeyPacket.isDecrypted} should be false, as
* otherwise calls to this function will throw an error.
* @param {String} passphrase The passphrase for this private key as string
* @returns {Promise<Boolean>}
* @throws {Error} if decryption was not successful
* @async
*/
async decrypt(passphrase) {
if (this.isDummy()) {
this.isEncrypted = false;
return false;
return;
}
if (this.isDecrypted()) {
@ -376,8 +375,6 @@ class SecretKeyPacket extends PublicKeyPacket {
this.isEncrypted = false;
this.keyMaterial = null;
this.s2k_usage = 0;
return true;
}
/**

View File

@ -161,7 +161,7 @@ class SignaturePacket {
* @param {Object} data Contains packets to be signed.
* @param {Boolean} detached (optional) whether to create a detached signature
* @param {Boolean} streaming (optional) whether to process data as a stream
* @returns {Promise<Boolean>}
* @throws {Error} if signing failed
* @async
*/
async sign(key, data, detached = false, streaming = false) {
@ -201,7 +201,6 @@ class SignaturePacket {
// same as the ones passed to sign.
this.verified = true;
}
return true;
}
/**
@ -672,7 +671,7 @@ class SignaturePacket {
* @param {String|Object} data data which on the signature applies
* @param {Boolean} detached (optional) whether to verify a detached signature
* @param {Boolean} streaming (optional) whether to process data as a stream
* @returns {Promise<Boolean>} True if message is verified, else false.
* @throws {Error} if signature validation failed
* @async
*/
async verify(key, signatureType, data, detached = false, streaming = false) {
@ -718,7 +717,6 @@ class SignaturePacket {
throw new Error('This key is intended to be revoked with an authorized key, which OpenPGP.js does not support.');
}
this.verified = true;
return true;
}
/**

View File

@ -125,7 +125,7 @@ class SymEncryptedSessionKeyPacket {
/**
* Decrypts the session key
* @param {String} passphrase The passphrase in string form
* @returns {Promise<Boolean>}
* @throws {Error} if decryption was not successful
* @async
*/
async decrypt(passphrase) {
@ -149,14 +149,12 @@ class SymEncryptedSessionKeyPacket {
} else {
this.sessionKey = key;
}
return true;
}
/**
* Encrypts the session key
* @param {String} passphrase The passphrase in string form
* @returns {Promise<Boolean>}
* @throws {Error} if encryption was not successful
* @async
*/
async encrypt(passphrase) {
@ -187,8 +185,6 @@ class SymEncryptedSessionKeyPacket {
const private_key = util.concatUint8Array([algo_enum, this.sessionKey]);
this.encrypted = await crypto.cfb.encrypt(algo, key, private_key, new Uint8Array(crypto.cipher[algo].blockSize));
}
return true;
}
}

View File

@ -83,7 +83,7 @@ class SymmetricallyEncryptedDataPacket {
* See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
* @param {module:enums.symmetric} sessionKeyAlgorithm Symmetric key algorithm to use
* @param {Uint8Array} key The key of cipher blocksize length to be used
* @returns {Promise<Boolean>}
* @throws {Error} if decryption was not successful
* @async
*/
async decrypt(sessionKeyAlgorithm, key, streaming) {
@ -104,8 +104,6 @@ class SymmetricallyEncryptedDataPacket {
OnePassSignaturePacket,
SignaturePacket
}, streaming);
return true;
}
/**
@ -113,7 +111,7 @@ class SymmetricallyEncryptedDataPacket {
* See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
* @param {module:enums.symmetric} sessionKeyAlgorithm Symmetric key algorithm to use
* @param {Uint8Array} key The key of cipher blocksize length to be used
* @returns {Promise<Boolean>}
* @throws {Error} if encryption was not successful
* @async
*/
async encrypt(algo, key) {
@ -123,8 +121,6 @@ class SymmetricallyEncryptedDataPacket {
const FRE = await crypto.cfb.encrypt(algo, key, prefix, new Uint8Array(crypto.cipher[algo].blockSize));
const ciphertext = await crypto.cfb.encrypt(algo, key, data, FRE.subarray(2));
this.encrypted = util.concat([FRE, ciphertext]);
return true;
}
}

View File

@ -3041,17 +3041,21 @@ module.exports = () => describe('Key', function() {
source.subKeys = [];
dest.subKeys = [];
expect(dest.isPublic()).to.be.true;
return dest.update(source).then(() => {
expect(dest.isPrivate()).to.be.true;
return Promise.all([
dest.verifyPrimaryKey().then(result => {
expect(source.verifyPrimaryKey()).to.eventually.equal(result);
}),
dest.users[0].verify(dest.primaryKey).then(result => {
expect(source.users[0].verify(source.primaryKey)).to.eventually.equal(result);
})
]);
});
await dest.update(source);
expect(dest.isPrivate()).to.be.true;
const { selfCertification: destCertification } = await dest.getPrimaryUser();
const { selfCertification: sourceCertification } = await source.getPrimaryUser();
destCertification.verified = null;
sourceCertification.verified = null;
await dest.verifyPrimaryKey().then(async () => expect(destCertification.verified).to.be.true);
await source.verifyPrimaryKey().then(async () => expect(sourceCertification.verified).to.be.true);
destCertification.verified = null;
sourceCertification.verified = null;
await dest.users[0].verify(dest.primaryKey).then(async () => expect(destCertification.verified).to.be.true);
await source.users[0].verify(source.primaryKey).then(async () => expect(sourceCertification.verified).to.be.true);
});
it('update() - merge private key into public key - mismatch throws error', async function() {

View File

@ -713,20 +713,16 @@ module.exports = () => describe("Packet", function() {
it('Secret key reading with signature verification.', async function() {
const key = new openpgp.PacketList();
await key.read((await openpgp.unarmor(armored_key)).data, openpgp);
return Promise.all([
expect(key[2].verify(key[0],
openpgp.enums.signature.certGeneric,
{
userId: key[1],
key: key[0]
})).to.eventually.be.true,
expect(key[4].verify(key[0],
openpgp.enums.signature.keyBinding,
{
key: key[0],
bind: key[3]
})).to.eventually.be.true
]);
expect(key[2].verified).to.be.null;
expect(key[4].verified).to.be.null;
await key[2].verify(
key[0], openpgp.enums.signature.certGeneric, { userId: key[1], key: key[0] }
).then(async () => expect(key[2].verified).to.be.true);
await key[4].verify(
key[0], openpgp.enums.signature.keyBinding, { key: key[0], bind: key[3] }
).then(async () => expect(key[4].verified).to.be.true);
});
it('Reading a signed, encrypted message.', async function() {
@ -760,10 +756,8 @@ module.exports = () => describe("Packet", function() {
payload.concat(await openpgp.stream.readToEnd(payload.stream, arr => arr));
await Promise.all([
expect(payload[2].verify(
key[0], openpgp.enums.signature.binary, payload[1]
)).to.eventually.be.true,
openpgp.stream.pipe(payload[1].getBytes(), new openpgp.stream.WritableStream())
payload[2].verify(key[0], openpgp.enums.signature.binary, payload[1]),
openpgp.stream.pipe(payload[1].getBytes(),new openpgp.stream.WritableStream())
]);
});
});
@ -930,7 +924,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
signed2.concat(await openpgp.stream.readToEnd(signed2.stream, arr => arr));
await Promise.all([
expect(signed2[1].verify(key, openpgp.enums.signature.text, signed2[0])).to.eventually.be.true,
signed2[1].verify(key, openpgp.enums.signature.text, signed2[0]),
openpgp.stream.pipe(signed2[0].getBytes(), new openpgp.stream.WritableStream())
]);
});

View File

@ -1521,17 +1521,21 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
// TODO add test with multiple revocation signatures
it('Verify primary key revocation signatures', async function() {
const pubKey = await openpgp.readArmoredKey(pub_revoked);
await expect(pubKey.revocationSignatures[0].verify(
pubKey.primaryKey, openpgp.enums.signature.keyRevocation, {key: pubKey.primaryKey}
)).to.eventually.be.true;
const revSig = pubKey.revocationSignatures[0];
revSig.verified = null;
await pubKey.revocationSignatures[0].verify(
pubKey.primaryKey, openpgp.enums.signature.keyRevocation, { key: pubKey.primaryKey }
).then(() => expect(revSig.verified).to.be.true);
});
// TODO add test with multiple revocation signatures
it('Verify subkey revocation signatures', async function() {
const pubKey = await openpgp.readArmoredKey(pub_revoked);
await expect(pubKey.subKeys[0].revocationSignatures[0].verify(
pubKey.primaryKey, openpgp.enums.signature.subkeyRevocation, {key: pubKey.primaryKey, bind: pubKey.subKeys[0].keyPacket}
)).to.eventually.be.true;
const revSig = pubKey.subKeys[0].revocationSignatures[0];
revSig.verified = null;
await revSig.verify(
pubKey.primaryKey, openpgp.enums.signature.subkeyRevocation, { key: pubKey.primaryKey, bind: pubKey.subKeys[0].keyPacket }
).then(() => expect(revSig.verified).to.be.true);
});
it('Verify key expiration date', async function() {

View File

@ -401,12 +401,16 @@ function omnibus() {
// Self Certificate is valid
const user = hi.users[0];
await expect(user.selfCertifications[0].verify(
const certificate = user.selfCertifications[0];
certificate.verified = null;
await certificate.verify(
primaryKey, openpgp.enums.signature.certGeneric, { userId: user.userId, key: primaryKey }
)).to.eventually.be.true;
).then(async () => expect(certificate.verified).to.be.true);
certificate.verified = null;
await user.verifyCertificate(
primaryKey, user.selfCertifications[0], [hi.toPublic()]
);
primaryKey, certificate, [hi.toPublic()]
).then(async () => expect(certificate.verified).to.be.true);
const options = {
userIds: { name: "Bye", email: "bye@good.bye" },
@ -421,19 +425,25 @@ function omnibus() {
// Self Certificate is valid
const user = bye.users[0];
await expect(user.selfCertifications[0].verify(
const certificate = user.selfCertifications[0];
certificate.verified = null;
await certificate.verify(
bye.primaryKey, openpgp.enums.signature.certGeneric, { userId: user.userId, key: bye.primaryKey }
)).to.eventually.be.true;
).then(async () => expect(certificate.verified).to.be.true);
certificate.verified = null;
await user.verifyCertificate(
bye.primaryKey, user.selfCertifications[0], [bye.toPublic()]
);
).then(async () => expect(certificate.verified).to.be.true);
return Promise.all([
// Hi trusts Bye!
bye.toPublic().signPrimaryUser([hi]).then(trustedBye => {
expect(trustedBye.users[0].otherCertifications[0].verify(
const hiCertificate = trustedBye.users[0].otherCertifications[0];
expect(hiCertificate.verified).to.be.true;
hiCertificate.verified = null;
return hiCertificate.verify(
primaryKey, openpgp.enums.signature.certGeneric, { userId: user.userId, key: bye.toPublic().primaryKey }
)).to.eventually.be.true;
).then(async () => expect(hiCertificate.verified).to.be.true);
}),
// Signing message
openpgp.sign(