Use consistent name casing ()

- Use PascalCase for classes, with uppercase acronyms.
- Use camelCase for function and variables. First word/acronym is always
  lowercase, otherwise acronyms are uppercase.

Also, make the packet classes' `tag` properties `static`.
This commit is contained in:
larabr 2021-03-25 19:56:59 +01:00 committed by GitHub
parent 8a57246ec4
commit 6cff19c44a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
91 changed files with 1586 additions and 1501 deletions

View File

@ -79,9 +79,9 @@ library to convert back and forth between them.
You can change the AEAD mode by setting one of the following options: You can change the AEAD mode by setting one of the following options:
``` ```
openpgp.config.preferredAeadAlgorithm = openpgp.enums.aead.eax // Default, native openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.eax // Default, native
openpgp.config.preferredAeadAlgorithm = openpgp.enums.aead.ocb // Non-native openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.ocb // Non-native
openpgp.config.preferredAeadAlgorithm = openpgp.enums.aead.experimentalGcm // **Non-standard**, fastest openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.experimentalGCM // **Non-standard**, fastest
``` ```
* For environments that don't provide native crypto, the library falls back to [asm.js](https://caniuse.com/#feat=asmjs) implementations of AES, SHA-1, and SHA-256. * For environments that don't provide native crypto, the library falls back to [asm.js](https://caniuse.com/#feat=asmjs) implementations of AES, SHA-1, and SHA-256.
@ -139,7 +139,7 @@ To test whether the lazy loading works, try to generate a key with a non-standar
```js ```js
import { generateKey } from 'openpgp/lightweight'; import { generateKey } from 'openpgp/lightweight';
await generateKey({ curve: 'brainpoolP512r1', userIds: [{ name: 'Test', email: 'test@test.com' }] }); await generateKey({ curve: 'brainpoolP512r1', userIDs: [{ name: 'Test', email: 'test@test.com' }] });
``` ```
For more examples of how to generate a key, see [Generate new key pair](#generate-new-key-pair). It is recommended to use `curve25519` instead of `brainpoolP512r1` by default. For more examples of how to generate a key, see [Generate new key pair](#generate-new-key-pair). It is recommended to use `curve25519` instead of `brainpoolP512r1` by default.
@ -395,7 +395,7 @@ and a subkey for encryption using Curve25519.
const { privateKeyArmored, publicKeyArmored, revocationCertificate } = await openpgp.generateKey({ const { privateKeyArmored, publicKeyArmored, revocationCertificate } = await openpgp.generateKey({
type: 'ecc', // Type of the key, defaults to ECC type: 'ecc', // Type of the key, defaults to ECC
curve: 'curve25519', // ECC curve name, defaults to curve25519 curve: 'curve25519', // ECC curve name, defaults to curve25519
userIds: [{ name: 'Jon Smith', email: 'jon@example.com' }], // you can pass multiple user IDs userIDs: [{ name: 'Jon Smith', email: 'jon@example.com' }], // you can pass multiple user IDs
passphrase: 'super long and hard to guess secret' // protects the private key passphrase: 'super long and hard to guess secret' // protects the private key
}); });
@ -412,7 +412,7 @@ RSA keys (increased compatibility):
const key = await openpgp.generateKey({ const key = await openpgp.generateKey({
type: 'rsa', // Type of the key type: 'rsa', // Type of the key
rsaBits: 4096, // RSA key size (defaults to 4096 bits) rsaBits: 4096, // RSA key size (defaults to 4096 bits)
userIds: [{ name: 'Jon Smith', email: 'jon@example.com' }], // you can pass multiple user IDs userIDs: [{ name: 'Jon Smith', email: 'jon@example.com' }], // you can pass multiple user IDs
passphrase: 'super long and hard to guess secret' // protects the private key passphrase: 'super long and hard to guess secret' // protects the private key
}); });
})(); })();
@ -473,7 +473,7 @@ Using the private key:
}); });
const { valid } = verified.signatures[0]; const { valid } = verified.signatures[0];
if (valid) { if (valid) {
console.log('signed by key id ' + verified.signatures[0].keyid.toHex()); console.log('signed by key id ' + verified.signatures[0].keyID.toHex());
} else { } else {
throw new Error('signature could not be verified'); throw new Error('signature could not be verified');
} }
@ -515,7 +515,7 @@ Using the private key:
}); });
const { valid } = verified.signatures[0]; const { valid } = verified.signatures[0];
if (valid) { if (valid) {
console.log('signed by key id ' + verified.signatures[0].keyid.toHex()); console.log('signed by key id ' + verified.signatures[0].keyID.toHex());
} else { } else {
throw new Error('signature could not be verified'); throw new Error('signature could not be verified');
} }
@ -563,7 +563,7 @@ Using the private key:
const { valid } = verified.signatures[0]; const { valid } = verified.signatures[0];
if (valid) { if (valid) {
console.log('signed by key id ' + verified.signatures[0].keyid.toHex()); console.log('signed by key id ' + verified.signatures[0].keyID.toHex());
} else { } else {
throw new Error('signature could not be verified'); throw new Error('signature could not be verified');
} }

91
openpgp.d.ts vendored
View File

@ -14,10 +14,10 @@ export function readKey(options: { binaryKey: Uint8Array, config?: PartialConfig
export function readKeys(options: { armoredKeys: string, config?: PartialConfig }): Promise<Key[]>; export function readKeys(options: { armoredKeys: string, config?: PartialConfig }): Promise<Key[]>;
export function readKeys(options: { binaryKeys: Uint8Array, config?: PartialConfig }): Promise<Key[]>; export function readKeys(options: { binaryKeys: Uint8Array, config?: PartialConfig }): Promise<Key[]>;
export function generateKey(options: KeyOptions): Promise<KeyPair>; export function generateKey(options: KeyOptions): Promise<KeyPair>;
export function generateSessionKey(options: { publicKeys: Key[], date?: Date, toUserIds?: UserID[], config?: PartialConfig }): Promise<SessionKey>; export function generateSessionKey(options: { publicKeys: Key[], date?: Date, toUserIDs?: UserID[], config?: PartialConfig }): Promise<SessionKey>;
export function decryptKey(options: { privateKey: Key; passphrase?: string | string[]; config?: PartialConfig }): Promise<Key>; export function decryptKey(options: { privateKey: Key; passphrase?: string | string[]; config?: PartialConfig }): Promise<Key>;
export function encryptKey(options: { privateKey: Key; passphrase?: string | string[]; config?: PartialConfig }): Promise<Key>; export function encryptKey(options: { privateKey: Key; passphrase?: string | string[]; config?: PartialConfig }): Promise<Key>;
export function reformatKey(options: { privateKey: Key; userIds?: UserID|UserID[]; passphrase?: string; keyExpirationTime?: number; config?: PartialConfig }): Promise<KeyPair>; export function reformatKey(options: { privateKey: Key; userIDs?: UserID|UserID[]; passphrase?: string; keyExpirationTime?: number; config?: PartialConfig }): Promise<KeyPair>;
export class Key { export class Key {
constructor(packetlist: PacketList<AnyPacket>); constructor(packetlist: PacketList<AnyPacket>);
@ -28,33 +28,33 @@ export class Key {
private keyPacket: PublicKeyPacket | SecretKeyPacket; private keyPacket: PublicKeyPacket | SecretKeyPacket;
public write(): Uint8Array; public write(): Uint8Array;
public armor(config?: Config): string; public armor(config?: Config): string;
public decrypt(passphrase: string | string[], keyId?: Keyid, config?: Config): Promise<void>; // throws on error public decrypt(passphrase: string | string[], keyID?: KeyID, config?: Config): Promise<void>; // throws on error
public encrypt(passphrase: string | string[], keyId?: Keyid, config?: Config): Promise<void>; // throws on error public encrypt(passphrase: string | string[], keyID?: KeyID, config?: Config): Promise<void>; // throws on error
public getExpirationTime(capability?: 'encrypt' | 'encrypt_sign' | 'sign', keyId?: Keyid, userId?: UserID, config?: Config): 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 getExpirationTime(capability?: 'encrypt' | 'encrypt_sign' | 'sign', keyID?: KeyID, userID?: UserID, config?: Config): 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 getKeyIDs(): KeyID[];
public getPrimaryUser(date?: Date, userId?: UserID, config?: Config): Promise<PrimaryUser>; // throws on error public getPrimaryUser(date?: Date, userID?: UserID, config?: Config): Promise<PrimaryUser>; // throws on error
public getUserIds(): string[]; public getUserIDs(): string[];
public isPrivate(): boolean; public isPrivate(): boolean;
public isPublic(): boolean; public isPublic(): boolean;
public toPublic(): Key; public toPublic(): Key;
public update(key: Key, config?: Config): void; public update(key: Key, config?: Config): void;
public signPrimaryUser(privateKeys: Key[], date?: Date, userId?: UserID, config?: Config): Promise<Key> public signPrimaryUser(privateKeys: Key[], date?: Date, userID?: UserID, config?: Config): Promise<Key>
public signAllUsers(privateKeys: Key[], config?: Config): Promise<Key> public signAllUsers(privateKeys: Key[], config?: Config): Promise<Key>
public verifyPrimaryKey(date?: Date, userId?: UserID, config?: Config): Promise<void>; // throws on error public verifyPrimaryKey(date?: Date, userID?: UserID, config?: Config): Promise<void>; // throws on error
public verifyPrimaryUser(publicKeys: Key[], date?: Date, userIds?: UserID, config?: Config): Promise<{ keyid: Keyid, valid: boolean | null }[]>; public verifyPrimaryUser(publicKeys: Key[], date?: Date, userIDs?: UserID, config?: Config): Promise<{ keyID: KeyID, valid: boolean | null }[]>;
public verifyAllUsers(publicKeys: Key[], config?: Config): Promise<{ userid: string, keyid: Keyid, valid: boolean | null }[]>; public verifyAllUsers(publicKeys: Key[], config?: Config): Promise<{ userID: string, keyID: KeyID, valid: boolean | null }[]>;
public isRevoked(signature: SignaturePacket, key?: AnyKeyPacket, date?: Date, config?: Config): Promise<boolean>; public isRevoked(signature: SignaturePacket, key?: AnyKeyPacket, date?: Date, config?: Config): Promise<boolean>;
public revoke(reason: { flag?: enums.reasonForRevocation; string?: string; }, date?: Date, config?: Config): Promise<Key>; public revoke(reason: { flag?: enums.reasonForRevocation; string?: string; }, date?: Date, config?: Config): Promise<Key>;
public getRevocationCertificate(date?: Date, config?: Config): Promise<Stream<string> | string | undefined>; public getRevocationCertificate(date?: Date, config?: Config): Promise<Stream<string> | string | undefined>;
public getEncryptionKey(keyid?: Keyid, date?: Date | null, userId?: UserID, config?: Config): Promise<Key | SubKey>; public getEncryptionKey(keyID?: KeyID, date?: Date | null, userID?: UserID, config?: Config): Promise<Key | SubKey>;
public getSigningKey(keyid?: Keyid, date?: Date | null, userId?: UserID, config?: Config): Promise<Key | SubKey>; public getSigningKey(keyID?: KeyID, date?: Date | null, userID?: UserID, config?: Config): Promise<Key | SubKey>;
public getKeys(keyId?: Keyid): (Key | SubKey)[]; public getKeys(keyID?: KeyID): (Key | SubKey)[];
public getSubkeys(keyId?: Keyid): SubKey[]; public getSubkeys(keyID?: KeyID): SubKey[];
public isDecrypted(): boolean; public isDecrypted(): boolean;
public getFingerprint(): string; public getFingerprint(): string;
public getCreationTime(): Date; public getCreationTime(): Date;
public getAlgorithmInfo(): AlgorithmInfo; public getAlgorithmInfo(): AlgorithmInfo;
public getKeyId(): Keyid; public getKeyID(): KeyID;
public addSubkey(options: SubKeyOptions): Promise<Key>; public addSubkey(options: SubKeyOptions): Promise<Key>;
} }
@ -68,11 +68,11 @@ export class SubKey {
public getFingerprint(): string; public getFingerprint(): string;
public getCreationTime(): Date; public getCreationTime(): Date;
public getAlgorithmInfo(): AlgorithmInfo; public getAlgorithmInfo(): AlgorithmInfo;
public getKeyId(): Keyid; public getKeyID(): KeyID;
} }
export interface User { export interface User {
userId: UserIDPacket | null; userID: UserIDPacket | null;
userAttribute: UserAttributePacket | null; userAttribute: UserAttributePacket | null;
selfCertifications: SignaturePacket[]; selfCertifications: SignaturePacket[];
otherCertifications: SignaturePacket[]; otherCertifications: SignaturePacket[];
@ -103,7 +103,7 @@ export class Signature {
} }
interface VerificationResult { interface VerificationResult {
keyid: Keyid; keyID: KeyID;
verified: Promise<null | boolean>; verified: Promise<null | boolean>;
signature: Promise<Signature>; signature: Promise<Signature>;
} }
@ -121,7 +121,7 @@ export class CleartextMessage {
/** Returns the key IDs of the keys that signed the cleartext message /** Returns the key IDs of the keys that signed the cleartext message
*/ */
getSigningKeyIds(): Keyid[]; getSigningKeyIDs(): KeyID[];
/** Get cleartext /** Get cleartext
*/ */
@ -131,7 +131,7 @@ export class CleartextMessage {
* *
* @param privateKeys private keys with decrypted secret key data for signing * @param privateKeys private keys with decrypted secret key data for signing
*/ */
sign(privateKeys: Key[], signature?: Signature, signingKeyIds?: Keyid[], date?: Date, userIds?: UserID[], config?: Config): void; sign(privateKeys: Key[], signature?: Signature, signingKeyIDs?: KeyID[], date?: Date, userIDs?: UserID[], config?: Config): void;
/** Verify signatures of cleartext signed message /** Verify signatures of cleartext signed message
* @param keys array of keys to verify signatures * @param keys array of keys to verify signatures
@ -262,11 +262,11 @@ export class Message<T extends MaybeStream<Data>> {
/** Encrypt the message /** Encrypt the message
@param keys array of keys, used to encrypt the message @param keys array of keys, used to encrypt the message
*/ */
public encrypt(keys?: Key[], passwords?: string[], sessionKeys?: SessionKey[], wildcard?: boolean, encryptionKeyIds?: Keyid[], date?: Date, userIds?: UserID[], streaming?: boolean, config?: Config): Promise<Message<MaybeStream<Data>>>; public encrypt(keys?: Key[], passwords?: string[], sessionKeys?: SessionKey[], wildcard?: boolean, encryptionKeyIDs?: KeyID[], date?: Date, userIDs?: UserID[], streaming?: boolean, config?: Config): Promise<Message<MaybeStream<Data>>>;
/** Returns the key IDs of the keys to which the session key is encrypted /** Returns the key IDs of the keys to which the session key is encrypted
*/ */
public getEncryptionKeyIds(): Keyid[]; public getEncryptionKeyIDs(): KeyID[];
/** Get literal data that is the body of the message /** Get literal data that is the body of the message
*/ */
@ -274,7 +274,7 @@ export class Message<T extends MaybeStream<Data>> {
/** Returns the key IDs of the keys that signed the message /** Returns the key IDs of the keys that signed the message
*/ */
public getSigningKeyIds(): Keyid[]; public getSigningKeyIDs(): KeyID[];
/** Get literal data as text /** Get literal data as text
*/ */
@ -285,7 +285,7 @@ export class Message<T extends MaybeStream<Data>> {
/** Sign the message (the literal data packet of the message) /** Sign the message (the literal data packet of the message)
@param privateKey private keys with decrypted secret key data for signing @param privateKey private keys with decrypted secret key data for signing
*/ */
public sign(privateKey: Key[], signature?: Signature, signingKeyIds?: Keyid[], date?: Date, userIds?: UserID[], streaming?: boolean, config?: Config): Promise<Message<T>>; public sign(privateKey: Key[], signature?: Signature, signingKeyIDs?: KeyID[], date?: Date, userIDs?: UserID[], streaming?: boolean, config?: Config): Promise<Message<T>>;
/** Unwrap compressed message /** Unwrap compressed message
*/ */
@ -320,7 +320,7 @@ interface Config {
allowUnauthenticatedMessages: boolean; allowUnauthenticatedMessages: boolean;
allowUnauthenticatedStream: boolean; allowUnauthenticatedStream: boolean;
checksumRequired: boolean; checksumRequired: boolean;
minRsaBits: number; minRSABits: number;
passwordCollisionCheck: boolean; passwordCollisionCheck: boolean;
revocationsExpire: boolean; revocationsExpire: boolean;
tolerant: boolean; tolerant: boolean;
@ -357,7 +357,7 @@ declare abstract class BasePublicKeyPacket extends BasePacket {
public getFingerprintBytes(): Uint8Array | null; public getFingerprintBytes(): Uint8Array | null;
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;
public publicParams: object; public publicParams: object;
} }
@ -396,7 +396,7 @@ export class SymEncryptedIntegrityProtectedDataPacket extends BasePacket {
} }
export class AEADEncryptedDataPacket extends BasePacket { export class AEADEncryptedDataPacket extends BasePacket {
public tag: enums.packet.AEADEncryptedData; public tag: enums.packet.aeadEncryptedData;
} }
export class PublicKeyEncryptedSessionKeyPaclet extends BasePacket { export class PublicKeyEncryptedSessionKeyPaclet extends BasePacket {
@ -433,8 +433,8 @@ export class UserIDPacket extends BasePacket {
public readonly name: string; public readonly name: string;
public readonly comment: string; public readonly comment: string;
public readonly email: string; public readonly email: string;
public readonly userid: string; public readonly userID: string;
static fromObject(userId: UserID): UserIDPacket; static fromObject(userID: UserID): UserIDPacket;
} }
export class SignaturePacket extends BasePacket { export class SignaturePacket extends BasePacket {
@ -460,7 +460,7 @@ export class SignaturePacket extends BasePacket {
public revocationKeyClass: null | number; public revocationKeyClass: null | number;
public revocationKeyAlgorithm: null | enums.publicKey; public revocationKeyAlgorithm: null | enums.publicKey;
public revocationKeyFingerprint: null | Uint8Array; public revocationKeyFingerprint: null | Uint8Array;
public issuerKeyId: Keyid; public issuerKeyID: KeyID;
public notation: null | { [name: string]: string }; public notation: null | { [name: string]: string };
public preferredHashAlgorithms: enums.hash[] | null; public preferredHashAlgorithms: enums.hash[] | null;
public preferredCompressionAlgorithms: enums.compression[] | null; public preferredCompressionAlgorithms: enums.compression[] | null;
@ -469,7 +469,7 @@ export class SignaturePacket extends BasePacket {
public isPrimaryUserID: null | boolean; public isPrimaryUserID: null | boolean;
public policyURI: null | string; public policyURI: null | string;
public keyFlags: Uint8Array | null; public keyFlags: Uint8Array | null;
public signersUserId: null | string; public signersUserID: null | string;
public reasonForRevocationFlag: null | enums.reasonForRevocation; public reasonForRevocationFlag: null | enums.reasonForRevocation;
public reasonForRevocationString: null | string; public reasonForRevocationString: null | string;
public features: Uint8Array | null; public features: Uint8Array | null;
@ -479,7 +479,7 @@ export class SignaturePacket extends BasePacket {
public embeddedSignature: null | SignaturePacket; public embeddedSignature: null | SignaturePacket;
public issuerKeyVersion: null | number; public issuerKeyVersion: null | number;
public issuerFingerprint: null | Uint8Array; public issuerFingerprint: null | Uint8Array;
public preferredAeadAlgorithms: enums.aead[] | null; public preferredAEADAlgorithms: enums.aead[] | null;
public verified: null | boolean; public verified: null | boolean;
public revoked: null | boolean; public revoked: null | boolean;
public sign(key: AnySecretKeyPacket, data: Uint8Array, detached?: boolean, streaming?: boolean): Promise<void>; public sign(key: AnySecretKeyPacket, data: Uint8Array, detached?: boolean, streaming?: boolean): Promise<void>;
@ -572,9 +572,9 @@ interface EncryptOptions {
/** (optional) use a key ID of 0 instead of the public key IDs */ /** (optional) use a key ID of 0 instead of the public key IDs */
wildcard?: boolean; wildcard?: boolean;
/** (optional) user ID to sign with, e.g. { name:'Steve Sender', email:'steve@openpgp.org' } */ /** (optional) user ID to sign with, e.g. { name:'Steve Sender', email:'steve@openpgp.org' } */
fromUserId?: UserID; fromUserID?: UserID;
/** (optional) user ID to encrypt for, e.g. { name:'Robert Receiver', email:'robert@openpgp.org' } */ /** (optional) user ID to encrypt for, e.g. { name:'Robert Receiver', email:'robert@openpgp.org' } */
toUserId?: UserID; toUserID?: UserID;
config?: PartialConfig; config?: PartialConfig;
} }
@ -608,7 +608,7 @@ interface SignOptions {
dataType?: DataPacketType; dataType?: DataPacketType;
detached?: boolean; detached?: boolean;
date?: Date; date?: Date;
fromUserId?: UserID; fromUserID?: UserID;
config?: PartialConfig; config?: PartialConfig;
} }
@ -638,7 +638,7 @@ interface KeyPair {
export type EllipticCurveName = 'ed25519' | 'curve25519' | 'p256' | 'p384' | 'p521' | 'secp256k1' | 'brainpoolP256r1' | 'brainpoolP384r1' | 'brainpoolP512r1'; export type EllipticCurveName = 'ed25519' | 'curve25519' | 'p256' | 'p384' | 'p521' | 'secp256k1' | 'brainpoolP256r1' | 'brainpoolP384r1' | 'brainpoolP512r1';
interface KeyOptions { interface KeyOptions {
userIds: UserID|UserID[]; userIDs: UserID|UserID[];
passphrase?: string; passphrase?: string;
type?: 'ecc' | 'rsa'; type?: 'ecc' | 'rsa';
curve?: EllipticCurveName; curve?: EllipticCurveName;
@ -659,11 +659,11 @@ interface SubKeyOptions {
config?: PartialConfig; config?: PartialConfig;
} }
declare class Keyid { declare class KeyID {
bytes: string; bytes: string;
equals(keyid: Keyid, matchWildcard?: boolean): boolean; equals(keyID: KeyID, matchWildcard?: boolean): boolean;
toHex(): string; toHex(): string;
static fromId(hex: string): Keyid; static fromID(hex: string): KeyID;
} }
interface DecryptMessageResult { interface DecryptMessageResult {
@ -691,7 +691,6 @@ export function unarmor(input: string, config?: Config): Promise<{ text: string,
/* ############## v5 ENUMS #################### */ /* ############## v5 ENUMS #################### */
export namespace enums { export namespace enums {
function read(type: typeof armor, e: armor): armorNames; function read(type: typeof armor, e: armor): armorNames;
function read(type: typeof compression, e: compression): compressionNames; function read(type: typeof compression, e: compression): compressionNames;
function read(type: typeof hash, e: hash): hashNames; function read(type: typeof hash, e: hash): hashNames;
@ -717,7 +716,7 @@ export namespace enums {
keySuperseded = 1, // Key is superseded (key revocations) keySuperseded = 1, // Key is superseded (key revocations)
keyCompromised = 2, // Key material has been compromised (key revocations) keyCompromised = 2, // Key material has been compromised (key revocations)
keyRetired = 3, // Key is retired and no longer used (key revocations) keyRetired = 3, // Key is retired and no longer used (key revocations)
useridInvalid = 32, // User ID information is no longer valid (cert revocations) userIDInvalid = 32, // User ID information is no longer valid (cert revocations)
} }
export type compressionNames = 'uncompressed' | 'zip' | 'zlib' | 'bzip2'; export type compressionNames = 'uncompressed' | 'zip' | 'zlib' | 'bzip2';
@ -740,7 +739,7 @@ export namespace enums {
} }
export type packetNames = 'publicKeyEncryptedSessionKey' | 'signature' | 'symEncryptedSessionKey' | 'onePassSignature' | 'secretKey' | 'publicKey' export type packetNames = 'publicKeyEncryptedSessionKey' | 'signature' | 'symEncryptedSessionKey' | 'onePassSignature' | 'secretKey' | 'publicKey'
| 'secretSubkey' | 'compressed' | 'symmetricallyEncrypted' | 'marker' | 'literal' | 'trust' | 'userid' | 'publicSubkey' | 'userAttribute' | 'secretSubkey' | 'compressed' | 'symmetricallyEncrypted' | 'marker' | 'literal' | 'trust' | 'userID' | 'publicSubkey' | 'userAttribute'
| 'symEncryptedIntegrityProtected' | 'modificationDetectionCode' | 'AEADEncryptedDataPacket'; | 'symEncryptedIntegrityProtected' | 'modificationDetectionCode' | 'AEADEncryptedDataPacket';
enum packet { enum packet {
publicKeyEncryptedSessionKey = 1, publicKeyEncryptedSessionKey = 1,
@ -760,7 +759,7 @@ export namespace enums {
userAttribute = 17, userAttribute = 17,
symEncryptedIntegrityProtectedData = 18, symEncryptedIntegrityProtectedData = 18,
modificationDetectionCode = 19, modificationDetectionCode = 19,
AEADEncryptedData = 20, aeadEncryptedData = 20,
} }
export type publicKeyNames = 'rsaEncryptSign' | 'rsaEncrypt' | 'rsaSign' | 'elgamal' | 'dsa' | 'ecdh' | 'ecdsa' | 'eddsa' | 'aedh' | 'aedsa'; export type publicKeyNames = 'rsaEncryptSign' | 'rsaEncrypt' | 'rsaSign' | 'elgamal' | 'dsa' | 'ecdh' | 'ecdsa' | 'eddsa' | 'aedh' | 'aedsa';
@ -832,6 +831,6 @@ export namespace enums {
enum aead { enum aead {
eax = 1, eax = 1,
ocb = 2, ocb = 2,
experimentalGcm = 100 // Private algorithm experimentalGCM = 100 // Private algorithm
} }
} }

View File

@ -23,6 +23,9 @@ import { Signature } from './signature';
import { createVerificationObjects, createSignaturePackets } from './message'; import { createVerificationObjects, createSignaturePackets } from './message';
import defaultConfig from './config'; import defaultConfig from './config';
// A Cleartext message can contain the following packets
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([SignaturePacket]);
/** /**
* Class that represents an OpenPGP cleartext signed message. * Class that represents an OpenPGP cleartext signed message.
* See {@link https://tools.ietf.org/html/rfc4880#section-7} * See {@link https://tools.ietf.org/html/rfc4880#section-7}
@ -43,32 +46,32 @@ export class CleartextMessage {
/** /**
* Returns the key IDs of the keys that signed the cleartext message * Returns the key IDs of the keys that signed the cleartext message
* @returns {Array<module:type/keyid~Keyid>} Array of keyid objects. * @returns {Array<module:type/keyid~KeyID>} Array of keyID objects.
*/ */
getSigningKeyIds() { getSigningKeyIDs() {
const keyIds = []; const keyIDs = [];
const signatureList = this.signature.packets; const signatureList = this.signature.packets;
signatureList.forEach(function(packet) { signatureList.forEach(function(packet) {
keyIds.push(packet.issuerKeyId); keyIDs.push(packet.issuerKeyID);
}); });
return keyIds; return keyIDs;
} }
/** /**
* Sign the cleartext message * Sign the cleartext message
* @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing * @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing
* @param {Signature} [signature] - Any existing detached signature * @param {Signature} [signature] - Any existing detached signature
* @param {Array<module:type/keyid~Keyid>} [signingKeyIds] - Array of key IDs to use for signing. Each signingKeyIds[i] corresponds to privateKeys[i] * @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to privateKeys[i]
* @param {Date} [date] - The creation time of the signature that should be created * @param {Date} [date] - The creation time of the signature that should be created
* @param {Array} [userIds] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] * @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {CleartextMessage} New cleartext message with signed content. * @returns {CleartextMessage} New cleartext message with signed content.
* @async * @async
*/ */
async sign(privateKeys, signature = null, signingKeyIds = [], date = new Date(), userIds = [], config = defaultConfig) { async sign(privateKeys, signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], config = defaultConfig) {
const literalDataPacket = new LiteralDataPacket(); const literalDataPacket = new LiteralDataPacket();
literalDataPacket.setText(this.text); literalDataPacket.setText(this.text);
const newSignature = new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIds, date, userIds, true, undefined, config)); const newSignature = new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIDs, date, userIDs, true, undefined, config));
return new CleartextMessage(this.text, newSignature); return new CleartextMessage(this.text, newSignature);
} }
@ -77,9 +80,9 @@ export class CleartextMessage {
* @param {Array<Key>} keys - Array of keys to verify signatures * @param {Array<Key>} keys - Array of keys to verify signatures
* @param {Date} [date] - Verify the signature against the given date, i.e. check signature creation time < date < expiration time * @param {Date} [date] - Verify the signature against the given date, i.e. check signature creation time < date < expiration time
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Array<{keyid: module:type/keyid~Keyid, * @returns {Array<{keyID: module:type/keyid~KeyID,
* signature: Promise<Signature>, * signature: Promise<Signature>,
* verified: Promise<Boolean>}>} List of signer's keyid and validity of signature. * verified: Promise<Boolean>}>} List of signer's keyID and validity of signature.
* @async * @async
*/ */
verify(keys, date = new Date(), config = defaultConfig) { verify(keys, date = new Date(), config = defaultConfig) {
@ -127,7 +130,6 @@ export class CleartextMessage {
} }
} }
/** /**
* Reads an OpenPGP cleartext signed message and returns a CleartextMessage object * Reads an OpenPGP cleartext signed message and returns a CleartextMessage object
* @param {Object} options * @param {Object} options
@ -147,7 +149,7 @@ export async function readCleartextMessage({ cleartextMessage, config }) {
throw new Error('No cleartext signed message.'); throw new Error('No cleartext signed message.');
} }
const packetlist = new PacketList(); const packetlist = new PacketList();
await packetlist.read(input.data, { SignaturePacket }, undefined, config); await packetlist.read(input.data, allowedPackets, undefined, config);
verifyHeaders(input.headers, packetlist); verifyHeaders(input.headers, packetlist);
const signature = new Signature(packetlist); const signature = new Signature(packetlist);
return new CleartextMessage(input.text, signature); return new CleartextMessage(input.text, signature);
@ -164,7 +166,7 @@ function verifyHeaders(headers, packetlist) {
const check = packet => algo => packet.hashAlgorithm === algo; const check = packet => algo => packet.hashAlgorithm === algo;
for (let i = 0; i < packetlist.length; i++) { for (let i = 0; i < packetlist.length; i++) {
if (packetlist[i].tag === enums.packet.signature && !hashAlgos.some(check(packetlist[i]))) { if (packetlist[i].constructor.tag === enums.packet.signature && !hashAlgos.some(check(packetlist[i]))) {
return false; return false;
} }
} }

View File

@ -56,9 +56,9 @@ export default {
* Default Authenticated Encryption with Additional Data (AEAD) encryption mode * Default Authenticated Encryption with Additional Data (AEAD) encryption mode
* Only has an effect when aeadProtect is set to true. * Only has an effect when aeadProtect is set to true.
* @memberof module:config * @memberof module:config
* @property {Integer} preferredAeadAlgorithm Default AEAD mode {@link module:enums.aead} * @property {Integer} preferredAEADAlgorithm Default AEAD mode {@link module:enums.aead}
*/ */
preferredAeadAlgorithm: enums.aead.eax, preferredAEADAlgorithm: enums.aead.eax,
/** /**
* Chunk Size Byte for Authenticated Encryption with Additional Data (AEAD) mode * Chunk Size Byte for Authenticated Encryption with Additional Data (AEAD) mode
* Only has an effect when aeadProtect is set to true. * Only has an effect when aeadProtect is set to true.
@ -105,9 +105,9 @@ export default {
checksumRequired: false, checksumRequired: false,
/** /**
* @memberof module:config * @memberof module:config
* @property {Number} minRsaBits Minimum RSA key size allowed for key generation and message signing, verification and encryption * @property {Number} minRSABits Minimum RSA key size allowed for key generation and message signing, verification and encryption
*/ */
minRsaBits: 2048, minRSABits: 2048,
/** /**
* Work-around for rare GPG decryption bug when encrypting with multiple passwords. * Work-around for rare GPG decryption bug when encrypting with multiple passwords.
* **Slower and slightly less secure** * **Slower and slightly less secure**
@ -162,11 +162,11 @@ export default {
commentString: "https://openpgpjs.org", commentString: "https://openpgpjs.org",
/** /**
* Max userid string length (used for parsing) * Max userID string length (used for parsing)
* @memberof module:config * @memberof module:config
* @property {Integer} maxUseridLength * @property {Integer} maxUserIDLength
*/ */
maxUseridLength: 1024 * 5, maxUserIDLength: 1024 * 5,
/** /**
* Contains notatations that are considered "known". Known notations do not trigger * Contains notatations that are considered "known". Known notations do not trigger
* validation error when the notation is marked as critical. * validation error when the notation is marked as critical.

View File

@ -3,14 +3,14 @@ import { AES_ECB } from '@openpgp/asmcrypto.js/dist_es8/aes/ecb';
// TODO use webCrypto or nodeCrypto when possible. // TODO use webCrypto or nodeCrypto when possible.
function aes(length) { function aes(length) {
const C = function(key) { const C = function(key) {
const aes_ecb = new AES_ECB(key); const aesECB = new AES_ECB(key);
this.encrypt = function(block) { this.encrypt = function(block) {
return aes_ecb.encrypt(block); return aesECB.encrypt(block);
}; };
this.decrypt = function(block) { this.decrypt = function(block) {
return aes_ecb.decrypt(block); return aesECB.decrypt(block);
}; };
}; };

View File

@ -258,7 +258,7 @@ Blowfish.prototype._F = function(xx) {
//* This method takes an array with two values, left and right //* This method takes an array with two values, left and right
//* and does NN rounds of Blowfish on them. //* and does NN rounds of Blowfish on them.
//* //*
Blowfish.prototype._encrypt_block = function(vals) { Blowfish.prototype._encryptBlock = function(vals) {
let dataL = vals[0]; let dataL = vals[0];
let dataR = vals[1]; let dataR = vals[1];
@ -289,7 +289,7 @@ Blowfish.prototype._encrypt_block = function(vals) {
//* instead. That will involve more looping, but it won't require //* instead. That will involve more looping, but it won't require
//* the F() method to deconstruct the vector. //* the F() method to deconstruct the vector.
//* //*
Blowfish.prototype.encrypt_block = function(vector) { Blowfish.prototype.encryptBlock = function(vector) {
let ii; let ii;
const vals = [0, 0]; const vals = [0, 0];
const off = this.BLOCKSIZE / 2; const off = this.BLOCKSIZE / 2;
@ -298,7 +298,7 @@ Blowfish.prototype.encrypt_block = function(vector) {
vals[1] = (vals[1] << 8) | (vector[ii + off] & 0x00FF); vals[1] = (vals[1] << 8) | (vector[ii + off] & 0x00FF);
} }
this._encrypt_block(vals); this._encryptBlock(vals);
const ret = []; const ret = [];
for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) { for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) {
@ -315,7 +315,7 @@ Blowfish.prototype.encrypt_block = function(vector) {
//* This method takes an array with two values, left and right //* This method takes an array with two values, left and right
//* and undoes NN rounds of Blowfish on them. //* and undoes NN rounds of Blowfish on them.
//* //*
Blowfish.prototype._decrypt_block = function(vals) { Blowfish.prototype._decryptBlock = function(vals) {
let dataL = vals[0]; let dataL = vals[0];
let dataR = vals[1]; let dataR = vals[1];
@ -368,14 +368,14 @@ Blowfish.prototype.init = function(key) {
const vals = [0x00000000, 0x00000000]; const vals = [0x00000000, 0x00000000];
for (ii = 0; ii < this.NN + 2; ii += 2) { for (ii = 0; ii < this.NN + 2; ii += 2) {
this._encrypt_block(vals); this._encryptBlock(vals);
this.parray[ii + 0] = vals[0]; this.parray[ii + 0] = vals[0];
this.parray[ii + 1] = vals[1]; this.parray[ii + 1] = vals[1];
} }
for (ii = 0; ii < 4; ++ii) { for (ii = 0; ii < 4; ++ii) {
for (jj = 0; jj < 256; jj += 2) { for (jj = 0; jj < 256; jj += 2) {
this._encrypt_block(vals); this._encryptBlock(vals);
this.sboxes[ii][jj + 0] = vals[0]; this.sboxes[ii][jj + 0] = vals[0];
this.sboxes[ii][jj + 1] = vals[1]; this.sboxes[ii][jj + 1] = vals[1];
} }
@ -388,7 +388,7 @@ function BF(key) {
this.bf.init(key); this.bf.init(key);
this.encrypt = function(block) { this.encrypt = function(block) {
return this.bf.encrypt_block(block); return this.bf.encryptBlock(block);
}; };
} }

View File

@ -14,7 +14,7 @@
// CAST5 constructor // CAST5 constructor
function OpenpgpSymencCast5() { function OpenPGPSymEncCAST5() {
this.BlockSize = 8; this.BlockSize = 8;
this.KeySize = 16; this.KeySize = 16;
@ -595,8 +595,8 @@ function OpenpgpSymencCast5() {
]; ];
} }
function Cast5(key) { function CAST5(key) {
this.cast5 = new OpenpgpSymencCast5(); this.cast5 = new OpenPGPSymEncCAST5();
this.cast5.setKey(key); this.cast5.setKey(key);
this.encrypt = function(block) { this.encrypt = function(block) {
@ -604,7 +604,7 @@ function Cast5(key) {
}; };
} }
Cast5.blockSize = Cast5.prototype.blockSize = 8; CAST5.blockSize = CAST5.prototype.blockSize = 8;
Cast5.keySize = Cast5.prototype.keySize = 16; CAST5.keySize = CAST5.prototype.keySize = 16;
export default Cast5; export default CAST5;

View File

@ -118,7 +118,7 @@ function des(keys, message, encrypt, mode, iv, padding) {
//pad the message depending on the padding parameter //pad the message depending on the padding parameter
//only add padding if encrypting - note that you need to use the same padding option for both encrypt and decrypt //only add padding if encrypting - note that you need to use the same padding option for both encrypt and decrypt
if (encrypt) { if (encrypt) {
message = des_addPadding(message, padding); message = desAddPadding(message, padding);
len = message.length; len = message.length;
} }
@ -234,18 +234,18 @@ function des(keys, message, encrypt, mode, iv, padding) {
//only remove padding if decrypting - note that you need to use the same padding option for both encrypt and decrypt //only remove padding if decrypting - note that you need to use the same padding option for both encrypt and decrypt
if (!encrypt) { if (!encrypt) {
result = des_removePadding(result, padding); result = desRemovePadding(result, padding);
} }
return result; return result;
} //end of des } //end of des
//des_createKeys //desCreateKeys
//this takes as input a 64 bit key (even though only 56 bits are used) //this takes as input a 64 bit key (even though only 56 bits are used)
//as an array of 2 integers, and returns 16 48 bit keys //as an array of 2 integers, and returns 16 48 bit keys
function des_createKeys(key) { function desCreateKeys(key) {
//declaring this locally speeds things up a bit //declaring this locally speeds things up a bit
const pc2bytes0 = [ const pc2bytes0 = [
0, 0x4, 0x20000000, 0x20000004, 0x10000, 0x10004, 0x20010000, 0x20010004, 0x200, 0x204, 0, 0x4, 0x20000000, 0x20000004, 0x10000, 0x10004, 0x20010000, 0x20010004, 0x200, 0x204,
@ -376,10 +376,10 @@ function des_createKeys(key) {
} //for each iterations } //for each iterations
//return the keys we've created //return the keys we've created
return keys; return keys;
} //end of des_createKeys } //end of desCreateKeys
function des_addPadding(message, padding) { function desAddPadding(message, padding) {
const padLength = 8 - (message.length % 8); const padLength = 8 - (message.length % 8);
let pad; let pad;
@ -406,7 +406,7 @@ function des_addPadding(message, padding) {
return paddedMessage; return paddedMessage;
} }
function des_removePadding(message, padding) { function desRemovePadding(message, padding) {
let padLength = null; let padLength = null;
let pad; let pad;
if (padding === 2) { // space padded if (padding === 2) { // space padded
@ -441,11 +441,11 @@ export function TripleDES(key) {
this.encrypt = function(block) { this.encrypt = function(block) {
return des( return des(
des_createKeys(this.key[2]), desCreateKeys(this.key[2]),
des( des(
des_createKeys(this.key[1]), desCreateKeys(this.key[1]),
des( des(
des_createKeys(this.key[0]), desCreateKeys(this.key[0]),
block, true, 0, null, null block, true, 0, null, null
), ),
false, 0, null, null false, 0, null, null
@ -463,12 +463,12 @@ export function DES(key) {
this.key = key; this.key = key;
this.encrypt = function(block, padding) { this.encrypt = function(block, padding) {
const keys = des_createKeys(this.key); const keys = desCreateKeys(this.key);
return des(keys, block, true, 0, null, padding); return des(keys, block, true, 0, null, padding);
}; };
this.decrypt = function(block, padding) { this.decrypt = function(block, padding) {
const keys = des_createKeys(this.key); const keys = desCreateKeys(this.key);
return des(keys, block, false, 0, null, padding); return des(keys, block, false, 0, null, padding);
}; };
} }

View File

@ -6,7 +6,7 @@
import aes from './aes'; import aes from './aes';
import { DES, TripleDES } from './des.js'; import { DES, TripleDES } from './des.js';
import Cast5 from './cast5'; import CAST5 from './cast5';
import TF from './twofish'; import TF from './twofish';
import BF from './blowfish'; import BF from './blowfish';
@ -54,7 +54,7 @@ export const tripledes = TripleDES;
* @see {@link https://tools.ietf.org/html/rfc2144|The CAST-128 Encryption Algorithm} * @see {@link https://tools.ietf.org/html/rfc2144|The CAST-128 Encryption Algorithm}
* @returns {Object} * @returns {Object}
*/ */
export const cast5 = Cast5; export const cast5 = CAST5;
/** /**
* Twofish Block Cipher (ID 10) * Twofish Block Cipher (ID 10)
* @function * @function

View File

@ -37,7 +37,7 @@ const blockLength = 16;
* @param {Uint8Array} data * @param {Uint8Array} data
* @param {Uint8Array} padding * @param {Uint8Array} padding
*/ */
function rightXorMut(data, padding) { function rightXORMut(data, padding) {
const offset = data.length - blockLength; const offset = data.length - blockLength;
for (let i = 0; i < blockLength; i++) { for (let i = 0; i < blockLength; i++) {
data[i + offset] ^= padding[i]; data[i + offset] ^= padding[i];
@ -49,13 +49,13 @@ function pad(data, padding, padding2) {
// if |M| in {n, 2n, 3n, ...} // if |M| in {n, 2n, 3n, ...}
if (data.length && data.length % blockLength === 0) { if (data.length && data.length % blockLength === 0) {
// then return M xor→ B, // then return M xor→ B,
return rightXorMut(data, padding); return rightXORMut(data, padding);
} }
// else return (M || 10^(n1(|M| mod n))) xor→ P // else return (M || 10^(n1(|M| mod n))) xor→ P
const padded = new Uint8Array(data.length + (blockLength - data.length % blockLength)); const padded = new Uint8Array(data.length + (blockLength - data.length % blockLength));
padded.set(data); padded.set(data);
padded[data.length] = 0b10000000; padded[data.length] = 0b10000000;
return rightXorMut(padded, padding2); return rightXORMut(padded, padding2);
} }
const zeroBlock = new Uint8Array(blockLength); const zeroBlock = new Uint8Array(blockLength);

View File

@ -243,7 +243,7 @@ export function parseEncSessionKeyParams(algo, bytes) {
export function serializeParams(algo, params) { export function serializeParams(algo, params) {
const orderedParams = Object.keys(params).map(name => { const orderedParams = Object.keys(params).map(name => {
const param = params[name]; const param = params[name];
return util.isUint8Array(param) ? util.uint8ArrayToMpi(param) : param.write(); return util.isUint8Array(param) ? util.uint8ArrayToMPI(param) : param.write();
}); });
return util.concatUint8Array(orderedParams); return util.concatUint8Array(orderedParams);
} }

View File

@ -21,7 +21,7 @@ const webCrypto = util.getWebCrypto();
const nodeCrypto = util.getNodeCrypto(); const nodeCrypto = util.getNodeCrypto();
const Buffer = util.getNodeBuffer(); const Buffer = util.getNodeBuffer();
function node_hash(type) { function nodeHash(type) {
return async function (data) { return async function (data) {
const shasum = nodeCrypto.createHash(type); const shasum = nodeCrypto.createHash(type);
return stream.transform(data, value => { return stream.transform(data, value => {
@ -30,7 +30,7 @@ function node_hash(type) {
}; };
} }
function hashjs_hash(hash, webCryptoHash) { function hashjsHash(hash, webCryptoHash) {
return async function(data, config = defaultConfig) { return async function(data, config = defaultConfig) {
if (!util.isStream(data) && webCrypto && webCryptoHash && data.length >= config.minBytesForWebCrypto) { if (!util.isStream(data) && webCrypto && webCryptoHash && data.length >= config.minBytesForWebCrypto) {
return new Uint8Array(await webCrypto.digest(webCryptoHash, data)); return new Uint8Array(await webCrypto.digest(webCryptoHash, data));
@ -42,7 +42,7 @@ function hashjs_hash(hash, webCryptoHash) {
}; };
} }
function asmcrypto_hash(hash, webCryptoHash) { function asmcryptoHash(hash, webCryptoHash) {
return async function(data, config = defaultConfig) { return async function(data, config = defaultConfig) {
if (util.isStream(data)) { if (util.isStream(data)) {
const hashInstance = new hash(); const hashInstance = new hash();
@ -57,45 +57,45 @@ function asmcrypto_hash(hash, webCryptoHash) {
}; };
} }
let hash_fns; let hashFunctions;
if (nodeCrypto) { // Use Node native crypto for all hash functions if (nodeCrypto) { // Use Node native crypto for all hash functions
hash_fns = { hashFunctions = {
md5: node_hash('md5'), md5: nodeHash('md5'),
sha1: node_hash('sha1'), sha1: nodeHash('sha1'),
sha224: node_hash('sha224'), sha224: nodeHash('sha224'),
sha256: node_hash('sha256'), sha256: nodeHash('sha256'),
sha384: node_hash('sha384'), sha384: nodeHash('sha384'),
sha512: node_hash('sha512'), sha512: nodeHash('sha512'),
ripemd: node_hash('ripemd160') ripemd: nodeHash('ripemd160')
}; };
} else { // Use JS fallbacks } else { // Use JS fallbacks
hash_fns = { hashFunctions = {
md5: md5, md5: md5,
sha1: asmcrypto_hash(Sha1, navigator.userAgent.indexOf('Edge') === -1 && 'SHA-1'), sha1: asmcryptoHash(Sha1, navigator.userAgent.indexOf('Edge') === -1 && 'SHA-1'),
sha224: hashjs_hash(sha224), sha224: hashjsHash(sha224),
sha256: asmcrypto_hash(Sha256, 'SHA-256'), sha256: asmcryptoHash(Sha256, 'SHA-256'),
sha384: hashjs_hash(sha384, 'SHA-384'), sha384: hashjsHash(sha384, 'SHA-384'),
sha512: hashjs_hash(sha512, 'SHA-512'), // asmcrypto sha512 is huge. sha512: hashjsHash(sha512, 'SHA-512'), // asmcrypto sha512 is huge.
ripemd: hashjs_hash(ripemd160) ripemd: hashjsHash(ripemd160)
}; };
} }
export default { export default {
/** @see module:md5 */ /** @see module:md5 */
md5: hash_fns.md5, md5: hashFunctions.md5,
/** @see asmCrypto */ /** @see asmCrypto */
sha1: hash_fns.sha1, sha1: hashFunctions.sha1,
/** @see hash.js */ /** @see hash.js */
sha224: hash_fns.sha224, sha224: hashFunctions.sha224,
/** @see asmCrypto */ /** @see asmCrypto */
sha256: hash_fns.sha256, sha256: hashFunctions.sha256,
/** @see hash.js */ /** @see hash.js */
sha384: hash_fns.sha384, sha384: hashFunctions.sha384,
/** @see asmCrypto */ /** @see asmCrypto */
sha512: hash_fns.sha512, sha512: hashFunctions.sha512,
/** @see hash.js */ /** @see hash.js */
ripemd: hash_fns.ripemd, ripemd: hashFunctions.ripemd,
/** /**
* Create a hash on the specified data using the specified algorithm * Create a hash on the specified data using the specified algorithm

View File

@ -16,7 +16,7 @@ import util from '../../util';
// MD5 Digest // MD5 Digest
async function md5(entree) { async function md5(entree) {
const digest = md51(util.uint8ArrayToStr(entree)); const digest = md51(util.uint8ArrayToString(entree));
return util.hexToUint8Array(hex(digest)); return util.hexToUint8Array(hex(digest));
} }

View File

@ -12,17 +12,14 @@
import * as cipher from './cipher'; import * as cipher from './cipher';
import hash from './hash'; import hash from './hash';
import * as cfb from './cfb'; import mode from './mode';
import gcm from './gcm';
import eax from './eax';
import ocb from './ocb';
import publicKey from './public_key'; import publicKey from './public_key';
import * as signature from './signature'; import * as signature from './signature';
import * as random from './random'; import * as random from './random';
import * as pkcs1 from './pkcs1'; import * as pkcs1 from './pkcs1';
import * as pkcs5 from './pkcs5'; import * as pkcs5 from './pkcs5';
import * as crypto from './crypto'; import * as crypto from './crypto';
import * as aes_kw from './aes_kw'; import * as aesKW from './aes_kw';
// TODO move cfb and gcm to cipher // TODO move cfb and gcm to cipher
const mod = { const mod = {
@ -30,15 +27,8 @@ const mod = {
cipher: cipher, cipher: cipher,
/** @see module:crypto/hash */ /** @see module:crypto/hash */
hash: hash, hash: hash,
/** @see module:crypto/cfb */ /** @see module:crypto/mode */
cfb: cfb, mode: mode,
/** @see module:crypto/gcm */
gcm: gcm,
experimentalGcm: gcm,
/** @see module:crypto/eax */
eax: eax,
/** @see module:crypto/ocb */
ocb: ocb,
/** @see module:crypto/public_key */ /** @see module:crypto/public_key */
publicKey: publicKey, publicKey: publicKey,
/** @see module:crypto/signature */ /** @see module:crypto/signature */
@ -50,7 +40,7 @@ const mod = {
/** @see module:crypto/pkcs5 */ /** @see module:crypto/pkcs5 */
pkcs5: pkcs5, pkcs5: pkcs5,
/** @see module:crypto/aes_kw */ /** @see module:crypto/aes_kw */
aes_kw: aes_kw aesKW: aesKW
}; };
Object.assign(mod, crypto); Object.assign(mod, crypto);

View File

@ -18,15 +18,15 @@
*/ */
/** /**
* @module crypto/cfb * @module crypto/mode/cfb
* @private * @private
*/ */
import { AES_CFB } from '@openpgp/asmcrypto.js/dist_es8/aes/cfb'; import { AES_CFB } from '@openpgp/asmcrypto.js/dist_es8/aes/cfb';
import stream from '@openpgp/web-stream-tools'; import stream from '@openpgp/web-stream-tools';
import * as cipher from './cipher'; import * as cipher from '../cipher';
import util from '../util'; import util from '../../util';
const webCrypto = util.getWebCrypto(); const webCrypto = util.getWebCrypto();
const nodeCrypto = util.getNodeCrypto(); const nodeCrypto = util.getNodeCrypto();

View File

@ -18,13 +18,13 @@
/** /**
* @fileoverview This module implements AES-EAX en/decryption on top of * @fileoverview This module implements AES-EAX en/decryption on top of
* native AES-CTR using either the WebCrypto API or Node.js' crypto API. * native AES-CTR using either the WebCrypto API or Node.js' crypto API.
* @module crypto/eax * @module crypto/mode/eax
* @private * @private
*/ */
import { AES_CTR } from '@openpgp/asmcrypto.js/dist_es8/aes/ctr'; import { AES_CTR } from '@openpgp/asmcrypto.js/dist_es8/aes/ctr';
import CMAC from './cmac'; import CMAC from '../cmac';
import util from '../util'; import util from '../../util';
const webCrypto = util.getWebCrypto(); const webCrypto = util.getWebCrypto();
const nodeCrypto = util.getNodeCrypto(); const nodeCrypto = util.getNodeCrypto();

View File

@ -18,12 +18,12 @@
/** /**
* @fileoverview This module wraps native AES-GCM en/decryption for both * @fileoverview This module wraps native AES-GCM en/decryption for both
* the WebCrypto api as well as node.js' crypto api. * the WebCrypto api as well as node.js' crypto api.
* @module crypto/gcm * @module crypto/mode/gcm
* @private * @private
*/ */
import { AES_GCM } from '@openpgp/asmcrypto.js/dist_es8/aes/gcm'; import { AES_GCM } from '@openpgp/asmcrypto.js/dist_es8/aes/gcm';
import util from '../util'; import util from '../../util';
const webCrypto = util.getWebCrypto(); // no GCM support in IE11, Safari 9 const webCrypto = util.getWebCrypto(); // no GCM support in IE11, Safari 9
const nodeCrypto = util.getNodeCrypto(); const nodeCrypto = util.getNodeCrypto();

22
src/crypto/mode/index.js Normal file
View File

@ -0,0 +1,22 @@
/**
* @fileoverview Cipher modes
* @module crypto/mode
* @private
*/
import * as cfb from './cfb';
import eax from './eax';
import ocb from './ocb';
import gcm from './gcm';
export default {
/** @see module:crypto/mode/cfb */
cfb: cfb,
/** @see module:crypto/mode/gcm */
gcm: gcm,
experimentalGCM: gcm,
/** @see module:crypto/mode/eax */
eax: eax,
/** @see module:crypto/mode/ocb */
ocb: ocb
};

View File

@ -17,12 +17,12 @@
/** /**
* @fileoverview This module implements AES-OCB en/decryption. * @fileoverview This module implements AES-OCB en/decryption.
* @module crypto/ocb * @module crypto/mode/ocb
* @private * @private
*/ */
import * as ciphers from './cipher'; import * as ciphers from '../cipher';
import util from '../util'; import util from '../../util';
const blockLength = 16; const blockLength = 16;

View File

@ -52,7 +52,7 @@ hash_headers[11] = [0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
* @returns {Uint8Array} Random padding. * @returns {Uint8Array} Random padding.
* @async * @async
*/ */
async function getPkcs1Padding(length) { async function getPKCS1Padding(length) {
const result = new Uint8Array(length); const result = new Uint8Array(length);
let count = 0; let count = 0;
while (count < length) { while (count < length) {
@ -82,7 +82,7 @@ export async function emeEncode(message, keyLength) {
} }
// Generate an octet string PS of length k - mLen - 3 consisting of // Generate an octet string PS of length k - mLen - 3 consisting of
// pseudo-randomly generated nonzero octets // pseudo-randomly generated nonzero octets
const PS = await getPkcs1Padding(keyLength - mLength - 3); const PS = await getPKCS1Padding(keyLength - mLength - 3);
// Concatenate PS, the message M, and other padding to form an // Concatenate PS, the message M, and other padding to form an
// encoded message EM of length k octets as EM = 0x00 || 0x02 || PS || 0x00 || M. // encoded message EM of length k octets as EM = 0x00 || 0x02 || PS || 0x00 || M.
const encoded = new Uint8Array(keyLength); const encoded = new Uint8Array(keyLength);

View File

@ -32,7 +32,7 @@ import { isProbablePrime } from './prime';
/** /**
* DSA Sign function * DSA Sign function
* @param {Integer} hash_algo * @param {Integer} hashAlgo
* @param {Uint8Array} hashed * @param {Uint8Array} hashed
* @param {Uint8Array} g * @param {Uint8Array} g
* @param {Uint8Array} p * @param {Uint8Array} p
@ -41,7 +41,7 @@ import { isProbablePrime } from './prime';
* @returns {{ r: Uint8Array, s: Uint8Array }} * @returns {{ r: Uint8Array, s: Uint8Array }}
* @async * @async
*/ */
export async function sign(hash_algo, hashed, g, p, q, x) { export async function sign(hashAlgo, hashed, g, p, q, x) {
const BigInteger = await util.getBigInteger(); const BigInteger = await util.getBigInteger();
const one = new BigInteger(1); const one = new BigInteger(1);
p = new BigInteger(p); p = new BigInteger(p);
@ -89,7 +89,7 @@ export async function sign(hash_algo, hashed, g, p, q, x) {
/** /**
* DSA Verify function * DSA Verify function
* @param {Integer} hash_algo * @param {Integer} hashAlgo
* @param {Uint8Array} r * @param {Uint8Array} r
* @param {Uint8Array} s * @param {Uint8Array} s
* @param {Uint8Array} hashed * @param {Uint8Array} hashed
@ -100,7 +100,7 @@ export async function sign(hash_algo, hashed, g, p, q, x) {
* @returns {boolean} * @returns {boolean}
* @async * @async
*/ */
export async function verify(hash_algo, r, s, hashed, g, p, q, y) { export async function verify(hashAlgo, r, s, hashed, g, p, q, y) {
const BigInteger = await util.getBigInteger(); const BigInteger = await util.getBigInteger();
const zero = new BigInteger(0); const zero = new BigInteger(0);
r = new BigInteger(r); r = new BigInteger(r);

View File

@ -131,19 +131,19 @@ const curves = {
}; };
class Curve { class Curve {
constructor(oid_or_name, params) { constructor(oidOrName, params) {
try { try {
if (util.isArray(oid_or_name) || if (util.isArray(oidOrName) ||
util.isUint8Array(oid_or_name)) { util.isUint8Array(oidOrName)) {
// by oid byte array // by oid byte array
oid_or_name = new OID(oid_or_name); oidOrName = new OID(oidOrName);
} }
if (oid_or_name instanceof OID) { if (oidOrName instanceof OID) {
// by curve OID // by curve OID
oid_or_name = oid_or_name.getName(); oidOrName = oidOrName.getName();
} }
// by curve name or oid string // by curve name or oid string
this.name = enums.write(enums.curve, oid_or_name); this.name = enums.write(enums.curve, oidOrName);
} catch (err) { } catch (err) {
throw new Error('Not valid curve'); throw new Error('Not valid curve');
} }
@ -198,7 +198,7 @@ class Curve {
} }
const indutnyCurve = await getIndutnyCurve(this.name); const indutnyCurve = await getIndutnyCurve(this.name);
keyPair = await indutnyCurve.genKeyPair({ keyPair = await indutnyCurve.genKeyPair({
entropy: util.uint8ArrayToStr(await getRandomBytes(32)) entropy: util.uint8ArrayToString(await getRandomBytes(32))
}); });
return { publicKey: new Uint8Array(keyPair.getPublic('array', false)), privateKey: keyPair.getPrivate().toArrayLike(Uint8Array) }; return { publicKey: new Uint8Array(keyPair.getPublic('array', false)), privateKey: keyPair.getPrivate().toArrayLike(Uint8Array) };
} }
@ -287,7 +287,7 @@ async function validateStandardParams(algo, oid, Q, d) {
} }
export { export {
Curve, curves, webCurves, nodeCurves, generate, getPreferredHashAlgo, jwkToRawPublic, rawPublicToJwk, privateToJwk, validateStandardParams Curve, curves, webCurves, nodeCurves, generate, getPreferredHashAlgo, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams
}; };
////////////////////////// //////////////////////////
@ -348,7 +348,7 @@ function jwkToRawPublic(jwk) {
* *
* @returns {JsonWebKey} Public key in jwk format. * @returns {JsonWebKey} Public key in jwk format.
*/ */
function rawPublicToJwk(payloadSize, name, publicKey) { function rawPublicToJWK(payloadSize, name, publicKey) {
const len = payloadSize; const len = payloadSize;
const bufX = publicKey.slice(1, len + 1); const bufX = publicKey.slice(1, len + 1);
const bufY = publicKey.slice(len + 1, len * 2 + 1); const bufY = publicKey.slice(len + 1, len * 2 + 1);
@ -371,8 +371,8 @@ function rawPublicToJwk(payloadSize, name, publicKey) {
* *
* @returns {JsonWebKey} Private key in jwk format. * @returns {JsonWebKey} Private key in jwk format.
*/ */
function privateToJwk(payloadSize, name, publicKey, privateKey) { function privateToJWK(payloadSize, name, publicKey, privateKey) {
const jwk = rawPublicToJwk(payloadSize, name, publicKey); const jwk = rawPublicToJWK(payloadSize, name, publicKey);
jwk.d = uint8ArrayToB64(privateKey, true); jwk.d = uint8ArrayToB64(privateKey, true);
return jwk; return jwk;
} }

View File

@ -22,8 +22,8 @@
*/ */
import nacl from '@openpgp/tweetnacl/nacl-fast-light.js'; import nacl from '@openpgp/tweetnacl/nacl-fast-light.js';
import { Curve, jwkToRawPublic, rawPublicToJwk, privateToJwk, validateStandardParams } from './curves'; import { Curve, jwkToRawPublic, rawPublicToJWK, privateToJWK, validateStandardParams } from './curves';
import * as aes_kw from '../../aes_kw'; import * as aesKW from '../../aes_kw';
import * as cipher from '../../cipher'; import * as cipher from '../../cipher';
import { getRandomBytes } from '../../random'; import { getRandomBytes } from '../../random';
import hash from '../../hash'; import hash from '../../hash';
@ -54,13 +54,13 @@ function buildEcdhParam(public_algo, oid, kdfParams, fingerprint) {
oid.write(), oid.write(),
new Uint8Array([public_algo]), new Uint8Array([public_algo]),
kdfParams.write(), kdfParams.write(),
util.strToUint8Array("Anonymous Sender "), util.stringToUint8Array("Anonymous Sender "),
fingerprint.subarray(0, 20) fingerprint.subarray(0, 20)
]); ]);
} }
// Key Derivation Function (RFC 6637) // Key Derivation Function (RFC 6637)
async function kdf(hash_algo, X, length, param, stripLeading = false, stripTrailing = false) { async function kdf(hashAlgo, X, length, param, stripLeading = false, stripTrailing = false) {
// Note: X is little endian for Curve25519, big-endian for all others. // Note: X is little endian for Curve25519, big-endian for all others.
// This is not ideal, but the RFC's are unclear // This is not ideal, but the RFC's are unclear
// https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-02#appendix-B // https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-02#appendix-B
@ -75,7 +75,7 @@ async function kdf(hash_algo, X, length, param, stripLeading = false, stripTrail
for (i = X.length - 1; i >= 0 && X[i] === 0; i--); for (i = X.length - 1; i >= 0 && X[i] === 0; i--);
X = X.subarray(0, i + 1); X = X.subarray(0, i + 1);
} }
const digest = await hash.digest(hash_algo, util.concatUint8Array([ const digest = await hash.digest(hashAlgo, util.concatUint8Array([
new Uint8Array([0, 0, 0, 1]), new Uint8Array([0, 0, 0, 1]),
X, X,
param param
@ -132,9 +132,9 @@ export async function encrypt(oid, kdfParams, data, Q, fingerprint) {
const curve = new Curve(oid); const curve = new Curve(oid);
const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q); const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q);
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint); const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
const cipher_algo = enums.read(enums.symmetric, kdfParams.cipher); const cipherAlgo = enums.read(enums.symmetric, kdfParams.cipher);
const Z = await kdf(kdfParams.hash, sharedKey, cipher[cipher_algo].keySize, param); const Z = await kdf(kdfParams.hash, sharedKey, cipher[cipherAlgo].keySize, param);
const wrappedKey = aes_kw.wrap(Z, m); const wrappedKey = aesKW.wrap(Z, m);
return { publicKey, wrappedKey }; return { publicKey, wrappedKey };
} }
@ -192,13 +192,13 @@ export async function decrypt(oid, kdfParams, V, C, Q, d, fingerprint) {
const curve = new Curve(oid); const curve = new Curve(oid);
const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d); const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d);
const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint); const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
const cipher_algo = enums.read(enums.symmetric, kdfParams.cipher); const cipherAlgo = enums.read(enums.symmetric, kdfParams.cipher);
let err; let err;
for (let i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {
try { try {
// Work around old go crypto bug and old OpenPGP.js bug, respectively. // Work around old go crypto bug and old OpenPGP.js bug, respectively.
const Z = await kdf(kdfParams.hash, sharedKey, cipher[cipher_algo].keySize, param, i === 1, i === 2); const Z = await kdf(kdfParams.hash, sharedKey, cipher[cipherAlgo].keySize, param, i === 1, i === 2);
return pkcs5.decode(aes_kw.unwrap(Z, C)); return pkcs5.decode(aesKW.unwrap(Z, C));
} catch (e) { } catch (e) {
err = e; err = e;
} }
@ -217,7 +217,7 @@ export async function decrypt(oid, kdfParams, V, C, Q, d, fingerprint) {
* @async * @async
*/ */
async function webPrivateEphemeralKey(curve, V, Q, d) { async function webPrivateEphemeralKey(curve, V, Q, d) {
const recipient = privateToJwk(curve.payloadSize, curve.web.web, Q, d); const recipient = privateToJWK(curve.payloadSize, curve.web.web, Q, d);
let privateKey = webCrypto.importKey( let privateKey = webCrypto.importKey(
"jwk", "jwk",
recipient, recipient,
@ -228,7 +228,7 @@ async function webPrivateEphemeralKey(curve, V, Q, d) {
true, true,
["deriveKey", "deriveBits"] ["deriveKey", "deriveBits"]
); );
const jwk = rawPublicToJwk(curve.payloadSize, curve.web.web, V); const jwk = rawPublicToJWK(curve.payloadSize, curve.web.web, V);
let sender = webCrypto.importKey( let sender = webCrypto.importKey(
"jwk", "jwk",
jwk, jwk,
@ -268,7 +268,7 @@ async function webPrivateEphemeralKey(curve, V, Q, d) {
* @async * @async
*/ */
async function webPublicEphemeralKey(curve, Q) { async function webPublicEphemeralKey(curve, Q) {
const jwk = rawPublicToJwk(curve.payloadSize, curve.web.web, Q); const jwk = rawPublicToJWK(curve.payloadSize, curve.web.web, Q);
let keyPair = webCrypto.generateKey( let keyPair = webCrypto.generateKey(
{ {
name: "ECDH", name: "ECDH",

View File

@ -25,7 +25,7 @@ import enums from '../../../enums';
import util from '../../../util'; import util from '../../../util';
import { getRandomBytes } from '../../random'; import { getRandomBytes } from '../../random';
import hash from '../../hash'; import hash from '../../hash';
import { Curve, webCurves, privateToJwk, rawPublicToJwk, validateStandardParams } from './curves'; import { Curve, webCurves, privateToJWK, rawPublicToJWK, validateStandardParams } from './curves';
import { getIndutnyCurve, keyFromPrivate, keyFromPublic } from './indutnyKey'; import { getIndutnyCurve, keyFromPrivate, keyFromPublic } from './indutnyKey';
const webCrypto = util.getWebCrypto(); const webCrypto = util.getWebCrypto();
@ -34,7 +34,7 @@ const nodeCrypto = util.getNodeCrypto();
/** /**
* Sign a message using the provided key * Sign a message using the provided key
* @param {module:type/oid} oid - Elliptic curve object identifier * @param {module:type/oid} oid - Elliptic curve object identifier
* @param {module:enums.hash} hash_algo - Hash algorithm used to sign * @param {module:enums.hash} hashAlgo - Hash algorithm used to sign
* @param {Uint8Array} message - Message to sign * @param {Uint8Array} message - Message to sign
* @param {Uint8Array} publicKey - Public key * @param {Uint8Array} publicKey - Public key
* @param {Uint8Array} privateKey - Private key used to sign the message * @param {Uint8Array} privateKey - Private key used to sign the message
@ -43,7 +43,7 @@ const nodeCrypto = util.getNodeCrypto();
* s: Uint8Array}} Signature of the message * s: Uint8Array}} Signature of the message
* @async * @async
*/ */
export async function sign(oid, hash_algo, message, publicKey, privateKey, hashed) { export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed) {
const curve = new Curve(oid); const curve = new Curve(oid);
if (message && !util.isStream(message)) { if (message && !util.isStream(message)) {
const keyPair = { publicKey, privateKey }; const keyPair = { publicKey, privateKey };
@ -52,7 +52,7 @@ export async function sign(oid, hash_algo, message, publicKey, privateKey, hashe
// If browser doesn't support a curve, we'll catch it // If browser doesn't support a curve, we'll catch it
try { try {
// Need to await to make sure browser succeeds // Need to await to make sure browser succeeds
return await webSign(curve, hash_algo, message, keyPair); return await webSign(curve, hashAlgo, message, keyPair);
} catch (err) { } catch (err) {
// We do not fallback if the error is related to key integrity // We do not fallback if the error is related to key integrity
// Unfortunaley Safari does not support p521 and throws a DataError when using it // Unfortunaley Safari does not support p521 and throws a DataError when using it
@ -65,7 +65,7 @@ export async function sign(oid, hash_algo, message, publicKey, privateKey, hashe
break; break;
} }
case 'node': { case 'node': {
const signature = await nodeSign(curve, hash_algo, message, keyPair); const signature = await nodeSign(curve, hashAlgo, message, keyPair);
return { return {
r: signature.r.toArrayLike(Uint8Array), r: signature.r.toArrayLike(Uint8Array),
s: signature.s.toArrayLike(Uint8Array) s: signature.s.toArrayLike(Uint8Array)
@ -79,7 +79,7 @@ export async function sign(oid, hash_algo, message, publicKey, privateKey, hashe
/** /**
* Verifies if a signature is valid for a message * Verifies if a signature is valid for a message
* @param {module:type/oid} oid - Elliptic curve object identifier * @param {module:type/oid} oid - Elliptic curve object identifier
* @param {module:enums.hash} hash_algo - Hash algorithm used in the signature * @param {module:enums.hash} hashAlgo - Hash algorithm used in the signature
* @param {{r: Uint8Array, * @param {{r: Uint8Array,
s: Uint8Array}} signature Signature to verify s: Uint8Array}} signature Signature to verify
* @param {Uint8Array} message - Message to verify * @param {Uint8Array} message - Message to verify
@ -88,14 +88,14 @@ export async function sign(oid, hash_algo, message, publicKey, privateKey, hashe
* @returns {Boolean} * @returns {Boolean}
* @async * @async
*/ */
export async function verify(oid, hash_algo, signature, message, publicKey, hashed) { export async function verify(oid, hashAlgo, signature, message, publicKey, hashed) {
const curve = new Curve(oid); const curve = new Curve(oid);
if (message && !util.isStream(message)) { if (message && !util.isStream(message)) {
switch (curve.type) { switch (curve.type) {
case 'web': case 'web':
try { try {
// Need to await to make sure browser succeeds // Need to await to make sure browser succeeds
return await webVerify(curve, hash_algo, signature, message, publicKey); return await webVerify(curve, hashAlgo, signature, message, publicKey);
} catch (err) { } catch (err) {
// We do not fallback if the error is related to key integrity // We do not fallback if the error is related to key integrity
// Unfortunately Safari does not support p521 and throws a DataError when using it // Unfortunately Safari does not support p521 and throws a DataError when using it
@ -107,10 +107,10 @@ export async function verify(oid, hash_algo, signature, message, publicKey, hash
} }
break; break;
case 'node': case 'node':
return nodeVerify(curve, hash_algo, signature, message, publicKey); return nodeVerify(curve, hashAlgo, signature, message, publicKey);
} }
} }
const digest = (typeof hash_algo === 'undefined') ? message : hashed; const digest = (typeof hashAlgo === 'undefined') ? message : hashed;
return ellipticVerify(curve, signature, digest, publicKey); return ellipticVerify(curve, signature, digest, publicKey);
} }
@ -172,9 +172,9 @@ async function ellipticVerify(curve, signature, digest, publicKey) {
return key.verify(digest, signature); return key.verify(digest, signature);
} }
async function webSign(curve, hash_algo, message, keyPair) { async function webSign(curve, hashAlgo, message, keyPair) {
const len = curve.payloadSize; const len = curve.payloadSize;
const jwk = privateToJwk(curve.payloadSize, webCurves[curve.name], keyPair.publicKey, keyPair.privateKey); const jwk = privateToJWK(curve.payloadSize, webCurves[curve.name], keyPair.publicKey, keyPair.privateKey);
const key = await webCrypto.importKey( const key = await webCrypto.importKey(
"jwk", "jwk",
jwk, jwk,
@ -191,7 +191,7 @@ async function webSign(curve, hash_algo, message, keyPair) {
{ {
"name": 'ECDSA', "name": 'ECDSA',
"namedCurve": webCurves[curve.name], "namedCurve": webCurves[curve.name],
"hash": { name: enums.read(enums.webHash, hash_algo) } "hash": { name: enums.read(enums.webHash, hashAlgo) }
}, },
key, key,
message message
@ -203,8 +203,8 @@ async function webSign(curve, hash_algo, message, keyPair) {
}; };
} }
async function webVerify(curve, hash_algo, { r, s }, message, publicKey) { async function webVerify(curve, hashAlgo, { r, s }, message, publicKey) {
const jwk = rawPublicToJwk(curve.payloadSize, webCurves[curve.name], publicKey); const jwk = rawPublicToJWK(curve.payloadSize, webCurves[curve.name], publicKey);
const key = await webCrypto.importKey( const key = await webCrypto.importKey(
"jwk", "jwk",
jwk, jwk,
@ -223,7 +223,7 @@ async function webVerify(curve, hash_algo, { r, s }, message, publicKey) {
{ {
"name": 'ECDSA', "name": 'ECDSA',
"namedCurve": webCurves[curve.name], "namedCurve": webCurves[curve.name],
"hash": { name: enums.read(enums.webHash, hash_algo) } "hash": { name: enums.read(enums.webHash, hashAlgo) }
}, },
key, key,
signature, signature,
@ -231,8 +231,8 @@ async function webVerify(curve, hash_algo, { r, s }, message, publicKey) {
); );
} }
async function nodeSign(curve, hash_algo, message, keyPair) { async function nodeSign(curve, hashAlgo, message, keyPair) {
const sign = nodeCrypto.createSign(enums.read(enums.hash, hash_algo)); const sign = nodeCrypto.createSign(enums.read(enums.hash, hashAlgo));
sign.write(message); sign.write(message);
sign.end(); sign.end();
const key = ECPrivateKey.encode({ const key = ECPrivateKey.encode({
@ -247,10 +247,10 @@ async function nodeSign(curve, hash_algo, message, keyPair) {
return ECDSASignature.decode(sign.sign(key), 'der'); return ECDSASignature.decode(sign.sign(key), 'der');
} }
async function nodeVerify(curve, hash_algo, { r, s }, message, publicKey) { async function nodeVerify(curve, hashAlgo, { r, s }, message, publicKey) {
const { default: BN } = await import('bn.js'); const { default: BN } = await import('bn.js');
const verify = nodeCrypto.createVerify(enums.read(enums.hash, hash_algo)); const verify = nodeCrypto.createVerify(enums.read(enums.hash, hashAlgo));
verify.write(message); verify.write(message);
verify.end(); verify.end();
const key = SubjectPublicKeyInfo.encode({ const key = SubjectPublicKeyInfo.encode({

View File

@ -32,7 +32,7 @@ nacl.hash = bytes => new Uint8Array(sha512().update(bytes).digest());
/** /**
* Sign a message using the provided key * Sign a message using the provided key
* @param {module:type/oid} oid - Elliptic curve object identifier * @param {module:type/oid} oid - Elliptic curve object identifier
* @param {module:enums.hash} hash_algo - Hash algorithm used to sign (must be sha256 or stronger) * @param {module:enums.hash} hashAlgo - Hash algorithm used to sign (must be sha256 or stronger)
* @param {Uint8Array} message - Message to sign * @param {Uint8Array} message - Message to sign
* @param {Uint8Array} publicKey - Public key * @param {Uint8Array} publicKey - Public key
* @param {Uint8Array} privateKey - Private key used to sign the message * @param {Uint8Array} privateKey - Private key used to sign the message
@ -41,8 +41,8 @@ nacl.hash = bytes => new Uint8Array(sha512().update(bytes).digest());
* s: Uint8Array}} Signature of the message * s: Uint8Array}} Signature of the message
* @async * @async
*/ */
export async function sign(oid, hash_algo, message, publicKey, privateKey, hashed) { export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed) {
if (hash.getHashByteLength(hash_algo) < hash.getHashByteLength(enums.hash.sha256)) { if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
// see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2 // see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
throw new Error('Hash algorithm too weak: sha256 or stronger is required for EdDSA.'); throw new Error('Hash algorithm too weak: sha256 or stronger is required for EdDSA.');
} }
@ -58,7 +58,7 @@ export async function sign(oid, hash_algo, message, publicKey, privateKey, hashe
/** /**
* Verifies if a signature is valid for a message * Verifies if a signature is valid for a message
* @param {module:type/oid} oid - Elliptic curve object identifier * @param {module:type/oid} oid - Elliptic curve object identifier
* @param {module:enums.hash} hash_algo - Hash algorithm used in the signature * @param {module:enums.hash} hashAlgo - Hash algorithm used in the signature
* @param {{r: Uint8Array, * @param {{r: Uint8Array,
s: Uint8Array}} signature Signature to verify the message s: Uint8Array}} signature Signature to verify the message
* @param {Uint8Array} m - Message to verify * @param {Uint8Array} m - Message to verify
@ -67,7 +67,7 @@ export async function sign(oid, hash_algo, message, publicKey, privateKey, hashe
* @returns {Boolean} * @returns {Boolean}
* @async * @async
*/ */
export async function verify(oid, hash_algo, { r, s }, m, publicKey, hashed) { export async function verify(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
const signature = util.concatUint8Array([r, s]); const signature = util.concatUint8Array([r, s]);
return nacl.sign.detached.verify(hashed, signature, publicKey.subarray(1)); return nacl.sign.detached.verify(hashed, signature, publicKey.subarray(1));
} }

View File

@ -71,7 +71,7 @@ const RSAPublicKey = util.detectNode() ? asn1.define('RSAPubliceKey', function (
/* eslint-enable no-invalid-this */ /* eslint-enable no-invalid-this */
/** Create signature /** Create signature
* @param {module:enums.hash} hash_algo - Hash algorithm * @param {module:enums.hash} hashAlgo - Hash algorithm
* @param {Uint8Array} data - Message * @param {Uint8Array} data - Message
* @param {Uint8Array} n - RSA public modulus * @param {Uint8Array} n - RSA public modulus
* @param {Uint8Array} e - RSA public exponent * @param {Uint8Array} e - RSA public exponent
@ -83,24 +83,24 @@ const RSAPublicKey = util.detectNode() ? asn1.define('RSAPubliceKey', function (
* @returns {Uint8Array} RSA Signature. * @returns {Uint8Array} RSA Signature.
* @async * @async
*/ */
export async function sign(hash_algo, data, n, e, d, p, q, u, hashed) { export async function sign(hashAlgo, data, n, e, d, p, q, u, hashed) {
if (data && !util.isStream(data)) { if (data && !util.isStream(data)) {
if (util.getWebCrypto()) { if (util.getWebCrypto()) {
try { try {
return await webSign(enums.read(enums.webHash, hash_algo), data, n, e, d, p, q, u); return await webSign(enums.read(enums.webHash, hashAlgo), data, n, e, d, p, q, u);
} catch (err) { } catch (err) {
util.printDebugError(err); util.printDebugError(err);
} }
} else if (util.getNodeCrypto()) { } else if (util.getNodeCrypto()) {
return nodeSign(hash_algo, data, n, e, d, p, q, u); return nodeSign(hashAlgo, data, n, e, d, p, q, u);
} }
} }
return bnSign(hash_algo, n, d, hashed); return bnSign(hashAlgo, n, d, hashed);
} }
/** /**
* Verify signature * Verify signature
* @param {module:enums.hash} hash_algo - Hash algorithm * @param {module:enums.hash} hashAlgo - Hash algorithm
* @param {Uint8Array} data - Message * @param {Uint8Array} data - Message
* @param {Uint8Array} s - Signature * @param {Uint8Array} s - Signature
* @param {Uint8Array} n - RSA public modulus * @param {Uint8Array} n - RSA public modulus
@ -109,19 +109,19 @@ export async function sign(hash_algo, data, n, e, d, p, q, u, hashed) {
* @returns {Boolean} * @returns {Boolean}
* @async * @async
*/ */
export async function verify(hash_algo, data, s, n, e, hashed) { export async function verify(hashAlgo, data, s, n, e, hashed) {
if (data && !util.isStream(data)) { if (data && !util.isStream(data)) {
if (util.getWebCrypto()) { if (util.getWebCrypto()) {
try { try {
return await webVerify(enums.read(enums.webHash, hash_algo), data, s, n, e); return await webVerify(enums.read(enums.webHash, hashAlgo), data, s, n, e);
} catch (err) { } catch (err) {
util.printDebugError(err); util.printDebugError(err);
} }
} else if (util.getNodeCrypto()) { } else if (util.getNodeCrypto()) {
return nodeVerify(hash_algo, data, s, n, e); return nodeVerify(hashAlgo, data, s, n, e);
} }
} }
return bnVerify(hash_algo, s, n, e, hashed); return bnVerify(hashAlgo, s, n, e, hashed);
} }
/** /**
@ -330,10 +330,10 @@ export async function validateParams(n, e, d, p, q, u) {
return true; return true;
} }
async function bnSign(hash_algo, n, d, hashed) { async function bnSign(hashAlgo, n, d, hashed) {
const BigInteger = await util.getBigInteger(); const BigInteger = await util.getBigInteger();
n = new BigInteger(n); n = new BigInteger(n);
const m = new BigInteger(await emsaEncode(hash_algo, hashed, n.byteLength())); const m = new BigInteger(await emsaEncode(hashAlgo, hashed, n.byteLength()));
d = new BigInteger(d); d = new BigInteger(d);
if (m.gte(n)) { if (m.gte(n)) {
throw new Error('Message size cannot exceed modulus size'); throw new Error('Message size cannot exceed modulus size');
@ -341,31 +341,31 @@ async function bnSign(hash_algo, n, d, hashed) {
return m.modExp(d, n).toUint8Array('be', n.byteLength()); return m.modExp(d, n).toUint8Array('be', n.byteLength());
} }
async function webSign(hash_name, data, n, e, d, p, q, u) { async function webSign(hashName, data, n, e, d, p, q, u) {
/** OpenPGP keys require that p < q, and Safari Web Crypto requires that p > q. /** OpenPGP keys require that p < q, and Safari Web Crypto requires that p > q.
* We swap them in privateToJwk, so it usually works out, but nevertheless, * We swap them in privateToJWK, so it usually works out, but nevertheless,
* not all OpenPGP keys are compatible with this requirement. * not all OpenPGP keys are compatible with this requirement.
* OpenPGP.js used to generate RSA keys the wrong way around (p > q), and still * OpenPGP.js used to generate RSA keys the wrong way around (p > q), and still
* does if the underlying Web Crypto does so (e.g. old MS Edge 50% of the time). * does if the underlying Web Crypto does so (e.g. old MS Edge 50% of the time).
*/ */
const jwk = await privateToJwk(n, e, d, p, q, u); const jwk = await privateToJWK(n, e, d, p, q, u);
const algo = { const algo = {
name: "RSASSA-PKCS1-v1_5", name: "RSASSA-PKCS1-v1_5",
hash: { name: hash_name } hash: { name: hashName }
}; };
const key = await webCrypto.importKey("jwk", jwk, algo, false, ["sign"]); const key = await webCrypto.importKey("jwk", jwk, algo, false, ["sign"]);
// add hash field for ms edge support // add hash field for ms edge support
return new Uint8Array(await webCrypto.sign({ "name": "RSASSA-PKCS1-v1_5", "hash": hash_name }, key, data)); return new Uint8Array(await webCrypto.sign({ "name": "RSASSA-PKCS1-v1_5", "hash": hashName }, key, data));
} }
async function nodeSign(hash_algo, data, n, e, d, p, q, u) { async function nodeSign(hashAlgo, data, n, e, d, p, q, u) {
const { default: BN } = await import('bn.js'); const { default: BN } = await import('bn.js');
const pBNum = new BN(p); const pBNum = new BN(p);
const qBNum = new BN(q); const qBNum = new BN(q);
const dBNum = new BN(d); const dBNum = new BN(d);
const dq = dBNum.mod(qBNum.subn(1)); // d mod (q-1) const dq = dBNum.mod(qBNum.subn(1)); // d mod (q-1)
const dp = dBNum.mod(pBNum.subn(1)); // d mod (p-1) const dp = dBNum.mod(pBNum.subn(1)); // d mod (p-1)
const sign = nodeCrypto.createSign(enums.read(enums.hash, hash_algo)); const sign = nodeCrypto.createSign(enums.read(enums.hash, hashAlgo));
sign.write(data); sign.write(data);
sign.end(); sign.end();
const keyObject = { const keyObject = {
@ -391,7 +391,7 @@ async function nodeSign(hash_algo, data, n, e, d, p, q, u) {
return new Uint8Array(sign.sign(pem)); return new Uint8Array(sign.sign(pem));
} }
async function bnVerify(hash_algo, s, n, e, hashed) { async function bnVerify(hashAlgo, s, n, e, hashed) {
const BigInteger = await util.getBigInteger(); const BigInteger = await util.getBigInteger();
n = new BigInteger(n); n = new BigInteger(n);
s = new BigInteger(s); s = new BigInteger(s);
@ -400,24 +400,24 @@ async function bnVerify(hash_algo, s, n, e, hashed) {
throw new Error('Signature size cannot exceed modulus size'); throw new Error('Signature size cannot exceed modulus size');
} }
const EM1 = s.modExp(e, n).toUint8Array('be', n.byteLength()); const EM1 = s.modExp(e, n).toUint8Array('be', n.byteLength());
const EM2 = await emsaEncode(hash_algo, hashed, n.byteLength()); const EM2 = await emsaEncode(hashAlgo, hashed, n.byteLength());
return util.equalsUint8Array(EM1, EM2); return util.equalsUint8Array(EM1, EM2);
} }
async function webVerify(hash_name, data, s, n, e) { async function webVerify(hashName, data, s, n, e) {
const jwk = publicToJwk(n, e); const jwk = publicToJWK(n, e);
const key = await webCrypto.importKey("jwk", jwk, { const key = await webCrypto.importKey("jwk", jwk, {
name: "RSASSA-PKCS1-v1_5", name: "RSASSA-PKCS1-v1_5",
hash: { name: hash_name } hash: { name: hashName }
}, false, ["verify"]); }, false, ["verify"]);
// add hash field for ms edge support // add hash field for ms edge support
return webCrypto.verify({ "name": "RSASSA-PKCS1-v1_5", "hash": hash_name }, key, s, data); return webCrypto.verify({ "name": "RSASSA-PKCS1-v1_5", "hash": hashName }, key, s, data);
} }
async function nodeVerify(hash_algo, data, s, n, e) { async function nodeVerify(hashAlgo, data, s, n, e) {
const { default: BN } = await import('bn.js'); const { default: BN } = await import('bn.js');
const verify = nodeCrypto.createVerify(enums.read(enums.hash, hash_algo)); const verify = nodeCrypto.createVerify(enums.read(enums.hash, hashAlgo));
verify.write(data); verify.write(data);
verify.end(); verify.end();
const keyObject = { const keyObject = {
@ -543,7 +543,7 @@ async function bnDecrypt(data, n, e, d, p, q, u) {
/** Convert Openpgp private key params to jwk key according to /** Convert Openpgp private key params to jwk key according to
* @link https://tools.ietf.org/html/rfc7517 * @link https://tools.ietf.org/html/rfc7517
* @param {String} hash_algo * @param {String} hashAlgo
* @param {Uint8Array} n * @param {Uint8Array} n
* @param {Uint8Array} e * @param {Uint8Array} e
* @param {Uint8Array} d * @param {Uint8Array} d
@ -551,7 +551,7 @@ async function bnDecrypt(data, n, e, d, p, q, u) {
* @param {Uint8Array} q * @param {Uint8Array} q
* @param {Uint8Array} u * @param {Uint8Array} u
*/ */
async function privateToJwk(n, e, d, p, q, u) { async function privateToJWK(n, e, d, p, q, u) {
const BigInteger = await util.getBigInteger(); const BigInteger = await util.getBigInteger();
const pNum = new BigInteger(p); const pNum = new BigInteger(p);
const qNum = new BigInteger(q); const qNum = new BigInteger(q);
@ -579,11 +579,11 @@ async function privateToJwk(n, e, d, p, q, u) {
/** Convert Openpgp key public params to jwk key according to /** Convert Openpgp key public params to jwk key according to
* @link https://tools.ietf.org/html/rfc7517 * @link https://tools.ietf.org/html/rfc7517
* @param {String} hash_algo * @param {String} hashAlgo
* @param {Uint8Array} n * @param {Uint8Array} n
* @param {Uint8Array} e * @param {Uint8Array} e
*/ */
function publicToJwk(n, e) { function publicToJWK(n, e) {
return { return {
kty: 'RSA', kty: 'RSA',
n: uint8ArrayToB64(n, true), n: uint8ArrayToB64(n, true),

View File

@ -30,8 +30,8 @@ if (Buffer) {
return new Uint8Array(b.buffer, b.byteOffset, b.byteLength); return new Uint8Array(b.buffer, b.byteOffset, b.byteLength);
}; };
} else { } else {
encodeChunk = buf => btoa(util.uint8ArrayToStr(buf)); encodeChunk = buf => btoa(util.uint8ArrayToString(buf));
decodeChunk = str => util.strToUint8Array(atob(str)); decodeChunk = str => util.stringToUint8Array(atob(str));
} }
/** /**

View File

@ -180,7 +180,7 @@ export default {
aead: { aead: {
eax: 1, eax: 1,
ocb: 2, ocb: 2,
experimentalGcm: 100 // Private algorithm experimentalGCM: 100 // Private algorithm
}, },
/** A list of packet types and numeric tags associated with them. /** A list of packet types and numeric tags associated with them.
@ -205,7 +205,7 @@ export default {
userAttribute: 17, userAttribute: 17,
symEncryptedIntegrityProtectedData: 18, symEncryptedIntegrityProtectedData: 18,
modificationDetectionCode: 19, modificationDetectionCode: 19,
AEADEncryptedData: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1 aeadEncryptedData: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1
}, },
/** Data types in the literal packet /** Data types in the literal packet
@ -367,16 +367,16 @@ export default {
preferredCompressionAlgorithms: 22, preferredCompressionAlgorithms: 22,
keyServerPreferences: 23, keyServerPreferences: 23,
preferredKeyServer: 24, preferredKeyServer: 24,
primaryUserId: 25, primaryUserID: 25,
policyUri: 26, policyURI: 26,
keyFlags: 27, keyFlags: 27,
signersUserId: 28, signersUserID: 28,
reasonForRevocation: 29, reasonForRevocation: 29,
features: 30, features: 30,
signatureTarget: 31, signatureTarget: 31,
embeddedSignature: 32, embeddedSignature: 32,
issuerFingerprint: 33, issuerFingerprint: 33,
preferredAeadAlgorithms: 34 preferredAEADAlgorithms: 34
}, },
/** Key flags /** Key flags
@ -430,7 +430,7 @@ export default {
/** Key is retired and no longer used (key revocations) */ /** Key is retired and no longer used (key revocations) */
keyRetired: 3, keyRetired: 3,
/** User ID information is no longer valid (cert revocations) */ /** User ID information is no longer valid (cert revocations) */
userIdInvalid: 32 userIDInvalid: 32
}, },
/** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.2.3.25|RFC4880bis-04, section 5.2.3.25} /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.2.3.25|RFC4880bis-04, section 5.2.3.25}

View File

@ -15,7 +15,16 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import { PacketList, UserIDPacket, SignaturePacket } from '../packet'; import {
PacketList,
UserIDPacket,
SignaturePacket,
PublicKeyPacket,
PublicSubkeyPacket,
SecretKeyPacket,
SecretSubkeyPacket,
UserAttributePacket
} from '../packet';
import Key from './key'; import Key from './key';
import * as helper from './helper'; import * as helper from './helper';
import enums from '../enums'; import enums from '../enums';
@ -23,13 +32,24 @@ import util from '../util';
import defaultConfig from '../config'; import defaultConfig from '../config';
import { unarmor } from '../encoding/armor'; import { unarmor } from '../encoding/armor';
// A Key can contain the following packets
const allowedKeyPackets = /*#__PURE__*/ util.constructAllowedPackets([
PublicKeyPacket,
PublicSubkeyPacket,
SecretKeyPacket,
SecretSubkeyPacket,
UserIDPacket,
UserAttributePacket,
SignaturePacket
]);
/** /**
* Generates a new OpenPGP key. Supports RSA and ECC keys. * Generates a new OpenPGP key. Supports RSA and ECC keys.
* By default, primary and subkeys will be of same type. * By default, primary and subkeys will be of same type.
* @param {ecc|rsa} options.type The primary key algorithm type: ECC or RSA * @param {ecc|rsa} options.type The primary key algorithm type: ECC or RSA
* @param {String} options.curve Elliptic curve for ECC keys * @param {String} options.curve Elliptic curve for ECC keys
* @param {Integer} options.rsaBits Number of bits for RSA keys * @param {Integer} options.rsaBits Number of bits for RSA keys
* @param {Array<String|Object>} options.userIds User IDs as strings or objects: 'Jo Doe <info@jo.com>' or { name:'Jo Doe', email:'info@jo.com' } * @param {Array<String|Object>} options.userIDs User IDs as strings or objects: 'Jo Doe <info@jo.com>' or { name:'Jo Doe', email:'info@jo.com' }
* @param {String} options.passphrase Passphrase used to encrypt the resulting private key * @param {String} options.passphrase Passphrase used to encrypt the resulting private key
* @param {Number} options.keyExpirationTime (optional) Number of seconds from the key creation time after which the key expires * @param {Number} options.keyExpirationTime (optional) Number of seconds from the key creation time after which the key expires
* @param {Date} options.date Creation date of the key and the key signatures * @param {Date} options.date Creation date of the key and the key signatures
@ -53,7 +73,7 @@ export async function generate(options, config) {
/** /**
* Reformats and signs an OpenPGP key with a given User ID. Currently only supports RSA keys. * Reformats and signs an OpenPGP key with a given User ID. Currently only supports RSA keys.
* @param {Key} options.privateKey The private key to reformat * @param {Key} options.privateKey The private key to reformat
* @param {Array<String|Object>} options.userIds User IDs as strings or objects: 'Jo Doe <info@jo.com>' or { name:'Jo Doe', email:'info@jo.com' } * @param {Array<String|Object>} options.userIDs User IDs as strings or objects: 'Jo Doe <info@jo.com>' or { name:'Jo Doe', email:'info@jo.com' }
* @param {String} options.passphrase Passphrase used to encrypt the resulting private key * @param {String} options.passphrase Passphrase used to encrypt the resulting private key
* @param {Number} options.keyExpirationTime Number of seconds from the key creation time after which the key expires * @param {Number} options.keyExpirationTime Number of seconds from the key creation time after which the key expires
* @param {Date} options.date Override the creation date of the key and the key signatures * @param {Date} options.date Override the creation date of the key and the key signatures
@ -133,14 +153,14 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
packetlist.push(secretKeyPacket); packetlist.push(secretKeyPacket);
await Promise.all(options.userIds.map(async function(userId, index) { await Promise.all(options.userIDs.map(async function(userID, index) {
function createPreferredAlgos(algos, preferredAlgo) { function createPreferredAlgos(algos, preferredAlgo) {
return [preferredAlgo, ...algos.filter(algo => algo !== preferredAlgo)]; return [preferredAlgo, ...algos.filter(algo => algo !== preferredAlgo)];
} }
const userIdPacket = UserIDPacket.fromObject(userId); const userIDPacket = UserIDPacket.fromObject(userID);
const dataToSign = {}; const dataToSign = {};
dataToSign.userId = userIdPacket; dataToSign.userID = userIDPacket;
dataToSign.key = secretKeyPacket; dataToSign.key = secretKeyPacket;
const signaturePacket = new SignaturePacket(options.date); const signaturePacket = new SignaturePacket(options.date);
signaturePacket.signatureType = enums.signature.certGeneric; signaturePacket.signatureType = enums.signature.certGeneric;
@ -154,10 +174,10 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
enums.symmetric.aes192 enums.symmetric.aes192
], config.preferredSymmetricAlgorithm); ], config.preferredSymmetricAlgorithm);
if (config.aeadProtect) { if (config.aeadProtect) {
signaturePacket.preferredAeadAlgorithms = createPreferredAlgos([ signaturePacket.preferredAEADAlgorithms = createPreferredAlgos([
enums.aead.eax, enums.aead.eax,
enums.aead.ocb enums.aead.ocb
], config.preferredAeadAlgorithm); ], config.preferredAEADAlgorithm);
} }
signaturePacket.preferredHashAlgorithms = createPreferredAlgos([ signaturePacket.preferredHashAlgorithms = createPreferredAlgos([
// prefer fast asm.js implementations (SHA-256) // prefer fast asm.js implementations (SHA-256)
@ -187,10 +207,10 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
} }
await signaturePacket.sign(secretKeyPacket, dataToSign); await signaturePacket.sign(secretKeyPacket, dataToSign);
return { userIdPacket, signaturePacket }; return { userIDPacket, signaturePacket };
})).then(list => { })).then(list => {
list.forEach(({ userIdPacket, signaturePacket }) => { list.forEach(({ userIDPacket, signaturePacket }) => {
packetlist.push(userIdPacket); packetlist.push(userIDPacket);
packetlist.push(signaturePacket); packetlist.push(signaturePacket);
}); });
}); });
@ -256,7 +276,7 @@ export async function readKey({ armoredKey, binaryKey, config }) {
input = binaryKey; input = binaryKey;
} }
const packetlist = new PacketList(); const packetlist = new PacketList();
await packetlist.read(input, helper.allowedKeyPackets, undefined, config); await packetlist.read(input, allowedKeyPackets, undefined, config);
return new Key(packetlist); return new Key(packetlist);
} }
@ -285,7 +305,7 @@ export async function readKeys({ armoredKeys, binaryKeys, config }) {
} }
const keys = []; const keys = [];
const packetlist = new PacketList(); const packetlist = new PacketList();
await packetlist.read(input, helper.allowedKeyPackets, undefined, config); await packetlist.read(input, allowedKeyPackets, undefined, config);
const keyIndex = packetlist.indexOfTag(enums.packet.publicKey, enums.packet.secretKey); const keyIndex = packetlist.indexOfTag(enums.packet.publicKey, enums.packet.secretKey);
if (keyIndex.length === 0) { if (keyIndex.length === 0) {
throw new Error('No key packet found'); throw new Error('No key packet found');

View File

@ -9,8 +9,6 @@ import {
PublicSubkeyPacket, PublicSubkeyPacket,
SecretKeyPacket, SecretKeyPacket,
SecretSubkeyPacket, SecretSubkeyPacket,
UserIDPacket,
UserAttributePacket,
SignaturePacket SignaturePacket
} from '../packet'; } from '../packet';
import enums from '../enums'; import enums from '../enums';
@ -18,16 +16,6 @@ import crypto from '../crypto';
import util from '../util'; import util from '../util';
import defaultConfig from '../config'; import defaultConfig from '../config';
export const allowedKeyPackets = {
PublicKeyPacket,
PublicSubkeyPacket,
SecretKeyPacket,
SecretSubkeyPacket,
UserIDPacket,
UserAttributePacket,
SignaturePacket
};
export async function generateSecretSubkey(options, config) { export async function generateSecretSubkey(options, config) {
const secretSubkeyPacket = new SecretSubkeyPacket(options.date, config); const secretSubkeyPacket = new SecretSubkeyPacket(options.date, config);
secretSubkeyPacket.packets = null; secretSubkeyPacket.packets = null;
@ -72,7 +60,7 @@ export async function getLatestValidSignature(signatures, primaryKey, signatureT
} }
if (!signature) { if (!signature) {
throw util.wrapError( throw util.wrapError(
`Could not find valid ${enums.read(enums.signature, signatureType)} signature in key ${primaryKey.getKeyId().toHex()}` `Could not find valid ${enums.read(enums.signature, signatureType)} signature in key ${primaryKey.getKeyID().toHex()}`
.replace('certGeneric ', 'self-') .replace('certGeneric ', 'self-')
.replace(/([a-z])([A-Z])/g, (_, $1, $2) => $1 + ' ' + $2.toLowerCase()) .replace(/([a-z])([A-Z])/g, (_, $1, $2) => $1 + ' ' + $2.toLowerCase())
, exception); , exception);
@ -126,20 +114,20 @@ export async function createBindingSignature(subkey, primaryKey, options, config
* @param {Key} [key] - The key to get preferences from * @param {Key} [key] - The key to get preferences from
* @param {SecretKeyPacket|SecretSubkeyPacket} keyPacket - key packet used for signing * @param {SecretKeyPacket|SecretSubkeyPacket} keyPacket - key packet used for signing
* @param {Date} [date] - Use the given date for verification instead of the current time * @param {Date} [date] - Use the given date for verification instead of the current time
* @param {Object} [userId] - User ID * @param {Object} [userID] - User ID
* @param {Object} config - full configuration * @param {Object} config - full configuration
* @returns {String} * @returns {String}
* @async * @async
*/ */
export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), userId = {}, config) { export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), userID = {}, config) {
let hash_algo = config.preferredHashAlgorithm; let hashAlgo = config.preferredHashAlgorithm;
let pref_algo = hash_algo; let prefAlgo = hashAlgo;
if (key) { if (key) {
const primaryUser = await key.getPrimaryUser(date, userId, config); const primaryUser = await key.getPrimaryUser(date, userID, config);
if (primaryUser.selfCertification.preferredHashAlgorithms) { if (primaryUser.selfCertification.preferredHashAlgorithms) {
[pref_algo] = primaryUser.selfCertification.preferredHashAlgorithms; [prefAlgo] = primaryUser.selfCertification.preferredHashAlgorithms;
hash_algo = crypto.hash.getHashByteLength(hash_algo) <= crypto.hash.getHashByteLength(pref_algo) ? hashAlgo = crypto.hash.getHashByteLength(hashAlgo) <= crypto.hash.getHashByteLength(prefAlgo) ?
pref_algo : hash_algo; prefAlgo : hashAlgo;
} }
} }
switch (Object.getPrototypeOf(keyPacket)) { switch (Object.getPrototypeOf(keyPacket)) {
@ -151,11 +139,11 @@ export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), us
case 'ecdh': case 'ecdh':
case 'ecdsa': case 'ecdsa':
case 'eddsa': case 'eddsa':
pref_algo = crypto.publicKey.elliptic.getPreferredHashAlgo(keyPacket.publicParams.oid); prefAlgo = crypto.publicKey.elliptic.getPreferredHashAlgo(keyPacket.publicParams.oid);
} }
} }
return crypto.hash.getHashByteLength(hash_algo) <= crypto.hash.getHashByteLength(pref_algo) ? return crypto.hash.getHashByteLength(hashAlgo) <= crypto.hash.getHashByteLength(prefAlgo) ?
pref_algo : hash_algo; prefAlgo : hashAlgo;
} }
/** /**
@ -163,12 +151,12 @@ export async function getPreferredHashAlgo(key, keyPacket, date = new Date(), us
* @param {symmetric|aead|compression} type - Type of preference to return * @param {symmetric|aead|compression} type - Type of preference to return
* @param {Array<Key>} [keys] - Set of keys * @param {Array<Key>} [keys] - Set of keys
* @param {Date} [date] - Use the given date for verification instead of the current time * @param {Date} [date] - Use the given date for verification instead of the current time
* @param {Array} [userIds] - User IDs * @param {Array} [userIDs] - User IDs
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {module:enums.symmetric|aead|compression} Preferred algorithm * @returns {module:enums.symmetric|aead|compression} Preferred algorithm
* @async * @async
*/ */
export async function getPreferredAlgo(type, keys = [], date = new Date(), userIds = [], config = defaultConfig) { export async function getPreferredAlgo(type, keys = [], date = new Date(), userIDs = [], config = defaultConfig) {
const defaultAlgo = { // these are all must-implement in rfc4880bis const defaultAlgo = { // these are all must-implement in rfc4880bis
'symmetric': enums.symmetric.aes128, 'symmetric': enums.symmetric.aes128,
'aead': enums.aead.eax, 'aead': enums.aead.eax,
@ -176,12 +164,12 @@ export async function getPreferredAlgo(type, keys = [], date = new Date(), userI
}[type]; }[type];
const preferredSenderAlgo = { const preferredSenderAlgo = {
'symmetric': config.preferredSymmetricAlgorithm, 'symmetric': config.preferredSymmetricAlgorithm,
'aead': config.preferredAeadAlgorithm, 'aead': config.preferredAEADAlgorithm,
'compression': config.preferredCompressionAlgorithm 'compression': config.preferredCompressionAlgorithm
}[type]; }[type];
const prefPropertyName = { const prefPropertyName = {
'symmetric': 'preferredSymmetricAlgorithms', 'symmetric': 'preferredSymmetricAlgorithms',
'aead': 'preferredAeadAlgorithms', 'aead': 'preferredAEADAlgorithms',
'compression': 'preferredCompressionAlgorithms' 'compression': 'preferredCompressionAlgorithms'
}[type]; }[type];
@ -189,7 +177,7 @@ export async function getPreferredAlgo(type, keys = [], date = new Date(), userI
// otherwise we use the default algo // otherwise we use the default algo
// if no keys are available, preferredSenderAlgo is returned // if no keys are available, preferredSenderAlgo is returned
const senderAlgoSupport = await Promise.all(keys.map(async function(key, i) { const senderAlgoSupport = await Promise.all(keys.map(async function(key, i) {
const primaryUser = await key.getPrimaryUser(date, userIds[i], config); const primaryUser = await key.getPrimaryUser(date, userIDs[i], config);
const recipientPrefs = primaryUser.selfCertification[prefPropertyName]; const recipientPrefs = primaryUser.selfCertification[prefPropertyName];
return !!recipientPrefs && recipientPrefs.indexOf(preferredSenderAlgo) >= 0; return !!recipientPrefs && recipientPrefs.indexOf(preferredSenderAlgo) >= 0;
})); }));
@ -203,14 +191,14 @@ export async function getPreferredAlgo(type, keys = [], date = new Date(), userI
* SecretSubkeyPacket} signingKeyPacket secret key packet for signing * SecretSubkeyPacket} signingKeyPacket secret key packet for signing
* @param {Object} [signatureProperties] - Properties to write on the signature packet before signing * @param {Object} [signatureProperties] - Properties to write on the signature packet before signing
* @param {Date} [date] - Override the creationtime of the signature * @param {Date} [date] - Override the creationtime of the signature
* @param {Object} [userId] - User ID * @param {Object} [userID] - User ID
* @param {Object} [detached] - Whether to create a detached signature packet * @param {Object} [detached] - Whether to create a detached signature packet
* @param {Boolean} [streaming] - Whether to process data as a stream * @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} config - full configuration * @param {Object} config - full configuration
* @returns {SignaturePacket} Signature packet. * @returns {SignaturePacket} Signature packet.
* @async * @async
*/ */
export async function createSignaturePacket(dataToSign, privateKey, signingKeyPacket, signatureProperties, date, userId, detached = false, streaming = false, config) { export async function createSignaturePacket(dataToSign, privateKey, signingKeyPacket, signatureProperties, date, userID, detached = false, streaming = false, config) {
if (signingKeyPacket.isDummy()) { if (signingKeyPacket.isDummy()) {
throw new Error('Cannot sign with a gnu-dummy key.'); throw new Error('Cannot sign with a gnu-dummy key.');
} }
@ -220,7 +208,7 @@ export async function createSignaturePacket(dataToSign, privateKey, signingKeyPa
const signaturePacket = new SignaturePacket(date); const signaturePacket = new SignaturePacket(date);
Object.assign(signaturePacket, signatureProperties); Object.assign(signaturePacket, signatureProperties);
signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm; signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
signaturePacket.hashAlgorithm = await getPreferredHashAlgo(privateKey, signingKeyPacket, date, userId, config); signaturePacket.hashAlgorithm = await getPreferredHashAlgo(privateKey, signingKeyPacket, date, userID, config);
await signaturePacket.sign(signingKeyPacket, dataToSign, detached, streaming); await signaturePacket.sign(signingKeyPacket, dataToSign, detached, streaming);
return signaturePacket; return signaturePacket;
} }
@ -241,7 +229,7 @@ export async function mergeSignatures(source, dest, attr, checkFn) {
await Promise.all(source.map(async function(sourceSig) { await Promise.all(source.map(async function(sourceSig) {
if (!sourceSig.isExpired() && (!checkFn || await checkFn(sourceSig)) && if (!sourceSig.isExpired() && (!checkFn || await checkFn(sourceSig)) &&
!dest[attr].some(function(destSig) { !dest[attr].some(function(destSig) {
return util.equalsUint8Array(destSig.write_params(), sourceSig.write_params()); return util.equalsUint8Array(destSig.writeParams(), sourceSig.writeParams());
})) { })) {
dest[attr].push(sourceSig); dest[attr].push(sourceSig);
} }
@ -269,7 +257,7 @@ export async function mergeSignatures(source, dest, attr, checkFn) {
export async function isDataRevoked(primaryKey, signatureType, dataToVerify, revocations, signature, key, date = new Date(), config) { export async function isDataRevoked(primaryKey, signatureType, dataToVerify, revocations, signature, key, date = new Date(), config) {
key = key || primaryKey; key = key || primaryKey;
const normDate = util.normalizeDate(date); const normDate = util.normalizeDate(date);
const revocationKeyIds = []; const revocationKeyIDs = [];
await Promise.all(revocations.map(async function(revocationSignature) { await Promise.all(revocations.map(async function(revocationSignature) {
try { try {
if ( if (
@ -281,23 +269,23 @@ export async function isDataRevoked(primaryKey, signatureType, dataToVerify, rev
// third-party revocation signatures here. (It could also be revoking a // third-party revocation signatures here. (It could also be revoking a
// third-party key certification, which should only affect // third-party key certification, which should only affect
// `verifyAllCertifications`.) // `verifyAllCertifications`.)
(!signature || revocationSignature.issuerKeyId.equals(signature.issuerKeyId)) && (!signature || revocationSignature.issuerKeyID.equals(signature.issuerKeyID)) &&
!(config.revocationsExpire && revocationSignature.isExpired(normDate)) !(config.revocationsExpire && revocationSignature.isExpired(normDate))
) { ) {
revocationSignature.verified || await revocationSignature.verify(key, signatureType, dataToVerify, undefined, undefined, config); revocationSignature.verified || await revocationSignature.verify(key, signatureType, dataToVerify, undefined, undefined, config);
// TODO get an identifier of the revoked object instead // TODO get an identifier of the revoked object instead
revocationKeyIds.push(revocationSignature.issuerKeyId); revocationKeyIDs.push(revocationSignature.issuerKeyID);
} }
} catch (e) {} } catch (e) {}
})); }));
// TODO further verify that this is the signature that should be revoked // TODO further verify that this is the signature that should be revoked
if (signature) { if (signature) {
signature.revoked = revocationKeyIds.some(keyId => keyId.equals(signature.issuerKeyId)) ? true : signature.revoked = revocationKeyIDs.some(keyID => keyID.equals(signature.issuerKeyID)) ? true :
signature.revoked || false; signature.revoked || false;
return signature.revoked; return signature.revoked;
} }
return revocationKeyIds.length > 0; return revocationKeyIDs.length > 0;
} }
export function getExpirationTime(keyPacket, signature) { export function getExpirationTime(keyPacket, signature) {
@ -313,16 +301,16 @@ export function getExpirationTime(keyPacket, signature) {
* Returns whether aead is supported by all keys in the set * Returns whether aead is supported by all keys in the set
* @param {Array<Key>} keys - Set of keys * @param {Array<Key>} keys - Set of keys
* @param {Date} [date] - Use the given date for verification instead of the current time * @param {Date} [date] - Use the given date for verification instead of the current time
* @param {Array} [userIds] - User IDs * @param {Array} [userIDs] - User IDs
* @param {Object} config - full configuration * @param {Object} config - full configuration
* @returns {Boolean} * @returns {Boolean}
* @async * @async
*/ */
export async function isAeadSupported(keys, date = new Date(), userIds = [], config = defaultConfig) { export async function isAEADSupported(keys, date = new Date(), userIDs = [], config = defaultConfig) {
let supported = true; let supported = true;
// TODO replace when Promise.some or Promise.any are implemented // TODO replace when Promise.some or Promise.any are implemented
await Promise.all(keys.map(async function(key, i) { await Promise.all(keys.map(async function(key, i) {
const primaryUser = await key.getPrimaryUser(date, userIds[i], config); const primaryUser = await key.getPrimaryUser(date, userIDs[i], config);
if (!primaryUser.selfCertification.features || if (!primaryUser.selfCertification.features ||
!(primaryUser.selfCertification.features[0] & enums.features.aead)) { !(primaryUser.selfCertification.features[0] & enums.features.aead)) {
supported = false; supported = false;
@ -415,7 +403,7 @@ export function checkKeyStrength(keyPacket, config) {
throw new Error(`${keyPacket.algorithm} keys are considered too weak.`); throw new Error(`${keyPacket.algorithm} keys are considered too weak.`);
} }
const rsaAlgos = new Set([enums.publicKey.rsaEncryptSign, enums.publicKey.rsaSign, enums.publicKey.rsaEncrypt]); const rsaAlgos = new Set([enums.publicKey.rsaEncryptSign, enums.publicKey.rsaSign, enums.publicKey.rsaEncrypt]);
if (rsaAlgos.has(keyAlgo) && util.uint8ArrayBitLength(keyPacket.publicParams.n) < config.minRsaBits) { if (rsaAlgos.has(keyAlgo) && util.uint8ArrayBitLength(keyPacket.publicParams.n) < config.minRSABits) {
throw new Error(`RSA keys shorter than ${config.minRsaBits} bits are considered too weak.`); throw new Error(`RSA keys shorter than ${config.minRSABits} bits are considered too weak.`);
} }
} }

View File

@ -7,7 +7,7 @@ import {
import { import {
getPreferredAlgo, getPreferredAlgo,
isAeadSupported, isAEADSupported,
getPreferredHashAlgo, getPreferredHashAlgo,
createSignaturePacket createSignaturePacket
} from './helper'; } from './helper';
@ -20,7 +20,7 @@ export {
generate, generate,
reformat, reformat,
getPreferredAlgo, getPreferredAlgo,
isAeadSupported, isAEADSupported,
getPreferredHashAlgo, getPreferredHashAlgo,
createSignaturePacket, createSignaturePacket,
Key Key

View File

@ -29,10 +29,13 @@ import User from './user';
import SubKey from './subkey'; import SubKey from './subkey';
import * as helper from './helper'; import * as helper from './helper';
// A key revocation certificate can contain the following packets
const allowedRevocationPackets = /*#__PURE__*/ util.constructAllowedPackets([SignaturePacket]);
/** /**
* Class that represents an OpenPGP key. Must contain a primary key. * Class that represents an OpenPGP key. Must contain a primary key.
* Can contain additional subkeys, signatures, user ids, user attributes. * Can contain additional subkeys, signatures, user ids, user attributes.
* @borrows PublicKeyPacket#getKeyId as Key#getKeyId * @borrows PublicKeyPacket#getKeyID as Key#getKeyID
* @borrows PublicKeyPacket#getFingerprint as Key#getFingerprint * @borrows PublicKeyPacket#getFingerprint as Key#getFingerprint
* @borrows PublicKeyPacket#hasSameFingerprintAs as Key#hasSameFingerprintAs * @borrows PublicKeyPacket#hasSameFingerprintAs as Key#hasSameFingerprintAs
* @borrows PublicKeyPacket#getAlgorithmInfo as Key#getAlgorithmInfo * @borrows PublicKeyPacket#getAlgorithmInfo as Key#getAlgorithmInfo
@ -68,17 +71,17 @@ class Key {
*/ */
packetlist2structure(packetlist) { packetlist2structure(packetlist) {
let user; let user;
let primaryKeyId; let primaryKeyID;
let subKey; let subKey;
for (let i = 0; i < packetlist.length; i++) { for (let i = 0; i < packetlist.length; i++) {
switch (packetlist[i].tag) { switch (packetlist[i].constructor.tag) {
case enums.packet.publicKey: case enums.packet.publicKey:
case enums.packet.secretKey: case enums.packet.secretKey:
if (this.keyPacket) { if (this.keyPacket) {
throw new Error('Key block contains multiple keys'); throw new Error('Key block contains multiple keys');
} }
this.keyPacket = packetlist[i]; this.keyPacket = packetlist[i];
primaryKeyId = this.getKeyId(); primaryKeyID = this.getKeyID();
break; break;
case enums.packet.userID: case enums.packet.userID:
case enums.packet.userAttribute: case enums.packet.userAttribute:
@ -101,7 +104,7 @@ class Key {
util.printDebug('Dropping certification signatures without preceding user packet'); util.printDebug('Dropping certification signatures without preceding user packet');
continue; continue;
} }
if (packetlist[i].issuerKeyId.equals(primaryKeyId)) { if (packetlist[i].issuerKeyID.equals(primaryKeyID)) {
user.selfCertifications.push(packetlist[i]); user.selfCertifications.push(packetlist[i]);
} else { } else {
user.otherCertifications.push(packetlist[i]); user.otherCertifications.push(packetlist[i]);
@ -164,15 +167,15 @@ class Key {
} }
/** /**
* Returns an array containing all public or private subkeys matching keyId; * Returns an array containing all public or private subkeys matching keyID;
* If keyId is not present, returns all subkeys. * If keyID is not present, returns all subkeys.
* @param {type/keyid} keyId * @param {type/keyid} keyID
* @returns {Array<SubKey>} * @returns {Array<SubKey>}
*/ */
getSubkeys(keyId = null) { getSubkeys(keyID = null) {
const subKeys = []; const subKeys = [];
this.subKeys.forEach(subKey => { this.subKeys.forEach(subKey => {
if (!keyId || subKey.getKeyId().equals(keyId, true)) { if (!keyID || subKey.getKeyID().equals(keyID, true)) {
subKeys.push(subKey); subKeys.push(subKey);
} }
}); });
@ -180,35 +183,35 @@ class Key {
} }
/** /**
* Returns an array containing all public or private keys matching keyId. * Returns an array containing all public or private keys matching keyID.
* If keyId is not present, returns all keys starting with the primary key. * If keyID is not present, returns all keys starting with the primary key.
* @param {type/keyid} keyId * @param {type/keyid} keyID
* @returns {Array<Key|SubKey>} * @returns {Array<Key|SubKey>}
*/ */
getKeys(keyId = null) { getKeys(keyID = null) {
const keys = []; const keys = [];
if (!keyId || this.getKeyId().equals(keyId, true)) { if (!keyID || this.getKeyID().equals(keyID, true)) {
keys.push(this); keys.push(this);
} }
return keys.concat(this.getSubkeys(keyId)); return keys.concat(this.getSubkeys(keyID));
} }
/** /**
* Returns key IDs of all keys * Returns key IDs of all keys
* @returns {Array<module:type/keyid~Keyid>} * @returns {Array<module:type/keyid~KeyID>}
*/ */
getKeyIds() { getKeyIDs() {
return this.getKeys().map(key => key.getKeyId()); return this.getKeys().map(key => key.getKeyID());
} }
/** /**
* Returns userids * Returns userIDs
* @returns {Array<string>} Array of userids. * @returns {Array<string>} Array of userIDs.
*/ */
getUserIds() { getUserIDs() {
return this.users.map(user => { return this.users.map(user => {
return user.userId ? user.userId.userid : null; return user.userID ? user.userID.userID : null;
}).filter(userid => userid !== null); }).filter(userID => userID !== null);
} }
/** /**
@ -216,7 +219,7 @@ class Key {
* @returns {Boolean} * @returns {Boolean}
*/ */
isPublic() { isPublic() {
return this.keyPacket.tag === enums.packet.publicKey; return this.keyPacket.constructor.tag === enums.packet.publicKey;
} }
/** /**
@ -224,7 +227,7 @@ class Key {
* @returns {Boolean} * @returns {Boolean}
*/ */
isPrivate() { isPrivate() {
return this.keyPacket.tag === enums.packet.secretKey; return this.keyPacket.constructor.tag === enums.packet.secretKey;
} }
/** /**
@ -239,7 +242,7 @@ class Key {
let pubKeyPacket; let pubKeyPacket;
let pubSubkeyPacket; let pubSubkeyPacket;
for (let i = 0; i < keyPackets.length; i++) { for (let i = 0; i < keyPackets.length; i++) {
switch (keyPackets[i].tag) { switch (keyPackets[i].constructor.tag) {
case enums.packet.secretKey: case enums.packet.secretKey:
bytes = keyPackets[i].writePublicKey(); bytes = keyPackets[i].writePublicKey();
pubKeyPacket = new PublicKeyPacket(); pubKeyPacket = new PublicKeyPacket();
@ -278,21 +281,21 @@ class Key {
} }
/** /**
* Returns last created key or key by given keyId that is available for signing and verification * Returns last created key or key by given keyID that is available for signing and verification
* @param {module:type/keyid~Keyid} keyId, optional * @param {module:type/keyid~KeyID} keyID, optional
* @param {Date} [date] - Use the given date for verification instead of the current time * @param {Date} [date] - Use the given date for verification instead of the current time
* @param {Object} userId, optional user ID * @param {Object} userID, optional user ID
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Key|SubKey|null} Key or null if no signing key has been found. * @returns {Key|SubKey|null} Key or null if no signing key has been found.
* @async * @async
*/ */
async getSigningKey(keyId = null, date = new Date(), userId = {}, config = defaultConfig) { async getSigningKey(keyID = null, date = new Date(), userID = {}, config = defaultConfig) {
await this.verifyPrimaryKey(date, userId, config); await this.verifyPrimaryKey(date, userID, config);
const primaryKey = this.keyPacket; const primaryKey = this.keyPacket;
const subKeys = this.subKeys.slice().sort((a, b) => b.keyPacket.created - a.keyPacket.created); const subKeys = this.subKeys.slice().sort((a, b) => b.keyPacket.created - a.keyPacket.created);
let exception; let exception;
for (const subKey of subKeys) { for (const subKey of subKeys) {
if (!keyId || subKey.getKeyId().equals(keyId)) { if (!keyID || subKey.getKeyID().equals(keyID)) {
try { try {
await subKey.verify(primaryKey, date, config); await subKey.verify(primaryKey, date, config);
const dataToVerify = { key: primaryKey, bind: subKey.keyPacket }; const dataToVerify = { key: primaryKey, bind: subKey.keyPacket };
@ -318,8 +321,8 @@ class Key {
} }
try { try {
const primaryUser = await this.getPrimaryUser(date, userId, config); const primaryUser = await this.getPrimaryUser(date, userID, config);
if ((!keyId || primaryKey.getKeyId().equals(keyId)) && if ((!keyID || primaryKey.getKeyID().equals(keyID)) &&
helper.isValidSigningKeyPacket(primaryKey, primaryUser.selfCertification, config)) { helper.isValidSigningKeyPacket(primaryKey, primaryUser.selfCertification, config)) {
helper.checkKeyStrength(primaryKey, config); helper.checkKeyStrength(primaryKey, config);
return this; return this;
@ -327,26 +330,26 @@ class Key {
} catch (e) { } catch (e) {
exception = e; exception = e;
} }
throw util.wrapError('Could not find valid signing key packet in key ' + this.getKeyId().toHex(), exception); throw util.wrapError('Could not find valid signing key packet in key ' + this.getKeyID().toHex(), exception);
} }
/** /**
* Returns last created key or key by given keyId that is available for encryption or decryption * Returns last created key or key by given keyID that is available for encryption or decryption
* @param {module:type/keyid~Keyid} keyId, optional * @param {module:type/keyid~KeyID} keyID, optional
* @param {Date} date, optional * @param {Date} date, optional
* @param {String} userId, optional * @param {String} userID, optional
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Key|SubKey|null} Key or null if no encryption key has been found. * @returns {Key|SubKey|null} Key or null if no encryption key has been found.
* @async * @async
*/ */
async getEncryptionKey(keyId, date = new Date(), userId = {}, config = defaultConfig) { async getEncryptionKey(keyID, date = new Date(), userID = {}, config = defaultConfig) {
await this.verifyPrimaryKey(date, userId, config); await this.verifyPrimaryKey(date, userID, config);
const primaryKey = this.keyPacket; const primaryKey = this.keyPacket;
// V4: by convention subkeys are preferred for encryption service // V4: by convention subkeys are preferred for encryption service
const subKeys = this.subKeys.slice().sort((a, b) => b.keyPacket.created - a.keyPacket.created); const subKeys = this.subKeys.slice().sort((a, b) => b.keyPacket.created - a.keyPacket.created);
let exception; let exception;
for (const subKey of subKeys) { for (const subKey of subKeys) {
if (!keyId || subKey.getKeyId().equals(keyId)) { if (!keyID || subKey.getKeyID().equals(keyID)) {
try { try {
await subKey.verify(primaryKey, date, config); await subKey.verify(primaryKey, date, config);
const dataToVerify = { key: primaryKey, bind: subKey.keyPacket }; const dataToVerify = { key: primaryKey, bind: subKey.keyPacket };
@ -363,8 +366,8 @@ class Key {
try { try {
// if no valid subkey for encryption, evaluate primary key // if no valid subkey for encryption, evaluate primary key
const primaryUser = await this.getPrimaryUser(date, userId, config); const primaryUser = await this.getPrimaryUser(date, userID, config);
if ((!keyId || primaryKey.getKeyId().equals(keyId)) && if ((!keyID || primaryKey.getKeyID().equals(keyID)) &&
helper.isValidEncryptionKeyPacket(primaryKey, primaryUser.selfCertification)) { helper.isValidEncryptionKeyPacket(primaryKey, primaryUser.selfCertification)) {
helper.checkKeyStrength(primaryKey, config); helper.checkKeyStrength(primaryKey, config);
return this; return this;
@ -372,24 +375,24 @@ class Key {
} catch (e) { } catch (e) {
exception = e; exception = e;
} }
throw util.wrapError('Could not find valid encryption key packet in key ' + this.getKeyId().toHex(), exception); throw util.wrapError('Could not find valid encryption key packet in key ' + this.getKeyID().toHex(), exception);
} }
/** /**
* Returns all keys that are available for decryption, matching the keyId when given * Returns all keys that are available for decryption, matching the keyID when given
* This is useful to retrieve keys for session key decryption * This is useful to retrieve keys for session key decryption
* @param {module:type/keyid~Keyid} keyId, optional * @param {module:type/keyid~KeyID} keyID, optional
* @param {Date} date, optional * @param {Date} date, optional
* @param {String} userId, optional * @param {String} userID, optional
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Array<Key|SubKey>} Array of decryption keys. * @returns {Array<Key|SubKey>} Array of decryption keys.
* @async * @async
*/ */
async getDecryptionKeys(keyId, date = new Date(), userId = {}, config = defaultConfig) { async getDecryptionKeys(keyID, date = new Date(), userID = {}, config = defaultConfig) {
const primaryKey = this.keyPacket; const primaryKey = this.keyPacket;
const keys = []; const keys = [];
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)) {
try { try {
const dataToVerify = { key: primaryKey, bind: this.subKeys[i].keyPacket }; const dataToVerify = { key: primaryKey, bind: this.subKeys[i].keyPacket };
const bindingSignature = await helper.getLatestValidSignature(this.subKeys[i].bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config); const bindingSignature = await helper.getLatestValidSignature(this.subKeys[i].bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config);
@ -401,8 +404,8 @@ class Key {
} }
// evaluate primary key // evaluate primary key
const primaryUser = await this.getPrimaryUser(date, userId, config); const primaryUser = await this.getPrimaryUser(date, userID, config);
if ((!keyId || primaryKey.getKeyId().equals(keyId, true)) && if ((!keyID || primaryKey.getKeyID().equals(keyID, true)) &&
helper.isValidDecryptionKeyPacket(primaryUser.selfCertification, config)) { helper.isValidDecryptionKeyPacket(primaryUser.selfCertification, config)) {
keys.push(this); keys.push(this);
} }
@ -411,19 +414,19 @@ class Key {
} }
/** /**
* Encrypts all secret key and subkey packets matching keyId * 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 {String|Array<String>} passphrases - If multiple passphrases, then should be in same order as packets each should encrypt
* @param {module:type/keyid~Keyid} keyId * @param {module:type/keyid~KeyID} keyID
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @throws {Error} if encryption failed for any key or subkey * @throws {Error} if encryption failed for any key or subkey
* @async * @async
*/ */
async encrypt(passphrases, keyId = null, config = defaultConfig) { async encrypt(passphrases, keyID = null, config = defaultConfig) {
if (!this.isPrivate()) { if (!this.isPrivate()) {
throw new Error("Nothing to encrypt in a public key"); throw new Error("Nothing to encrypt in a public key");
} }
const keys = this.getKeys(keyId); const keys = this.getKeys(keyID);
passphrases = util.isArray(passphrases) ? passphrases : new Array(keys.length).fill(passphrases); passphrases = util.isArray(passphrases) ? passphrases : new Array(keys.length).fill(passphrases);
if (passphrases.length !== keys.length) { if (passphrases.length !== keys.length) {
throw new Error("Invalid number of passphrases for key"); throw new Error("Invalid number of passphrases for key");
@ -437,27 +440,27 @@ class Key {
} }
/** /**
* Decrypts all secret key and subkey packets matching keyId * Decrypts all secret key and subkey packets matching keyID
* @param {String|Array<String>} passphrases * @param {String|Array<String>} passphrases
* @param {module:type/keyid~Keyid} keyId * @param {module:type/keyid~KeyID} keyID
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @throws {Error} if any matching key or subkey packets did not decrypt successfully * @throws {Error} if any matching key or subkey packets did not decrypt successfully
* @async * @async
*/ */
async decrypt(passphrases, keyId = null, config = defaultConfig) { async decrypt(passphrases, keyID = null, config = defaultConfig) {
if (!this.isPrivate()) { if (!this.isPrivate()) {
throw new Error("Nothing to decrypt in a public key"); throw new Error("Nothing to decrypt in a public key");
} }
passphrases = util.isArray(passphrases) ? passphrases : [passphrases]; passphrases = util.isArray(passphrases) ? passphrases : [passphrases];
await Promise.all(this.getKeys(keyId).map(async function(key) { await Promise.all(this.getKeys(keyID).map(async function(key) {
let decrypted = false; let decrypted = false;
let error = null; let error = null;
await Promise.all(passphrases.map(async function(passphrase) { await Promise.all(passphrases.map(async function(passphrase) {
try { try {
await key.keyPacket.decrypt(passphrase); await key.keyPacket.decrypt(passphrase);
// If we are decrypting a single key packet, we also validate it directly // If we are decrypting a single key packet, we also validate it directly
if (keyId) await key.keyPacket.validate(); if (keyID) await key.keyPacket.validate();
decrypted = true; decrypted = true;
} catch (e) { } catch (e) {
error = e; error = e;
@ -468,7 +471,7 @@ class Key {
} }
})); }));
if (!keyId) { if (!keyID) {
// The full key should be decrypted and we can validate it all // The full key should be decrypted and we can validate it all
await this.validate(config); await this.validate(config);
} }
@ -505,7 +508,7 @@ class Key {
* It is enough to validate any signing keys * It is enough to validate any signing keys
* since its binding signatures are also checked * since its binding signatures are also checked
*/ */
const signingKey = await this.getSigningKey(null, null, undefined, { ...config, rejectPublicKeyAlgorithms: new Set(), minRsaBits: 0 }); const signingKey = await this.getSigningKey(null, null, undefined, { ...config, rejectPublicKeyAlgorithms: new Set(), minRSABits: 0 });
// This could again be a dummy key // This could again be a dummy key
if (signingKey && !signingKey.keyPacket.isDummy()) { if (signingKey && !signingKey.keyPacket.isDummy()) {
signingKeyPacket = signingKey.keyPacket; signingKeyPacket = signingKey.keyPacket;
@ -561,19 +564,19 @@ class Key {
* Verify primary key. Checks for revocation signatures, expiration time * Verify primary key. Checks for revocation signatures, expiration time
* and valid self signature. Throws if the primary key is invalid. * and valid self signature. Throws if the primary key is invalid.
* @param {Date} [date] - Use the given date for verification instead of the current time * @param {Date} [date] - Use the given date for verification instead of the current time
* @param {Object} [userId] - User ID * @param {Object} [userID] - User ID
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @throws {Error} If key verification failed * @throws {Error} If key verification failed
* @async * @async
*/ */
async verifyPrimaryKey(date = new Date(), userId = {}, config = defaultConfig) { async verifyPrimaryKey(date = new Date(), userID = {}, config = defaultConfig) {
const primaryKey = this.keyPacket; const primaryKey = this.keyPacket;
// check for key revocation signatures // check for key revocation signatures
if (await this.isRevoked(null, null, date, config)) { if (await this.isRevoked(null, null, date, config)) {
throw new Error('Primary key is revoked'); throw new Error('Primary key is revoked');
} }
// check for valid, unrevoked, unexpired self signature // check for valid, unrevoked, unexpired self signature
const { selfCertification } = await this.getPrimaryUser(date, userId, config); const { selfCertification } = await this.getPrimaryUser(date, userID, config);
// check for expiration time // check for expiration time
if (helper.isDataExpired(primaryKey, selfCertification, date)) { if (helper.isDataExpired(primaryKey, selfCertification, date)) {
throw new Error('Primary key is expired'); throw new Error('Primary key is expired');
@ -586,30 +589,30 @@ class Key {
* Returns null if `capabilities` is passed and the key does not have the specified capabilities or is revoked or invalid. * Returns null if `capabilities` is passed and the key does not have the specified capabilities or is revoked or invalid.
* Returns Infinity if the key doesn't expire. * Returns Infinity if the key doesn't expire.
* @param {encrypt|sign|encrypt_sign} capabilities, optional * @param {encrypt|sign|encrypt_sign} capabilities, optional
* @param {module:type/keyid~Keyid} keyId, optional * @param {module:type/keyid~KeyID} keyID, optional
* @param {Object} userId, optional user ID * @param {Object} userID, optional user ID
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Date | Infinity | null} * @returns {Date | Infinity | null}
* @async * @async
*/ */
async getExpirationTime(capabilities, keyId, userId, config = defaultConfig) { async getExpirationTime(capabilities, keyID, userID, config = defaultConfig) {
const primaryUser = await this.getPrimaryUser(null, userId, config); const primaryUser = await this.getPrimaryUser(null, userID, config);
const selfCert = primaryUser.selfCertification; const selfCert = primaryUser.selfCertification;
const keyExpiry = helper.getExpirationTime(this.keyPacket, selfCert); const keyExpiry = helper.getExpirationTime(this.keyPacket, selfCert);
const sigExpiry = selfCert.getExpirationTime(); const sigExpiry = selfCert.getExpirationTime();
let expiry = keyExpiry < sigExpiry ? keyExpiry : sigExpiry; let expiry = keyExpiry < sigExpiry ? keyExpiry : sigExpiry;
if (capabilities === 'encrypt' || capabilities === 'encrypt_sign') { if (capabilities === 'encrypt' || capabilities === 'encrypt_sign') {
const encryptKey = const encryptKey =
await this.getEncryptionKey(keyId, expiry, userId, { ...config, rejectPublicKeyAlgorithms: new Set(), minRsaBits: 0 }).catch(() => {}) || await this.getEncryptionKey(keyID, expiry, userID, { ...config, rejectPublicKeyAlgorithms: new Set(), minRSABits: 0 }).catch(() => {}) ||
await this.getEncryptionKey(keyId, null, userId, { ...config, rejectPublicKeyAlgorithms: new Set(), minRsaBits: 0 }).catch(() => {}); await this.getEncryptionKey(keyID, null, userID, { ...config, rejectPublicKeyAlgorithms: new Set(), minRSABits: 0 }).catch(() => {});
if (!encryptKey) return null; if (!encryptKey) return null;
const encryptExpiry = await encryptKey.getExpirationTime(this.keyPacket, undefined, config); const encryptExpiry = await encryptKey.getExpirationTime(this.keyPacket, undefined, config);
if (encryptExpiry < expiry) expiry = encryptExpiry; if (encryptExpiry < expiry) expiry = encryptExpiry;
} }
if (capabilities === 'sign' || capabilities === 'encrypt_sign') { if (capabilities === 'sign' || capabilities === 'encrypt_sign') {
const signKey = const signKey =
await this.getSigningKey(keyId, expiry, userId, { ...config, rejectPublicKeyAlgorithms: new Set(), minRsaBits: 0 }).catch(() => {}) || await this.getSigningKey(keyID, expiry, userID, { ...config, rejectPublicKeyAlgorithms: new Set(), minRSABits: 0 }).catch(() => {}) ||
await this.getSigningKey(keyId, null, userId, { ...config, rejectPublicKeyAlgorithms: new Set(), minRsaBits: 0 }).catch(() => {}); await this.getSigningKey(keyID, null, userID, { ...config, rejectPublicKeyAlgorithms: new Set(), minRSABits: 0 }).catch(() => {});
if (!signKey) return null; if (!signKey) return null;
const signExpiry = await signKey.getExpirationTime(this.keyPacket, undefined, config); const signExpiry = await signKey.getExpirationTime(this.keyPacket, undefined, config);
if (signExpiry < expiry) expiry = signExpiry; if (signExpiry < expiry) expiry = signExpiry;
@ -622,30 +625,30 @@ class Key {
* - if multiple primary users exist, returns the one with the latest self signature * - if multiple primary users exist, returns the one with the latest self signature
* - otherwise, returns the user with the latest self signature * - otherwise, returns the user with the latest self signature
* @param {Date} [date] - Use the given date for verification instead of the current time * @param {Date} [date] - Use the given date for verification instead of the current time
* @param {Object} [userId] - User ID to get instead of the primary user, if it exists * @param {Object} [userID] - User ID to get instead of the primary user, if it exists
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Promise<{user: User, * @returns {Promise<{user: User,
* selfCertification: SignaturePacket}>} The primary user and the self signature * selfCertification: SignaturePacket}>} The primary user and the self signature
* @async * @async
*/ */
async getPrimaryUser(date = new Date(), userId = {}, config = defaultConfig) { async getPrimaryUser(date = new Date(), userID = {}, config = defaultConfig) {
const primaryKey = this.keyPacket; const primaryKey = this.keyPacket;
const users = []; const users = [];
let exception; let exception;
for (let i = 0; i < this.users.length; i++) { for (let i = 0; i < this.users.length; i++) {
try { try {
const user = this.users[i]; const user = this.users[i];
if (!user.userId) { if (!user.userID) {
continue; continue;
} }
if ( if (
(userId.name !== undefined && user.userId.name !== userId.name) || (userID.name !== undefined && user.userID.name !== userID.name) ||
(userId.email !== undefined && user.userId.email !== userId.email) || (userID.email !== undefined && user.userID.email !== userID.email) ||
(userId.comment !== undefined && user.userId.comment !== userId.comment) (userID.comment !== undefined && user.userID.comment !== userID.comment)
) { ) {
throw new Error('Could not find user that matches that user ID'); throw new Error('Could not find user that matches that user ID');
} }
const dataToVerify = { userId: user.userId, key: primaryKey }; const dataToVerify = { userID: user.userID, key: primaryKey };
const selfCertification = await helper.getLatestValidSignature(user.selfCertifications, primaryKey, enums.signature.certGeneric, dataToVerify, date, config); const selfCertification = await helper.getLatestValidSignature(user.selfCertifications, primaryKey, enums.signature.certGeneric, dataToVerify, date, config);
users.push({ index: i, user, selfCertification }); users.push({ index: i, user, selfCertification });
} catch (e) { } catch (e) {
@ -711,8 +714,8 @@ class Key {
await Promise.all(key.users.map(async srcUser => { await Promise.all(key.users.map(async srcUser => {
let found = false; let found = false;
await Promise.all(this.users.map(async dstUser => { await Promise.all(this.users.map(async dstUser => {
if ((srcUser.userId && dstUser.userId && if ((srcUser.userID && dstUser.userID &&
(srcUser.userId.userid === dstUser.userId.userid)) || (srcUser.userID.userID === dstUser.userID.userID)) ||
(srcUser.userAttribute && (srcUser.userAttribute.equals(dstUser.userAttribute)))) { (srcUser.userAttribute && (srcUser.userAttribute.equals(dstUser.userAttribute)))) {
await dstUser.update(srcUser, this.keyPacket, config); await dstUser.update(srcUser, this.keyPacket, config);
found = true; found = true;
@ -797,12 +800,12 @@ class Key {
async applyRevocationCertificate(revocationCertificate, config = defaultConfig) { async applyRevocationCertificate(revocationCertificate, config = defaultConfig) {
const input = await unarmor(revocationCertificate, config); const input = await unarmor(revocationCertificate, config);
const packetlist = new PacketList(); const packetlist = new PacketList();
await packetlist.read(input.data, { SignaturePacket }, undefined, config); await packetlist.read(input.data, allowedRevocationPackets, undefined, config);
const revocationSignature = packetlist.findPacket(enums.packet.signature); const revocationSignature = packetlist.findPacket(enums.packet.signature);
if (!revocationSignature || revocationSignature.signatureType !== enums.signature.keyRevocation) { if (!revocationSignature || revocationSignature.signatureType !== enums.signature.keyRevocation) {
throw new Error('Could not find revocation signature packet'); throw new Error('Could not find revocation signature packet');
} }
if (!revocationSignature.issuerKeyId.equals(this.getKeyId())) { if (!revocationSignature.issuerKeyID.equals(this.getKeyID())) {
throw new Error('Revocation signature does not match key'); throw new Error('Revocation signature does not match key');
} }
if (revocationSignature.isExpired()) { if (revocationSignature.isExpired()) {
@ -822,13 +825,13 @@ class Key {
* Signs primary user of key * Signs primary user of key
* @param {Array<Key>} privateKeys - decrypted private keys for signing * @param {Array<Key>} privateKeys - decrypted private keys for signing
* @param {Date} [date] - Use the given date for verification instead of the current time * @param {Date} [date] - Use the given date for verification instead of the current time
* @param {Object} [userId] - User ID to get instead of the primary user, if it exists * @param {Object} [userID] - User ID to get instead of the primary user, if it exists
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Key} New public key with new certificate signature. * @returns {Key} New public key with new certificate signature.
* @async * @async
*/ */
async signPrimaryUser(privateKeys, date, userId, config = defaultConfig) { async signPrimaryUser(privateKeys, date, userID, config = defaultConfig) {
const { index, user } = await this.getPrimaryUser(date, userId, config); const { index, user } = await this.getPrimaryUser(date, userID, config);
const userSign = await user.sign(this.keyPacket, privateKeys, config); const userSign = await user.sign(this.keyPacket, privateKeys, config);
const key = await this.clone(); const key = await this.clone();
key.users[index] = userSign; key.users[index] = userSign;
@ -857,17 +860,17 @@ class Key {
* - otherwise, verifies all certificates signed with given keys. * - otherwise, verifies all certificates signed with given keys.
* @param {Array<Key>} keys - array of keys to verify certificate signatures * @param {Array<Key>} keys - array of keys to verify certificate signatures
* @param {Date} [date] - Use the given date for verification instead of the current time * @param {Date} [date] - Use the given date for verification instead of the current time
* @param {Object} [userId] - User ID to get instead of the primary user, if it exists * @param {Object} [userID] - User ID to get instead of the primary user, if it exists
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Promise<Array<{keyid: module:type/keyid~Keyid, * @returns {Promise<Array<{keyID: module:type/keyid~KeyID,
* valid: Boolean}>>} List of signer's keyid and validity of signature * valid: Boolean}>>} List of signer's keyID and validity of signature
* @async * @async
*/ */
async verifyPrimaryUser(keys, date, userId, config = defaultConfig) { async verifyPrimaryUser(keys, date, userID, config = defaultConfig) {
const primaryKey = this.keyPacket; const primaryKey = this.keyPacket;
const { user } = await this.getPrimaryUser(date, userId, config); const { user } = await this.getPrimaryUser(date, userID, config);
const results = keys ? await user.verifyAllCertifications(primaryKey, keys, undefined, config) : const results = keys ? await user.verifyAllCertifications(primaryKey, keys, undefined, config) :
[{ keyid: primaryKey.keyid, valid: await user.verify(primaryKey, undefined, config).catch(() => false) }]; [{ keyID: primaryKey.keyID, valid: await user.verify(primaryKey, undefined, config).catch(() => false) }];
return results; return results;
} }
@ -877,9 +880,9 @@ class Key {
* - otherwise, verifies all certificates signed with given keys. * - otherwise, verifies all certificates signed with given keys.
* @param {Array<Key>} keys - array of keys to verify certificate signatures * @param {Array<Key>} keys - array of keys to verify certificate signatures
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Promise<Array<{userid: String, * @returns {Promise<Array<{userID: String,
* keyid: module:type/keyid~Keyid, * keyID: module:type/keyid~KeyID,
* valid: Boolean}>>} list of userid, signer's keyid and validity of signature * valid: Boolean}>>} list of userID, signer's keyID and validity of signature
* @async * @async
*/ */
async verifyAllUsers(keys, config = defaultConfig) { async verifyAllUsers(keys, config = defaultConfig) {
@ -887,11 +890,11 @@ class Key {
const primaryKey = this.keyPacket; const primaryKey = this.keyPacket;
await Promise.all(this.users.map(async function(user) { await Promise.all(this.users.map(async function(user) {
const signatures = keys ? await user.verifyAllCertifications(primaryKey, keys, undefined, config) : const signatures = keys ? await user.verifyAllCertifications(primaryKey, keys, undefined, config) :
[{ keyid: primaryKey.keyid, valid: await user.verify(primaryKey, undefined, config).catch(() => false) }]; [{ keyID: primaryKey.keyID, valid: await user.verify(primaryKey, undefined, config).catch(() => false) }];
signatures.forEach(signature => { signatures.forEach(signature => {
results.push({ results.push({
userid: user.userId.userid, userID: user.userID.userID,
keyid: signature.keyid, keyID: signature.keyID,
valid: signature.valid valid: signature.valid
}); });
}); });
@ -920,8 +923,8 @@ class Key {
if (options.passphrase) { if (options.passphrase) {
throw new Error("Subkey could not be encrypted here, please encrypt whole key"); throw new Error("Subkey could not be encrypted here, please encrypt whole key");
} }
if (options.rsaBits < config.minRsaBits) { if (options.rsaBits < config.minRSABits) {
throw new Error(`rsaBits should be at least ${config.minRsaBits}, got: ${options.rsaBits}`); throw new Error(`rsaBits should be at least ${config.minRSABits}, got: ${options.rsaBits}`);
} }
const secretKeyPacket = this.primaryKey; const secretKeyPacket = this.primaryKey;
if (secretKeyPacket.isDummy()) { if (secretKeyPacket.isDummy()) {
@ -944,9 +947,10 @@ class Key {
} }
} }
['getKeyId', 'getFingerprint', 'getAlgorithmInfo', 'getCreationTime', 'hasSameFingerprintAs'].forEach(name => { ['getKeyID', 'getFingerprint', 'getAlgorithmInfo', 'getCreationTime', 'hasSameFingerprintAs'].forEach(name => {
Key.prototype[name] = Key.prototype[name] =
SubKey.prototype[name]; SubKey.prototype[name];
}); });
export default Key; export default Key;

View File

@ -10,7 +10,7 @@ import defaultConfig from '../config';
/** /**
* Class that represents a subkey packet and the relevant signatures. * Class that represents a subkey packet and the relevant signatures.
* @borrows PublicSubkeyPacket#getKeyId as SubKey#getKeyId * @borrows PublicSubkeyPacket#getKeyID as SubKey#getKeyID
* @borrows PublicSubkeyPacket#getFingerprint as SubKey#getFingerprint * @borrows PublicSubkeyPacket#getFingerprint as SubKey#getFingerprint
* @borrows PublicSubkeyPacket#hasSameFingerprintAs as SubKey#hasSameFingerprintAs * @borrows PublicSubkeyPacket#hasSameFingerprintAs as SubKey#hasSameFingerprintAs
* @borrows PublicSubkeyPacket#getAlgorithmInfo as SubKey#getAlgorithmInfo * @borrows PublicSubkeyPacket#getAlgorithmInfo as SubKey#getAlgorithmInfo
@ -125,8 +125,8 @@ class SubKey {
throw new Error('SubKey update method: fingerprints of subkeys not equal'); throw new Error('SubKey update method: fingerprints of subkeys not equal');
} }
// key packet // key packet
if (this.keyPacket.tag === enums.packet.publicSubkey && if (this.keyPacket.constructor.tag === enums.packet.publicSubkey &&
subKey.keyPacket.tag === enums.packet.secretSubkey) { subKey.keyPacket.constructor.tag === enums.packet.secretSubkey) {
this.keyPacket = subKey.keyPacket; this.keyPacket = subKey.keyPacket;
} }
// update missing binding signatures // update missing binding signatures
@ -134,7 +134,7 @@ class SubKey {
const dataToVerify = { key: primaryKey, bind: that.keyPacket }; const dataToVerify = { key: primaryKey, bind: that.keyPacket };
await helper.mergeSignatures(subKey, this, 'bindingSignatures', async function(srcBindSig) { await helper.mergeSignatures(subKey, this, 'bindingSignatures', async function(srcBindSig) {
for (let i = 0; i < that.bindingSignatures.length; i++) { for (let i = 0; i < that.bindingSignatures.length; i++) {
if (that.bindingSignatures[i].issuerKeyId.equals(srcBindSig.issuerKeyId)) { if (that.bindingSignatures[i].issuerKeyID.equals(srcBindSig.issuerKeyID)) {
if (srcBindSig.created > that.bindingSignatures[i].created) { if (srcBindSig.created > that.bindingSignatures[i].created) {
that.bindingSignatures[i] = srcBindSig; that.bindingSignatures[i] = srcBindSig;
} }
@ -190,7 +190,7 @@ class SubKey {
} }
} }
['getKeyId', 'getFingerprint', 'getAlgorithmInfo', 'getCreationTime', 'isDecrypted'].forEach(name => { ['getKeyID', 'getFingerprint', 'getAlgorithmInfo', 'getCreationTime', 'isDecrypted'].forEach(name => {
SubKey.prototype[name] = SubKey.prototype[name] =
function() { function() {
return this.keyPacket[name](); return this.keyPacket[name]();

View File

@ -16,8 +16,8 @@ class User {
if (!(this instanceof User)) { if (!(this instanceof User)) {
return new User(userPacket); return new User(userPacket);
} }
this.userId = userPacket.tag === enums.packet.userID ? userPacket : null; this.userID = userPacket.constructor.tag === enums.packet.userID ? userPacket : null;
this.userAttribute = userPacket.tag === enums.packet.userAttribute ? userPacket : null; this.userAttribute = userPacket.constructor.tag === enums.packet.userAttribute ? userPacket : null;
this.selfCertifications = []; this.selfCertifications = [];
this.otherCertifications = []; this.otherCertifications = [];
this.revocationSignatures = []; this.revocationSignatures = [];
@ -29,7 +29,7 @@ class User {
*/ */
toPacketlist() { toPacketlist() {
const packetlist = new PacketList(); const packetlist = new PacketList();
packetlist.push(this.userId || this.userAttribute); packetlist.push(this.userID || this.userAttribute);
packetlist.concat(this.revocationSignatures); packetlist.concat(this.revocationSignatures);
packetlist.concat(this.selfCertifications); packetlist.concat(this.selfCertifications);
packetlist.concat(this.otherCertifications); packetlist.concat(this.otherCertifications);
@ -47,11 +47,11 @@ class User {
*/ */
async sign(primaryKey, privateKeys, config) { async sign(primaryKey, privateKeys, config) {
const dataToSign = { const dataToSign = {
userId: this.userId, userID: this.userID,
userAttribute: this.userAttribute, userAttribute: this.userAttribute,
key: primaryKey key: primaryKey
}; };
const user = new User(dataToSign.userId || dataToSign.userAttribute); const user = new User(dataToSign.userID || dataToSign.userAttribute);
user.otherCertifications = await Promise.all(privateKeys.map(async function(privateKey) { user.otherCertifications = await Promise.all(privateKeys.map(async function(privateKey) {
if (privateKey.isPublic()) { if (privateKey.isPublic()) {
throw new Error('Need private key for signing'); throw new Error('Need private key for signing');
@ -88,7 +88,7 @@ class User {
return isDataRevoked( return isDataRevoked(
primaryKey, enums.signature.certRevocation, { primaryKey, enums.signature.certRevocation, {
key: primaryKey, key: primaryKey,
userId: this.userId, userID: this.userID,
userAttribute: this.userAttribute userAttribute: this.userAttribute
}, this.revocationSignatures, certificate, key, date, config }, this.revocationSignatures, certificate, key, date, config
); );
@ -107,17 +107,17 @@ class User {
*/ */
async verifyCertificate(primaryKey, certificate, keys, date = new Date(), config) { async verifyCertificate(primaryKey, certificate, keys, date = new Date(), config) {
const that = this; const that = this;
const keyid = certificate.issuerKeyId; const keyID = certificate.issuerKeyID;
const dataToVerify = { const dataToVerify = {
userId: this.userId, userID: this.userID,
userAttribute: this.userAttribute, userAttribute: this.userAttribute,
key: primaryKey key: primaryKey
}; };
const results = await Promise.all(keys.map(async function(key) { const results = await Promise.all(keys.map(async function(key) {
if (!key.getKeyIds().some(id => id.equals(keyid))) { if (!key.getKeyIDs().some(id => id.equals(keyID))) {
return null; return null;
} }
const signingKey = await key.getSigningKey(keyid, date, undefined, config); const signingKey = await key.getSigningKey(keyID, date, undefined, config);
if (certificate.revoked || await that.isRevoked(primaryKey, certificate, signingKey.keyPacket, date, config)) { if (certificate.revoked || await that.isRevoked(primaryKey, certificate, signingKey.keyPacket, date, config)) {
throw new Error('User certificate is revoked'); throw new Error('User certificate is revoked');
} }
@ -141,8 +141,8 @@ class User {
* @param {Array<Key>} keys - Array of keys to verify certificate signatures * @param {Array<Key>} keys - Array of keys to verify certificate signatures
* @param {Date} date - Use the given date instead of the current time * @param {Date} date - Use the given date instead of the current time
* @param {Object} config - Full configuration * @param {Object} config - Full configuration
* @returns {Promise<Array<{keyid: module:type/keyid~Keyid, * @returns {Promise<Array<{keyID: module:type/keyid~KeyID,
* valid: Boolean}>>} List of signer's keyid and validity of signature * valid: Boolean}>>} List of signer's keyID and validity of signature
* @async * @async
*/ */
async verifyAllCertifications(primaryKey, keys, date = new Date(), config) { async verifyAllCertifications(primaryKey, keys, date = new Date(), config) {
@ -150,7 +150,7 @@ class User {
const certifications = this.selfCertifications.concat(this.otherCertifications); const certifications = this.selfCertifications.concat(this.otherCertifications);
return Promise.all(certifications.map(async function(certification) { return Promise.all(certifications.map(async function(certification) {
return { return {
keyid: certification.issuerKeyId, keyID: certification.issuerKeyID,
valid: await that.verifyCertificate(primaryKey, certification, keys, date, config).catch(() => false) valid: await that.verifyCertificate(primaryKey, certification, keys, date, config).catch(() => false)
}; };
})); }));
@ -173,7 +173,7 @@ class User {
} }
const that = this; const that = this;
const dataToVerify = { const dataToVerify = {
userId: this.userId, userID: this.userID,
userAttribute: this.userAttribute, userAttribute: this.userAttribute,
key: primaryKey key: primaryKey
}; };
@ -212,7 +212,7 @@ class User {
*/ */
async update(user, primaryKey, config) { async update(user, primaryKey, config) {
const dataToVerify = { const dataToVerify = {
userId: this.userId, userID: this.userID,
userAttribute: this.userAttribute, userAttribute: this.userAttribute,
key: primaryKey key: primaryKey
}; };

View File

@ -17,11 +17,13 @@
import stream from '@openpgp/web-stream-tools'; import stream from '@openpgp/web-stream-tools';
import { armor, unarmor } from './encoding/armor'; import { armor, unarmor } from './encoding/armor';
import type_keyid from './type/keyid'; import KeyID from './type/keyid';
import defaultConfig from './config'; import defaultConfig from './config';
import crypto from './crypto'; import crypto from './crypto';
import enums from './enums'; import enums from './enums';
import util from './util'; import util from './util';
import { Signature } from './signature';
import { getPreferredHashAlgo, getPreferredAlgo, isAEADSupported, createSignaturePacket } from './key';
import { import {
PacketList, PacketList,
LiteralDataPacket, LiteralDataPacket,
@ -34,8 +36,23 @@ import {
OnePassSignaturePacket, OnePassSignaturePacket,
SignaturePacket SignaturePacket
} from './packet'; } from './packet';
import { Signature } from './signature';
import { getPreferredHashAlgo, getPreferredAlgo, isAeadSupported, createSignaturePacket } from './key'; // A Message can contain the following packets
const allowedMessagePackets = /*#__PURE__*/ util.constructAllowedPackets([
LiteralDataPacket,
CompressedDataPacket,
AEADEncryptedDataPacket,
SymEncryptedIntegrityProtectedDataPacket,
SymmetricallyEncryptedDataPacket,
PublicKeyEncryptedSessionKeyPacket,
SymEncryptedSessionKeyPacket,
OnePassSignaturePacket,
SignaturePacket
]);
// A SKESK packet can contain the following packets
const allowedSymSessionKeyPackets = /*#__PURE__*/ util.constructAllowedPackets([SymEncryptedSessionKeyPacket]);
// A detached signature can contain the following packets
const allowedDetachedSignaturePackets = /*#__PURE__*/ util.constructAllowedPackets([SignaturePacket]);
/** /**
* Class that represents an OpenPGP message. * Class that represents an OpenPGP message.
@ -52,37 +69,37 @@ export class Message {
/** /**
* Returns the key IDs of the keys to which the session key is encrypted * Returns the key IDs of the keys to which the session key is encrypted
* @returns {Array<module:type/keyid~Keyid>} Array of keyid objects. * @returns {Array<module:type/keyid~KeyID>} Array of keyID objects.
*/ */
getEncryptionKeyIds() { getEncryptionKeyIDs() {
const keyIds = []; const keyIDs = [];
const pkESKeyPacketlist = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey); const pkESKeyPacketlist = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey);
pkESKeyPacketlist.forEach(function(packet) { pkESKeyPacketlist.forEach(function(packet) {
keyIds.push(packet.publicKeyId); keyIDs.push(packet.publicKeyID);
}); });
return keyIds; return keyIDs;
} }
/** /**
* Returns the key IDs of the keys that signed the message * Returns the key IDs of the keys that signed the message
* @returns {Array<module:type/keyid~Keyid>} Array of keyid objects. * @returns {Array<module:type/keyid~KeyID>} Array of keyID objects.
*/ */
getSigningKeyIds() { getSigningKeyIDs() {
const keyIds = []; const keyIDs = [];
const msg = this.unwrapCompressed(); const msg = this.unwrapCompressed();
// search for one pass signatures // search for one pass signatures
const onePassSigList = msg.packets.filterByTag(enums.packet.onePassSignature); const onePassSigList = msg.packets.filterByTag(enums.packet.onePassSignature);
onePassSigList.forEach(function(packet) { onePassSigList.forEach(function(packet) {
keyIds.push(packet.issuerKeyId); keyIDs.push(packet.issuerKeyID);
}); });
// if nothing found look for signature packets // if nothing found look for signature packets
if (!keyIds.length) { if (!keyIDs.length) {
const signatureList = msg.packets.filterByTag(enums.packet.signature); const signatureList = msg.packets.filterByTag(enums.packet.signature);
signatureList.forEach(function(packet) { signatureList.forEach(function(packet) {
keyIds.push(packet.issuerKeyId); keyIDs.push(packet.issuerKeyID);
}); });
} }
return keyIds; return keyIDs;
} }
/** /**
@ -101,7 +118,7 @@ export class Message {
const symEncryptedPacketlist = this.packets.filterByTag( const symEncryptedPacketlist = this.packets.filterByTag(
enums.packet.symmetricallyEncryptedData, enums.packet.symmetricallyEncryptedData,
enums.packet.symEncryptedIntegrityProtectedData, enums.packet.symEncryptedIntegrityProtectedData,
enums.packet.AEADEncryptedData enums.packet.aeadEncryptedData
); );
if (symEncryptedPacketlist.length === 0) { if (symEncryptedPacketlist.length === 0) {
@ -159,7 +176,7 @@ export class Message {
let packets; let packets;
if (i) { if (i) {
packets = new PacketList(); packets = new PacketList();
await packets.read(symESKeyPacketlist.write(), { SymEncryptedSessionKeyPacket }); await packets.read(symESKeyPacketlist.write(), allowedSymSessionKeyPackets);
} else { } else {
packets = symESKeyPacketlist; packets = symESKeyPacketlist;
} }
@ -186,14 +203,14 @@ export class Message {
enums.symmetric.cast5 // Golang OpenPGP fallback enums.symmetric.cast5 // Golang OpenPGP fallback
]; ];
try { try {
const primaryUser = await privateKey.getPrimaryUser(undefined, undefined, config); // TODO: Pass userId from somewhere. const primaryUser = await privateKey.getPrimaryUser(undefined, undefined, config); // TODO: Pass userID from somewhere.
if (primaryUser.selfCertification.preferredSymmetricAlgorithms) { if (primaryUser.selfCertification.preferredSymmetricAlgorithms) {
algos = algos.concat(primaryUser.selfCertification.preferredSymmetricAlgorithms); algos = algos.concat(primaryUser.selfCertification.preferredSymmetricAlgorithms);
} }
} catch (e) {} } catch (e) {}
// do not check key expiration to allow decryption of old messages // do not check key expiration to allow decryption of old messages
const privateKeyPackets = (await privateKey.getDecryptionKeys(keyPacket.publicKeyId, null, undefined, config)).map(key => key.keyPacket); const privateKeyPackets = (await privateKey.getDecryptionKeys(keyPacket.publicKeyID, null, undefined, config)).map(key => key.keyPacket);
await Promise.all(privateKeyPackets.map(async function(privateKeyPacket) { await Promise.all(privateKeyPackets.map(async function(privateKeyPacket) {
if (!privateKeyPacket || privateKeyPacket.isDummy()) { if (!privateKeyPacket || privateKeyPacket.isDummy()) {
return; return;
@ -225,7 +242,7 @@ export class Message {
if (keyPackets.length > 1) { if (keyPackets.length > 1) {
const seen = {}; const seen = {};
keyPackets = keyPackets.filter(function(item) { keyPackets = keyPackets.filter(function(item) {
const k = item.sessionKeyAlgorithm + util.uint8ArrayToStr(item.sessionKey); const k = item.sessionKeyAlgorithm + util.uint8ArrayToString(item.sessionKey);
if (seen.hasOwnProperty(k)) { if (seen.hasOwnProperty(k)) {
return false; return false;
} }
@ -276,15 +293,15 @@ export class Message {
* Generate a new session key object, taking the algorithm preferences of the passed public keys into account, if any. * Generate a new session key object, taking the algorithm preferences of the passed public keys into account, if any.
* @param {Array<Key>} [keys] - Public key(s) to select algorithm preferences for * @param {Array<Key>} [keys] - Public key(s) to select algorithm preferences for
* @param {Date} [date] - Date to select algorithm preferences at * @param {Date} [date] - Date to select algorithm preferences at
* @param {Array<Object>} [userIds] - User IDs to select algorithm preferences for * @param {Array<Object>} [userIDs] - User IDs to select algorithm preferences for
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {{ data: Uint8Array, algorithm: String }} Object with session key data and algorithm. * @returns {{ data: Uint8Array, algorithm: String }} Object with session key data and algorithm.
* @async * @async
*/ */
static async generateSessionKey(keys = [], date = new Date(), userIds = [], config = defaultConfig) { static async generateSessionKey(keys = [], date = new Date(), userIDs = [], config = defaultConfig) {
const algorithm = enums.read(enums.symmetric, await getPreferredAlgo('symmetric', keys, date, userIds, config)); const algorithm = enums.read(enums.symmetric, await getPreferredAlgo('symmetric', keys, date, userIDs, config));
const aeadAlgorithm = config.aeadProtect && await isAeadSupported(keys, date, userIds, config) ? const aeadAlgorithm = config.aeadProtect && await isAEADSupported(keys, date, userIDs, config) ?
enums.read(enums.aead, await getPreferredAlgo('aead', keys, date, userIds, config)) : enums.read(enums.aead, await getPreferredAlgo('aead', keys, date, userIDs, config)) :
undefined; undefined;
const sessionKeyData = await crypto.generateSessionKey(algorithm); const sessionKeyData = await crypto.generateSessionKey(algorithm);
@ -297,21 +314,21 @@ export class Message {
* @param {Array<String>} [passwords] - Password(s) for message encryption * @param {Array<String>} [passwords] - Password(s) for message encryption
* @param {Object} [sessionKey] - Session key in the form: { data:Uint8Array, algorithm:String, [aeadAlgorithm:String] } * @param {Object} [sessionKey] - Session key in the form: { data:Uint8Array, algorithm:String, [aeadAlgorithm:String] }
* @param {Boolean} [wildcard] - Use a key ID of 0 instead of the public key IDs * @param {Boolean} [wildcard] - Use a key ID of 0 instead of the public key IDs
* @param {Array<module:type/keyid~Keyid>} [encryptionKeyIds] - Array of key IDs to use for encryption. Each encryptionKeyIds[i] corresponds to publicKeys[i] * @param {Array<module:type/keyid~KeyID>} [encryptionKeyIDs] - Array of key IDs to use for encryption. Each encryptionKeyIDs[i] corresponds to publicKeys[i]
* @param {Date} [date] - Override the creation date of the literal package * @param {Date} [date] - Override the creation date of the literal package
* @param {Array<Object>} [userIds] - User IDs to encrypt for, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }] * @param {Array<Object>} [userIDs] - User IDs to encrypt for, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }]
* @param {Boolean} [streaming] - Whether to process data as a stream * @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Message} New message with encrypted content. * @returns {Message} New message with encrypted content.
* @async * @async
*/ */
async encrypt(keys, passwords, sessionKey, wildcard = false, encryptionKeyIds = [], date = new Date(), userIds = [], streaming, config = defaultConfig) { async encrypt(keys, passwords, sessionKey, wildcard = false, encryptionKeyIDs = [], date = new Date(), userIDs = [], streaming, config = defaultConfig) {
if (sessionKey) { if (sessionKey) {
if (!util.isUint8Array(sessionKey.data) || !util.isString(sessionKey.algorithm)) { if (!util.isUint8Array(sessionKey.data) || !util.isString(sessionKey.algorithm)) {
throw new Error('Invalid session key for encryption.'); throw new Error('Invalid session key for encryption.');
} }
} else if (keys && keys.length) { } else if (keys && keys.length) {
sessionKey = await Message.generateSessionKey(keys, date, userIds, config); sessionKey = await Message.generateSessionKey(keys, date, userIDs, config);
} else if (passwords && passwords.length) { } else if (passwords && passwords.length) {
sessionKey = await Message.generateSessionKey(undefined, undefined, undefined, config); sessionKey = await Message.generateSessionKey(undefined, undefined, undefined, config);
} else { } else {
@ -320,7 +337,7 @@ export class Message {
const { data: sessionKeyData, algorithm, aeadAlgorithm } = sessionKey; const { data: sessionKeyData, algorithm, aeadAlgorithm } = sessionKey;
const msg = await Message.encryptSessionKey(sessionKeyData, algorithm, aeadAlgorithm, keys, passwords, wildcard, encryptionKeyIds, date, userIds, config); const msg = await Message.encryptSessionKey(sessionKeyData, algorithm, aeadAlgorithm, keys, passwords, wildcard, encryptionKeyIDs, date, userIDs, config);
let symEncryptedPacket; let symEncryptedPacket;
if (aeadAlgorithm) { if (aeadAlgorithm) {
@ -342,25 +359,25 @@ export class Message {
* Encrypt a session key either with public keys, passwords, or both at once. * Encrypt a session key either with public keys, passwords, or both at once.
* @param {Uint8Array} sessionKey - session key for encryption * @param {Uint8Array} sessionKey - session key for encryption
* @param {String} algorithm - session key algorithm * @param {String} algorithm - session key algorithm
* @param {String} [aeadAlgorithm] - Aead algorithm, e.g. 'eax' or 'ocb' * @param {String} [aeadAlgorithm] - AEAD algorithm, e.g. 'eax' or 'ocb'
* @param {Array<Key>} [publicKeys] - Public key(s) for message encryption * @param {Array<Key>} [publicKeys] - Public key(s) for message encryption
* @param {Array<String>} [passwords] - For message encryption * @param {Array<String>} [passwords] - For message encryption
* @param {Boolean} [wildcard] - Use a key ID of 0 instead of the public key IDs * @param {Boolean} [wildcard] - Use a key ID of 0 instead of the public key IDs
* @param {Array<module:type/keyid~Keyid>} [encryptionKeyIds] - Array of key IDs to use for encryption. Each encryptionKeyIds[i] corresponds to publicKeys[i] * @param {Array<module:type/keyid~KeyID>} [encryptionKeyIDs] - Array of key IDs to use for encryption. Each encryptionKeyIDs[i] corresponds to publicKeys[i]
* @param {Date} [date] - Override the date * @param {Date} [date] - Override the date
* @param {Array} [userIds] - User IDs to encrypt for, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }] * @param {Array} [userIDs] - User IDs to encrypt for, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }]
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Message} New message with encrypted content. * @returns {Message} New message with encrypted content.
* @async * @async
*/ */
static async encryptSessionKey(sessionKey, algorithm, aeadAlgorithm, publicKeys, passwords, wildcard = false, encryptionKeyIds = [], date = new Date(), userIds = [], config = defaultConfig) { static async encryptSessionKey(sessionKey, algorithm, aeadAlgorithm, publicKeys, passwords, wildcard = false, encryptionKeyIDs = [], date = new Date(), userIDs = [], config = defaultConfig) {
const packetlist = new PacketList(); const packetlist = new PacketList();
if (publicKeys) { if (publicKeys) {
const results = await Promise.all(publicKeys.map(async function(publicKey, i) { const results = await Promise.all(publicKeys.map(async function(publicKey, i) {
const encryptionKey = await publicKey.getEncryptionKey(encryptionKeyIds[i], date, userIds, config); const encryptionKey = await publicKey.getEncryptionKey(encryptionKeyIDs[i], date, userIDs, config);
const pkESKeyPacket = new PublicKeyEncryptedSessionKeyPacket(); const pkESKeyPacket = new PublicKeyEncryptedSessionKeyPacket();
pkESKeyPacket.publicKeyId = wildcard ? type_keyid.wildcard() : encryptionKey.getKeyId(); pkESKeyPacket.publicKeyID = wildcard ? KeyID.wildcard() : encryptionKey.getKeyID();
pkESKeyPacket.publicKeyAlgorithm = encryptionKey.keyPacket.algorithm; pkESKeyPacket.publicKeyAlgorithm = encryptionKey.keyPacket.algorithm;
pkESKeyPacket.sessionKey = sessionKey; pkESKeyPacket.sessionKey = sessionKey;
pkESKeyPacket.sessionKeyAlgorithm = algorithm; pkESKeyPacket.sessionKeyAlgorithm = algorithm;
@ -413,15 +430,15 @@ export class Message {
* Sign the message (the literal data packet of the message) * Sign the message (the literal data packet of the message)
* @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing * @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing
* @param {Signature} [signature] - Any existing detached signature to add to the message * @param {Signature} [signature] - Any existing detached signature to add to the message
* @param {Array<module:type/keyid~Keyid>} [signingKeyIds] - Array of key IDs to use for signing. Each signingKeyIds[i] corresponds to privateKeys[i] * @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to privateKeys[i]
* @param {Date} [date] - Override the creation time of the signature * @param {Date} [date] - Override the creation time of the signature
* @param {Array} [userIds] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] * @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
* @param {Boolean} [streaming] - Whether to process data as a stream * @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Message} New message with signed content. * @returns {Message} New message with signed content.
* @async * @async
*/ */
async sign(privateKeys = [], signature = null, signingKeyIds = [], date = new Date(), userIds = [], streaming = false, config = defaultConfig) { async sign(privateKeys = [], signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], streaming = false, config = defaultConfig) {
const packetlist = new PacketList(); const packetlist = new PacketList();
const literalDataPacket = this.packets.findPacket(enums.packet.literalData); const literalDataPacket = this.packets.findPacket(enums.packet.literalData);
@ -443,7 +460,7 @@ export class Message {
onePassSig.signatureType = signaturePacket.signatureType; onePassSig.signatureType = signaturePacket.signatureType;
onePassSig.hashAlgorithm = signaturePacket.hashAlgorithm; onePassSig.hashAlgorithm = signaturePacket.hashAlgorithm;
onePassSig.publicKeyAlgorithm = signaturePacket.publicKeyAlgorithm; onePassSig.publicKeyAlgorithm = signaturePacket.publicKeyAlgorithm;
onePassSig.issuerKeyId = signaturePacket.issuerKeyId; onePassSig.issuerKeyID = signaturePacket.issuerKeyID;
if (!privateKeys.length && i === 0) { if (!privateKeys.length && i === 0) {
onePassSig.flags = 1; onePassSig.flags = 1;
} }
@ -455,13 +472,13 @@ export class Message {
if (privateKey.isPublic()) { if (privateKey.isPublic()) {
throw new Error('Need private key for signing'); throw new Error('Need private key for signing');
} }
const signingKeyId = signingKeyIds[privateKeys.length - 1 - i]; const signingKeyID = signingKeyIDs[privateKeys.length - 1 - i];
const signingKey = await privateKey.getSigningKey(signingKeyId, date, userIds, config); const signingKey = await privateKey.getSigningKey(signingKeyID, date, userIDs, config);
const onePassSig = new OnePassSignaturePacket(); const onePassSig = new OnePassSignaturePacket();
onePassSig.signatureType = signatureType; onePassSig.signatureType = signatureType;
onePassSig.hashAlgorithm = await getPreferredHashAlgo(privateKey, signingKey.keyPacket, date, userIds, config); onePassSig.hashAlgorithm = await getPreferredHashAlgo(privateKey, signingKey.keyPacket, date, userIDs, config);
onePassSig.publicKeyAlgorithm = signingKey.keyPacket.algorithm; onePassSig.publicKeyAlgorithm = signingKey.keyPacket.algorithm;
onePassSig.issuerKeyId = signingKey.getKeyId(); onePassSig.issuerKeyID = signingKey.getKeyID();
if (i === privateKeys.length - 1) { if (i === privateKeys.length - 1) {
onePassSig.flags = 1; onePassSig.flags = 1;
} }
@ -471,7 +488,7 @@ export class Message {
}); });
packetlist.push(literalDataPacket); packetlist.push(literalDataPacket);
packetlist.concat(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIds, date, userIds, false, streaming, config)); packetlist.concat(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIDs, date, userIDs, false, streaming, config));
return new Message(packetlist); return new Message(packetlist);
} }
@ -501,20 +518,20 @@ export class Message {
* Create a detached signature for the message (the literal data packet of the message) * Create a detached signature for the message (the literal data packet of the message)
* @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing * @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing
* @param {Signature} [signature] - Any existing detached signature * @param {Signature} [signature] - Any existing detached signature
* @param {Array<module:type/keyid~Keyid>} [signingKeyIds] - Array of key IDs to use for signing. Each signingKeyIds[i] corresponds to privateKeys[i] * @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to privateKeys[i]
* @param {Date} [date] - Override the creation time of the signature * @param {Date} [date] - Override the creation time of the signature
* @param {Array} [userIds] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] * @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
* @param {Boolean} [streaming] - Whether to process data as a stream * @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Signature} New detached signature of message content. * @returns {Signature} New detached signature of message content.
* @async * @async
*/ */
async signDetached(privateKeys = [], signature = null, signingKeyIds = [], date = new Date(), userIds = [], streaming = false, config = defaultConfig) { async signDetached(privateKeys = [], signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], streaming = false, config = defaultConfig) {
const literalDataPacket = this.packets.findPacket(enums.packet.literalData); const literalDataPacket = this.packets.findPacket(enums.packet.literalData);
if (!literalDataPacket) { if (!literalDataPacket) {
throw new Error('No literal data packet to sign.'); throw new Error('No literal data packet to sign.');
} }
return new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIds, date, userIds, true, streaming, config)); return new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIDs, date, userIDs, true, streaming, config));
} }
/** /**
@ -523,9 +540,9 @@ export class Message {
* @param {Date} [date] - Verify the signature against the given date, i.e. check signature creation time < date < expiration time * @param {Date} [date] - Verify the signature against the given date, i.e. check signature creation time < date < expiration time
* @param {Boolean} [streaming] - Whether to process data as a stream * @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Array<{keyid: module:type/keyid~Keyid, * @returns {Array<{keyID: module:type/keyid~KeyID,
* signature: Promise<Signature>, * signature: Promise<Signature>,
* verified: Promise<Boolean>}>} List of signer's keyid and validity of signatures. * verified: Promise<Boolean>}>} List of signer's keyID and validity of signatures.
* @async * @async
*/ */
async verify(keys, date = new Date(), streaming, config = defaultConfig) { async verify(keys, date = new Date(), streaming, config = defaultConfig) {
@ -578,9 +595,9 @@ export class Message {
* @param {Signature} signature * @param {Signature} signature
* @param {Date} date - Verify the signature against the given date, i.e. check signature creation time < date < expiration time * @param {Date} date - Verify the signature against the given date, i.e. check signature creation time < date < expiration time
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Array<{keyid: module:type/keyid~Keyid, * @returns {Array<{keyID: module:type/keyid~KeyID,
* signature: Promise<Signature>, * signature: Promise<Signature>,
* verified: Promise<Boolean>}>} List of signer's keyid and validity of signature. * verified: Promise<Boolean>}>} List of signer's keyID and validity of signature.
* @async * @async
*/ */
verifyDetached(signature, keys, date = new Date(), streaming, config = defaultConfig) { verifyDetached(signature, keys, date = new Date(), streaming, config = defaultConfig) {
@ -610,7 +627,10 @@ export class Message {
* @param {String|Uint8Array} detachedSignature - The detached ASCII-armored or Uint8Array PGP signature * @param {String|Uint8Array} detachedSignature - The detached ASCII-armored or Uint8Array PGP signature
*/ */
async appendSignature(detachedSignature) { async appendSignature(detachedSignature) {
await this.packets.read(util.isUint8Array(detachedSignature) ? detachedSignature : (await unarmor(detachedSignature)).data, { SignaturePacket }); await this.packets.read(
util.isUint8Array(detachedSignature) ? detachedSignature : (await unarmor(detachedSignature)).data,
allowedDetachedSignaturePackets
);
} }
/** /**
@ -693,9 +713,9 @@ export class Message {
* @param {LiteralDataPacket} literalDataPacket - the literal data packet to sign * @param {LiteralDataPacket} literalDataPacket - the literal data packet to sign
* @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing * @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing
* @param {Signature} [signature] - Any existing detached signature to append * @param {Signature} [signature] - Any existing detached signature to append
* @param {Array<module:type/keyid~Keyid>} [signingKeyIds] - Array of key IDs to use for signing. Each signingKeyIds[i] corresponds to privateKeys[i] * @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to privateKeys[i]
* @param {Date} [date] - Override the creationtime of the signature * @param {Date} [date] - Override the creationtime of the signature
* @param {Array} [userIds] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }] * @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
* @param {Boolean} [detached] - Whether to create detached signature packets * @param {Boolean} [detached] - Whether to create detached signature packets
* @param {Boolean} [streaming] - Whether to process data as a stream * @param {Boolean} [streaming] - Whether to process data as a stream
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
@ -703,7 +723,7 @@ export class Message {
* @async * @async
* @private * @private
*/ */
export async function createSignaturePackets(literalDataPacket, privateKeys, signature = null, signingKeyIds = [], date = new Date(), userIds = [], detached = false, streaming = false, config = defaultConfig) { export async function createSignaturePackets(literalDataPacket, privateKeys, signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], detached = false, streaming = false, config = defaultConfig) {
const packetlist = new PacketList(); const packetlist = new PacketList();
// If data packet was created from Uint8Array, use binary, otherwise use text // If data packet was created from Uint8Array, use binary, otherwise use text
@ -711,12 +731,12 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig
enums.signature.binary : enums.signature.text; enums.signature.binary : enums.signature.text;
await Promise.all(privateKeys.map(async (privateKey, i) => { await Promise.all(privateKeys.map(async (privateKey, i) => {
const userId = userIds[i]; const userID = userIDs[i];
if (privateKey.isPublic()) { if (privateKey.isPublic()) {
throw new Error('Need private key for signing'); throw new Error('Need private key for signing');
} }
const signingKey = await privateKey.getSigningKey(signingKeyIds[i], date, userId, config); const signingKey = await privateKey.getSigningKey(signingKeyIDs[i], date, userID, config);
return createSignaturePacket(literalDataPacket, privateKey, signingKey.keyPacket, { signatureType }, date, userId, detached, streaming, config); return createSignaturePacket(literalDataPacket, privateKey, signingKey.keyPacket, { signatureType }, date, userID, detached, streaming, config);
})).then(signatureList => { })).then(signatureList => {
signatureList.forEach(signaturePacket => packetlist.push(signaturePacket)); signatureList.forEach(signaturePacket => packetlist.push(signaturePacket));
}); });
@ -729,7 +749,7 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig
} }
/** /**
* Create object containing signer's keyid and validity of signature * Create object containing signer's keyID and validity of signature
* @param {SignaturePacket} signature - Signature packets * @param {SignaturePacket} signature - Signature packets
* @param {Array<LiteralDataPacket>} literalDataList - Array of literal data packets * @param {Array<LiteralDataPacket>} literalDataList - Array of literal data packets
* @param {Array<Key>} keys - Array of keys to verify signatures * @param {Array<Key>} keys - Array of keys to verify signatures
@ -737,9 +757,9 @@ export async function createSignaturePackets(literalDataPacket, privateKeys, sig
* i.e. check signature creation time < date < expiration time * i.e. check signature creation time < date < expiration time
* @param {Boolean} [detached] - Whether to verify detached signature packets * @param {Boolean} [detached] - Whether to verify detached signature packets
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {{keyid: module:type/keyid~Keyid, * @returns {{keyID: module:type/keyid~KeyID,
* signature: Promise<Signature>, * signature: Promise<Signature>,
* verified: Promise<Boolean>}} signer's keyid and validity of signature * verified: Promise<Boolean>}} signer's keyID and validity of signature
* @async * @async
* @private * @private
*/ */
@ -749,24 +769,24 @@ async function createVerificationObject(signature, literalDataList, keys, date =
let keyError; let keyError;
for (const key of keys) { for (const key of keys) {
const issuerKeys = key.getKeys(signature.issuerKeyId); const issuerKeys = key.getKeys(signature.issuerKeyID);
if (issuerKeys.length > 0) { if (issuerKeys.length > 0) {
primaryKey = key; primaryKey = key;
break; break;
} }
} }
if (!primaryKey) { if (!primaryKey) {
keyError = new Error(`Could not find signing key with key ID ${signature.issuerKeyId.toHex()}`); keyError = new Error(`Could not find signing key with key ID ${signature.issuerKeyID.toHex()}`);
} else { } else {
try { try {
signingKey = await primaryKey.getSigningKey(signature.issuerKeyId, null, undefined, config); signingKey = await primaryKey.getSigningKey(signature.issuerKeyID, null, undefined, config);
} catch (e) { } catch (e) {
keyError = e; keyError = e;
} }
} }
const signaturePacket = signature.correspondingSig || signature; const signaturePacket = signature.correspondingSig || signature;
const verifiedSig = { const verifiedSig = {
keyid: signature.issuerKeyId, keyID: signature.issuerKeyID,
verified: (async () => { verified: (async () => {
if (keyError) { if (keyError) {
throw keyError; throw keyError;
@ -803,7 +823,7 @@ async function createVerificationObject(signature, literalDataList, keys, date =
} }
/** /**
* Create list of objects containing signer's keyid and validity of signature * Create list of objects containing signer's keyID and validity of signature
* @param {Array<SignaturePacket>} signatureList - Array of signature packets * @param {Array<SignaturePacket>} signatureList - Array of signature packets
* @param {Array<LiteralDataPacket>} literalDataList - Array of literal data packets * @param {Array<LiteralDataPacket>} literalDataList - Array of literal data packets
* @param {Array<Key>} keys - Array of keys to verify signatures * @param {Array<Key>} keys - Array of keys to verify signatures
@ -811,9 +831,9 @@ async function createVerificationObject(signature, literalDataList, keys, date =
* i.e. check signature creation time < date < expiration time * i.e. check signature creation time < date < expiration time
* @param {Boolean} [detached] - Whether to verify detached signature packets * @param {Boolean} [detached] - Whether to verify detached signature packets
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
* @returns {Array<{keyid: module:type/keyid~Keyid, * @returns {Array<{keyID: module:type/keyid~KeyID,
* signature: Promise<Signature>, * signature: Promise<Signature>,
* verified: Promise<Boolean>}>} list of signer's keyid and validity of signatures * verified: Promise<Boolean>}>} list of signer's keyID and validity of signatures
* @async * @async
* @private * @private
*/ */
@ -853,18 +873,9 @@ export async function readMessage({ armoredMessage, binaryMessage, config }) {
input = data; input = data;
} }
const packetlist = new PacketList(); const packetlist = new PacketList();
await packetlist.read(input, { await packetlist.read(input, allowedMessagePackets, streamType, config);
LiteralDataPacket,
CompressedDataPacket,
AEADEncryptedDataPacket,
SymEncryptedIntegrityProtectedDataPacket,
SymmetricallyEncryptedDataPacket,
PublicKeyEncryptedSessionKeyPacket,
SymEncryptedSessionKeyPacket,
OnePassSignaturePacket,
SignaturePacket
}, streamType, config);
const message = new Message(packetlist); const message = new Message(packetlist);
message.fromStream = streamType; message.fromStream = streamType;
return message; return message;
} }

View File

@ -41,7 +41,7 @@ if (globalThis.ReadableStream) {
* Generates a new OpenPGP key pair. Supports RSA and ECC keys. By default, primary and subkeys will be of same type. * Generates a new OpenPGP key pair. Supports RSA and ECC keys. By default, primary and subkeys will be of same type.
* @param {Object} options * @param {Object} options
* @param {'ecc'|'rsa'} [options.type='ecc'] - The primary key algorithm type: ECC (default) or RSA * @param {'ecc'|'rsa'} [options.type='ecc'] - The primary key algorithm type: ECC (default) or RSA
* @param {Object|Array<Object>} options.userIds - User IDs as objects: `{ name: 'Jo Doe', email: 'info@jo.com' }` * @param {Object|Array<Object>} options.userIDs - User IDs as objects: `{ name: 'Jo Doe', email: 'info@jo.com' }`
* @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the generated private key * @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the generated private key
* @param {Number} [options.rsaBits=4096] - Number of bits for RSA keys * @param {Number} [options.rsaBits=4096] - Number of bits for RSA keys
* @param {String} [options.curve='curve25519'] - Elliptic curve for ECC keys: * @param {String} [options.curve='curve25519'] - Elliptic curve for ECC keys:
@ -57,12 +57,12 @@ if (globalThis.ReadableStream) {
* @async * @async
* @static * @static
*/ */
export function generateKey({ userIds = [], passphrase = "", type = "ecc", rsaBits = 4096, curve = "curve25519", keyExpirationTime = 0, date = new Date(), subkeys = [{}], config }) { export function generateKey({ userIDs = [], passphrase = "", type = "ecc", rsaBits = 4096, curve = "curve25519", keyExpirationTime = 0, date = new Date(), subkeys = [{}], config }) {
config = { ...defaultConfig, ...config }; config = { ...defaultConfig, ...config };
userIds = toArray(userIds); userIDs = toArray(userIDs);
const options = { userIds, passphrase, type, rsaBits, curve, keyExpirationTime, date, subkeys }; const options = { userIDs, passphrase, type, rsaBits, curve, keyExpirationTime, date, subkeys };
if (type === "rsa" && rsaBits < config.minRsaBits) { if (type === "rsa" && rsaBits < config.minRSABits) {
throw new Error(`rsaBits should be at least ${config.minRsaBits}, got: ${rsaBits}`); throw new Error(`rsaBits should be at least ${config.minRSABits}, got: ${rsaBits}`);
} }
return generate(options, config).then(async key => { return generate(options, config).then(async key => {
@ -84,7 +84,7 @@ export function generateKey({ userIds = [], passphrase = "", type = "ecc", rsaBi
* Reformats signature packets for a key and rewraps key object. * Reformats signature packets for a key and rewraps key object.
* @param {Object} options * @param {Object} options
* @param {Key} options.privateKey - Private key to reformat * @param {Key} options.privateKey - Private key to reformat
* @param {Object|Array<Object>} options.userIds - User IDs as objects: `{ name: 'Jo Doe', email: 'info@jo.com' }` * @param {Object|Array<Object>} options.userIDs - User IDs as objects: `{ name: 'Jo Doe', email: 'info@jo.com' }`
* @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the generated private key * @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the generated private key
* @param {Number} [options.keyExpirationTime=0 (never expires)] - Number of seconds from the key creation time after which the key expires * @param {Number} [options.keyExpirationTime=0 (never expires)] - Number of seconds from the key creation time after which the key expires
* @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config} * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
@ -93,10 +93,10 @@ export function generateKey({ userIds = [], passphrase = "", type = "ecc", rsaBi
* @async * @async
* @static * @static
*/ */
export function reformatKey({ privateKey, userIds = [], passphrase = "", keyExpirationTime = 0, date, config }) { export function reformatKey({ privateKey, userIDs = [], passphrase = "", keyExpirationTime = 0, date, config }) {
config = { ...defaultConfig, ...config }; config = { ...defaultConfig, ...config };
userIds = toArray(userIds); userIDs = toArray(userIDs);
const options = { privateKey, userIds, passphrase, keyExpirationTime, date }; const options = { privateKey, userIDs, passphrase, keyExpirationTime, date };
return reformat(options, config).then(async key => { return reformat(options, config).then(async key => {
const revocationCertificate = await key.getRevocationCertificate(date, config); const revocationCertificate = await key.getRevocationCertificate(date, config);
@ -240,19 +240,19 @@ export async function encryptKey({ privateKey, passphrase, config }) {
* @param {'web'|'ponyfill'|'node'|false} [options.streaming=type of stream `message` was created from, if any] - Whether to return data as a stream * @param {'web'|'ponyfill'|'node'|false} [options.streaming=type of stream `message` was created from, if any] - Whether to return data as a stream
* @param {Signature} [options.signature] - A detached signature to add to the encrypted message * @param {Signature} [options.signature] - A detached signature to add to the encrypted message
* @param {Boolean} [options.wildcard=false] - Use a key ID of 0 instead of the public key IDs * @param {Boolean} [options.wildcard=false] - Use a key ID of 0 instead of the public key IDs
* @param {Array<module:type/keyid~Keyid>} [options.signingKeyIds=latest-created valid signing (sub)keys] - Array of key IDs to use for signing. Each `signingKeyIds[i]` corresponds to `privateKeys[i]` * @param {Array<module:type/keyid~KeyID>} [options.signingKeyIDs=latest-created valid signing (sub)keys] - Array of key IDs to use for signing. Each `signingKeyIDs[i]` corresponds to `privateKeys[i]`
* @param {Array<module:type/keyid~Keyid>} [options.encryptionKeyIds=latest-created valid encryption (sub)keys] - Array of key IDs to use for encryption. Each `encryptionKeyIds[i]` corresponds to `publicKeys[i]` * @param {Array<module:type/keyid~KeyID>} [options.encryptionKeyIDs=latest-created valid encryption (sub)keys] - Array of key IDs to use for encryption. Each `encryptionKeyIDs[i]` corresponds to `publicKeys[i]`
* @param {Date} [options.date=current date] - Override the creation date of the message signature * @param {Date} [options.date=current date] - Override the creation date of the message signature
* @param {Array<Object>} [options.fromUserIds=primary user IDs] - Array of user IDs to sign with, one per key in `privateKeys`, e.g. `[{ name: 'Steve Sender', email: 'steve@openpgp.org' }]` * @param {Array<Object>} [options.fromUserIDs=primary user IDs] - Array of user IDs to sign with, one per key in `privateKeys`, e.g. `[{ name: 'Steve Sender', email: 'steve@openpgp.org' }]`
* @param {Array<Object>} [options.toUserIds=primary user IDs] - Array of user IDs to encrypt for, one per key in `publicKeys`, e.g. `[{ name: 'Robert Receiver', email: 'robert@openpgp.org' }]` * @param {Array<Object>} [options.toUserIDs=primary user IDs] - Array of user IDs to encrypt for, one per key in `publicKeys`, e.g. `[{ name: 'Robert Receiver', email: 'robert@openpgp.org' }]`
* @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config} * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
* @returns {String|ReadableStream<String>|NodeStream<String>|Uint8Array|ReadableStream<Uint8Array>|NodeStream<Uint8Array>} Encrypted message (string if `armor` was true, the default; Uint8Array if `armor` was false). * @returns {String|ReadableStream<String>|NodeStream<String>|Uint8Array|ReadableStream<Uint8Array>|NodeStream<Uint8Array>} Encrypted message (string if `armor` was true, the default; Uint8Array if `armor` was false).
* @async * @async
* @static * @static
*/ */
export function encrypt({ message, publicKeys, privateKeys, passwords, sessionKey, armor = true, streaming = message && message.fromStream, detached = false, signature = null, wildcard = false, signingKeyIds = [], encryptionKeyIds = [], date = new Date(), fromUserIds = [], toUserIds = [], config }) { export function encrypt({ message, publicKeys, privateKeys, passwords, sessionKey, armor = true, streaming = message && message.fromStream, detached = false, signature = null, wildcard = false, signingKeyIDs = [], encryptionKeyIDs = [], date = new Date(), fromUserIDs = [], toUserIDs = [], config }) {
config = { ...defaultConfig, ...config }; config = { ...defaultConfig, ...config };
checkMessage(message); publicKeys = toArray(publicKeys); privateKeys = toArray(privateKeys); passwords = toArray(passwords); fromUserIds = toArray(fromUserIds); toUserIds = toArray(toUserIds); checkMessage(message); publicKeys = toArray(publicKeys); privateKeys = toArray(privateKeys); passwords = toArray(passwords); fromUserIDs = toArray(fromUserIDs); toUserIDs = toArray(toUserIDs);
if (detached) { if (detached) {
throw new Error("detached option has been removed from openpgp.encrypt. Separately call openpgp.sign instead. Don't forget to remove privateKeys option as well."); throw new Error("detached option has been removed from openpgp.encrypt. Separately call openpgp.sign instead. Don't forget to remove privateKeys option as well.");
} }
@ -262,13 +262,13 @@ export function encrypt({ message, publicKeys, privateKeys, passwords, sessionKe
privateKeys = []; privateKeys = [];
} }
if (privateKeys.length || signature) { // sign the message only if private keys or signature is specified if (privateKeys.length || signature) { // sign the message only if private keys or signature is specified
message = await message.sign(privateKeys, signature, signingKeyIds, date, fromUserIds, message.fromStream, config); message = await message.sign(privateKeys, signature, signingKeyIDs, date, fromUserIDs, message.fromStream, config);
} }
message = message.compress( message = message.compress(
await getPreferredAlgo('compression', publicKeys, date, toUserIds, config), await getPreferredAlgo('compression', publicKeys, date, toUserIDs, config),
config config
); );
message = await message.encrypt(publicKeys, passwords, sessionKey, wildcard, encryptionKeyIds, date, toUserIds, streaming, config); message = await message.encrypt(publicKeys, passwords, sessionKey, wildcard, encryptionKeyIDs, date, toUserIDs, streaming, config);
const data = armor ? message.armor(config) : message.write(); const data = armor ? message.armor(config) : message.write();
return convertStream(data, streaming, armor ? 'utf8' : 'binary'); return convertStream(data, streaming, armor ? 'utf8' : 'binary');
}).catch(onError.bind(null, 'Error encrypting message')); }).catch(onError.bind(null, 'Error encrypting message'));
@ -296,7 +296,7 @@ export function encrypt({ message, publicKeys, privateKeys, passwords, sessionKe
* filename: String, * filename: String,
* signatures: [ * signatures: [
* { * {
* keyid: module:type/keyid~Keyid, * keyID: module:type/keyid~KeyID,
* verified: Promise<Boolean>, * verified: Promise<Boolean>,
* valid: Boolean (if streaming was false) * valid: Boolean (if streaming was false)
* }, ... * }, ...
@ -341,29 +341,29 @@ export function decrypt({ message, privateKeys, passwords, sessionKeys, publicKe
* @param {Boolean} [options.armor=true] - Whether the return values should be ascii armored (true, the default) or binary (false) * @param {Boolean} [options.armor=true] - Whether the return values should be ascii armored (true, the default) or binary (false)
* @param {'web'|'ponyfill'|'node'|false} [options.streaming=type of stream `message` was created from, if any] - Whether to return data as a stream. Defaults to the type of stream `message` was created from, if any. * @param {'web'|'ponyfill'|'node'|false} [options.streaming=type of stream `message` was created from, if any] - Whether to return data as a stream. Defaults to the type of stream `message` was created from, if any.
* @param {Boolean} [options.detached=false] - If the return value should contain a detached signature * @param {Boolean} [options.detached=false] - If the return value should contain a detached signature
* @param {Array<module:type/keyid~Keyid>} [options.signingKeyIds=latest-created valid signing (sub)keys] - Array of key IDs to use for signing. Each signingKeyIds[i] corresponds to privateKeys[i] * @param {Array<module:type/keyid~KeyID>} [options.signingKeyIDs=latest-created valid signing (sub)keys] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to privateKeys[i]
* @param {Date} [options.date=current date] - Override the creation date of the signature * @param {Date} [options.date=current date] - Override the creation date of the signature
* @param {Array<Object>} [options.fromUserIds=primary user IDs] - Array of user IDs to sign with, one per key in `privateKeys`, e.g. `[{ name: 'Steve Sender', email: 'steve@openpgp.org' }]` * @param {Array<Object>} [options.fromUserIDs=primary user IDs] - Array of user IDs to sign with, one per key in `privateKeys`, e.g. `[{ name: 'Steve Sender', email: 'steve@openpgp.org' }]`
* @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config} * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
* @returns {String|ReadableStream<String>|NodeStream<String>|Uint8Array|ReadableStream<Uint8Array>|NodeStream<Uint8Array>} Signed message (string if `armor` was true, the default; Uint8Array if `armor` was false). * @returns {String|ReadableStream<String>|NodeStream<String>|Uint8Array|ReadableStream<Uint8Array>|NodeStream<Uint8Array>} Signed message (string if `armor` was true, the default; Uint8Array if `armor` was false).
* @async * @async
* @static * @static
*/ */
export function sign({ message, privateKeys, armor = true, streaming = message && message.fromStream, detached = false, signingKeyIds = [], date = new Date(), fromUserIds = [], config }) { export function sign({ message, privateKeys, armor = true, streaming = message && message.fromStream, detached = false, signingKeyIDs = [], date = new Date(), fromUserIDs = [], config }) {
config = { ...defaultConfig, ...config }; config = { ...defaultConfig, ...config };
checkCleartextOrMessage(message); checkCleartextOrMessage(message);
if (message instanceof CleartextMessage && !armor) throw new Error("Can't sign non-armored cleartext message"); if (message instanceof CleartextMessage && !armor) throw new Error("Can't sign non-armored cleartext message");
if (message instanceof CleartextMessage && detached) throw new Error("Can't detach-sign a cleartext message"); if (message instanceof CleartextMessage && detached) throw new Error("Can't detach-sign a cleartext message");
privateKeys = toArray(privateKeys); fromUserIds = toArray(fromUserIds); privateKeys = toArray(privateKeys); fromUserIDs = toArray(fromUserIDs);
return Promise.resolve().then(async function() { return Promise.resolve().then(async function() {
let signature; let signature;
if (message instanceof CleartextMessage) { if (message instanceof CleartextMessage) {
signature = await message.sign(privateKeys, undefined, signingKeyIds, date, fromUserIds, config); signature = await message.sign(privateKeys, undefined, signingKeyIDs, date, fromUserIDs, config);
} else if (detached) { } else if (detached) {
signature = await message.signDetached(privateKeys, undefined, signingKeyIds, date, fromUserIds, message.fromStream, config); signature = await message.signDetached(privateKeys, undefined, signingKeyIDs, date, fromUserIDs, message.fromStream, config);
} else { } else {
signature = await message.sign(privateKeys, undefined, signingKeyIds, date, fromUserIds, message.fromStream, config); signature = await message.sign(privateKeys, undefined, signingKeyIDs, date, fromUserIDs, message.fromStream, config);
} }
signature = armor ? signature.armor(config) : signature.write(); signature = armor ? signature.armor(config) : signature.write();
if (detached) { if (detached) {
@ -395,7 +395,7 @@ export function sign({ message, privateKeys, armor = true, streaming = message &
* data: Uint8Array|ReadableStream<Uint8Array>|NodeStream, (if `message` was a Message) * data: Uint8Array|ReadableStream<Uint8Array>|NodeStream, (if `message` was a Message)
* signatures: [ * signatures: [
* { * {
* keyid: module:type/keyid~Keyid, * keyID: module:type/keyid~KeyID,
* verified: Promise<Boolean>, * verified: Promise<Boolean>,
* valid: Boolean (if `streaming` was false) * valid: Boolean (if `streaming` was false)
* }, ... * }, ...
@ -438,19 +438,19 @@ export function verify({ message, publicKeys, format = 'utf8', streaming = messa
* @param {Object} options * @param {Object} options
* @param {Key|Array<Key>} options.publicKeys - Array of public keys or single key used to select algorithm preferences for * @param {Key|Array<Key>} options.publicKeys - Array of public keys or single key used to select algorithm preferences for
* @param {Date} [options.date=current date] - Date to select algorithm preferences at * @param {Date} [options.date=current date] - Date to select algorithm preferences at
* @param {Array} [options.toUserIds=primary user IDs] - User IDs to select algorithm preferences for * @param {Array} [options.toUserIDs=primary user IDs] - User IDs to select algorithm preferences for
* @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config} * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
* @returns {{ data: Uint8Array, algorithm: String }} Object with session key data and algorithm. * @returns {{ data: Uint8Array, algorithm: String }} Object with session key data and algorithm.
* @async * @async
* @static * @static
*/ */
export function generateSessionKey({ publicKeys, date = new Date(), toUserIds = [], config }) { export function generateSessionKey({ publicKeys, date = new Date(), toUserIDs = [], config }) {
config = { ...defaultConfig, ...config }; config = { ...defaultConfig, ...config };
publicKeys = toArray(publicKeys); toUserIds = toArray(toUserIds); publicKeys = toArray(publicKeys); toUserIDs = toArray(toUserIDs);
return Promise.resolve().then(async function() { return Promise.resolve().then(async function() {
return Message.generateSessionKey(publicKeys, date, toUserIds, config); return Message.generateSessionKey(publicKeys, date, toUserIDs, config);
}).catch(onError.bind(null, 'Error generating session key')); }).catch(onError.bind(null, 'Error generating session key'));
} }
@ -461,26 +461,26 @@ export function generateSessionKey({ publicKeys, date = new Date(), toUserIds =
* @param {Object} options * @param {Object} options
* @param {Uint8Array} options.data - The session key to be encrypted e.g. 16 random bytes (for aes128) * @param {Uint8Array} options.data - The session key to be encrypted e.g. 16 random bytes (for aes128)
* @param {String} options.algorithm - Algorithm of the symmetric session key e.g. 'aes128' or 'aes256' * @param {String} options.algorithm - Algorithm of the symmetric session key e.g. 'aes128' or 'aes256'
* @param {String} [options.aeadAlgorithm] - Aead algorithm, e.g. 'eax' or 'ocb' * @param {String} [options.aeadAlgorithm] - AEAD algorithm, e.g. 'eax' or 'ocb'
* @param {Key|Array<Key>} [options.publicKeys] - Array of public keys or single key, used to encrypt the key * @param {Key|Array<Key>} [options.publicKeys] - Array of public keys or single key, used to encrypt the key
* @param {String|Array<String>} [options.passwords] - Passwords for the message * @param {String|Array<String>} [options.passwords] - Passwords for the message
* @param {Boolean} [options.armor=true] - Whether the return values should be ascii armored (true, the default) or binary (false) * @param {Boolean} [options.armor=true] - Whether the return values should be ascii armored (true, the default) or binary (false)
* @param {Boolean} [options.wildcard=false] - Use a key ID of 0 instead of the public key IDs * @param {Boolean} [options.wildcard=false] - Use a key ID of 0 instead of the public key IDs
* @param {Array<module:type/keyid~Keyid>} [options.encryptionKeyIds=latest-created valid encryption (sub)keys] - Array of key IDs to use for encryption. Each encryptionKeyIds[i] corresponds to publicKeys[i] * @param {Array<module:type/keyid~KeyID>} [options.encryptionKeyIDs=latest-created valid encryption (sub)keys] - Array of key IDs to use for encryption. Each encryptionKeyIDs[i] corresponds to publicKeys[i]
* @param {Date} [options.date=current date] - Override the date * @param {Date} [options.date=current date] - Override the date
* @param {Array} [options.toUserIds=primary user IDs] - Array of user IDs to encrypt for, one per key in `publicKeys`, e.g. `[{ name: 'Phil Zimmermann', email: 'phil@openpgp.org' }]` * @param {Array} [options.toUserIDs=primary user IDs] - Array of user IDs to encrypt for, one per key in `publicKeys`, e.g. `[{ name: 'Phil Zimmermann', email: 'phil@openpgp.org' }]`
* @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config} * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
* @returns {String|Uint8Array} Encrypted session keys (string if `armor` was true, the default; Uint8Array if `armor` was false). * @returns {String|Uint8Array} Encrypted session keys (string if `armor` was true, the default; Uint8Array if `armor` was false).
* @async * @async
* @static * @static
*/ */
export function encryptSessionKey({ data, algorithm, aeadAlgorithm, publicKeys, passwords, armor = true, wildcard = false, encryptionKeyIds = [], date = new Date(), toUserIds = [], config }) { export function encryptSessionKey({ data, algorithm, aeadAlgorithm, publicKeys, passwords, armor = true, wildcard = false, encryptionKeyIDs = [], date = new Date(), toUserIDs = [], config }) {
config = { ...defaultConfig, ...config }; config = { ...defaultConfig, ...config };
checkBinary(data); checkString(algorithm, 'algorithm'); publicKeys = toArray(publicKeys); passwords = toArray(passwords); toUserIds = toArray(toUserIds); checkBinary(data); checkString(algorithm, 'algorithm'); publicKeys = toArray(publicKeys); passwords = toArray(passwords); toUserIDs = toArray(toUserIDs);
return Promise.resolve().then(async function() { return Promise.resolve().then(async function() {
const message = await Message.encryptSessionKey(data, algorithm, aeadAlgorithm, publicKeys, passwords, wildcard, encryptionKeyIds, date, toUserIds, config); const message = await Message.encryptSessionKey(data, algorithm, aeadAlgorithm, publicKeys, passwords, wildcard, encryptionKeyIDs, date, toUserIDs, config);
return armor ? message.armor(config) : message.write(); return armor ? message.armor(config) : message.write();
}).catch(onError.bind(null, 'Error encrypting session key')); }).catch(onError.bind(null, 'Error encrypting session key'));

View File

@ -19,13 +19,20 @@ import stream from '@openpgp/web-stream-tools';
import crypto from '../crypto'; import crypto from '../crypto';
import enums from '../enums'; import enums from '../enums';
import util from '../util'; import util from '../util';
import { import defaultConfig from '../config';
import LiteralDataPacket from './literal_data';
import CompressedDataPacket from './compressed_data';
import OnePassSignaturePacket from './one_pass_signature';
import SignaturePacket from './signature';
// An AEAD-encrypted Data packet can contain the following packet types
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([
LiteralDataPacket, LiteralDataPacket,
CompressedDataPacket, CompressedDataPacket,
OnePassSignaturePacket, OnePassSignaturePacket,
SignaturePacket SignaturePacket
} from '../packet'; ]);
import defaultConfig from '../config';
const VERSION = 1; // A one-octet version number of the data packet. const VERSION = 1; // A one-octet version number of the data packet.
@ -37,8 +44,11 @@ const VERSION = 1; // A one-octet version number of the data packet.
* AEAD Protected Data Packet * AEAD Protected Data Packet
*/ */
class AEADEncryptedDataPacket { class AEADEncryptedDataPacket {
static get tag() {
return enums.packet.aeadEncryptedData;
}
constructor() { constructor() {
this.tag = enums.packet.AEADEncryptedData;
this.version = VERSION; this.version = VERSION;
this.cipherAlgo = null; this.cipherAlgo = null;
this.aeadAlgorithm = 'eax'; this.aeadAlgorithm = 'eax';
@ -61,7 +71,7 @@ class AEADEncryptedDataPacket {
this.cipherAlgo = await reader.readByte(); this.cipherAlgo = await reader.readByte();
this.aeadAlgo = await reader.readByte(); this.aeadAlgo = await reader.readByte();
this.chunkSizeByte = await reader.readByte(); this.chunkSizeByte = await reader.readByte();
const mode = crypto[enums.read(enums.aead, this.aeadAlgo)]; const mode = crypto.mode[enums.read(enums.aead, this.aeadAlgo)];
this.iv = await reader.readBytes(mode.ivLength); this.iv = await reader.readBytes(mode.ivLength);
this.encrypted = reader.remainder(); this.encrypted = reader.remainder();
}); });
@ -84,12 +94,7 @@ class AEADEncryptedDataPacket {
* @async * @async
*/ */
async decrypt(sessionKeyAlgorithm, key, streaming) { async decrypt(sessionKeyAlgorithm, key, streaming) {
await this.packets.read(await this.crypt('decrypt', key, stream.clone(this.encrypted), streaming), { await this.packets.read(await this.crypt('decrypt', key, stream.clone(this.encrypted), streaming), allowedPackets, streaming);
LiteralDataPacket,
CompressedDataPacket,
OnePassSignaturePacket,
SignaturePacket
}, streaming);
} }
/** /**
@ -104,7 +109,7 @@ class AEADEncryptedDataPacket {
async encrypt(sessionKeyAlgorithm, key, streaming, config = defaultConfig) { async encrypt(sessionKeyAlgorithm, key, streaming, config = defaultConfig) {
this.cipherAlgo = enums.write(enums.symmetric, sessionKeyAlgorithm); this.cipherAlgo = enums.write(enums.symmetric, sessionKeyAlgorithm);
this.aeadAlgo = enums.write(enums.aead, this.aeadAlgorithm); this.aeadAlgo = enums.write(enums.aead, this.aeadAlgorithm);
const mode = crypto[enums.read(enums.aead, this.aeadAlgo)]; const mode = crypto.mode[enums.read(enums.aead, this.aeadAlgo)];
this.iv = await crypto.random.getRandomBytes(mode.ivLength); // generate new random IV this.iv = await crypto.random.getRandomBytes(mode.ivLength); // generate new random IV
this.chunkSizeByte = config.aeadChunkSizeByte; this.chunkSizeByte = config.aeadChunkSizeByte;
const data = this.packets.write(); const data = this.packets.write();
@ -122,7 +127,7 @@ class AEADEncryptedDataPacket {
*/ */
async crypt(fn, key, data, streaming) { async crypt(fn, key, data, streaming) {
const cipher = enums.read(enums.symmetric, this.cipherAlgo); const cipher = enums.read(enums.symmetric, this.cipherAlgo);
const mode = crypto[enums.read(enums.aead, this.aeadAlgo)]; const mode = crypto.mode[enums.read(enums.aead, this.aeadAlgo)];
const modeInstance = await mode(cipher, key); const modeInstance = await mode(cipher, key);
const tagLengthIfDecrypting = fn === 'decrypt' ? mode.tagLength : 0; const tagLengthIfDecrypting = fn === 'decrypt' ? mode.tagLength : 0;
const tagLengthIfEncrypting = fn === 'encrypt' ? mode.tagLength : 0; const tagLengthIfEncrypting = fn === 'encrypt' ? mode.tagLength : 0;
@ -132,7 +137,7 @@ class AEADEncryptedDataPacket {
const adataTagArray = new Uint8Array(adataBuffer); const adataTagArray = new Uint8Array(adataBuffer);
const adataView = new DataView(adataBuffer); const adataView = new DataView(adataBuffer);
const chunkIndexArray = new Uint8Array(adataBuffer, 5, 8); const chunkIndexArray = new Uint8Array(adataBuffer, 5, 8);
adataArray.set([0xC0 | this.tag, this.version, this.cipherAlgo, this.aeadAlgo, this.chunkSizeByte], 0); adataArray.set([0xC0 | AEADEncryptedDataPacket.tag, this.version, this.cipherAlgo, this.aeadAlgo, this.chunkSizeByte], 0);
let chunkIndex = 0; let chunkIndex = 0;
let latestPromise = Promise.resolve(); let latestPromise = Promise.resolve();
let cryptedBytes = 0; let cryptedBytes = 0;

View File

@ -21,27 +21,3 @@ export { default as UserIDPacket } from './userid.js';
export { default as SecretSubkeyPacket } from './secret_subkey.js'; export { default as SecretSubkeyPacket } from './secret_subkey.js';
export { default as SignaturePacket } from './signature.js'; export { default as SignaturePacket } from './signature.js';
export { default as TrustPacket } from './trust.js'; export { default as TrustPacket } from './trust.js';
/**
* Allocate a new packet
* @function newPacketFromTag
* @param {String} tag - Property name from {@link module:enums.packet}
* @returns {Object} New packet object with type based on tag.
*/
export function newPacketFromTag(tag, allowedPackets) {
const className = packetClassFromTagName(tag);
if (!allowedPackets[className]) {
throw new Error('Packet not allowed in this context: ' + className);
}
return new allowedPackets[className]();
}
/**
* Convert tag name to class name
* @param {String} tag - Property name from {@link module:enums.packet}
* @returns {String}
* @private
*/
function packetClassFromTagName(tag) {
return tag.substr(0, 1).toUpperCase() + tag.substr(1) + 'Packet';
}

View File

@ -23,11 +23,17 @@ import stream from '@openpgp/web-stream-tools';
import enums from '../enums'; import enums from '../enums';
import util from '../util'; import util from '../util';
import defaultConfig from '../config'; import defaultConfig from '../config';
import {
import LiteralDataPacket from './literal_data';
import OnePassSignaturePacket from './one_pass_signature';
import SignaturePacket from './signature';
// A Compressed Data packet can contain the following packet types
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([
LiteralDataPacket, LiteralDataPacket,
OnePassSignaturePacket, OnePassSignaturePacket,
SignaturePacket SignaturePacket
} from '../packet'; ]);
/** /**
* Implementation of the Compressed Data Packet (Tag 8) * Implementation of the Compressed Data Packet (Tag 8)
@ -38,15 +44,14 @@ import {
* a Signature or One-Pass Signature packet, and contains a literal data packet. * a Signature or One-Pass Signature packet, and contains a literal data packet.
*/ */
class CompressedDataPacket { class CompressedDataPacket {
static get tag() {
return enums.packet.compressedData;
}
/** /**
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
*/ */
constructor(config = defaultConfig) { constructor(config = defaultConfig) {
/**
* Packet type
* @type {module:enums.packet}
*/
this.tag = enums.packet.compressedData;
/** /**
* List of packets * List of packets
* @type {PacketList} * @type {PacketList}
@ -111,11 +116,7 @@ class CompressedDataPacket {
throw new Error(this.algorithm + ' decompression not supported'); throw new Error(this.algorithm + ' decompression not supported');
} }
await this.packets.read(decompress_fns[this.algorithm](this.compressed), { await this.packets.read(decompress_fns[this.algorithm](this.compressed), allowedPackets, streaming);
LiteralDataPacket,
OnePassSignaturePacket,
SignaturePacket
}, streaming);
} }
/** /**
@ -193,3 +194,4 @@ const decompress_fns = nodeZlib ? {
zlib: /*#__PURE__*/ pako_zlib(Inflate), zlib: /*#__PURE__*/ pako_zlib(Inflate),
bzip2: /*#__PURE__*/ bzip2(BunzipDecode) bzip2: /*#__PURE__*/ bzip2(BunzipDecode)
}; };

View File

@ -27,11 +27,14 @@ import util from '../util';
* further interpreted. * further interpreted.
*/ */
class LiteralDataPacket { class LiteralDataPacket {
static get tag() {
return enums.packet.literalData;
}
/** /**
* @param {Date} date - The creation date of the literal package * @param {Date} date - The creation date of the literal package
*/ */
constructor(date = new Date()) { constructor(date = new Date()) {
this.tag = enums.packet.literalData;
this.format = 'utf8'; // default format for literal data packets this.format = 'utf8'; // default format for literal data packets
this.date = util.normalizeDate(date); this.date = util.normalizeDate(date);
this.text = null; // textual data representation this.text = null; // textual data representation
@ -59,7 +62,7 @@ class LiteralDataPacket {
*/ */
getText(clone = false) { getText(clone = false) {
if (this.text === null || util.isStream(this.text)) { // Assume that this.text has been read if (this.text === null || util.isStream(this.text)) { // Assume that this.text has been read
this.text = util.decodeUtf8(util.nativeEOL(this.getBytes(clone))); this.text = util.decodeUTF8(util.nativeEOL(this.getBytes(clone)));
} }
return this.text; return this.text;
} }
@ -84,7 +87,7 @@ class LiteralDataPacket {
getBytes(clone = false) { getBytes(clone = false) {
if (this.data === null) { if (this.data === null) {
// encode UTF8 and normalize EOL to \r\n // encode UTF8 and normalize EOL to \r\n
this.data = util.canonicalizeEOL(util.encodeUtf8(this.text)); this.data = util.canonicalizeEOL(util.encodeUTF8(this.text));
} }
if (clone) { if (clone) {
return stream.passiveClone(this.data); return stream.passiveClone(this.data);
@ -110,7 +113,6 @@ class LiteralDataPacket {
return this.filename; return this.filename;
} }
/** /**
* Parsing function for a literal data packet (tag 11). * Parsing function for a literal data packet (tag 11).
* *
@ -123,7 +125,7 @@ class LiteralDataPacket {
const format = enums.read(enums.literal, await reader.readByte()); const format = enums.read(enums.literal, await reader.readByte());
const filename_len = await reader.readByte(); const filename_len = await reader.readByte();
this.filename = util.decodeUtf8(await reader.readBytes(filename_len)); this.filename = util.decodeUTF8(await reader.readBytes(filename_len));
this.date = util.readDate(await reader.readBytes(4)); this.date = util.readDate(await reader.readBytes(4));
@ -139,7 +141,7 @@ class LiteralDataPacket {
* @returns {Uint8Array} Uint8Array representation of the packet. * @returns {Uint8Array} Uint8Array representation of the packet.
*/ */
writeHeader() { writeHeader() {
const filename = util.encodeUtf8(this.filename); const filename = util.encodeUTF8(this.filename);
const filename_length = new Uint8Array([filename.length]); const filename_length = new Uint8Array([filename.length]);
const format = new Uint8Array([enums.write(enums.literal, this.format)]); const format = new Uint8Array([enums.write(enums.literal, this.format)]);

View File

@ -31,8 +31,8 @@ import enums from '../enums';
* Such a packet MUST be ignored when received. * Such a packet MUST be ignored when received.
*/ */
class MarkerPacket { class MarkerPacket {
constructor() { static get tag() {
this.tag = enums.packet.marker; return enums.packet.marker;
} }
/** /**

View File

@ -17,7 +17,7 @@
import stream from '@openpgp/web-stream-tools'; import stream from '@openpgp/web-stream-tools';
import SignaturePacket from './signature'; import SignaturePacket from './signature';
import type_keyid from '../type/keyid'; import KeyID from '../type/keyid';
import enums from '../enums'; import enums from '../enums';
import util from '../util'; import util from '../util';
@ -32,12 +32,11 @@ import util from '../util';
* can compute the entire signed message in one pass. * can compute the entire signed message in one pass.
*/ */
class OnePassSignaturePacket { class OnePassSignaturePacket {
static get tag() {
return enums.packet.onePassSignature;
}
constructor() { constructor() {
/**
* Packet type
* @type {module:enums.packet}
*/
this.tag = enums.packet.onePassSignature;
/** A one-octet version number. The current version is 3. */ /** A one-octet version number. The current version is 3. */
this.version = null; this.version = null;
/** /**
@ -57,7 +56,7 @@ class OnePassSignaturePacket {
*/ */
this.publicKeyAlgorithm = null; this.publicKeyAlgorithm = null;
/** An eight-octet number holding the Key ID of the signing key. */ /** An eight-octet number holding the Key ID of the signing key. */
this.issuerKeyId = null; this.issuerKeyID = null;
/** /**
* A one-octet number holding a flag showing whether the signature is nested. * A one-octet number holding a flag showing whether the signature is nested.
* A zero value indicates that the next packet is another One-Pass Signature packet * A zero value indicates that the next packet is another One-Pass Signature packet
@ -87,8 +86,8 @@ class OnePassSignaturePacket {
this.publicKeyAlgorithm = bytes[mypos++]; this.publicKeyAlgorithm = bytes[mypos++];
// An eight-octet number holding the Key ID of the signing key. // An eight-octet number holding the Key ID of the signing key.
this.issuerKeyId = new type_keyid(); this.issuerKeyID = new KeyID();
this.issuerKeyId.read(bytes.subarray(mypos, mypos + 8)); this.issuerKeyID.read(bytes.subarray(mypos, mypos + 8));
mypos += 8; mypos += 8;
// A one-octet number holding a flag showing whether the signature // A one-octet number holding a flag showing whether the signature
@ -110,7 +109,7 @@ class OnePassSignaturePacket {
const end = new Uint8Array([this.flags]); const end = new Uint8Array([this.flags]);
return util.concatUint8Array([start, this.issuerKeyId.write(), end]); return util.concatUint8Array([start, this.issuerKeyID.write(), end]);
} }
calculateTrailer(...args) { calculateTrailer(...args) {
@ -119,14 +118,14 @@ class OnePassSignaturePacket {
async verify() { async verify() {
const correspondingSig = await this.correspondingSig; const correspondingSig = await this.correspondingSig;
if (!correspondingSig || correspondingSig.tag !== enums.packet.signature) { if (!correspondingSig || correspondingSig.constructor.tag !== enums.packet.signature) {
throw new Error('Corresponding signature packet missing'); throw new Error('Corresponding signature packet missing');
} }
if ( if (
correspondingSig.signatureType !== this.signatureType || correspondingSig.signatureType !== this.signatureType ||
correspondingSig.hashAlgorithm !== this.hashAlgorithm || correspondingSig.hashAlgorithm !== this.hashAlgorithm ||
correspondingSig.publicKeyAlgorithm !== this.publicKeyAlgorithm || correspondingSig.publicKeyAlgorithm !== this.publicKeyAlgorithm ||
!correspondingSig.issuerKeyId.equals(this.issuerKeyId) !correspondingSig.issuerKeyID.equals(this.issuerKeyID)
) { ) {
throw new Error('Corresponding signature packet does not match one-pass signature packet'); throw new Error('Corresponding signature packet does not match one-pass signature packet');
} }

View File

@ -106,7 +106,7 @@ export function supportsStreaming(tag_type) {
enums.packet.compressedData, enums.packet.compressedData,
enums.packet.symmetricallyEncryptedData, enums.packet.symmetricallyEncryptedData,
enums.packet.symEncryptedIntegrityProtectedData, enums.packet.symEncryptedIntegrityProtectedData,
enums.packet.AEADEncryptedData enums.packet.aeadEncryptedData
].includes(tag_type); ].includes(tag_type);
} }
@ -130,21 +130,21 @@ export async function readPackets(input, streaming, callback) {
const headerByte = await reader.readByte(); const headerByte = await reader.readByte();
let tag = -1; let tag = -1;
let format = -1; let format = -1;
let packet_length; let packetLength;
format = 0; // 0 = old format; 1 = new format format = 0; // 0 = old format; 1 = new format
if ((headerByte & 0x40) !== 0) { if ((headerByte & 0x40) !== 0) {
format = 1; format = 1;
} }
let packet_length_type; let packetLengthType;
if (format) { if (format) {
// new format header // new format header
tag = headerByte & 0x3F; // bit 5-0 tag = headerByte & 0x3F; // bit 5-0
} else { } else {
// old format header // old format header
tag = (headerByte & 0x3F) >> 2; // bit 5-2 tag = (headerByte & 0x3F) >> 2; // bit 5-2
packet_length_type = headerByte & 0x03; // bit 1-0 packetLengthType = headerByte & 0x03; // bit 1-0
} }
const packetSupportsStreaming = supportsStreaming(tag); const packetSupportsStreaming = supportsStreaming(tag);
@ -162,21 +162,21 @@ export async function readPackets(input, streaming, callback) {
do { do {
if (!format) { if (!format) {
// 4.2.1. Old Format Packet Lengths // 4.2.1. Old Format Packet Lengths
switch (packet_length_type) { switch (packetLengthType) {
case 0: case 0:
// The packet has a one-octet length. The header is 2 octets // The packet has a one-octet length. The header is 2 octets
// long. // long.
packet_length = await reader.readByte(); packetLength = await reader.readByte();
break; break;
case 1: case 1:
// The packet has a two-octet length. The header is 3 octets // The packet has a two-octet length. The header is 3 octets
// long. // long.
packet_length = (await reader.readByte() << 8) | await reader.readByte(); packetLength = (await reader.readByte() << 8) | await reader.readByte();
break; break;
case 2: case 2:
// The packet has a four-octet length. The header is 5 // The packet has a four-octet length. The header is 5
// octets long. // octets long.
packet_length = (await reader.readByte() << 24) | (await reader.readByte() << 16) | (await reader.readByte() << packetLength = (await reader.readByte() << 24) | (await reader.readByte() << 16) | (await reader.readByte() <<
8) | await reader.readByte(); 8) | await reader.readByte();
break; break;
default: default:
@ -190,7 +190,7 @@ export async function readPackets(input, streaming, callback) {
// definite length, or a new format header. The new format // definite length, or a new format header. The new format
// headers described below have a mechanism for precisely // headers described below have a mechanism for precisely
// encoding data of indeterminate length. // encoding data of indeterminate length.
packet_length = Infinity; packetLength = Infinity;
break; break;
} }
} else { // 4.2.2. New Format Packet Lengths } else { // 4.2.2. New Format Packet Lengths
@ -198,38 +198,38 @@ export async function readPackets(input, streaming, callback) {
const lengthByte = await reader.readByte(); const lengthByte = await reader.readByte();
wasPartialLength = false; wasPartialLength = false;
if (lengthByte < 192) { if (lengthByte < 192) {
packet_length = lengthByte; packetLength = lengthByte;
// 4.2.2.2. Two-Octet Lengths // 4.2.2.2. Two-Octet Lengths
} else if (lengthByte >= 192 && lengthByte < 224) { } else if (lengthByte >= 192 && lengthByte < 224) {
packet_length = ((lengthByte - 192) << 8) + (await reader.readByte()) + 192; packetLength = ((lengthByte - 192) << 8) + (await reader.readByte()) + 192;
// 4.2.2.4. Partial Body Lengths // 4.2.2.4. Partial Body Lengths
} else if (lengthByte > 223 && lengthByte < 255) { } else if (lengthByte > 223 && lengthByte < 255) {
packet_length = 1 << (lengthByte & 0x1F); packetLength = 1 << (lengthByte & 0x1F);
wasPartialLength = true; wasPartialLength = true;
if (!packetSupportsStreaming) { if (!packetSupportsStreaming) {
throw new TypeError('This packet type does not support partial lengths.'); throw new TypeError('This packet type does not support partial lengths.');
} }
// 4.2.2.3. Five-Octet Lengths // 4.2.2.3. Five-Octet Lengths
} else { } else {
packet_length = (await reader.readByte() << 24) | (await reader.readByte() << 16) | (await reader.readByte() << packetLength = (await reader.readByte() << 24) | (await reader.readByte() << 16) | (await reader.readByte() <<
8) | await reader.readByte(); 8) | await reader.readByte();
} }
} }
if (packet_length > 0) { if (packetLength > 0) {
let bytesRead = 0; let bytesRead = 0;
while (true) { while (true) {
if (writer) await writer.ready; if (writer) await writer.ready;
const { done, value } = await reader.read(); const { done, value } = await reader.read();
if (done) { if (done) {
if (packet_length === Infinity) break; if (packetLength === Infinity) break;
throw new Error('Unexpected end of packet'); throw new Error('Unexpected end of packet');
} }
const chunk = packet_length === Infinity ? value : value.subarray(0, packet_length - bytesRead); const chunk = packetLength === Infinity ? value : value.subarray(0, packetLength - bytesRead);
if (writer) await writer.write(chunk); if (writer) await writer.write(chunk);
else packet.push(chunk); else packet.push(chunk);
bytesRead += value.length; bytesRead += value.length;
if (bytesRead >= packet_length) { if (bytesRead >= packetLength) {
reader.unshift(value.subarray(packet_length - bytesRead + value.length)); reader.unshift(value.subarray(packetLength - bytesRead + value.length));
break; break;
} }
} }

View File

@ -1,14 +1,27 @@
import stream from '@openpgp/web-stream-tools'; import stream from '@openpgp/web-stream-tools';
import * as packets from './all_packets';
import { import {
readPackets, supportsStreaming, readPackets, supportsStreaming,
writeTag, writeHeader, writeTag, writeHeader,
writePartialLength, writeSimpleLength writePartialLength, writeSimpleLength
} from './packet'; } from './packet';
import enums from '../enums';
import util from '../util'; import util from '../util';
import enums from '../enums';
import defaultConfig from '../config'; import defaultConfig from '../config';
/**
* Instantiate a new packet given its tag
* @function newPacketFromTag
* @param {module:enums.packet} tag - Property value from {@link module:enums.packet}
* @param {Object} allowedPackets - mapping where keys are allowed packet tags, pointing to their Packet class
* @returns {Object} New packet object with type based on tag
*/
export function newPacketFromTag(tag, allowedPackets) {
if (!allowedPackets[tag]) {
throw new Error(`Packet not allowed in this context: ${enums.read(enums.packets, tag)}`);
}
return new allowedPackets[tag]();
}
/** /**
* This class represents a list of openpgp packets. * This class represents a list of openpgp packets.
* Take care when iterating over it - the packets themselves * Take care when iterating over it - the packets themselves
@ -28,8 +41,7 @@ class PacketList extends Array {
await writer.ready; await writer.ready;
const done = await readPackets(readable, streaming, async parsed => { const done = await readPackets(readable, streaming, async parsed => {
try { try {
const tag = enums.read(enums.packet, parsed.tag); const packet = newPacketFromTag(parsed.tag, allowedPackets);
const packet = packets.newPacketFromTag(tag, allowedPackets);
packet.packets = new PacketList(); packet.packets = new PacketList();
packet.fromStream = util.isStream(parsed.packet); packet.fromStream = util.isStream(parsed.packet);
await packet.read(parsed.packet, config, streaming); await packet.read(parsed.packet, config, streaming);
@ -64,7 +76,7 @@ class PacketList extends Array {
} else { } else {
this.stream = null; this.stream = null;
} }
if (done || supportsStreaming(value.tag)) { if (done || supportsStreaming(value.constructor.tag)) {
break; break;
} }
} }
@ -81,11 +93,11 @@ class PacketList extends Array {
for (let i = 0; i < this.length; i++) { for (let i = 0; i < this.length; i++) {
const packetbytes = this[i].write(); const packetbytes = this[i].write();
if (util.isStream(packetbytes) && supportsStreaming(this[i].tag)) { if (util.isStream(packetbytes) && supportsStreaming(this[i].constructor.tag)) {
let buffer = []; let buffer = [];
let bufferLength = 0; let bufferLength = 0;
const minLength = 512; const minLength = 512;
arr.push(writeTag(this[i].tag)); arr.push(writeTag(this[i].constructor.tag));
arr.push(stream.transform(packetbytes, value => { arr.push(stream.transform(packetbytes, value => {
buffer.push(value); buffer.push(value);
bufferLength += value.length; bufferLength += value.length;
@ -103,9 +115,9 @@ class PacketList extends Array {
let length = 0; let length = 0;
arr.push(stream.transform(stream.clone(packetbytes), value => { arr.push(stream.transform(stream.clone(packetbytes), value => {
length += value.length; length += value.length;
}, () => writeHeader(this[i].tag, length))); }, () => writeHeader(this[i].constructor.tag, length)));
} else { } else {
arr.push(writeHeader(this[i].tag, packetbytes.length)); arr.push(writeHeader(this[i].constructor.tag, packetbytes.length));
} }
arr.push(packetbytes); arr.push(packetbytes);
} }
@ -138,7 +150,7 @@ class PacketList extends Array {
const handle = tag => packetType => tag === packetType; const handle = tag => packetType => tag === packetType;
for (let i = 0; i < this.length; i++) { for (let i = 0; i < this.length; i++) {
if (args.some(handle(this[i].tag))) { if (args.some(handle(this[i].constructor.tag))) {
filtered.push(this[i]); filtered.push(this[i]);
} }
} }
@ -152,7 +164,7 @@ class PacketList extends Array {
* @returns {Packet|undefined} * @returns {Packet|undefined}
*/ */
findPacket(type) { findPacket(type) {
return this.find(packet => packet.tag === type); return this.find(packet => packet.constructor.tag === type);
} }
/** /**
@ -165,7 +177,7 @@ class PacketList extends Array {
const handle = tag => packetType => tag === packetType; const handle = tag => packetType => tag === packetType;
for (let i = 0; i < this.length; i++) { for (let i = 0; i < this.length; i++) {
if (args.some(handle(that[i].tag))) { if (args.some(handle(that[i].constructor.tag))) {
tagIndex.push(i); tagIndex.push(i);
} }
} }

View File

@ -19,7 +19,7 @@
import { Sha1 } from '@openpgp/asmcrypto.js/dist_es8/hash/sha1/sha1'; import { Sha1 } from '@openpgp/asmcrypto.js/dist_es8/hash/sha1/sha1';
import { Sha256 } from '@openpgp/asmcrypto.js/dist_es8/hash/sha256/sha256'; import { Sha256 } from '@openpgp/asmcrypto.js/dist_es8/hash/sha256/sha256';
import type_keyid from '../type/keyid'; import KeyID from '../type/keyid';
import defaultConfig from '../config'; import defaultConfig from '../config';
import crypto from '../crypto'; import crypto from '../crypto';
import enums from '../enums'; import enums from '../enums';
@ -37,16 +37,15 @@ import util from '../util';
* key (sometimes called an OpenPGP certificate). * key (sometimes called an OpenPGP certificate).
*/ */
class PublicKeyPacket { class PublicKeyPacket {
static get tag() {
return enums.packet.publicKey;
}
/** /**
* @param {Date} [date] - Creation date * @param {Date} [date] - Creation date
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
*/ */
constructor(date = new Date(), config = defaultConfig) { constructor(date = new Date(), config = defaultConfig) {
/**
* Packet type
* @type {module:enums.packet}
*/
this.tag = enums.packet.publicKey;
/** /**
* Packet version * Packet version
* @type {Integer} * @type {Integer}
@ -78,10 +77,10 @@ class PublicKeyPacket {
*/ */
this.fingerprint = null; this.fingerprint = null;
/** /**
* Keyid * KeyID
* @type {module:type/keyid~Keyid} * @type {module:type/keyid~KeyID}
*/ */
this.keyid = null; this.keyID = null;
} }
/** /**
@ -176,19 +175,19 @@ class PublicKeyPacket {
/** /**
* Calculates the key id of the key * Calculates the key id of the key
* @returns {module:type/keyid~Keyid} A 8 byte key id. * @returns {module:type/keyid~KeyID} A 8 byte key id.
*/ */
getKeyId() { getKeyID() {
if (this.keyid) { if (this.keyID) {
return this.keyid; return this.keyID;
} }
this.keyid = new type_keyid(); this.keyID = new KeyID();
if (this.version === 5) { if (this.version === 5) {
this.keyid.read(util.hexToUint8Array(this.getFingerprint()).subarray(0, 8)); this.keyID.read(util.hexToUint8Array(this.getFingerprint()).subarray(0, 8));
} else if (this.version === 4) { } else if (this.version === 4) {
this.keyid.read(util.hexToUint8Array(this.getFingerprint()).subarray(12, 20)); this.keyID.read(util.hexToUint8Array(this.getFingerprint()).subarray(12, 20));
} }
return this.keyid; return this.keyID;
} }
/** /**

View File

@ -15,7 +15,7 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import type_keyid from '../type/keyid'; import KeyID from '../type/keyid';
import crypto from '../crypto'; import crypto from '../crypto';
import enums from '../enums'; import enums from '../enums';
import util from '../util'; import util from '../util';
@ -37,11 +37,14 @@ import util from '../util';
* decrypt the message. * decrypt the message.
*/ */
class PublicKeyEncryptedSessionKeyPacket { class PublicKeyEncryptedSessionKeyPacket {
static get tag() {
return enums.packet.publicKeyEncryptedSessionKey;
}
constructor() { constructor() {
this.tag = enums.packet.publicKeyEncryptedSessionKey;
this.version = 3; this.version = 3;
this.publicKeyId = new type_keyid(); this.publicKeyID = new KeyID();
this.publicKeyAlgorithm = null; this.publicKeyAlgorithm = null;
this.sessionKey = null; this.sessionKey = null;
@ -58,7 +61,7 @@ class PublicKeyEncryptedSessionKeyPacket {
*/ */
read(bytes) { read(bytes) {
this.version = bytes[0]; this.version = bytes[0];
this.publicKeyId.read(bytes.subarray(1, bytes.length)); this.publicKeyID.read(bytes.subarray(1, bytes.length));
this.publicKeyAlgorithm = enums.read(enums.publicKey, bytes[9]); this.publicKeyAlgorithm = enums.read(enums.publicKey, bytes[9]);
const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm); const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
@ -75,7 +78,7 @@ class PublicKeyEncryptedSessionKeyPacket {
const arr = [ const arr = [
new Uint8Array([this.version]), new Uint8Array([this.version]),
this.publicKeyId.write(), this.publicKeyID.write(),
new Uint8Array([enums.write(enums.publicKey, this.publicKeyAlgorithm)]), new Uint8Array([enums.write(enums.publicKey, this.publicKeyAlgorithm)]),
crypto.serializeParams(algo, this.encrypted) crypto.serializeParams(algo, this.encrypted)
]; ];

View File

@ -27,13 +27,17 @@ import enums from '../enums';
* @extends PublicKeyPacket * @extends PublicKeyPacket
*/ */
class PublicSubkeyPacket extends PublicKeyPacket { class PublicSubkeyPacket extends PublicKeyPacket {
static get tag() {
return enums.packet.publicSubkey;
}
/** /**
* @param {Date} [date] - Creation date * @param {Date} [date] - Creation date
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
*/ */
// eslint-disable-next-line no-useless-constructor
constructor(date, config) { constructor(date, config) {
super(date, config); super(date, config);
this.tag = enums.packet.publicSubkey;
} }
} }

View File

@ -16,7 +16,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import PublicKeyPacket from './public_key'; import PublicKeyPacket from './public_key';
import type_s2k from '../type/s2k'; import S2K from '../type/s2k';
import crypto from '../crypto'; import crypto from '../crypto';
import enums from '../enums'; import enums from '../enums';
import util from '../util'; import util from '../util';
@ -29,17 +29,16 @@ import defaultConfig from '../config';
* @extends PublicKeyPacket * @extends PublicKeyPacket
*/ */
class SecretKeyPacket extends PublicKeyPacket { class SecretKeyPacket extends PublicKeyPacket {
static get tag() {
return enums.packet.secretKey;
}
/** /**
* @param {Date} [date] - Creation date * @param {Date} [date] - Creation date
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
*/ */
constructor(date = new Date(), config = defaultConfig) { constructor(date = new Date(), config = defaultConfig) {
super(date, config); super(date, config);
/**
* Packet type
* @type {module:enums.packet}
*/
this.tag = enums.packet.secretKey;
/** /**
* Secret-key data * Secret-key data
*/ */
@ -52,7 +51,7 @@ class SecretKeyPacket extends PublicKeyPacket {
* S2K usage * S2K usage
* @type {Integer} * @type {Integer}
*/ */
this.s2k_usage = 0; this.s2kUsage = 0;
/** /**
* S2K object * S2K object
* @type {type/s2k} * @type {type/s2k}
@ -90,7 +89,7 @@ class SecretKeyPacket extends PublicKeyPacket {
// indicates that the secret-key data is not encrypted. 255 or 254 // indicates that the secret-key data is not encrypted. 255 or 254
// indicates that a string-to-key specifier is being given. Any // indicates that a string-to-key specifier is being given. Any
// other value is a symmetric-key encryption algorithm identifier. // other value is a symmetric-key encryption algorithm identifier.
this.s2k_usage = bytes[i++]; this.s2kUsage = bytes[i++];
// - Only for a version 5 packet, a one-octet scalar octet count of // - Only for a version 5 packet, a one-octet scalar octet count of
// the next 4 optional fields. // the next 4 optional fields.
@ -100,13 +99,13 @@ class SecretKeyPacket extends PublicKeyPacket {
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
// one-octet symmetric encryption algorithm. // one-octet symmetric encryption algorithm.
if (this.s2k_usage === 255 || this.s2k_usage === 254 || this.s2k_usage === 253) { if (this.s2kUsage === 255 || this.s2kUsage === 254 || this.s2kUsage === 253) {
this.symmetric = bytes[i++]; this.symmetric = bytes[i++];
this.symmetric = enums.read(enums.symmetric, this.symmetric); this.symmetric = enums.read(enums.symmetric, this.symmetric);
// - [Optional] If string-to-key usage octet was 253, a one-octet // - [Optional] If string-to-key usage octet was 253, a one-octet
// AEAD algorithm. // AEAD algorithm.
if (this.s2k_usage === 253) { if (this.s2kUsage === 253) {
this.aead = bytes[i++]; this.aead = bytes[i++];
this.aead = enums.read(enums.aead, this.aead); this.aead = enums.read(enums.aead, this.aead);
} }
@ -114,21 +113,21 @@ class SecretKeyPacket extends PublicKeyPacket {
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
// string-to-key specifier. The length of the string-to-key // string-to-key specifier. The length of the string-to-key
// specifier is implied by its type, as described above. // specifier is implied by its type, as described above.
this.s2k = new type_s2k(); this.s2k = new S2K();
i += this.s2k.read(bytes.subarray(i, bytes.length)); i += this.s2k.read(bytes.subarray(i, bytes.length));
if (this.s2k.type === 'gnu-dummy') { if (this.s2k.type === 'gnu-dummy') {
return; return;
} }
} else if (this.s2k_usage) { } else if (this.s2kUsage) {
this.symmetric = this.s2k_usage; this.symmetric = this.s2kUsage;
this.symmetric = enums.read(enums.symmetric, this.symmetric); this.symmetric = enums.read(enums.symmetric, this.symmetric);
} }
// - [Optional] If secret data is encrypted (string-to-key usage octet // - [Optional] If secret data is encrypted (string-to-key usage octet
// not zero), an Initial Vector (IV) of the same length as the // not zero), an Initial Vector (IV) of the same length as the
// cipher's block size. // cipher's block size.
if (this.s2k_usage) { if (this.s2kUsage) {
this.iv = bytes.subarray( this.iv = bytes.subarray(
i, i,
i + crypto.cipher[this.symmetric].blockSize i + crypto.cipher[this.symmetric].blockSize
@ -147,7 +146,7 @@ class SecretKeyPacket extends PublicKeyPacket {
// key data. These algorithm-specific fields are as described // key data. These algorithm-specific fields are as described
// below. // below.
this.keyMaterial = bytes.subarray(i); this.keyMaterial = bytes.subarray(i);
this.isEncrypted = !!this.s2k_usage; this.isEncrypted = !!this.s2kUsage;
if (!this.isEncrypted) { if (!this.isEncrypted) {
const cleartext = this.keyMaterial.subarray(0, -2); const cleartext = this.keyMaterial.subarray(0, -2);
@ -171,17 +170,17 @@ class SecretKeyPacket extends PublicKeyPacket {
write() { write() {
const arr = [this.writePublicKey()]; const arr = [this.writePublicKey()];
arr.push(new Uint8Array([this.s2k_usage])); arr.push(new Uint8Array([this.s2kUsage]));
const optionalFieldsArr = []; const optionalFieldsArr = [];
// - [Optional] If string-to-key usage octet was 255, 254, or 253, a // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
// one- octet symmetric encryption algorithm. // one- octet symmetric encryption algorithm.
if (this.s2k_usage === 255 || this.s2k_usage === 254 || this.s2k_usage === 253) { if (this.s2kUsage === 255 || this.s2kUsage === 254 || this.s2kUsage === 253) {
optionalFieldsArr.push(enums.write(enums.symmetric, this.symmetric)); optionalFieldsArr.push(enums.write(enums.symmetric, this.symmetric));
// - [Optional] If string-to-key usage octet was 253, a one-octet // - [Optional] If string-to-key usage octet was 253, a one-octet
// AEAD algorithm. // AEAD algorithm.
if (this.s2k_usage === 253) { if (this.s2kUsage === 253) {
optionalFieldsArr.push(enums.write(enums.aead, this.aead)); optionalFieldsArr.push(enums.write(enums.aead, this.aead));
} }
@ -194,7 +193,7 @@ class SecretKeyPacket extends PublicKeyPacket {
// - [Optional] If secret data is encrypted (string-to-key usage octet // - [Optional] If secret data is encrypted (string-to-key usage octet
// not zero), an Initial Vector (IV) of the same length as the // not zero), an Initial Vector (IV) of the same length as the
// cipher's block size. // cipher's block size.
if (this.s2k_usage && this.s2k.type !== 'gnu-dummy') { if (this.s2kUsage && this.s2k.type !== 'gnu-dummy') {
optionalFieldsArr.push(...this.iv); optionalFieldsArr.push(...this.iv);
} }
@ -204,7 +203,7 @@ class SecretKeyPacket extends PublicKeyPacket {
arr.push(new Uint8Array(optionalFieldsArr)); arr.push(new Uint8Array(optionalFieldsArr));
if (!this.isDummy()) { if (!this.isDummy()) {
if (!this.s2k_usage) { if (!this.s2kUsage) {
const algo = enums.write(enums.publicKey, this.algorithm); const algo = enums.write(enums.publicKey, this.algorithm);
const cleartextParams = crypto.serializeParams(algo, this.privateParams); const cleartextParams = crypto.serializeParams(algo, this.privateParams);
this.keyMaterial = util.concatUint8Array([ this.keyMaterial = util.concatUint8Array([
@ -253,11 +252,11 @@ class SecretKeyPacket extends PublicKeyPacket {
} }
this.isEncrypted = null; this.isEncrypted = null;
this.keyMaterial = null; this.keyMaterial = null;
this.s2k = new type_s2k(config); this.s2k = new S2K(config);
this.s2k.algorithm = 0; this.s2k.algorithm = 0;
this.s2k.c = 0; this.s2k.c = 0;
this.s2k.type = 'gnu-dummy'; this.s2k.type = 'gnu-dummy';
this.s2k_usage = 254; this.s2kUsage = 254;
this.symmetric = 'aes256'; this.symmetric = 'aes256';
} }
@ -281,13 +280,13 @@ class SecretKeyPacket extends PublicKeyPacket {
} }
if (this.isDecrypted() && !passphrase) { if (this.isDecrypted() && !passphrase) {
this.s2k_usage = 0; this.s2kUsage = 0;
return; return;
} else if (!passphrase) { } else if (!passphrase) {
throw new Error('The key must be decrypted before removing passphrase protection.'); throw new Error('The key must be decrypted before removing passphrase protection.');
} }
this.s2k = new type_s2k(config); this.s2k = new S2K(config);
this.s2k.salt = await crypto.random.getRandomBytes(8); this.s2k.salt = await crypto.random.getRandomBytes(8);
const algo = enums.write(enums.publicKey, this.algorithm); const algo = enums.write(enums.publicKey, this.algorithm);
const cleartext = crypto.serializeParams(algo, this.privateParams); const cleartext = crypto.serializeParams(algo, this.privateParams);
@ -297,14 +296,14 @@ class SecretKeyPacket extends PublicKeyPacket {
this.iv = await crypto.random.getRandomBytes(blockLen); this.iv = await crypto.random.getRandomBytes(blockLen);
if (config.aeadProtect) { if (config.aeadProtect) {
this.s2k_usage = 253; this.s2kUsage = 253;
this.aead = 'eax'; this.aead = 'eax';
const mode = crypto[this.aead]; const mode = crypto.mode[this.aead];
const modeInstance = await mode(this.symmetric, key); const modeInstance = await mode(this.symmetric, key);
this.keyMaterial = await modeInstance.encrypt(cleartext, this.iv.subarray(0, mode.ivLength), new Uint8Array()); this.keyMaterial = await modeInstance.encrypt(cleartext, this.iv.subarray(0, mode.ivLength), new Uint8Array());
} else { } else {
this.s2k_usage = 254; this.s2kUsage = 254;
this.keyMaterial = await crypto.cfb.encrypt(this.symmetric, key, util.concatUint8Array([ this.keyMaterial = await crypto.mode.cfb.encrypt(this.symmetric, key, util.concatUint8Array([
cleartext, cleartext,
await crypto.hash.sha1(cleartext, config) await crypto.hash.sha1(cleartext, config)
]), this.iv, config); ]), this.iv, config);
@ -329,17 +328,17 @@ class SecretKeyPacket extends PublicKeyPacket {
} }
let key; let key;
if (this.s2k_usage === 254 || this.s2k_usage === 253) { if (this.s2kUsage === 254 || this.s2kUsage === 253) {
key = await produceEncryptionKey(this.s2k, passphrase, this.symmetric); key = await produceEncryptionKey(this.s2k, passphrase, this.symmetric);
} else if (this.s2k_usage === 255) { } else if (this.s2kUsage === 255) {
throw new Error('Encrypted private key is authenticated using an insecure two-byte hash'); throw new Error('Encrypted private key is authenticated using an insecure two-byte hash');
} else { } else {
throw new Error('Private key is encrypted using an insecure S2K function: unsalted MD5'); throw new Error('Private key is encrypted using an insecure S2K function: unsalted MD5');
} }
let cleartext; let cleartext;
if (this.s2k_usage === 253) { if (this.s2kUsage === 253) {
const mode = crypto[this.aead]; const mode = crypto.mode[this.aead];
try { try {
const modeInstance = await mode(this.symmetric, key); const modeInstance = await mode(this.symmetric, key);
cleartext = await modeInstance.decrypt(this.keyMaterial, this.iv.subarray(0, mode.ivLength), new Uint8Array()); cleartext = await modeInstance.decrypt(this.keyMaterial, this.iv.subarray(0, mode.ivLength), new Uint8Array());
@ -350,7 +349,7 @@ class SecretKeyPacket extends PublicKeyPacket {
throw err; throw err;
} }
} else { } else {
const cleartextWithHash = await crypto.cfb.decrypt(this.symmetric, key, this.keyMaterial, this.iv); const cleartextWithHash = await crypto.mode.cfb.decrypt(this.symmetric, key, this.keyMaterial, this.iv);
cleartext = cleartextWithHash.subarray(0, -20); cleartext = cleartextWithHash.subarray(0, -20);
const hash = await crypto.hash.sha1(cleartext); const hash = await crypto.hash.sha1(cleartext);
@ -369,7 +368,7 @@ class SecretKeyPacket extends PublicKeyPacket {
} }
this.isEncrypted = false; this.isEncrypted = false;
this.keyMaterial = null; this.keyMaterial = null;
this.s2k_usage = 0; this.s2kUsage = 0;
} }
/** /**
@ -427,7 +426,7 @@ class SecretKeyPacket extends PublicKeyPacket {
} }
async function produceEncryptionKey(s2k, passphrase, algorithm) { async function produceEncryptionKey(s2k, passphrase, algorithm) {
return s2k.produce_key( return s2k.produceKey(
passphrase, passphrase,
crypto.cipher[algorithm].keySize crypto.cipher[algorithm].keySize
); );

View File

@ -25,13 +25,16 @@ import defaultConfig from '../config';
* @extends SecretKeyPacket * @extends SecretKeyPacket
*/ */
class SecretSubkeyPacket extends SecretKeyPacket { class SecretSubkeyPacket extends SecretKeyPacket {
static get tag() {
return enums.packet.secretSubkey;
}
/** /**
* @param {Date} [date] - Creation date * @param {Date} [date] - Creation date
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
*/ */
constructor(date = new Date(), config = defaultConfig) { constructor(date = new Date(), config = defaultConfig) {
super(date, config); super(date, config);
this.tag = enums.packet.secretSubkey;
} }
} }

View File

@ -17,7 +17,7 @@
import stream from '@openpgp/web-stream-tools'; import stream from '@openpgp/web-stream-tools';
import { readSimpleLength, writeSimpleLength } from './packet'; import { readSimpleLength, writeSimpleLength } from './packet';
import type_keyid from '../type/keyid.js'; import KeyID from '../type/keyid.js';
import crypto from '../crypto'; import crypto from '../crypto';
import enums from '../enums'; import enums from '../enums';
import util from '../util'; import util from '../util';
@ -32,11 +32,14 @@ import defaultConfig from '../config';
* block of text, and a signature that is a certification of a User ID. * block of text, and a signature that is a certification of a User ID.
*/ */
class SignaturePacket { class SignaturePacket {
static get tag() {
return enums.packet.signature;
}
/** /**
* @param {Date} date - The creation date of the signature * @param {Date} date - The creation date of the signature
*/ */
constructor(date = new Date()) { constructor(date = new Date()) {
this.tag = enums.packet.signature;
this.version = 4; // This is set to 5 below if we sign with a V5 key. this.version = 4; // This is set to 5 below if we sign with a V5 key.
this.signatureType = null; this.signatureType = null;
this.hashAlgorithm = null; this.hashAlgorithm = null;
@ -60,7 +63,7 @@ class SignaturePacket {
this.revocationKeyClass = null; this.revocationKeyClass = null;
this.revocationKeyAlgorithm = null; this.revocationKeyAlgorithm = null;
this.revocationKeyFingerprint = null; this.revocationKeyFingerprint = null;
this.issuerKeyId = new type_keyid(); this.issuerKeyID = new KeyID();
this.rawNotations = []; this.rawNotations = [];
this.notations = {}; this.notations = {};
this.preferredHashAlgorithms = null; this.preferredHashAlgorithms = null;
@ -70,7 +73,7 @@ class SignaturePacket {
this.isPrimaryUserID = null; this.isPrimaryUserID = null;
this.policyURI = null; this.policyURI = null;
this.keyFlags = null; this.keyFlags = null;
this.signersUserId = null; this.signersUserID = null;
this.reasonForRevocationFlag = null; this.reasonForRevocationFlag = null;
this.reasonForRevocationString = null; this.reasonForRevocationString = null;
this.features = null; this.features = null;
@ -80,7 +83,7 @@ class SignaturePacket {
this.embeddedSignature = null; this.embeddedSignature = null;
this.issuerKeyVersion = null; this.issuerKeyVersion = null;
this.issuerFingerprint = null; this.issuerFingerprint = null;
this.preferredAeadAlgorithms = null; this.preferredAEADAlgorithms = null;
this.verified = null; this.verified = null;
this.revoked = null; this.revoked = null;
@ -104,7 +107,7 @@ class SignaturePacket {
this.hashAlgorithm = bytes[i++]; this.hashAlgorithm = bytes[i++];
// hashed subpackets // hashed subpackets
i += this.read_sub_packets(bytes.subarray(i, bytes.length), true); i += this.readSubPackets(bytes.subarray(i, bytes.length), true);
// A V4 signature hashes the packet body // A V4 signature hashes the packet body
// starting from its first field, the version number, through the end // starting from its first field, the version number, through the end
@ -115,7 +118,7 @@ class SignaturePacket {
this.signatureData = bytes.subarray(0, i); this.signatureData = bytes.subarray(0, i);
// unhashed subpackets // unhashed subpackets
i += this.read_sub_packets(bytes.subarray(i, bytes.length), false); i += this.readSubPackets(bytes.subarray(i, bytes.length), false);
// Two-octet field holding left 16 bits of signed hash value. // Two-octet field holding left 16 bits of signed hash value.
this.signedHashValue = bytes.subarray(i, i + 2); this.signedHashValue = bytes.subarray(i, i + 2);
@ -127,7 +130,7 @@ class SignaturePacket {
/** /**
* @returns {Uint8Array | ReadableStream<Uint8Array>} * @returns {Uint8Array | ReadableStream<Uint8Array>}
*/ */
write_params() { writeParams() {
if (this.params instanceof Promise) { if (this.params instanceof Promise) {
return stream.fromAsync( return stream.fromAsync(
async () => crypto.serializeParams(this.publicKeyAlgorithm, await this.params) async () => crypto.serializeParams(this.publicKeyAlgorithm, await this.params)
@ -139,9 +142,9 @@ class SignaturePacket {
write() { write() {
const arr = []; const arr = [];
arr.push(this.signatureData); arr.push(this.signatureData);
arr.push(this.write_unhashed_sub_packets()); arr.push(this.writeUnhashedSubPackets());
arr.push(this.signedHashValue); arr.push(this.signedHashValue);
arr.push(this.write_params()); arr.push(this.writeParams());
return util.concat(arr); return util.concat(arr);
} }
@ -166,10 +169,10 @@ class SignaturePacket {
this.issuerKeyVersion = key.version; this.issuerKeyVersion = key.version;
this.issuerFingerprint = key.getFingerprintBytes(); this.issuerFingerprint = key.getFingerprintBytes();
this.issuerKeyId = key.getKeyId(); this.issuerKeyID = key.getKeyID();
// Add hashed subpackets // Add hashed subpackets
arr.push(this.write_hashed_sub_packets()); arr.push(this.writeHashedSubPackets());
this.signatureData = util.concat(arr); this.signatureData = util.concat(arr);
@ -197,40 +200,40 @@ class SignaturePacket {
* Creates Uint8Array of bytes of all subpacket data except Issuer and Embedded Signature subpackets * Creates Uint8Array of bytes of all subpacket data except Issuer and Embedded Signature subpackets
* @returns {Uint8Array} Subpacket data. * @returns {Uint8Array} Subpacket data.
*/ */
write_hashed_sub_packets() { writeHashedSubPackets() {
const sub = enums.signatureSubpacket; const sub = enums.signatureSubpacket;
const arr = []; const arr = [];
let bytes; let bytes;
if (this.created !== null) { if (this.created !== null) {
arr.push(write_sub_packet(sub.signatureCreationTime, util.writeDate(this.created))); arr.push(writeSubPacket(sub.signatureCreationTime, util.writeDate(this.created)));
} }
if (this.signatureExpirationTime !== null) { if (this.signatureExpirationTime !== null) {
arr.push(write_sub_packet(sub.signatureExpirationTime, util.writeNumber(this.signatureExpirationTime, 4))); arr.push(writeSubPacket(sub.signatureExpirationTime, util.writeNumber(this.signatureExpirationTime, 4)));
} }
if (this.exportable !== null) { if (this.exportable !== null) {
arr.push(write_sub_packet(sub.exportableCertification, new Uint8Array([this.exportable ? 1 : 0]))); arr.push(writeSubPacket(sub.exportableCertification, new Uint8Array([this.exportable ? 1 : 0])));
} }
if (this.trustLevel !== null) { if (this.trustLevel !== null) {
bytes = new Uint8Array([this.trustLevel, this.trustAmount]); bytes = new Uint8Array([this.trustLevel, this.trustAmount]);
arr.push(write_sub_packet(sub.trustSignature, bytes)); arr.push(writeSubPacket(sub.trustSignature, bytes));
} }
if (this.regularExpression !== null) { if (this.regularExpression !== null) {
arr.push(write_sub_packet(sub.regularExpression, this.regularExpression)); arr.push(writeSubPacket(sub.regularExpression, this.regularExpression));
} }
if (this.revocable !== null) { if (this.revocable !== null) {
arr.push(write_sub_packet(sub.revocable, new Uint8Array([this.revocable ? 1 : 0]))); arr.push(writeSubPacket(sub.revocable, new Uint8Array([this.revocable ? 1 : 0])));
} }
if (this.keyExpirationTime !== null) { if (this.keyExpirationTime !== null) {
arr.push(write_sub_packet(sub.keyExpirationTime, util.writeNumber(this.keyExpirationTime, 4))); arr.push(writeSubPacket(sub.keyExpirationTime, util.writeNumber(this.keyExpirationTime, 4)));
} }
if (this.preferredSymmetricAlgorithms !== null) { if (this.preferredSymmetricAlgorithms !== null) {
bytes = util.strToUint8Array(util.uint8ArrayToStr(this.preferredSymmetricAlgorithms)); bytes = util.stringToUint8Array(util.uint8ArrayToString(this.preferredSymmetricAlgorithms));
arr.push(write_sub_packet(sub.preferredSymmetricAlgorithms, bytes)); arr.push(writeSubPacket(sub.preferredSymmetricAlgorithms, bytes));
} }
if (this.revocationKeyClass !== null) { if (this.revocationKeyClass !== null) {
bytes = new Uint8Array([this.revocationKeyClass, this.revocationKeyAlgorithm]); bytes = new Uint8Array([this.revocationKeyClass, this.revocationKeyAlgorithm]);
bytes = util.concat([bytes, this.revocationKeyFingerprint]); bytes = util.concat([bytes, this.revocationKeyFingerprint]);
arr.push(write_sub_packet(sub.revocationKey, bytes)); arr.push(writeSubPacket(sub.revocationKey, bytes));
} }
this.rawNotations.forEach(([{ name, value, humanReadable }]) => { this.rawNotations.forEach(([{ name, value, humanReadable }]) => {
bytes = [new Uint8Array([humanReadable ? 0x80 : 0, 0, 0, 0])]; bytes = [new Uint8Array([humanReadable ? 0x80 : 0, 0, 0, 0])];
@ -238,56 +241,56 @@ class SignaturePacket {
bytes.push(util.writeNumber(name.length, 2)); bytes.push(util.writeNumber(name.length, 2));
// 2 octets of value length // 2 octets of value length
bytes.push(util.writeNumber(value.length, 2)); bytes.push(util.writeNumber(value.length, 2));
bytes.push(util.strToUint8Array(name)); bytes.push(util.stringToUint8Array(name));
bytes.push(value); bytes.push(value);
bytes = util.concat(bytes); bytes = util.concat(bytes);
arr.push(write_sub_packet(sub.notationData, bytes)); arr.push(writeSubPacket(sub.notationData, bytes));
}); });
if (this.preferredHashAlgorithms !== null) { if (this.preferredHashAlgorithms !== null) {
bytes = util.strToUint8Array(util.uint8ArrayToStr(this.preferredHashAlgorithms)); bytes = util.stringToUint8Array(util.uint8ArrayToString(this.preferredHashAlgorithms));
arr.push(write_sub_packet(sub.preferredHashAlgorithms, bytes)); arr.push(writeSubPacket(sub.preferredHashAlgorithms, bytes));
} }
if (this.preferredCompressionAlgorithms !== null) { if (this.preferredCompressionAlgorithms !== null) {
bytes = util.strToUint8Array(util.uint8ArrayToStr(this.preferredCompressionAlgorithms)); bytes = util.stringToUint8Array(util.uint8ArrayToString(this.preferredCompressionAlgorithms));
arr.push(write_sub_packet(sub.preferredCompressionAlgorithms, bytes)); arr.push(writeSubPacket(sub.preferredCompressionAlgorithms, bytes));
} }
if (this.keyServerPreferences !== null) { if (this.keyServerPreferences !== null) {
bytes = util.strToUint8Array(util.uint8ArrayToStr(this.keyServerPreferences)); bytes = util.stringToUint8Array(util.uint8ArrayToString(this.keyServerPreferences));
arr.push(write_sub_packet(sub.keyServerPreferences, bytes)); arr.push(writeSubPacket(sub.keyServerPreferences, bytes));
} }
if (this.preferredKeyServer !== null) { if (this.preferredKeyServer !== null) {
arr.push(write_sub_packet(sub.preferredKeyServer, util.strToUint8Array(this.preferredKeyServer))); arr.push(writeSubPacket(sub.preferredKeyServer, util.stringToUint8Array(this.preferredKeyServer)));
} }
if (this.isPrimaryUserID !== null) { if (this.isPrimaryUserID !== null) {
arr.push(write_sub_packet(sub.primaryUserId, new Uint8Array([this.isPrimaryUserID ? 1 : 0]))); arr.push(writeSubPacket(sub.primaryUserID, new Uint8Array([this.isPrimaryUserID ? 1 : 0])));
} }
if (this.policyURI !== null) { if (this.policyURI !== null) {
arr.push(write_sub_packet(sub.policyUri, util.strToUint8Array(this.policyURI))); arr.push(writeSubPacket(sub.policyURI, util.stringToUint8Array(this.policyURI)));
} }
if (this.keyFlags !== null) { if (this.keyFlags !== null) {
bytes = util.strToUint8Array(util.uint8ArrayToStr(this.keyFlags)); bytes = util.stringToUint8Array(util.uint8ArrayToString(this.keyFlags));
arr.push(write_sub_packet(sub.keyFlags, bytes)); arr.push(writeSubPacket(sub.keyFlags, bytes));
} }
if (this.signersUserId !== null) { if (this.signersUserID !== null) {
arr.push(write_sub_packet(sub.signersUserId, util.strToUint8Array(this.signersUserId))); arr.push(writeSubPacket(sub.signersUserID, util.stringToUint8Array(this.signersUserID)));
} }
if (this.reasonForRevocationFlag !== null) { if (this.reasonForRevocationFlag !== null) {
bytes = util.strToUint8Array(String.fromCharCode(this.reasonForRevocationFlag) + this.reasonForRevocationString); bytes = util.stringToUint8Array(String.fromCharCode(this.reasonForRevocationFlag) + this.reasonForRevocationString);
arr.push(write_sub_packet(sub.reasonForRevocation, bytes)); arr.push(writeSubPacket(sub.reasonForRevocation, bytes));
} }
if (this.features !== null) { if (this.features !== null) {
bytes = util.strToUint8Array(util.uint8ArrayToStr(this.features)); bytes = util.stringToUint8Array(util.uint8ArrayToString(this.features));
arr.push(write_sub_packet(sub.features, bytes)); arr.push(writeSubPacket(sub.features, bytes));
} }
if (this.signatureTargetPublicKeyAlgorithm !== null) { if (this.signatureTargetPublicKeyAlgorithm !== null) {
bytes = [new Uint8Array([this.signatureTargetPublicKeyAlgorithm, this.signatureTargetHashAlgorithm])]; bytes = [new Uint8Array([this.signatureTargetPublicKeyAlgorithm, this.signatureTargetHashAlgorithm])];
bytes.push(util.strToUint8Array(this.signatureTargetHash)); bytes.push(util.stringToUint8Array(this.signatureTargetHash));
bytes = util.concat(bytes); bytes = util.concat(bytes);
arr.push(write_sub_packet(sub.signatureTarget, bytes)); arr.push(writeSubPacket(sub.signatureTarget, bytes));
} }
if (this.preferredAeadAlgorithms !== null) { if (this.preferredAEADAlgorithms !== null) {
bytes = util.strToUint8Array(util.uint8ArrayToStr(this.preferredAeadAlgorithms)); bytes = util.stringToUint8Array(util.uint8ArrayToString(this.preferredAEADAlgorithms));
arr.push(write_sub_packet(sub.preferredAeadAlgorithms, bytes)); arr.push(writeSubPacket(sub.preferredAEADAlgorithms, bytes));
} }
const result = util.concat(arr); const result = util.concat(arr);
@ -300,22 +303,22 @@ class SignaturePacket {
* Creates Uint8Array of bytes of Issuer and Embedded Signature subpackets * Creates Uint8Array of bytes of Issuer and Embedded Signature subpackets
* @returns {Uint8Array} Subpacket data. * @returns {Uint8Array} Subpacket data.
*/ */
write_unhashed_sub_packets() { writeUnhashedSubPackets() {
const sub = enums.signatureSubpacket; const sub = enums.signatureSubpacket;
const arr = []; const arr = [];
let bytes; let bytes;
if (!this.issuerKeyId.isNull() && this.issuerKeyVersion !== 5) { if (!this.issuerKeyID.isNull() && this.issuerKeyVersion !== 5) {
// If the version of [the] key is greater than 4, this subpacket // If the version of [the] key is greater than 4, this subpacket
// MUST NOT be included in the signature. // MUST NOT be included in the signature.
arr.push(write_sub_packet(sub.issuer, this.issuerKeyId.write())); arr.push(writeSubPacket(sub.issuer, this.issuerKeyID.write()));
} }
if (this.embeddedSignature !== null) { if (this.embeddedSignature !== null) {
arr.push(write_sub_packet(sub.embeddedSignature, this.embeddedSignature.write())); arr.push(writeSubPacket(sub.embeddedSignature, this.embeddedSignature.write()));
} }
if (this.issuerFingerprint !== null) { if (this.issuerFingerprint !== null) {
bytes = [new Uint8Array([this.issuerKeyVersion]), this.issuerFingerprint]; bytes = [new Uint8Array([this.issuerKeyVersion]), this.issuerFingerprint];
bytes = util.concat(bytes); bytes = util.concat(bytes);
arr.push(write_sub_packet(sub.issuerFingerprint, bytes)); arr.push(writeSubPacket(sub.issuerFingerprint, bytes));
} }
this.unhashedSubpackets.forEach(data => { this.unhashedSubpackets.forEach(data => {
arr.push(writeSimpleLength(data.length)); arr.push(writeSimpleLength(data.length));
@ -330,10 +333,10 @@ class SignaturePacket {
// V4 signature sub packets // V4 signature sub packets
read_sub_packet(bytes, trusted = true) { readSubPacket(bytes, trusted = true) {
let mypos = 0; let mypos = 0;
const read_array = (prop, bytes) => { const readArray = (prop, bytes) => {
this[prop] = []; this[prop] = [];
for (let i = 0; i < bytes.length; i++) { for (let i = 0; i < bytes.length; i++) {
@ -402,7 +405,7 @@ class SignaturePacket {
} }
case 11: case 11:
// Preferred Symmetric Algorithms // Preferred Symmetric Algorithms
read_array('preferredSymmetricAlgorithms', bytes.subarray(mypos, bytes.length)); readArray('preferredSymmetricAlgorithms', bytes.subarray(mypos, bytes.length));
break; break;
case 12: case 12:
// Revocation Key // Revocation Key
@ -416,7 +419,7 @@ class SignaturePacket {
case 16: case 16:
// Issuer // Issuer
this.issuerKeyId.read(bytes.subarray(mypos, bytes.length)); this.issuerKeyID.read(bytes.subarray(mypos, bytes.length));
break; break;
case 20: { case 20: {
@ -430,31 +433,31 @@ class SignaturePacket {
const n = util.readNumber(bytes.subarray(mypos, mypos + 2)); const n = util.readNumber(bytes.subarray(mypos, mypos + 2));
mypos += 2; mypos += 2;
const name = util.uint8ArrayToStr(bytes.subarray(mypos, mypos + m)); const name = util.uint8ArrayToString(bytes.subarray(mypos, mypos + m));
const value = bytes.subarray(mypos + m, mypos + m + n); const value = bytes.subarray(mypos + m, mypos + m + n);
this.rawNotations.push({ name, humanReadable, value, critical }); this.rawNotations.push({ name, humanReadable, value, critical });
if (humanReadable) { if (humanReadable) {
this.notations[name] = util.uint8ArrayToStr(value); this.notations[name] = util.uint8ArrayToString(value);
} }
break; break;
} }
case 21: case 21:
// Preferred Hash Algorithms // Preferred Hash Algorithms
read_array('preferredHashAlgorithms', bytes.subarray(mypos, bytes.length)); readArray('preferredHashAlgorithms', bytes.subarray(mypos, bytes.length));
break; break;
case 22: case 22:
// Preferred Compression Algorithms // Preferred Compression Algorithms
read_array('preferredCompressionAlgorithms', bytes.subarray(mypos, bytes.length)); readArray('preferredCompressionAlgorithms', bytes.subarray(mypos, bytes.length));
break; break;
case 23: case 23:
// Key Server Preferences // Key Server Preferences
read_array('keyServerPreferences', bytes.subarray(mypos, bytes.length)); readArray('keyServerPreferences', bytes.subarray(mypos, bytes.length));
break; break;
case 24: case 24:
// Preferred Key Server // Preferred Key Server
this.preferredKeyServer = util.uint8ArrayToStr(bytes.subarray(mypos, bytes.length)); this.preferredKeyServer = util.uint8ArrayToString(bytes.subarray(mypos, bytes.length));
break; break;
case 25: case 25:
// Primary User ID // Primary User ID
@ -462,24 +465,24 @@ class SignaturePacket {
break; break;
case 26: case 26:
// Policy URI // Policy URI
this.policyURI = util.uint8ArrayToStr(bytes.subarray(mypos, bytes.length)); this.policyURI = util.uint8ArrayToString(bytes.subarray(mypos, bytes.length));
break; break;
case 27: case 27:
// Key Flags // Key Flags
read_array('keyFlags', bytes.subarray(mypos, bytes.length)); readArray('keyFlags', bytes.subarray(mypos, bytes.length));
break; break;
case 28: case 28:
// Signer's User ID // Signer's User ID
this.signersUserId = util.uint8ArrayToStr(bytes.subarray(mypos, bytes.length)); this.signersUserID = util.uint8ArrayToString(bytes.subarray(mypos, bytes.length));
break; break;
case 29: case 29:
// Reason for Revocation // Reason for Revocation
this.reasonForRevocationFlag = bytes[mypos++]; this.reasonForRevocationFlag = bytes[mypos++];
this.reasonForRevocationString = util.uint8ArrayToStr(bytes.subarray(mypos, bytes.length)); this.reasonForRevocationString = util.uint8ArrayToString(bytes.subarray(mypos, bytes.length));
break; break;
case 30: case 30:
// Features // Features
read_array('features', bytes.subarray(mypos, bytes.length)); readArray('features', bytes.subarray(mypos, bytes.length));
break; break;
case 31: { case 31: {
// Signature Target // Signature Target
@ -489,7 +492,7 @@ class SignaturePacket {
const len = crypto.getHashByteLength(this.signatureTargetHashAlgorithm); const len = crypto.getHashByteLength(this.signatureTargetHashAlgorithm);
this.signatureTargetHash = util.uint8ArrayToStr(bytes.subarray(mypos, mypos + len)); this.signatureTargetHash = util.uint8ArrayToString(bytes.subarray(mypos, mypos + len));
break; break;
} }
case 32: case 32:
@ -502,14 +505,14 @@ class SignaturePacket {
this.issuerKeyVersion = bytes[mypos++]; this.issuerKeyVersion = bytes[mypos++];
this.issuerFingerprint = bytes.subarray(mypos, bytes.length); this.issuerFingerprint = bytes.subarray(mypos, bytes.length);
if (this.issuerKeyVersion === 5) { if (this.issuerKeyVersion === 5) {
this.issuerKeyId.read(this.issuerFingerprint); this.issuerKeyID.read(this.issuerFingerprint);
} else { } else {
this.issuerKeyId.read(this.issuerFingerprint.subarray(-8)); this.issuerKeyID.read(this.issuerFingerprint.subarray(-8));
} }
break; break;
case 34: case 34:
// Preferred AEAD Algorithms // Preferred AEAD Algorithms
read_array.call(this, 'preferredAeadAlgorithms', bytes.subarray(mypos, bytes.length)); readArray.call(this, 'preferredAEADAlgorithms', bytes.subarray(mypos, bytes.length));
break; break;
default: { default: {
const err = new Error("Unknown signature subpacket type " + type + " @:" + mypos); const err = new Error("Unknown signature subpacket type " + type + " @:" + mypos);
@ -522,18 +525,18 @@ class SignaturePacket {
} }
} }
read_sub_packets(bytes, trusted = true, config) { readSubPackets(bytes, trusted = true, config) {
// Two-octet scalar octet count for following subpacket data. // Two-octet scalar octet count for following subpacket data.
const subpacket_length = util.readNumber(bytes.subarray(0, 2)); const subpacketLength = util.readNumber(bytes.subarray(0, 2));
let i = 2; let i = 2;
// subpacket data set (zero or more subpackets) // subpacket data set (zero or more subpackets)
while (i < 2 + subpacket_length) { while (i < 2 + subpacketLength) {
const len = readSimpleLength(bytes.subarray(i, bytes.length)); const len = readSimpleLength(bytes.subarray(i, bytes.length));
i += len.offset; i += len.offset;
this.read_sub_packet(bytes.subarray(i, i + len.len), trusted, config); this.readSubPacket(bytes.subarray(i, i + len.len), trusted, config);
i += len.len; i += len.len;
} }
@ -548,7 +551,7 @@ class SignaturePacket {
switch (type) { switch (type) {
case t.binary: case t.binary:
if (data.text !== null) { if (data.text !== null) {
return util.encodeUtf8(data.getText(true)); return util.encodeUTF8(data.getText(true));
} }
return data.getBytes(true); return data.getBytes(true);
@ -568,14 +571,14 @@ class SignaturePacket {
let packet; let packet;
let tag; let tag;
if (data.userId) { if (data.userID) {
tag = 0xB4; tag = 0xB4;
packet = data.userId; packet = data.userID;
} else if (data.userAttribute) { } else if (data.userAttribute) {
tag = 0xD1; tag = 0xD1;
packet = data.userAttribute; packet = data.userAttribute;
} else { } else {
throw new Error('Either a userId or userAttribute packet needs to be ' + throw new Error('Either a userID or userAttribute packet needs to be ' +
'supplied for certification.'); 'supplied for certification.');
} }
@ -734,6 +737,8 @@ class SignaturePacket {
} }
} }
export default SignaturePacket;
/** /**
* Creates a string representation of a sub signature packet * Creates a string representation of a sub signature packet
* @see {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.1|RFC4880 5.2.3.1} * @see {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.1|RFC4880 5.2.3.1}
@ -743,12 +748,10 @@ class SignaturePacket {
* @returns {String} A string-representation of a sub signature packet. * @returns {String} A string-representation of a sub signature packet.
* @private * @private
*/ */
function write_sub_packet(type, data) { function writeSubPacket(type, data) {
const arr = []; const arr = [];
arr.push(writeSimpleLength(data.length + 1)); arr.push(writeSimpleLength(data.length + 1));
arr.push(new Uint8Array([type])); arr.push(new Uint8Array([type]));
arr.push(data); arr.push(data);
return util.concat(arr); return util.concat(arr);
} }
export default SignaturePacket;

View File

@ -19,13 +19,20 @@ import stream from '@openpgp/web-stream-tools';
import crypto from '../crypto'; import crypto from '../crypto';
import enums from '../enums'; import enums from '../enums';
import util from '../util'; import util from '../util';
import { import defaultConfig from '../config';
import LiteralDataPacket from './literal_data';
import CompressedDataPacket from './compressed_data';
import OnePassSignaturePacket from './one_pass_signature';
import SignaturePacket from './signature';
// A SEIP packet can contain the following packet types
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([
LiteralDataPacket, LiteralDataPacket,
CompressedDataPacket, CompressedDataPacket,
OnePassSignaturePacket, OnePassSignaturePacket,
SignaturePacket SignaturePacket
} from '../packet'; ]);
import defaultConfig from '../config';
const VERSION = 1; // A one-octet version number of the data packet. const VERSION = 1; // A one-octet version number of the data packet.
@ -40,8 +47,11 @@ const VERSION = 1; // A one-octet version number of the data packet.
* packet. * packet.
*/ */
class SymEncryptedIntegrityProtectedDataPacket { class SymEncryptedIntegrityProtectedDataPacket {
static get tag() {
return enums.packet.symEncryptedIntegrityProtectedData;
}
constructor() { constructor() {
this.tag = enums.packet.symEncryptedIntegrityProtectedData;
this.version = VERSION; this.version = VERSION;
/** The encrypted payload. */ /** The encrypted payload. */
this.encrypted = null; // string this.encrypted = null; // string
@ -93,7 +103,7 @@ class SymEncryptedIntegrityProtectedDataPacket {
const hash = await crypto.hash.sha1(stream.passiveClone(tohash)); const hash = await crypto.hash.sha1(stream.passiveClone(tohash));
const plaintext = util.concat([tohash, hash]); const plaintext = util.concat([tohash, hash]);
this.encrypted = await crypto.cfb.encrypt(sessionKeyAlgorithm, key, plaintext, new Uint8Array(crypto.cipher[sessionKeyAlgorithm].blockSize), config); this.encrypted = await crypto.mode.cfb.encrypt(sessionKeyAlgorithm, key, plaintext, new Uint8Array(crypto.cipher[sessionKeyAlgorithm].blockSize), config);
return true; return true;
} }
@ -109,7 +119,7 @@ class SymEncryptedIntegrityProtectedDataPacket {
async decrypt(sessionKeyAlgorithm, key, streaming, config = defaultConfig) { async decrypt(sessionKeyAlgorithm, key, streaming, config = defaultConfig) {
let encrypted = stream.clone(this.encrypted); let encrypted = stream.clone(this.encrypted);
if (!streaming) encrypted = await stream.readToEnd(encrypted); if (!streaming) encrypted = await stream.readToEnd(encrypted);
const decrypted = await crypto.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(crypto.cipher[sessionKeyAlgorithm].blockSize)); const decrypted = await crypto.mode.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(crypto.cipher[sessionKeyAlgorithm].blockSize));
// there must be a modification detection code packet as the // there must be a modification detection code packet as the
// last packet and everything gets hashed except the hash itself // last packet and everything gets hashed except the hash itself
@ -130,12 +140,7 @@ class SymEncryptedIntegrityProtectedDataPacket {
if (!util.isStream(encrypted) || !config.allowUnauthenticatedStream) { if (!util.isStream(encrypted) || !config.allowUnauthenticatedStream) {
packetbytes = await stream.readToEnd(packetbytes); packetbytes = await stream.readToEnd(packetbytes);
} }
await this.packets.read(packetbytes, { await this.packets.read(packetbytes, allowedPackets, streaming);
LiteralDataPacket,
CompressedDataPacket,
OnePassSignaturePacket,
SignaturePacket
}, streaming);
return true; return true;
} }
} }

View File

@ -15,7 +15,7 @@
// License along with this library; if not, write to the Free Software // License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import type_s2k from '../type/s2k'; import S2K from '../type/s2k';
import defaultConfig from '../config'; import defaultConfig from '../config';
import crypto from '../crypto'; import crypto from '../crypto';
import enums from '../enums'; import enums from '../enums';
@ -35,16 +35,19 @@ import util from '../util';
* the Symmetric-Key Encrypted Session Key packet. * the Symmetric-Key Encrypted Session Key packet.
*/ */
class SymEncryptedSessionKeyPacket { class SymEncryptedSessionKeyPacket {
static get tag() {
return enums.packet.symEncryptedSessionKey;
}
/** /**
* @param {Object} [config] - Full configuration, defaults to openpgp.config * @param {Object} [config] - Full configuration, defaults to openpgp.config
*/ */
constructor(config = defaultConfig) { constructor(config = defaultConfig) {
this.tag = enums.packet.symEncryptedSessionKey;
this.version = config.aeadProtect ? 5 : 4; this.version = config.aeadProtect ? 5 : 4;
this.sessionKey = null; this.sessionKey = null;
this.sessionKeyEncryptionAlgorithm = null; this.sessionKeyEncryptionAlgorithm = null;
this.sessionKeyAlgorithm = 'aes256'; this.sessionKeyAlgorithm = 'aes256';
this.aeadAlgorithm = enums.read(enums.aead, config.preferredAeadAlgorithm); this.aeadAlgorithm = enums.read(enums.aead, config.preferredAEADAlgorithm);
this.encrypted = null; this.encrypted = null;
this.s2k = null; this.s2k = null;
this.iv = null; this.iv = null;
@ -70,11 +73,11 @@ class SymEncryptedSessionKeyPacket {
} }
// A string-to-key (S2K) specifier, length as defined above. // A string-to-key (S2K) specifier, length as defined above.
this.s2k = new type_s2k(); this.s2k = new S2K();
offset += this.s2k.read(bytes.subarray(offset, bytes.length)); offset += this.s2k.read(bytes.subarray(offset, bytes.length));
if (this.version === 5) { if (this.version === 5) {
const mode = crypto[this.aeadAlgorithm]; const mode = crypto.mode[this.aeadAlgorithm];
// A starting initialization vector of size specified by the AEAD // A starting initialization vector of size specified by the AEAD
// algorithm. // algorithm.
@ -128,15 +131,15 @@ class SymEncryptedSessionKeyPacket {
this.sessionKeyAlgorithm; this.sessionKeyAlgorithm;
const length = crypto.cipher[algo].keySize; const length = crypto.cipher[algo].keySize;
const key = await this.s2k.produce_key(passphrase, length); const key = await this.s2k.produceKey(passphrase, length);
if (this.version === 5) { if (this.version === 5) {
const mode = crypto[this.aeadAlgorithm]; const mode = crypto.mode[this.aeadAlgorithm];
const adata = new Uint8Array([0xC0 | this.tag, this.version, enums.write(enums.symmetric, this.sessionKeyEncryptionAlgorithm), enums.write(enums.aead, this.aeadAlgorithm)]); const adata = new Uint8Array([0xC0 | SymEncryptedSessionKeyPacket.tag, this.version, enums.write(enums.symmetric, this.sessionKeyEncryptionAlgorithm), enums.write(enums.aead, this.aeadAlgorithm)]);
const modeInstance = await mode(algo, key); const modeInstance = await mode(algo, key);
this.sessionKey = await modeInstance.decrypt(this.encrypted, this.iv, adata); this.sessionKey = await modeInstance.decrypt(this.encrypted, this.iv, adata);
} else if (this.encrypted !== null) { } else if (this.encrypted !== null) {
const decrypted = await crypto.cfb.decrypt(algo, key, this.encrypted, new Uint8Array(crypto.cipher[algo].blockSize)); const decrypted = await crypto.mode.cfb.decrypt(algo, key, this.encrypted, new Uint8Array(crypto.cipher[algo].blockSize));
this.sessionKeyAlgorithm = enums.read(enums.symmetric, decrypted[0]); this.sessionKeyAlgorithm = enums.read(enums.symmetric, decrypted[0]);
this.sessionKey = decrypted.subarray(1, decrypted.length); this.sessionKey = decrypted.subarray(1, decrypted.length);
@ -159,26 +162,26 @@ class SymEncryptedSessionKeyPacket {
this.sessionKeyEncryptionAlgorithm = algo; this.sessionKeyEncryptionAlgorithm = algo;
this.s2k = new type_s2k(config); this.s2k = new S2K(config);
this.s2k.salt = await crypto.random.getRandomBytes(8); this.s2k.salt = await crypto.random.getRandomBytes(8);
const length = crypto.cipher[algo].keySize; const length = crypto.cipher[algo].keySize;
const key = await this.s2k.produce_key(passphrase, length); const key = await this.s2k.produceKey(passphrase, length);
if (this.sessionKey === null) { if (this.sessionKey === null) {
this.sessionKey = await crypto.generateSessionKey(this.sessionKeyAlgorithm); this.sessionKey = await crypto.generateSessionKey(this.sessionKeyAlgorithm);
} }
if (this.version === 5) { if (this.version === 5) {
const mode = crypto[this.aeadAlgorithm]; const mode = crypto.mode[this.aeadAlgorithm];
this.iv = await crypto.random.getRandomBytes(mode.ivLength); // generate new random IV this.iv = await crypto.random.getRandomBytes(mode.ivLength); // generate new random IV
const adata = new Uint8Array([0xC0 | this.tag, this.version, enums.write(enums.symmetric, this.sessionKeyEncryptionAlgorithm), enums.write(enums.aead, this.aeadAlgorithm)]); const adata = new Uint8Array([0xC0 | SymEncryptedSessionKeyPacket.tag, this.version, enums.write(enums.symmetric, this.sessionKeyEncryptionAlgorithm), enums.write(enums.aead, this.aeadAlgorithm)]);
const modeInstance = await mode(algo, key); const modeInstance = await mode(algo, key);
this.encrypted = await modeInstance.encrypt(this.sessionKey, this.iv, adata); this.encrypted = await modeInstance.encrypt(this.sessionKey, this.iv, adata);
} else { } else {
const algo_enum = new Uint8Array([enums.write(enums.symmetric, this.sessionKeyAlgorithm)]); const algo_enum = new Uint8Array([enums.write(enums.symmetric, this.sessionKeyAlgorithm)]);
const private_key = util.concatUint8Array([algo_enum, this.sessionKey]); 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), config); this.encrypted = await crypto.mode.cfb.encrypt(algo, key, private_key, new Uint8Array(crypto.cipher[algo].blockSize), config);
} }
} }
} }

View File

@ -19,13 +19,20 @@ import stream from '@openpgp/web-stream-tools';
import crypto from '../crypto'; import crypto from '../crypto';
import enums from '../enums'; import enums from '../enums';
import util from '../util'; import util from '../util';
import { import defaultConfig from '../config';
import LiteralDataPacket from './literal_data';
import CompressedDataPacket from './compressed_data';
import OnePassSignaturePacket from './one_pass_signature';
import SignaturePacket from './signature';
// A SE packet can contain the following packet types
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([
LiteralDataPacket, LiteralDataPacket,
CompressedDataPacket, CompressedDataPacket,
OnePassSignaturePacket, OnePassSignaturePacket,
SignaturePacket SignaturePacket
} from '../packet'; ]);
import defaultConfig from '../config';
/** /**
* Implementation of the Symmetrically Encrypted Data Packet (Tag 9) * Implementation of the Symmetrically Encrypted Data Packet (Tag 9)
@ -38,12 +45,11 @@ import defaultConfig from '../config';
* that form whole OpenPGP messages). * that form whole OpenPGP messages).
*/ */
class SymmetricallyEncryptedDataPacket { class SymmetricallyEncryptedDataPacket {
static get tag() {
return enums.packet.symmetricallyEncryptedData;
}
constructor() { constructor() {
/**
* Packet type
* @type {module:enums.packet}
*/
this.tag = enums.packet.symmetricallyEncryptedData;
/** /**
* Encrypted secret-key data * Encrypted secret-key data
*/ */
@ -80,17 +86,12 @@ class SymmetricallyEncryptedDataPacket {
} }
const encrypted = await stream.readToEnd(stream.clone(this.encrypted)); const encrypted = await stream.readToEnd(stream.clone(this.encrypted));
const decrypted = await crypto.cfb.decrypt(sessionKeyAlgorithm, key, const decrypted = await crypto.mode.cfb.decrypt(sessionKeyAlgorithm, key,
encrypted.subarray(crypto.cipher[sessionKeyAlgorithm].blockSize + 2), encrypted.subarray(crypto.cipher[sessionKeyAlgorithm].blockSize + 2),
encrypted.subarray(2, crypto.cipher[sessionKeyAlgorithm].blockSize + 2) encrypted.subarray(2, crypto.cipher[sessionKeyAlgorithm].blockSize + 2)
); );
await this.packets.read(decrypted, { await this.packets.read(decrypted, allowedPackets, streaming);
LiteralDataPacket,
CompressedDataPacket,
OnePassSignaturePacket,
SignaturePacket
}, streaming);
} }
/** /**
@ -106,8 +107,8 @@ class SymmetricallyEncryptedDataPacket {
const data = this.packets.write(); const data = this.packets.write();
const prefix = await crypto.getPrefixRandom(algo); const prefix = await crypto.getPrefixRandom(algo);
const FRE = await crypto.cfb.encrypt(algo, key, prefix, new Uint8Array(crypto.cipher[algo].blockSize), config); const FRE = await crypto.mode.cfb.encrypt(algo, key, prefix, new Uint8Array(crypto.cipher[algo].blockSize), config);
const ciphertext = await crypto.cfb.encrypt(algo, key, data, FRE.subarray(2), config); const ciphertext = await crypto.mode.cfb.encrypt(algo, key, data, FRE.subarray(2), config);
this.encrypted = util.concat([FRE, ciphertext]); this.encrypted = util.concat([FRE, ciphertext]);
} }
} }

View File

@ -18,8 +18,8 @@ import enums from '../enums';
* other than local keyring files. * other than local keyring files.
*/ */
class TrustPacket { class TrustPacket {
constructor() { static get tag() {
this.tag = enums.packet.trust; return enums.packet.trust;
} }
/** /**

View File

@ -37,8 +37,11 @@ import util from '../util';
* an implementation may use any method desired. * an implementation may use any method desired.
*/ */
class UserAttributePacket { class UserAttributePacket {
static get tag() {
return enums.packet.userAttribute;
}
constructor() { constructor() {
this.tag = enums.packet.userAttribute;
this.attributes = []; this.attributes = [];
} }
@ -52,7 +55,7 @@ class UserAttributePacket {
const len = readSimpleLength(bytes.subarray(i, bytes.length)); const len = readSimpleLength(bytes.subarray(i, bytes.length));
i += len.offset; i += len.offset;
this.attributes.push(util.uint8ArrayToStr(bytes.subarray(i, i + len.len))); this.attributes.push(util.uint8ArrayToString(bytes.subarray(i, i + len.len)));
i += len.len; i += len.len;
} }
} }
@ -65,7 +68,7 @@ class UserAttributePacket {
const arr = []; const arr = [];
for (let i = 0; i < this.attributes.length; i++) { for (let i = 0; i < this.attributes.length; i++) {
arr.push(writeSimpleLength(this.attributes[i].length)); arr.push(writeSimpleLength(this.attributes[i].length));
arr.push(util.strToUint8Array(this.attributes[i])); arr.push(util.stringToUint8Array(this.attributes[i]));
} }
return util.concatUint8Array(arr); return util.concatUint8Array(arr);
} }

View File

@ -31,13 +31,16 @@ import defaultConfig from '../config';
* specifies the length of the User ID. * specifies the length of the User ID.
*/ */
class UserIDPacket { class UserIDPacket {
static get tag() {
return enums.packet.userID;
}
constructor() { constructor() {
this.tag = enums.packet.userID;
/** A string containing the user id. Usually in the form /** A string containing the user id. Usually in the form
* John Doe <john@example.com> * John Doe <john@example.com>
* @type {String} * @type {String}
*/ */
this.userid = ''; this.userID = '';
this.name = ''; this.name = '';
this.email = ''; this.email = '';
@ -46,24 +49,24 @@ class UserIDPacket {
/** /**
* Create UserIDPacket instance from object * Create UserIDPacket instance from object
* @param {Object} userId - Object specifying userId name, email and comment * @param {Object} userID - Object specifying userID name, email and comment
* @returns {UserIDPacket} * @returns {UserIDPacket}
* @static * @static
*/ */
static fromObject(userId) { static fromObject(userID) {
if (util.isString(userId) || if (util.isString(userID) ||
(userId.name && !util.isString(userId.name)) || (userID.name && !util.isString(userID.name)) ||
(userId.email && !util.isEmailAddress(userId.email)) || (userID.email && !util.isEmailAddress(userID.email)) ||
(userId.comment && !util.isString(userId.comment))) { (userID.comment && !util.isString(userID.comment))) {
throw new Error('Invalid user ID format'); throw new Error('Invalid user ID format');
} }
const packet = new UserIDPacket(); const packet = new UserIDPacket();
Object.assign(packet, userId); Object.assign(packet, userID);
const components = []; const components = [];
if (packet.name) components.push(packet.name); if (packet.name) components.push(packet.name);
if (packet.comment) components.push(`(${packet.comment})`); if (packet.comment) components.push(`(${packet.comment})`);
if (packet.email) components.push(`<${packet.email}>`); if (packet.email) components.push(`<${packet.email}>`);
packet.userid = components.join(' '); packet.userID = components.join(' ');
return packet; return packet;
} }
@ -72,17 +75,17 @@ class UserIDPacket {
* @param {Uint8Array} input - Payload of a tag 13 packet * @param {Uint8Array} input - Payload of a tag 13 packet
*/ */
read(bytes, config = defaultConfig) { read(bytes, config = defaultConfig) {
const userid = util.decodeUtf8(bytes); const userID = util.decodeUTF8(bytes);
if (userid.length > config.maxUseridLength) { if (userID.length > config.maxUserIDLength) {
throw new Error('User ID string is too long'); throw new Error('User ID string is too long');
} }
try { try {
const { name, address: email, comments } = emailAddresses.parseOneAddress({ input: userid, atInDisplayName: true }); const { name, address: email, comments } = emailAddresses.parseOneAddress({ input: userID, atInDisplayName: true });
this.comment = comments.replace(/^\(|\)$/g, ''); this.comment = comments.replace(/^\(|\)$/g, '');
this.name = name; this.name = name;
this.email = email; this.email = email;
} catch (e) {} } catch (e) {}
this.userid = userid; this.userID = userID;
} }
/** /**
@ -90,7 +93,7 @@ class UserIDPacket {
* @returns {Uint8Array} Binary representation. * @returns {Uint8Array} Binary representation.
*/ */
write() { write() {
return util.encodeUtf8(this.userid); return util.encodeUTF8(this.userID);
} }
} }

View File

@ -18,8 +18,12 @@
import { armor, unarmor } from './encoding/armor'; import { armor, unarmor } from './encoding/armor';
import { PacketList, SignaturePacket } from './packet'; import { PacketList, SignaturePacket } from './packet';
import enums from './enums'; import enums from './enums';
import util from './util';
import defaultConfig from './config'; import defaultConfig from './config';
// A Signature can contain the following packets
const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([SignaturePacket]);
/** /**
* Class that represents an OpenPGP signature. * Class that represents an OpenPGP signature.
*/ */
@ -73,6 +77,6 @@ export async function readSignature({ armoredSignature, binarySignature, config
input = data; input = data;
} }
const packetlist = new PacketList(); const packetlist = new PacketList();
await packetlist.read(input, { SignaturePacket }, undefined, config); await packetlist.read(input, allowedPackets, undefined, config);
return new Signature(packetlist); return new Signature(packetlist);
} }

View File

@ -29,7 +29,7 @@ class ECDHSymmetricKey {
if (typeof data === 'undefined') { if (typeof data === 'undefined') {
data = new Uint8Array([]); data = new Uint8Array([]);
} else if (util.isString(data)) { } else if (util.isString(data)) {
data = util.strToUint8Array(data); data = util.stringToUint8Array(data);
} else { } else {
data = new Uint8Array(data); data = new Uint8Array(data);
} }

View File

@ -31,7 +31,7 @@ import util from '../util.js';
* section "Enhanced Key Formats" below describes how Key IDs are * section "Enhanced Key Formats" below describes how Key IDs are
* formed. * formed.
*/ */
class Keyid { class KeyID {
constructor() { constructor() {
this.bytes = ''; this.bytes = '';
} }
@ -41,7 +41,7 @@ class Keyid {
* @param {Uint8Array} bytes - Input to read the key id from * @param {Uint8Array} bytes - Input to read the key id from
*/ */
read(bytes) { read(bytes) {
this.bytes = util.uint8ArrayToStr(bytes.subarray(0, 8)); this.bytes = util.uint8ArrayToString(bytes.subarray(0, 8));
} }
/** /**
@ -49,7 +49,7 @@ class Keyid {
* @returns {Uint8Array} Key ID as a Uint8Array. * @returns {Uint8Array} Key ID as a Uint8Array.
*/ */
write() { write() {
return util.strToUint8Array(this.bytes); return util.stringToUint8Array(this.bytes);
} }
/** /**
@ -57,16 +57,16 @@ class Keyid {
* @returns {String} Key ID as a hexadecimal string. * @returns {String} Key ID as a hexadecimal string.
*/ */
toHex() { toHex() {
return util.strToHex(this.bytes); return util.stringToHex(this.bytes);
} }
/** /**
* Checks equality of Key ID's * Checks equality of Key ID's
* @param {Keyid} keyid * @param {KeyID} keyID
* @param {Boolean} matchWildcard - Indicates whether to check if either keyid is a wildcard * @param {Boolean} matchWildcard - Indicates whether to check if either keyID is a wildcard
*/ */
equals(keyid, matchWildcard = false) { equals(keyID, matchWildcard = false) {
return (matchWildcard && (keyid.isWildcard() || this.isWildcard())) || this.bytes === keyid.bytes; return (matchWildcard && (keyID.isWildcard() || this.isWildcard())) || this.bytes === keyID.bytes;
} }
/** /**
@ -85,21 +85,21 @@ class Keyid {
return /^0+$/.test(this.toHex()); return /^0+$/.test(this.toHex());
} }
static mapToHex(keyId) { static mapToHex(keyID) {
return keyId.toHex(); return keyID.toHex();
} }
static fromId(hex) { static fromID(hex) {
const keyid = new Keyid(); const keyID = new KeyID();
keyid.read(util.hexToUint8Array(hex)); keyID.read(util.hexToUint8Array(hex));
return keyid; return keyID;
} }
static wildcard() { static wildcard() {
const keyid = new Keyid(); const keyID = new KeyID();
keyid.read(new Uint8Array(8)); keyID.read(new Uint8Array(8));
return keyid; return keyID;
} }
} }
export default Keyid; export default KeyID;

View File

@ -50,7 +50,7 @@ class S2K {
this.salt = null; this.salt = null;
} }
get_count() { getCount() {
// Exponent bias, defined in RFC4880 // Exponent bias, defined in RFC4880
const expbias = 6; const expbias = 6;
@ -88,7 +88,7 @@ class S2K {
break; break;
case 'gnu': case 'gnu':
if (util.uint8ArrayToStr(bytes.subarray(i, i + 3)) === "GNU") { if (util.uint8ArrayToString(bytes.subarray(i, i + 3)) === "GNU") {
i += 3; // GNU i += 3; // GNU
const gnuExtType = 1000 + bytes[i++]; const gnuExtType = 1000 + bytes[i++];
if (gnuExtType === 1001) { if (gnuExtType === 1001) {
@ -115,7 +115,7 @@ class S2K {
*/ */
write() { write() {
if (this.type === 'gnu-dummy') { if (this.type === 'gnu-dummy') {
return new Uint8Array([101, 0, ...util.strToUint8Array('GNU'), 1]); return new Uint8Array([101, 0, ...util.stringToUint8Array('GNU'), 1]);
} }
const arr = [new Uint8Array([enums.write(enums.s2k, this.type), enums.write(enums.hash, this.algorithm)])]; const arr = [new Uint8Array([enums.write(enums.s2k, this.type), enums.write(enums.hash, this.algorithm)])];
@ -146,8 +146,8 @@ class S2K {
* @returns {Uint8Array} Produced key with a length corresponding to. * @returns {Uint8Array} Produced key with a length corresponding to.
* hashAlgorithm hash length * hashAlgorithm hash length
*/ */
async produce_key(passphrase, numBytes) { async produceKey(passphrase, numBytes) {
passphrase = util.encodeUtf8(passphrase); passphrase = util.encodeUTF8(passphrase);
const algorithm = enums.write(enums.hash, this.algorithm); const algorithm = enums.write(enums.hash, this.algorithm);
const arr = []; const arr = [];
@ -166,7 +166,7 @@ class S2K {
case 'iterated': { case 'iterated': {
const data = util.concatUint8Array([this.salt, passphrase]); const data = util.concatUint8Array([this.salt, passphrase]);
let datalen = data.length; let datalen = data.length;
const count = Math.max(this.get_count(), datalen); const count = Math.max(this.getCount(), datalen);
toHash = new Uint8Array(prefixlen + count); toHash = new Uint8Array(prefixlen + count);
toHash.set(data, prefixlen); toHash.set(data, prefixlen);
for (let pos = prefixlen + datalen; pos < count; pos += datalen, datalen *= 2) { for (let pos = prefixlen + datalen; pos < count; pos += datalen, datalen *= 2) {

View File

@ -131,7 +131,7 @@ const util = {
* @param {String} str - String to convert * @param {String} str - String to convert
* @returns {String} String containing the hexadecimal values. * @returns {String} String containing the hexadecimal values.
*/ */
strToHex: function (str) { stringToHex: function (str) {
if (str === null) { if (str === null) {
return ""; return "";
} }
@ -154,7 +154,7 @@ const util = {
* @param {String} str - Hex string to convert * @param {String} str - Hex string to convert
* @returns {String} * @returns {String}
*/ */
hexToStr: function (hex) { hexToString: function (hex) {
let str = ''; let str = '';
for (let i = 0; i < hex.length; i += 2) { for (let i = 0; i < hex.length; i += 2) {
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
@ -191,7 +191,7 @@ const util = {
* @param {Uint8Array} bin - An array of 8-bit integers to convert * @param {Uint8Array} bin - An array of 8-bit integers to convert
* @returns {Uint8Array} MPI-formatted Uint8Array. * @returns {Uint8Array} MPI-formatted Uint8Array.
*/ */
uint8ArrayToMpi: function (bin) { uint8ArrayToMPI: function (bin) {
const bitSize = util.uint8ArrayBitLength(bin); const bitSize = util.uint8ArrayBitLength(bin);
if (bitSize === 0) { if (bitSize === 0) {
throw new Error('Zero MPI'); throw new Error('Zero MPI');
@ -254,10 +254,10 @@ const util = {
* @param {String} str - String to convert * @param {String} str - String to convert
* @returns {Uint8Array} An array of 8-bit integers. * @returns {Uint8Array} An array of 8-bit integers.
*/ */
strToUint8Array: function (str) { stringToUint8Array: function (str) {
return stream.transform(str, str => { return stream.transform(str, str => {
if (!util.isString(str)) { if (!util.isString(str)) {
throw new Error('strToUint8Array: Data must be in the form of a string'); throw new Error('stringToUint8Array: Data must be in the form of a string');
} }
const result = new Uint8Array(str.length); const result = new Uint8Array(str.length);
@ -273,7 +273,7 @@ const util = {
* @param {Uint8Array} bytes - An array of 8-bit integers to convert * @param {Uint8Array} bytes - An array of 8-bit integers to convert
* @returns {String} String representation of the array. * @returns {String} String representation of the array.
*/ */
uint8ArrayToStr: function (bytes) { uint8ArrayToString: function (bytes) {
bytes = new Uint8Array(bytes); bytes = new Uint8Array(bytes);
const result = []; const result = [];
const bs = 1 << 14; const bs = 1 << 14;
@ -290,7 +290,7 @@ const util = {
* @param {String|ReadableStream} str - The string to convert * @param {String|ReadableStream} str - The string to convert
* @returns {Uint8Array|ReadableStream} A valid squence of utf8 bytes. * @returns {Uint8Array|ReadableStream} A valid squence of utf8 bytes.
*/ */
encodeUtf8: function (str) { encodeUTF8: function (str) {
const encoder = new TextEncoder('utf-8'); const encoder = new TextEncoder('utf-8');
// eslint-disable-next-line no-inner-declarations // eslint-disable-next-line no-inner-declarations
function process(value, lastChunk = false) { function process(value, lastChunk = false) {
@ -304,7 +304,7 @@ const util = {
* @param {Uint8Array|ReadableStream} utf8 - A valid squence of utf8 bytes * @param {Uint8Array|ReadableStream} utf8 - A valid squence of utf8 bytes
* @returns {String|ReadableStream} A native javascript string. * @returns {String|ReadableStream} A native javascript string.
*/ */
decodeUtf8: function (utf8) { decodeUTF8: function (utf8) {
const decoder = new TextDecoder('utf-8'); const decoder = new TextDecoder('utf-8');
// eslint-disable-next-line no-inner-declarations // eslint-disable-next-line no-inner-declarations
function process(value, lastChunk = false) { function process(value, lastChunk = false) {
@ -379,7 +379,7 @@ const util = {
/** /**
* Helper function to print a debug message. Debug * Helper function to print a debug message. Debug
* messages are only printed if * messages are only printed if
* Different than print_debug because will call Uint8ArrayToHex iff necessary. * Different than printDebug because will call Uint8ArrayToHex iff necessary.
* @param {String} str - String of the debug message * @param {String} str - String of the debug message
*/ */
printDebugHexArrayDump: function (str, arrToHex) { printDebugHexArrayDump: function (str, arrToHex) {
@ -392,12 +392,12 @@ const util = {
/** /**
* Helper function to print a debug message. Debug * Helper function to print a debug message. Debug
* messages are only printed if * messages are only printed if
* Different than print_debug because will call strToHex iff necessary. * Different than printDebug because will call stringToHex iff necessary.
* @param {String} str - String of the debug message * @param {String} str - String of the debug message
*/ */
printDebugHexStrDump: function (str, strToHex) { printDebugHexStrDump: function (str, stringToHex) {
if (debugMode) { if (debugMode) {
str += util.strToHex(strToHex); str += util.stringToHex(stringToHex);
console.log(str); console.log(str);
} }
}, },
@ -466,13 +466,13 @@ const util = {
* @param {Uint8Array} data * @param {Uint8Array} data
*/ */
double: function(data) { double: function(data) {
const double_var = new Uint8Array(data.length); const doubleVar = new Uint8Array(data.length);
const last = data.length - 1; const last = data.length - 1;
for (let i = 0; i < last; i++) { for (let i = 0; i < last; i++) {
double_var[i] = (data[i] << 1) ^ (data[i + 1] >> 7); doubleVar[i] = (data[i] << 1) ^ (data[i + 1] >> 7);
} }
double_var[last] = (data[last] << 1) ^ ((data[0] >> 7) * 0x87); doubleVar[last] = (data[last] << 1) ^ ((data[0] >> 7) * 0x87);
return double_var; return doubleVar;
}, },
/** /**
@ -674,6 +674,23 @@ const util = {
} catch (e) {} } catch (e) {}
return error; return error;
},
/**
* Map allowed packet tags to corresponding classes
* Meant to be used to format `allowedPacket` for Packetlist.read
* @param {Array<Object>} allowedClasses
* @returns {Object} map from enum.packet to corresponding *Packet class
*/
constructAllowedPackets: function(allowedClasses) {
const map = {};
allowedClasses.forEach(PacketClass => {
if (!PacketClass.tag) {
throw new Error('Invalid input: expected a packet class');
}
map[PacketClass.tag] = PacketClass;
});
return map;
} }
}; };

View File

@ -1,4 +1,4 @@
const aes_kw = require('../../src/crypto/aes_kw'); const aesKW = require('../../src/crypto/aes_kw');
const util = require('../../src/util'); const util = require('../../src/util');
const expect = require('chai').expect; const expect = require('chai').expect;
@ -47,11 +47,11 @@ module.exports = () => describe('AES Key Wrap and Unwrap', function () {
it(test[0], function(done) { it(test[0], function(done) {
const kek = util.hexToUint8Array(test[1]); const kek = util.hexToUint8Array(test[1]);
const input = test[2].replace(/\s/g, ""); const input = test[2].replace(/\s/g, "");
const input_bin = util.hexToStr(input); const input_bin = util.hexToString(input);
const output = test[3].replace(/\s/g, ""); const output = test[3].replace(/\s/g, "");
const output_bin = util.hexToStr(output); const output_bin = util.hexToString(output);
expect(util.uint8ArrayToHex(aes_kw.wrap(kek, input_bin)).toUpperCase()).to.equal(output); expect(util.uint8ArrayToHex(aesKW.wrap(kek, input_bin)).toUpperCase()).to.equal(output);
expect(util.uint8ArrayToHex(aes_kw.unwrap(kek, output_bin)).toUpperCase()).to.equal(input); expect(util.uint8ArrayToHex(aesKW.unwrap(kek, output_bin)).toUpperCase()).to.equal(input);
done(); done();
}); });
}); });

View File

@ -7,10 +7,10 @@ const { expect } = chai;
module.exports = () => it('Blowfish cipher test with test vectors from https://www.schneier.com/code/vectors.txt', function(done) { module.exports = () => it('Blowfish cipher test with test vectors from https://www.schneier.com/code/vectors.txt', function(done) {
function test_bf(input, key, output) { function test_bf(input, key, output) {
const blowfish = new BF(util.uint8ArrayToStr(key)); const blowfish = new BF(util.uint8ArrayToString(key));
const result = util.uint8ArrayToStr(blowfish.encrypt(input)); const result = util.uint8ArrayToString(blowfish.encrypt(input));
return (util.strToHex(result) === util.strToHex(util.uint8ArrayToStr(output))); return (util.stringToHex(result) === util.stringToHex(util.uint8ArrayToString(output)));
} }
const testvectors = [[[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78]], const testvectors = [[[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00],[0x4E,0xF9,0x97,0x45,0x61,0x98,0xDD,0x78]],

View File

@ -1,4 +1,4 @@
const Cast5 = require('../../../src/crypto/cipher/cast5'); const CAST5 = require('../../../src/crypto/cipher/cast5');
const util = require('../../../src/util'); const util = require('../../../src/util');
const chai = require('chai'); const chai = require('chai');
@ -7,10 +7,10 @@ const { expect } = chai;
module.exports = () => it('CAST-128 cipher test with test vectors from RFC2144', function (done) { module.exports = () => it('CAST-128 cipher test with test vectors from RFC2144', function (done) {
function test_cast(input, key, output) { function test_cast(input, key, output) {
const cast5 = new Cast5(key); const cast5 = new CAST5(key);
const result = util.uint8ArrayToStr(cast5.encrypt(input)); const result = util.uint8ArrayToString(cast5.encrypt(input));
return util.strToHex(result) === util.strToHex(util.uint8ArrayToStr(output)); return util.stringToHex(result) === util.stringToHex(util.uint8ArrayToString(output));
} }
const testvectors = [[[0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x23,0x8B,0x4F,0xE5,0x84,0x7E,0x44,0xB2]]]; const testvectors = [[[0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A],[0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF],[0x23,0x8B,0x4F,0xE5,0x84,0x7E,0x44,0xB2]]];

View File

@ -77,12 +77,12 @@ module.exports = () => describe('TripleDES (EDE) cipher test with test vectors f
for (let i = 0; i < testvectors.length; i++) { for (let i = 0; i < testvectors.length; i++) {
const des = new TripleDES(key); const des = new TripleDES(key);
const encr = util.uint8ArrayToStr(des.encrypt(testvectors[i][0], key)); const encr = util.uint8ArrayToString(des.encrypt(testvectors[i][0], key));
expect(encr, 'vector with block ' + util.uint8ArrayToHex(testvectors[i][0]) + expect(encr, 'vector with block ' + util.uint8ArrayToHex(testvectors[i][0]) +
' and key ' + util.strToHex(util.uint8ArrayToStr(key)) + ' and key ' + util.stringToHex(util.uint8ArrayToString(key)) +
' should be ' + util.uint8ArrayToHex(testvectors[i][1]) + ' should be ' + util.uint8ArrayToHex(testvectors[i][1]) +
' != ' + util.uint8ArrayToHex(encr)).to.be.equal(util.uint8ArrayToStr(testvectors[i][1])); ' != ' + util.uint8ArrayToHex(encr)).to.be.equal(util.uint8ArrayToString(testvectors[i][1]));
} }
done(); done();
}); });
@ -124,18 +124,18 @@ module.exports = () => describe('TripleDES (EDE) cipher test with test vectors f
const encrypted = des.encrypt(thisVectorSet[i][0], padding); const encrypted = des.encrypt(thisVectorSet[i][0], padding);
const decrypted = des.decrypt(encrypted, padding); const decrypted = des.decrypt(encrypted, padding);
expect(util.uint8ArrayToStr(encrypted), 'vector with block [' + util.uint8ArrayToHex(thisVectorSet[i][0]) + expect(util.uint8ArrayToString(encrypted), 'vector with block [' + util.uint8ArrayToHex(thisVectorSet[i][0]) +
'] and key [' + util.strToHex(util.uint8ArrayToStr(key)) + '] and key [' + util.stringToHex(util.uint8ArrayToString(key)) +
'] and padding [' + padding + '] and padding [' + padding +
'] should be ' + util.uint8ArrayToHex(thisVectorSet[i][1]) + '] should be ' + util.uint8ArrayToHex(thisVectorSet[i][1]) +
' - Actually [' + util.uint8ArrayToHex(encrypted) + ' - Actually [' + util.uint8ArrayToHex(encrypted) +
']').to.equal(util.uint8ArrayToStr(thisVectorSet[i][1])); ']').to.equal(util.uint8ArrayToString(thisVectorSet[i][1]));
expect(util.uint8ArrayToStr(decrypted), 'vector with block [' + util.uint8ArrayToHex(thisVectorSet[i][0]) + expect(util.uint8ArrayToString(decrypted), 'vector with block [' + util.uint8ArrayToHex(thisVectorSet[i][0]) +
'] and key [' + util.strToHex(util.uint8ArrayToStr(key)) + '] and key [' + util.stringToHex(util.uint8ArrayToString(key)) +
'] and padding [' + padding + '] and padding [' + padding +
'] should be ' + util.uint8ArrayToHex(thisVectorSet[i][0]) + '] should be ' + util.uint8ArrayToHex(thisVectorSet[i][0]) +
' - Actually [' + util.uint8ArrayToHex(decrypted) + ' - Actually [' + util.uint8ArrayToHex(decrypted) +
']').to.equal(util.uint8ArrayToStr(thisVectorSet[i][0])); ']').to.equal(util.uint8ArrayToString(thisVectorSet[i][0]));
} }
} }
done(); done();

View File

@ -7,7 +7,7 @@ const { expect } = chai;
module.exports = () => it('Twofish with test vectors from https://www.schneier.com/code/ecb_ival.txt', function(done) { module.exports = () => it('Twofish with test vectors from https://www.schneier.com/code/ecb_ival.txt', function(done) {
function tfencrypt(block, key) { function tfencrypt(block, key) {
const tf = new TF(util.strToUint8Array(key)); const tf = new TF(util.stringToUint8Array(key));
return tf.encrypt(block); return tf.encrypt(block);
} }
@ -36,34 +36,34 @@ module.exports = () => it('Twofish with test vectors from https://www.schneier.c
if (i === 0) { if (i === 0) {
blk = start_short; blk = start_short;
key = util.uint8ArrayToStr(start); key = util.uint8ArrayToString(start);
ct = testvectors[0]; ct = testvectors[0];
res = util.uint8ArrayToStr(tfencrypt(blk,key)); res = util.uint8ArrayToString(tfencrypt(blk,key));
exp = util.uint8ArrayToStr(ct); exp = util.uint8ArrayToString(ct);
} else if (i === 1) { } else if (i === 1) {
blk = testvectors[0]; blk = testvectors[0];
key = util.uint8ArrayToStr(start); key = util.uint8ArrayToString(start);
ct = testvectors[1]; ct = testvectors[1];
res = util.uint8ArrayToStr(tfencrypt(blk,key)); res = util.uint8ArrayToString(tfencrypt(blk,key));
exp = util.uint8ArrayToStr(ct); exp = util.uint8ArrayToString(ct);
} else if (i === 2) { } else if (i === 2) {
blk = testvectors[i - 1]; blk = testvectors[i - 1];
key = util.uint8ArrayToStr(testvectors[i - 2].concat(start_short)); key = util.uint8ArrayToString(testvectors[i - 2].concat(start_short));
ct = testvectors[i]; ct = testvectors[i];
res = util.uint8ArrayToStr(tfencrypt(blk,key)); res = util.uint8ArrayToString(tfencrypt(blk,key));
exp = util.uint8ArrayToStr(ct); exp = util.uint8ArrayToString(ct);
} else if (i < 10 || i > 46) { } else if (i < 10 || i > 46) {
blk = testvectors[i - 1]; blk = testvectors[i - 1];
key = util.uint8ArrayToStr(testvectors[i - 2].concat(testvectors[i - 3])); key = util.uint8ArrayToString(testvectors[i - 2].concat(testvectors[i - 3]));
ct = testvectors[i]; ct = testvectors[i];
res = util.uint8ArrayToStr(tfencrypt(blk,key)); res = util.uint8ArrayToString(tfencrypt(blk,key));
exp = util.uint8ArrayToStr(ct); exp = util.uint8ArrayToString(ct);
} else { } else {
testvectors[i] = tfencrypt(testvectors[i - 1],util.uint8ArrayToStr(testvectors[i - 2].concat(testvectors[i - 3]))); testvectors[i] = tfencrypt(testvectors[i - 1],util.uint8ArrayToString(testvectors[i - 2].concat(testvectors[i - 3])));
continue; continue;
} }
expect(res, 'vector with block ' + util.uint8ArrayToHex(blk) + expect(res, 'vector with block ' + util.uint8ArrayToHex(blk) +
' with key ' + util.strToHex(key) + ' with key ' + util.stringToHex(key) +
' should be ' + util.uint8ArrayToHex(ct) + ' should be ' + util.uint8ArrayToHex(ct) +
' but is ' + util.uint8ArrayToHex(tfencrypt(blk,key))).to.equal(exp); ' but is ' + util.uint8ArrayToHex(tfencrypt(blk,key))).to.equal(exp);
} }

View File

@ -207,7 +207,7 @@ module.exports = () => describe('API functional testing', function() {
const elGamalPublicParams = crypto.parsePublicKeyParams(algoElGamal, elGamalPublicKeyMaterial).publicParams; const elGamalPublicParams = crypto.parsePublicKeyParams(algoElGamal, elGamalPublicKeyMaterial).publicParams;
const elGamalPrivateParams = crypto.parsePrivateKeyParams(algoElGamal, elGamalPrivateKeyMaterial).privateParams; const elGamalPrivateParams = crypto.parsePrivateKeyParams(algoElGamal, elGamalPrivateKeyMaterial).privateParams;
const data = util.strToUint8Array("foobar"); const data = util.stringToUint8Array("foobar");
describe('Sign and verify', function () { describe('Sign and verify', function () {
it('RSA', async function () { it('RSA', async function () {
@ -242,8 +242,8 @@ module.exports = () => describe('API functional testing', function() {
await Promise.all(symmAlgos.map(async function(algo) { await Promise.all(symmAlgos.map(async function(algo) {
const symmKey = await crypto.generateSessionKey(algo); const symmKey = await crypto.generateSessionKey(algo);
const IV = new Uint8Array(crypto.cipher[algo].blockSize); const IV = new Uint8Array(crypto.cipher[algo].blockSize);
const symmencData = await crypto.cfb.encrypt(algo, symmKey, util.strToUint8Array(plaintext), IV, openpgp.config); const symmencData = await crypto.mode.cfb.encrypt(algo, symmKey, util.stringToUint8Array(plaintext), IV, openpgp.config);
const text = util.uint8ArrayToStr(await crypto.cfb.decrypt(algo, symmKey, symmencData, new Uint8Array(crypto.cipher[algo].blockSize))); const text = util.uint8ArrayToString(await crypto.mode.cfb.decrypt(algo, symmKey, symmencData, new Uint8Array(crypto.cipher[algo].blockSize)));
expect(text).to.equal(plaintext); expect(text).to.equal(plaintext);
})); }));
} }

View File

@ -2,7 +2,7 @@
// Adapted from https://github.com/artjomb/cryptojs-extension/blob/8c61d159/test/eax.js // Adapted from https://github.com/artjomb/cryptojs-extension/blob/8c61d159/test/eax.js
const EAX = require('../../src/crypto/eax'); const EAX = require('../../src/crypto/mode/eax');
const util = require('../../src/util'); const util = require('../../src/util');
const sandbox = require('sinon/lib/sinon/sandbox'); const sandbox = require('sinon/lib/sinon/sandbox');

View File

@ -16,7 +16,7 @@ const key_data = elliptic_data.key_data;
module.exports = () => describe('ECDH key exchange @lightweight', function () { module.exports = () => describe('ECDH key exchange @lightweight', function () {
const decrypt_message = function (oid, hash, cipher, priv, pub, ephemeral, data, fingerprint) { const decrypt_message = function (oid, hash, cipher, priv, pub, ephemeral, data, fingerprint) {
if (util.isString(data)) { if (util.isString(data)) {
data = util.strToUint8Array(data); data = util.stringToUint8Array(data);
} else { } else {
data = new Uint8Array(data); data = new Uint8Array(data);
} }
@ -143,7 +143,7 @@ module.exports = () => describe('ECDH key exchange @lightweight', function () {
const curve = new elliptic_curves.Curve('secp256k1'); const curve = new elliptic_curves.Curve('secp256k1');
const oid = new OID(curve.oid); const oid = new OID(curve.oid);
const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher });
const data = util.strToUint8Array('test'); const data = util.stringToUint8Array('test');
expect( expect(
ecdh.encrypt(oid, kdfParams, data, Q1, fingerprint1) ecdh.encrypt(oid, kdfParams, data, Q1, fingerprint1)
).to.be.rejectedWith(Error, /Public key is not valid for specified curve|Failed to translate Buffer to a EC_POINT|Unknown point format/); ).to.be.rejectedWith(Error, /Public key is not valid for specified curve|Failed to translate Buffer to a EC_POINT|Unknown point format/);
@ -152,7 +152,7 @@ module.exports = () => describe('ECDH key exchange @lightweight', function () {
const curve = new elliptic_curves.Curve('curve25519'); const curve = new elliptic_curves.Curve('curve25519');
const oid = new OID(curve.oid); const oid = new OID(curve.oid);
const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher });
const data = util.strToUint8Array('test'); const data = util.stringToUint8Array('test');
const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q1, fingerprint1); const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q1, fingerprint1);
await expect( await expect(
ecdh.decrypt(oid, kdfParams, V, C, Q2, d2, fingerprint1) ecdh.decrypt(oid, kdfParams, V, C, Q2, d2, fingerprint1)
@ -162,7 +162,7 @@ module.exports = () => describe('ECDH key exchange @lightweight', function () {
const curve = new elliptic_curves.Curve('curve25519'); const curve = new elliptic_curves.Curve('curve25519');
const oid = new OID(curve.oid); const oid = new OID(curve.oid);
const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher });
const data = util.strToUint8Array('test'); const data = util.stringToUint8Array('test');
const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q2, fingerprint1); const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q2, fingerprint1);
await expect( await expect(
ecdh.decrypt(oid, kdfParams, V, C, Q2, d2, fingerprint2) ecdh.decrypt(oid, kdfParams, V, C, Q2, d2, fingerprint2)
@ -172,7 +172,7 @@ module.exports = () => describe('ECDH key exchange @lightweight', function () {
const curve = new elliptic_curves.Curve('curve25519'); const curve = new elliptic_curves.Curve('curve25519');
const oid = new OID(curve.oid); const oid = new OID(curve.oid);
const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher });
const data = util.strToUint8Array('test'); const data = util.stringToUint8Array('test');
const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q1, fingerprint1); const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q1, fingerprint1);
expect(await ecdh.decrypt(oid, kdfParams, V, C, Q1, d1, fingerprint1)).to.deep.equal(data); expect(await ecdh.decrypt(oid, kdfParams, V, C, Q1, d1, fingerprint1)).to.deep.equal(data);
}); });
@ -182,7 +182,7 @@ module.exports = () => describe('ECDH key exchange @lightweight', function () {
const curve = new elliptic_curves.Curve(curveName); const curve = new elliptic_curves.Curve(curveName);
const oid = new OID(curve.oid); const oid = new OID(curve.oid);
const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher });
const data = util.strToUint8Array('test'); const data = util.stringToUint8Array('test');
const Q = key_data[curveName].pub; const Q = key_data[curveName].pub;
const d = key_data[curveName].priv; const d = key_data[curveName].priv;
const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q, fingerprint1); const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q, fingerprint1);
@ -225,7 +225,7 @@ module.exports = () => describe('ECDH key exchange @lightweight', function () {
const curve = new elliptic_curves.Curve(curveName); const curve = new elliptic_curves.Curve(curveName);
const oid = new OID(curve.oid); const oid = new OID(curve.oid);
const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher }); const kdfParams = new KDFParams({ hash: curve.hash, cipher: curve.cipher });
const data = util.strToUint8Array('test'); const data = util.stringToUint8Array('test');
const Q = key_data[curveName].pub; const Q = key_data[curveName].pub;
const d = key_data[curveName].priv; const d = key_data[curveName].priv;
const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q, fingerprint1); const { publicKey: V, wrappedKey: C } = await ecdh.encrypt(oid, kdfParams, data, Q, fingerprint1);

View File

@ -125,7 +125,7 @@ module.exports = () => describe('Elliptic Curve Cryptography @lightweight', func
const verify_signature = async function (oid, hash, r, s, message, pub) { const verify_signature = async function (oid, hash, r, s, message, pub) {
if (util.isString(message)) { if (util.isString(message)) {
message = util.strToUint8Array(message); message = util.stringToUint8Array(message);
} else if (!util.isUint8Array(message)) { } else if (!util.isUint8Array(message)) {
message = new Uint8Array(message); message = new Uint8Array(message);
} }

View File

@ -45,22 +45,22 @@ module.exports = () => describe('Symmetric AES-GCM (experimental)', function() {
this.skip(); // eslint-disable-line no-invalid-this this.skip(); // eslint-disable-line no-invalid-this
} }
const key = await crypto.generateSessionKey(algo); const key = await crypto.generateSessionKey(algo);
const iv = await crypto.random.getRandomBytes(crypto.gcm.ivLength); const iv = await crypto.random.getRandomBytes(crypto.mode.gcm.ivLength);
const nativeEncryptSpy = webCrypto ? sinonSandbox.spy(webCrypto, 'encrypt') : sinonSandbox.spy(nodeCrypto, 'createCipheriv'); const nativeEncryptSpy = webCrypto ? sinonSandbox.spy(webCrypto, 'encrypt') : sinonSandbox.spy(nodeCrypto, 'createCipheriv');
const nativeDecryptSpy = webCrypto ? sinonSandbox.spy(webCrypto, 'decrypt') : sinonSandbox.spy(nodeCrypto, 'createDecipheriv'); const nativeDecryptSpy = webCrypto ? sinonSandbox.spy(webCrypto, 'decrypt') : sinonSandbox.spy(nodeCrypto, 'createDecipheriv');
nativeEncrypt || disableNative(); nativeEncrypt || disableNative();
let modeInstance = await crypto.gcm(algo, key); let modeInstance = await crypto.mode.gcm(algo, key);
const ciphertext = await modeInstance.encrypt(util.strToUint8Array(plaintext), iv); const ciphertext = await modeInstance.encrypt(util.stringToUint8Array(plaintext), iv);
enableNative(); enableNative();
nativeDecrypt || disableNative(); nativeDecrypt || disableNative();
modeInstance = await crypto.gcm(algo, key); modeInstance = await crypto.mode.gcm(algo, key);
const decrypted = await modeInstance.decrypt(util.strToUint8Array(util.uint8ArrayToStr(ciphertext)), iv); const decrypted = await modeInstance.decrypt(util.stringToUint8Array(util.uint8ArrayToString(ciphertext)), iv);
enableNative(); enableNative();
const decryptedStr = util.uint8ArrayToStr(decrypted); const decryptedStr = util.uint8ArrayToString(decrypted);
expect(decryptedStr).to.equal(plaintext); expect(decryptedStr).to.equal(plaintext);
if (algo !== 'aes192') { // not implemented by webcrypto if (algo !== 'aes192') { // not implemented by webcrypto

View File

@ -6,10 +6,10 @@ const chai = require('chai');
const { expect } = chai; const { expect } = chai;
module.exports = () => it('MD5 with test vectors from RFC 1321', async function() { module.exports = () => it('MD5 with test vectors from RFC 1321', async function() {
expect(util.strToHex(util.uint8ArrayToStr(await md5(util.strToUint8Array(''))), 'MD5("") = d41d8cd98f00b204e9800998ecf8427e')).to.equal('d41d8cd98f00b204e9800998ecf8427e'); expect(util.stringToHex(util.uint8ArrayToString(await md5(util.stringToUint8Array(''))), 'MD5("") = d41d8cd98f00b204e9800998ecf8427e')).to.equal('d41d8cd98f00b204e9800998ecf8427e');
expect(util.strToHex(util.uint8ArrayToStr(await md5(util.strToUint8Array('abc'))), 'MD5("a") = 0cc175b9c0f1b6a831c399e269772661')).to.equal('900150983cd24fb0d6963f7d28e17f72'); expect(util.stringToHex(util.uint8ArrayToString(await md5(util.stringToUint8Array('abc'))), 'MD5("a") = 0cc175b9c0f1b6a831c399e269772661')).to.equal('900150983cd24fb0d6963f7d28e17f72');
expect(util.strToHex(util.uint8ArrayToStr(await md5(util.strToUint8Array('message digest'))), 'MD5("message digest") = f96b697d7cb7938d525a2f31aaf161d0')).to.equal('f96b697d7cb7938d525a2f31aaf161d0'); expect(util.stringToHex(util.uint8ArrayToString(await md5(util.stringToUint8Array('message digest'))), 'MD5("message digest") = f96b697d7cb7938d525a2f31aaf161d0')).to.equal('f96b697d7cb7938d525a2f31aaf161d0');
expect(util.strToHex(util.uint8ArrayToStr(await md5(util.strToUint8Array('abcdefghijklmnopqrstuvwxyz'))), 'MD5("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b')).to.equal('c3fcd3d76192e4007dfb496cca67e13b'); expect(util.stringToHex(util.uint8ArrayToString(await md5(util.stringToUint8Array('abcdefghijklmnopqrstuvwxyz'))), 'MD5("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b')).to.equal('c3fcd3d76192e4007dfb496cca67e13b');
expect(util.strToHex(util.uint8ArrayToStr(await md5(util.strToUint8Array('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'))), 'MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f')).to.equal('d174ab98d277d9f5a5611c2c9f419d9f'); expect(util.stringToHex(util.uint8ArrayToString(await md5(util.stringToUint8Array('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'))), 'MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = d174ab98d277d9f5a5611c2c9f419d9f')).to.equal('d174ab98d277d9f5a5611c2c9f419d9f');
expect(util.strToHex(util.uint8ArrayToStr(await md5(util.strToUint8Array('12345678901234567890123456789012345678901234567890123456789012345678901234567890'))), 'MD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a')).to.equal('57edf4a22be3c955ac49da2e2107b67a'); expect(util.stringToHex(util.uint8ArrayToString(await md5(util.stringToUint8Array('12345678901234567890123456789012345678901234567890123456789012345678901234567890'))), 'MD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890") = 57edf4a22be3c955ac49da2e2107b67a')).to.equal('57edf4a22be3c955ac49da2e2107b67a');
}); });

View File

@ -6,8 +6,8 @@ const chai = require('chai');
const { expect } = chai; const { expect } = chai;
module.exports = () => it("RIPE-MD 160 bits with test vectors from https://homes.esat.kuleuven.be/~bosselae/ripemd160.html", async function() { module.exports = () => it("RIPE-MD 160 bits with test vectors from https://homes.esat.kuleuven.be/~bosselae/ripemd160.html", async function() {
expect(util.strToHex(util.uint8ArrayToStr(await rmdString(util.strToUint8Array(''))), 'RMDstring("") = 9c1185a5c5e9fc54612808977ee8f548b2258d31')).to.equal('9c1185a5c5e9fc54612808977ee8f548b2258d31'); expect(util.stringToHex(util.uint8ArrayToString(await rmdString(util.stringToUint8Array(''))), 'RMDstring("") = 9c1185a5c5e9fc54612808977ee8f548b2258d31')).to.equal('9c1185a5c5e9fc54612808977ee8f548b2258d31');
expect(util.strToHex(util.uint8ArrayToStr(await rmdString(util.strToUint8Array('a'))), 'RMDstring("a") = 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe')).to.equal('0bdc9d2d256b3ee9daae347be6f4dc835a467ffe'); expect(util.stringToHex(util.uint8ArrayToString(await rmdString(util.stringToUint8Array('a'))), 'RMDstring("a") = 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe')).to.equal('0bdc9d2d256b3ee9daae347be6f4dc835a467ffe');
expect(util.strToHex(util.uint8ArrayToStr(await rmdString(util.strToUint8Array('abc'))), 'RMDstring("abc") = 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc')).to.equal('8eb208f7e05d987a9b044a8e98c6b087f15a0bfc'); expect(util.stringToHex(util.uint8ArrayToString(await rmdString(util.stringToUint8Array('abc'))), 'RMDstring("abc") = 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc')).to.equal('8eb208f7e05d987a9b044a8e98c6b087f15a0bfc');
expect(util.strToHex(util.uint8ArrayToStr(await rmdString(util.strToUint8Array('message digest'))), 'RMDstring("message digest") = 5d0689ef49d2fae572b881b123a85ffa21595f36')).to.equal('5d0689ef49d2fae572b881b123a85ffa21595f36'); expect(util.stringToHex(util.uint8ArrayToString(await rmdString(util.stringToUint8Array('message digest'))), 'RMDstring("message digest") = 5d0689ef49d2fae572b881b123a85ffa21595f36')).to.equal('5d0689ef49d2fae572b881b123a85ffa21595f36');
}); });

View File

@ -6,14 +6,14 @@ const chai = require('chai');
const { expect } = chai; const { expect } = chai;
module.exports = () => it('SHA* with test vectors from NIST FIPS 180-2', async function() { module.exports = () => it('SHA* with test vectors from NIST FIPS 180-2', async function() {
expect(util.strToHex(util.uint8ArrayToStr(await hash.sha1(util.strToUint8Array('abc'))), 'hash.sha1("abc") = a9993e364706816aba3e25717850c26c9cd0d89d')).to.equal('a9993e364706816aba3e25717850c26c9cd0d89d'); expect(util.stringToHex(util.uint8ArrayToString(await hash.sha1(util.stringToUint8Array('abc'))), 'hash.sha1("abc") = a9993e364706816aba3e25717850c26c9cd0d89d')).to.equal('a9993e364706816aba3e25717850c26c9cd0d89d');
expect(util.strToHex(util.uint8ArrayToStr(await hash.sha1(util.strToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'))), 'hash.sha1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 84983e441c3bd26ebaae4aa1f95129e5e54670f1')).to.equal('84983e441c3bd26ebaae4aa1f95129e5e54670f1'); expect(util.stringToHex(util.uint8ArrayToString(await hash.sha1(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'))), 'hash.sha1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 84983e441c3bd26ebaae4aa1f95129e5e54670f1')).to.equal('84983e441c3bd26ebaae4aa1f95129e5e54670f1');
expect(util.strToHex(util.uint8ArrayToStr(await hash.sha224(util.strToUint8Array('abc'))), 'hash.sha224("abc") = 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7')).to.equal('23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7'); expect(util.stringToHex(util.uint8ArrayToString(await hash.sha224(util.stringToUint8Array('abc'))), 'hash.sha224("abc") = 23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7')).to.equal('23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7');
expect(util.strToHex(util.uint8ArrayToStr(await hash.sha224(util.strToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'))), 'hash.sha224("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525')).to.equal('75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525'); expect(util.stringToHex(util.uint8ArrayToString(await hash.sha224(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'))), 'hash.sha224("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525')).to.equal('75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525');
expect(util.strToHex(util.uint8ArrayToStr(await hash.sha256(util.strToUint8Array('abc'))), 'hash.sha256("abc") = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad')).to.equal('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad'); expect(util.stringToHex(util.uint8ArrayToString(await hash.sha256(util.stringToUint8Array('abc'))), 'hash.sha256("abc") = ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad')).to.equal('ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad');
expect(util.strToHex(util.uint8ArrayToStr(await hash.sha256(util.strToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'))), 'hash.sha256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1')).to.equal('248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1'); expect(util.stringToHex(util.uint8ArrayToString(await hash.sha256(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'))), 'hash.sha256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1')).to.equal('248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1');
expect(util.strToHex(util.uint8ArrayToStr(await hash.sha384(util.strToUint8Array('abc'))), 'hash.sha384("abc") = cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7')).to.equal('cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7'); expect(util.stringToHex(util.uint8ArrayToString(await hash.sha384(util.stringToUint8Array('abc'))), 'hash.sha384("abc") = cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7')).to.equal('cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7');
expect(util.strToHex(util.uint8ArrayToStr(await hash.sha384(util.strToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'))), 'hash.sha384("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b')).to.equal('3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b'); expect(util.stringToHex(util.uint8ArrayToString(await hash.sha384(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'))), 'hash.sha384("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b')).to.equal('3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b');
expect(util.strToHex(util.uint8ArrayToStr(await hash.sha512(util.strToUint8Array('abc'))), 'hash.sha512("abc") = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f')).to.equal('ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f'); expect(util.stringToHex(util.uint8ArrayToString(await hash.sha512(util.stringToUint8Array('abc'))), 'hash.sha512("abc") = ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f')).to.equal('ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f');
expect(util.strToHex(util.uint8ArrayToStr(await hash.sha512(util.strToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'))), 'hash.sha512("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445')).to.equal('204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445'); expect(util.stringToHex(util.uint8ArrayToString(await hash.sha512(util.stringToUint8Array('abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq'))), 'hash.sha512("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445')).to.equal('204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445');
}); });

View File

@ -2,7 +2,7 @@
// Adapted from https://github.com/artjomb/cryptojs-extension/blob/8c61d159/test/eax.js // Adapted from https://github.com/artjomb/cryptojs-extension/blob/8c61d159/test/eax.js
const OCB = require('../../src/crypto/ocb'); const OCB = require('../../src/crypto/mode/ocb');
const util = require('../../src/util'); const util = require('../../src/util');
const chai = require('chai'); const chai = require('chai');

View File

@ -53,12 +53,12 @@ module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptogra
const bits = 1024; const bits = 1024;
const { publicParams, privateParams } = await crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits); const { publicParams, privateParams } = await crypto.generateParams(openpgp.enums.publicKey.rsaSign, bits);
const message = await random.getRandomBytes(64); const message = await random.getRandomBytes(64);
const hash_algo = openpgp.enums.write(openpgp.enums.hash, 'sha256'); const hashAlgo = openpgp.enums.write(openpgp.enums.hash, 'sha256');
const hashed = await crypto.hash.digest(hash_algo, message); const hashed = await crypto.hash.digest(hashAlgo, message);
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams }; const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
const signature = await crypto.publicKey.rsa.sign(hash_algo, message, n, e, d, p, q, u, hashed); const signature = await crypto.publicKey.rsa.sign(hashAlgo, message, n, e, d, p, q, u, hashed);
expect(signature).to.exist; expect(signature).to.exist;
const verify = await crypto.publicKey.rsa.verify(hash_algo, message, signature, n, e, hashed); const verify = await crypto.publicKey.rsa.verify(hashAlgo, message, signature, n, e, hashed);
expect(verify).to.be.true; expect(verify).to.be.true;
}); });
@ -97,12 +97,12 @@ module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptogra
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams }; const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
const message = await random.getRandomBytes(64); const message = await random.getRandomBytes(64);
const hashName = 'sha256'; const hashName = 'sha256';
const hash_algo = openpgp.enums.write(openpgp.enums.hash, hashName); const hashAlgo = openpgp.enums.write(openpgp.enums.hash, hashName);
const hashed = await crypto.hash.digest(hash_algo, message); const hashed = await crypto.hash.digest(hashAlgo, message);
enableNative(); enableNative();
const signatureNative = await crypto.publicKey.rsa.sign(hash_algo, message, n, e, d, p, q, u, hashed); const signatureNative = await crypto.publicKey.rsa.sign(hashAlgo, message, n, e, d, p, q, u, hashed);
disableNative(); disableNative();
const signatureBN = await crypto.publicKey.rsa.sign(hash_algo, message, n, e, d, p, q, u, hashed); const signatureBN = await crypto.publicKey.rsa.sign(hashAlgo, message, n, e, d, p, q, u, hashed);
expect(util.uint8ArrayToHex(signatureNative)).to.be.equal(util.uint8ArrayToHex(signatureBN)); expect(util.uint8ArrayToHex(signatureNative)).to.be.equal(util.uint8ArrayToHex(signatureBN));
}); });
@ -112,13 +112,13 @@ module.exports = () => (!native ? describe.skip : describe)('basic RSA cryptogra
const { n, e, d, p, q, u } = { ...publicParams, ...privateParams }; const { n, e, d, p, q, u } = { ...publicParams, ...privateParams };
const message = await random.getRandomBytes(64); const message = await random.getRandomBytes(64);
const hashName = 'sha256'; const hashName = 'sha256';
const hash_algo = openpgp.enums.write(openpgp.enums.hash, hashName); const hashAlgo = openpgp.enums.write(openpgp.enums.hash, hashName);
const hashed = await crypto.hash.digest(hash_algo, message); const hashed = await crypto.hash.digest(hashAlgo, message);
enableNative(); enableNative();
const signatureNative = await crypto.publicKey.rsa.sign(hash_algo, message, n, e, d, p, q, u, hashed); const signatureNative = await crypto.publicKey.rsa.sign(hashAlgo, message, n, e, d, p, q, u, hashed);
const verifyNative = await crypto.publicKey.rsa.verify(hash_algo, message, signatureNative, n, e); const verifyNative = await crypto.publicKey.rsa.verify(hashAlgo, message, signatureNative, n, e);
disableNative(); disableNative();
const verifyBN = await crypto.publicKey.rsa.verify(hash_algo, message, signatureNative, n, e, hashed); const verifyBN = await crypto.publicKey.rsa.verify(hashAlgo, message, signatureNative, n, e, hashed);
expect(verifyNative).to.be.true; expect(verifyNative).to.be.true;
expect(verifyBN).to.be.true; expect(verifyBN).to.be.true;
}); });

View File

@ -85,7 +85,7 @@ module.exports = () => {
describe('EdDSA parameter validation', function() { describe('EdDSA parameter validation', function() {
let eddsaKey; let eddsaKey;
before(async () => { before(async () => {
eddsaKey = (await openpgp.generateKey({ curve: 'ed25519', userIds: [{ name: 'Test', email: 'test@test.com' }] })).key; eddsaKey = (await openpgp.generateKey({ curve: 'ed25519', userIDs: [{ name: 'Test', email: 'test@test.com' }] })).key;
}); });
it('EdDSA params should be valid', async function() { it('EdDSA params should be valid', async function() {
@ -109,9 +109,9 @@ module.exports = () => {
let ecdhKey; let ecdhKey;
let ecdsaKey; let ecdsaKey;
before(async () => { before(async () => {
eddsaKey = (await openpgp.generateKey({ curve: 'ed25519', userIds: [{ name: 'Test', email: 'test@test.com' }] })).key; eddsaKey = (await openpgp.generateKey({ curve: 'ed25519', userIDs: [{ name: 'Test', email: 'test@test.com' }] })).key;
ecdhKey = eddsaKey.subKeys[0]; ecdhKey = eddsaKey.subKeys[0];
ecdsaKey = (await openpgp.generateKey({ curve: 'p256', userIds: [{ name: 'Test', email: 'test@test.com' }] })).key; ecdsaKey = (await openpgp.generateKey({ curve: 'p256', userIDs: [{ name: 'Test', email: 'test@test.com' }] })).key;
}); });
it('EdDSA params are not valid for ECDH', async function() { it('EdDSA params are not valid for ECDH', async function() {
@ -194,10 +194,10 @@ module.exports = () => {
let ecdhKey; let ecdhKey;
before(async () => { before(async () => {
if (curve !== 'curve25519') { if (curve !== 'curve25519') {
ecdsaKey = (await openpgp.generateKey({ curve, userIds: [{ name: 'Test', email: 'test@test.com' }] })).key; ecdsaKey = (await openpgp.generateKey({ curve, userIDs: [{ name: 'Test', email: 'test@test.com' }] })).key;
ecdhKey = ecdsaKey.subKeys[0]; ecdhKey = ecdsaKey.subKeys[0];
} else { } else {
const eddsaKey = (await openpgp.generateKey({ curve: 'ed25519', userIds: [{ name: 'Test', email: 'test@test.com' }] })).key; const eddsaKey = (await openpgp.generateKey({ curve: 'ed25519', userIDs: [{ name: 'Test', email: 'test@test.com' }] })).key;
ecdhKey = eddsaKey.subKeys[0]; ecdhKey = eddsaKey.subKeys[0];
} }
}); });
@ -244,7 +244,7 @@ module.exports = () => {
describe('RSA parameter validation', function() { describe('RSA parameter validation', function() {
let rsaKey; let rsaKey;
before(async () => { before(async () => {
rsaKey = (await openpgp.generateKey({ type: 'rsa', rsaBits: 2048, userIds: [{ name: 'Test', email: 'test@test.com' }] })).key; rsaKey = (await openpgp.generateKey({ type: 'rsa', rsaBits: 2048, userIDs: [{ name: 'Test', email: 'test@test.com' }] })).key;
}); });
it('generated RSA params are valid', async function() { it('generated RSA params are valid', async function() {

View File

@ -174,7 +174,7 @@ EJ4QcD/oQ6x1M/8X/iKQCtxZP8RnlrbH7ExkNON5s5g=
return data[name].pub_key; return data[name].pub_key;
} }
const pub = await openpgp.readKey({ armoredKey: data[name].pub }); const pub = await openpgp.readKey({ armoredKey: data[name].pub });
expect(pub.getKeyId().toHex()).to.equal(data[name].id); expect(pub.getKeyID().toHex()).to.equal(data[name].id);
data[name].pub_key = pub; data[name].pub_key = pub;
return pub; return pub;
} }
@ -184,7 +184,7 @@ EJ4QcD/oQ6x1M/8X/iKQCtxZP8RnlrbH7ExkNON5s5g=
} }
const pk = await openpgp.readKey({ armoredKey: data[name].priv }); const pk = await openpgp.readKey({ armoredKey: data[name].priv });
expect(pk).to.exist; expect(pk).to.exist;
expect(pk.getKeyId().toHex()).to.equal(data[name].id); expect(pk.getKeyID().toHex()).to.equal(data[name].id);
await pk.decrypt(data[name].pass); await pk.decrypt(data[name].pass);
data[name].priv_key = pk; data[name].priv_key = pk;
return pk; return pk;
@ -283,10 +283,10 @@ function omnibus() {
const testData = input.createSomeMessage(); const testData = input.createSomeMessage();
const testData2 = input.createSomeMessage(); const testData2 = input.createSomeMessage();
const firstKey = await openpgp.generateKey({ userIds: { name: "Hi", email: "hi@hel.lo" }, curve: "brainpoolP256r1" }); const firstKey = await openpgp.generateKey({ userIDs: { name: "Hi", email: "hi@hel.lo" }, curve: "brainpoolP256r1" });
const hi = firstKey.key; const hi = firstKey.key;
const pubHi = hi.toPublic(); const pubHi = hi.toPublic();
const secondKey = await openpgp.generateKey({ userIds: { name: "Bye", email: "bye@good.bye" }, curve: "brainpoolP256r1" }); const secondKey = await openpgp.generateKey({ userIDs: { name: "Bye", email: "bye@good.bye" }, curve: "brainpoolP256r1" });
const bye = secondKey.key; const bye = secondKey.key;
const pubBye = bye.toPublic(); const pubBye = bye.toPublic();

View File

@ -13,7 +13,7 @@ module.exports = () => describe('Custom configuration', function() {
try { try {
const opt = { const opt = {
userIds: { name: 'Test User', email: 'text@example.com' } userIDs: { name: 'Test User', email: 'text@example.com' }
}; };
const { key, privateKeyArmored } = await openpgp.generateKey(opt); const { key, privateKeyArmored } = await openpgp.generateKey(opt);
expect(key.keyPacket.version).to.equal(4); expect(key.keyPacket.version).to.equal(4);
@ -26,7 +26,7 @@ module.exports = () => describe('Custom configuration', function() {
preferredHashAlgorithm: openpgp.enums.hash.sha512 preferredHashAlgorithm: openpgp.enums.hash.sha512
}; };
const opt2 = { const opt2 = {
userIds: { name: 'Test User', email: 'text@example.com' }, userIDs: { name: 'Test User', email: 'text@example.com' },
config config
}; };
const { key: key2, privateKeyArmored: privateKeyArmored2 } = await openpgp.generateKey(opt2); const { key: key2, privateKeyArmored: privateKeyArmored2 } = await openpgp.generateKey(opt2);
@ -49,10 +49,10 @@ module.exports = () => describe('Custom configuration', function() {
openpgp.config.showComment = false; openpgp.config.showComment = false;
try { try {
const userIds = { name: 'Test User', email: 'text2@example.com' }; const userIDs = { name: 'Test User', email: 'text2@example.com' };
const { key: origKey } = await openpgp.generateKey({ userIds }); const { key: origKey } = await openpgp.generateKey({ userIDs });
const opt = { privateKey: origKey, userIds }; const opt = { privateKey: origKey, userIDs };
const { key: refKey, privateKeyArmored: refKeyArmored } = await openpgp.reformatKey(opt); const { key: refKey, privateKeyArmored: refKeyArmored } = await openpgp.reformatKey(opt);
const prefs = refKey.users[0].selfCertifications[0]; const prefs = refKey.users[0].selfCertifications[0];
expect(prefs.preferredCompressionAlgorithms[0]).to.equal(openpgp.config.preferredCompressionAlgorithm); expect(prefs.preferredCompressionAlgorithms[0]).to.equal(openpgp.config.preferredCompressionAlgorithm);
@ -65,7 +65,7 @@ module.exports = () => describe('Custom configuration', function() {
preferredHashAlgorithm: openpgp.enums.hash.sha512, preferredHashAlgorithm: openpgp.enums.hash.sha512,
rejectPublicKeyAlgorithms: new Set([openpgp.enums.publicKey.eddsa]) // should not matter in this context rejectPublicKeyAlgorithms: new Set([openpgp.enums.publicKey.eddsa]) // should not matter in this context
}; };
const opt2 = { privateKey: origKey, userIds, config }; const opt2 = { privateKey: origKey, userIDs, config };
const { key: refKey2, privateKeyArmored: refKeyArmored2 } = await openpgp.reformatKey(opt2); const { key: refKey2, privateKeyArmored: refKeyArmored2 } = await openpgp.reformatKey(opt2);
const prefs2 = refKey2.users[0].selfCertifications[0]; const prefs2 = refKey2.users[0].selfCertifications[0];
expect(prefs2.preferredCompressionAlgorithms[0]).to.equal(config.preferredCompressionAlgorithm); expect(prefs2.preferredCompressionAlgorithms[0]).to.equal(config.preferredCompressionAlgorithm);
@ -84,8 +84,8 @@ module.exports = () => describe('Custom configuration', function() {
openpgp.config.showComment = false; openpgp.config.showComment = false;
try { try {
const userIds = { name: 'Test User', email: 'text2@example.com' }; const userIDs = { name: 'Test User', email: 'text2@example.com' };
const { key, revocationCertificate } = await openpgp.generateKey({ userIds }); const { key, revocationCertificate } = await openpgp.generateKey({ userIDs });
const opt = { key }; const opt = { key };
const { privateKeyArmored: revKeyArmored } = await openpgp.revokeKey(opt); const { privateKeyArmored: revKeyArmored } = await openpgp.revokeKey(opt);
@ -107,10 +107,10 @@ module.exports = () => describe('Custom configuration', function() {
}); });
it('openpgp.decryptKey', async function() { it('openpgp.decryptKey', async function() {
const userIds = { name: 'Test User', email: 'text2@example.com' }; const userIDs = { name: 'Test User', email: 'text2@example.com' };
const passphrase = '12345678'; const passphrase = '12345678';
const { key } = await openpgp.generateKey({ userIds, passphrase }); const { key } = await openpgp.generateKey({ userIDs, passphrase });
key.keyPacket.makeDummy(); key.keyPacket.makeDummy();
const opt = { const opt = {
@ -127,14 +127,14 @@ module.exports = () => describe('Custom configuration', function() {
try { try {
const passphrase = '12345678'; const passphrase = '12345678';
const userIds = { name: 'Test User', email: 'text2@example.com' }; const userIDs = { name: 'Test User', email: 'text2@example.com' };
const { key: privateKey } = await openpgp.generateKey({ userIds }); const { key: privateKey } = await openpgp.generateKey({ userIDs });
const encKey = await openpgp.encryptKey({ privateKey, userIds, passphrase }); const encKey = await openpgp.encryptKey({ privateKey, userIDs, passphrase });
expect(encKey.keyPacket.s2k.c).to.equal(openpgp.config.s2kIterationCountByte); expect(encKey.keyPacket.s2k.c).to.equal(openpgp.config.s2kIterationCountByte);
const config = { s2kIterationCountByte: 123 }; const config = { s2kIterationCountByte: 123 };
const encKey2 = await openpgp.encryptKey({ privateKey, userIds, passphrase, config }); const encKey2 = await openpgp.encryptKey({ privateKey, userIDs, passphrase, config });
expect(encKey2.keyPacket.s2k.c).to.equal(config.s2kIterationCountByte); expect(encKey2.keyPacket.s2k.c).to.equal(config.s2kIterationCountByte);
} finally { } finally {
openpgp.config.s2kIterationCountByte = s2kIterationCountByteVal; openpgp.config.s2kIterationCountByte = s2kIterationCountByteVal;
@ -155,9 +155,9 @@ module.exports = () => describe('Custom configuration', function() {
const encrypted = await openpgp.readMessage({ armoredMessage: armored }); const encrypted = await openpgp.readMessage({ armoredMessage: armored });
const { packets: [skesk, encData] } = encrypted; const { packets: [skesk, encData] } = encrypted;
expect(skesk.version).to.equal(4); // cfb expect(skesk.version).to.equal(4); // cfb
expect(encData.tag).to.equal(openpgp.enums.packet.symEncryptedIntegrityProtectedData); expect(encData.constructor.tag).to.equal(openpgp.enums.packet.symEncryptedIntegrityProtectedData);
const { packets: [literal] } = await encrypted.decrypt(null, passwords, null, encrypted.fromStream, openpgp.config); const { packets: [literal] } = await encrypted.decrypt(null, passwords, null, encrypted.fromStream, openpgp.config);
expect(literal.tag).to.equal(openpgp.enums.packet.literalData); expect(literal.constructor.tag).to.equal(openpgp.enums.packet.literalData);
const config = { const config = {
aeadProtect: true, aeadProtect: true,
@ -168,13 +168,13 @@ module.exports = () => describe('Custom configuration', function() {
const encrypted2 = await openpgp.readMessage({ armoredMessage: armored2 }); const encrypted2 = await openpgp.readMessage({ armoredMessage: armored2 });
const { packets: [skesk2, encData2] } = encrypted2; const { packets: [skesk2, encData2] } = encrypted2;
expect(skesk2.version).to.equal(5); expect(skesk2.version).to.equal(5);
expect(encData2.tag).to.equal(openpgp.enums.packet.AEADEncryptedData); expect(encData2.constructor.tag).to.equal(openpgp.enums.packet.aeadEncryptedData);
const { packets: [compressed] } = await encrypted2.decrypt(null, passwords, null, encrypted2.fromStream, openpgp.config); const { packets: [compressed] } = await encrypted2.decrypt(null, passwords, null, encrypted2.fromStream, openpgp.config);
expect(compressed.tag).to.equal(openpgp.enums.packet.compressedData); expect(compressed.constructor.tag).to.equal(openpgp.enums.packet.compressedData);
expect(compressed.algorithm).to.equal("zip"); expect(compressed.algorithm).to.equal("zip");
const userIds = { name: 'Test User', email: 'text2@example.com' }; const userIDs = { name: 'Test User', email: 'text2@example.com' };
const { key } = await openpgp.generateKey({ userIds }); const { key } = await openpgp.generateKey({ userIDs });
await expect(openpgp.encrypt({ await expect(openpgp.encrypt({
message, publicKeys: [key], config: { rejectPublicKeyAlgorithms: new Set([openpgp.enums.publicKey.ecdh]) } message, publicKeys: [key], config: { rejectPublicKeyAlgorithms: new Set([openpgp.enums.publicKey.ecdh]) }
})).to.be.eventually.rejectedWith(/ecdh keys are considered too weak/); })).to.be.eventually.rejectedWith(/ecdh keys are considered too weak/);
@ -187,8 +187,8 @@ module.exports = () => describe('Custom configuration', function() {
it('openpgp.decrypt', async function() { it('openpgp.decrypt', async function() {
const plaintext = 'test'; const plaintext = 'test';
const message = openpgp.Message.fromText(plaintext); const message = openpgp.Message.fromText(plaintext);
const userIds = { name: 'Test User', email: 'text2@example.com' }; const userIDs = { name: 'Test User', email: 'text2@example.com' };
const { key } = await openpgp.generateKey({ userIds, type: 'rsa', rsaBits: 2048 }); const { key } = await openpgp.generateKey({ userIDs, type: 'rsa', rsaBits: 2048 });
const armoredMessage = await openpgp.encrypt({ message, publicKeys:[key], privateKeys: [key] }); const armoredMessage = await openpgp.encrypt({ message, publicKeys:[key], privateKeys: [key] });
const { data, signatures } = await openpgp.decrypt({ const { data, signatures } = await openpgp.decrypt({
@ -203,7 +203,7 @@ module.exports = () => describe('Custom configuration', function() {
message: await openpgp.readMessage({ armoredMessage }), message: await openpgp.readMessage({ armoredMessage }),
privateKeys: [key], privateKeys: [key],
publicKeys: [key], publicKeys: [key],
config: { minRsaBits: 4096 } config: { minRSABits: 4096 }
}); });
expect(data2).to.equal(plaintext); expect(data2).to.equal(plaintext);
expect(signatures2[0].valid).to.be.false; expect(signatures2[0].valid).to.be.false;
@ -221,8 +221,8 @@ module.exports = () => describe('Custom configuration', function() {
}); });
it('openpgp.sign', async function() { it('openpgp.sign', async function() {
const userIds = { name: 'Test User', email: 'text2@example.com' }; const userIDs = { name: 'Test User', email: 'text2@example.com' };
const { privateKeyArmored } = await openpgp.generateKey({ userIds }); const { privateKeyArmored } = await openpgp.generateKey({ userIDs });
const key = await openpgp.readKey({ armoredKey: privateKeyArmored }); const key = await openpgp.readKey({ armoredKey: privateKeyArmored });
const message = openpgp.Message.fromText("test"); const message = openpgp.Message.fromText("test");
@ -249,8 +249,8 @@ module.exports = () => describe('Custom configuration', function() {
}); });
it('openpgp.verify', async function() { it('openpgp.verify', async function() {
const userIds = { name: 'Test User', email: 'text2@example.com' }; const userIDs = { name: 'Test User', email: 'text2@example.com' };
const { privateKeyArmored } = await openpgp.generateKey({ userIds }); const { privateKeyArmored } = await openpgp.generateKey({ userIDs });
const key = await openpgp.readKey({ armoredKey: privateKeyArmored }); const key = await openpgp.readKey({ armoredKey: privateKeyArmored });
const config = { rejectMessageHashAlgorithms: new Set([openpgp.enums.hash.sha256, openpgp.enums.hash.sha512]) }; const config = { rejectMessageHashAlgorithms: new Set([openpgp.enums.hash.sha256, openpgp.enums.hash.sha512]) };

View File

@ -13,10 +13,10 @@ module.exports = () => describe('Elliptic Curve Cryptography for NIST P-256,P-38
const testData = input.createSomeMessage(); const testData = input.createSomeMessage();
const testData2 = input.createSomeMessage(); const testData2 = input.createSomeMessage();
const firstKey = await openpgp.generateKey({ userIds: { name: "Hi", email: "hi@hel.lo" }, curve: "p256" }); const firstKey = await openpgp.generateKey({ userIDs: { name: "Hi", email: "hi@hel.lo" }, curve: "p256" });
const hi = firstKey.key; const hi = firstKey.key;
const pubHi = hi.toPublic(); const pubHi = hi.toPublic();
const secondKey = await openpgp.generateKey({ userIds: { name: "Bye", email: "bye@good.bye" }, curve: "p256" }); const secondKey = await openpgp.generateKey({ userIDs: { name: "Bye", email: "bye@good.bye" }, curve: "p256" });
const bye = secondKey.key; const bye = secondKey.key;
const pubBye = bye.toPublic(); const pubBye = bye.toPublic();
@ -54,7 +54,7 @@ module.exports = () => describe('Elliptic Curve Cryptography for NIST P-256,P-38
it('Sign message', async function () { it('Sign message', async function () {
const testData = input.createSomeMessage(); const testData = input.createSomeMessage();
const options = { userIds: { name: "Hi", email: "hi@hel.lo" }, curve: "p256" }; const options = { userIDs: { name: "Hi", email: "hi@hel.lo" }, curve: "p256" };
const firstKey = await openpgp.generateKey(options); const firstKey = await openpgp.generateKey(options);
const signature = await openpgp.sign({ message: openpgp.CleartextMessage.fromText(testData), privateKeys: firstKey.key }); const signature = await openpgp.sign({ message: openpgp.CleartextMessage.fromText(testData), privateKeys: firstKey.key });
const msg = await openpgp.readCleartextMessage({ cleartextMessage: signature }); const msg = await openpgp.readCleartextMessage({ cleartextMessage: signature });
@ -64,9 +64,9 @@ module.exports = () => describe('Elliptic Curve Cryptography for NIST P-256,P-38
it('encrypt and sign message', async function () { it('encrypt and sign message', async function () {
const testData = input.createSomeMessage(); const testData = input.createSomeMessage();
let options = { userIds: { name: "Hi", email: "hi@hel.lo" }, curve: "p256" }; let options = { userIDs: { name: "Hi", email: "hi@hel.lo" }, curve: "p256" };
const firstKey = await openpgp.generateKey(options); const firstKey = await openpgp.generateKey(options);
options = { userIds: { name: "Bye", email: "bye@good.bye" }, curve: "p256" }; options = { userIDs: { name: "Bye", email: "bye@good.bye" }, curve: "p256" };
const secondKey = await openpgp.generateKey(options); const secondKey = await openpgp.generateKey(options);
const encrypted = await openpgp.encrypt( const encrypted = await openpgp.encrypt(
{ message: openpgp.Message.fromText(testData), { message: openpgp.Message.fromText(testData),

View File

@ -142,7 +142,7 @@ module.exports = () => describe('Elliptic Curve Cryptography for secp256k1 curve
} }
const pub = await openpgp.readKey({ armoredKey: data[name].pub }); const pub = await openpgp.readKey({ armoredKey: data[name].pub });
expect(pub).to.exist; expect(pub).to.exist;
expect(pub.getKeyId().toHex()).to.equal(data[name].id); expect(pub.getKeyID().toHex()).to.equal(data[name].id);
data[name].pub_key = pub; data[name].pub_key = pub;
return pub; return pub;
} }
@ -152,20 +152,20 @@ module.exports = () => describe('Elliptic Curve Cryptography for secp256k1 curve
} }
const pk = await openpgp.readKey({ armoredKey: data[name].priv }); const pk = await openpgp.readKey({ armoredKey: data[name].priv });
expect(pk).to.exist; expect(pk).to.exist;
expect(pk.getKeyId().toHex()).to.equal(data[name].id); expect(pk.getKeyID().toHex()).to.equal(data[name].id);
await pk.decrypt(data[name].pass); await pk.decrypt(data[name].pass);
data[name].priv_key = pk; data[name].priv_key = pk;
return pk; return pk;
} }
it('Load public key', async function () { it('Load public key', async function () {
const romeoPublic = await load_pub_key('romeo'); const romeoPublic = await load_pub_key('romeo');
expect(romeoPublic.users[0].userId.name).to.equal('Romeo Montague'); expect(romeoPublic.users[0].userID.name).to.equal('Romeo Montague');
expect(romeoPublic.users[0].userId.email).to.equal('romeo@example.net'); expect(romeoPublic.users[0].userID.email).to.equal('romeo@example.net');
expect(romeoPublic.users[0].userId.comment).to.equal('secp256k1'); expect(romeoPublic.users[0].userID.comment).to.equal('secp256k1');
const julietPublic = await load_pub_key('juliet'); const julietPublic = await load_pub_key('juliet');
expect(julietPublic.users[0].userId.name).to.equal('Juliet Capulet'); expect(julietPublic.users[0].userID.name).to.equal('Juliet Capulet');
expect(julietPublic.users[0].userId.email).to.equal('juliet@example.net'); expect(julietPublic.users[0].userID.email).to.equal('juliet@example.net');
expect(julietPublic.users[0].userId.comment).to.equal('secp256k1'); expect(julietPublic.users[0].userID.comment).to.equal('secp256k1');
}); });
it('Load private key', async function () { it('Load private key', async function () {
await load_priv_key('romeo'); await load_priv_key('romeo');
@ -222,7 +222,7 @@ module.exports = () => describe('Elliptic Curve Cryptography for secp256k1 curve
}); });
it('Generate key', function () { it('Generate key', function () {
const options = { const options = {
userIds: { name: "Hamlet (secp256k1)", email: "hamlet@example.net" }, userIDs: { name: "Hamlet (secp256k1)", email: "hamlet@example.net" },
curve: "secp256k1", curve: "secp256k1",
passphrase: "ophelia" passphrase: "ophelia"
}; };

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@ const openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp
const crypto = require('../../src/crypto'); const crypto = require('../../src/crypto');
const random = require('../../src/crypto/random'); const random = require('../../src/crypto/random');
const util = require('../../src/util'); const util = require('../../src/util');
const keyIdType = require('../../src/type/keyid'); const keyIDType = require('../../src/type/keyid');
const spy = require('sinon/lib/sinon/spy'); const spy = require('sinon/lib/sinon/spy');
const input = require('./testInputs.js'); const input = require('./testInputs.js');
@ -710,7 +710,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
describe('generateKey - validate user ids', function() { describe('generateKey - validate user ids', function() {
it('should fail for invalid user name', async function() { it('should fail for invalid user name', async function() {
const opt = { const opt = {
userIds: [{ name: {}, email: 'text@example.com' }] userIDs: [{ name: {}, email: 'text@example.com' }]
}; };
const test = openpgp.generateKey(opt); const test = openpgp.generateKey(opt);
await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/); await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/);
@ -718,7 +718,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
it('should fail for invalid user email address', async function() { it('should fail for invalid user email address', async function() {
const opt = { const opt = {
userIds: [{ name: 'Test User', email: 'textexample.com' }] userIDs: [{ name: 'Test User', email: 'textexample.com' }]
}; };
const test = openpgp.generateKey(opt); const test = openpgp.generateKey(opt);
await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/); await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/);
@ -726,7 +726,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
it('should fail for invalid user email address', async function() { it('should fail for invalid user email address', async function() {
const opt = { const opt = {
userIds: [{ name: 'Test User', email: 'text@examplecom' }] userIDs: [{ name: 'Test User', email: 'text@examplecom' }]
}; };
const test = openpgp.generateKey(opt); const test = openpgp.generateKey(opt);
await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/); await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/);
@ -734,7 +734,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
it('should fail for string user ID', async function() { it('should fail for string user ID', async function() {
const opt = { const opt = {
userIds: 'Test User <text@example.com>' userIDs: 'Test User <text@example.com>'
}; };
const test = openpgp.generateKey(opt); const test = openpgp.generateKey(opt);
await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/); await expect(test).to.eventually.be.rejectedWith(/Invalid user ID format/);
@ -742,28 +742,28 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
it('should work for valid single user ID object', function() { it('should work for valid single user ID object', function() {
const opt = { const opt = {
userIds: { name: 'Test User', email: 'text@example.com' } userIDs: { name: 'Test User', email: 'text@example.com' }
}; };
return openpgp.generateKey(opt); return openpgp.generateKey(opt);
}); });
it('should work for array of user ID objects', function() { it('should work for array of user ID objects', function() {
const opt = { const opt = {
userIds: [{ name: 'Test User', email: 'text@example.com' }] userIDs: [{ name: 'Test User', email: 'text@example.com' }]
}; };
return openpgp.generateKey(opt); return openpgp.generateKey(opt);
}); });
it('should work for undefined name', function() { it('should work for undefined name', function() {
const opt = { const opt = {
userIds: { email: 'text@example.com' } userIDs: { email: 'text@example.com' }
}; };
return openpgp.generateKey(opt); return openpgp.generateKey(opt);
}); });
it('should work for an undefined email address', function() { it('should work for an undefined email address', function() {
const opt = { const opt = {
userIds: { name: 'Test User' } userIDs: { name: 'Test User' }
}; };
return openpgp.generateKey(opt); return openpgp.generateKey(opt);
}); });
@ -773,15 +773,15 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
it('should have default params set', function() { it('should have default params set', function() {
const now = util.normalizeDate(new Date()); const now = util.normalizeDate(new Date());
const opt = { const opt = {
userIds: { name: 'Test User', email: 'text@example.com' }, userIDs: { name: 'Test User', email: 'text@example.com' },
passphrase: 'secret', passphrase: 'secret',
date: now date: now
}; };
return openpgp.generateKey(opt).then(async function(newKey) { return openpgp.generateKey(opt).then(async function(newKey) {
expect(newKey.key).to.exist; expect(newKey.key).to.exist;
expect(newKey.key.users.length).to.equal(1); expect(newKey.key.users.length).to.equal(1);
expect(newKey.key.users[0].userId.name).to.equal('Test User'); expect(newKey.key.users[0].userID.name).to.equal('Test User');
expect(newKey.key.users[0].userId.email).to.equal('text@example.com'); expect(newKey.key.users[0].userID.email).to.equal('text@example.com');
expect(newKey.key.getAlgorithmInfo().rsaBits).to.equal(undefined); expect(newKey.key.getAlgorithmInfo().rsaBits).to.equal(undefined);
expect(newKey.key.getAlgorithmInfo().curve).to.equal('ed25519'); expect(newKey.key.getAlgorithmInfo().curve).to.equal('ed25519');
expect(+newKey.key.getCreationTime()).to.equal(+now); expect(+newKey.key.getCreationTime()).to.equal(+now);
@ -800,11 +800,11 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
describe('generateKey - integration tests', function() { describe('generateKey - integration tests', function() {
it('should work', function() { it('should work', function() {
const opt = { const opt = {
userIds: [{ name: 'Test User', email: 'text@example.com' }] userIDs: [{ name: 'Test User', email: 'text@example.com' }]
}; };
return openpgp.generateKey(opt).then(function(newKey) { return openpgp.generateKey(opt).then(function(newKey) {
expect(newKey.key.getUserIds()[0]).to.equal('Test User <text@example.com>'); expect(newKey.key.getUserIDs()[0]).to.equal('Test User <text@example.com>');
expect(newKey.publicKeyArmored).to.match(/^-----BEGIN PGP PUBLIC/); expect(newKey.publicKeyArmored).to.match(/^-----BEGIN PGP PUBLIC/);
expect(newKey.privateKeyArmored).to.match(/^-----BEGIN PGP PRIVATE/); expect(newKey.privateKeyArmored).to.match(/^-----BEGIN PGP PRIVATE/);
}); });
@ -824,10 +824,10 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
let privateKeyMismatchingParams; let privateKeyMismatchingParams;
let aeadProtectVal; let aeadProtectVal;
let preferredAeadAlgorithmVal; let preferredAEADAlgorithmVal;
let aeadChunkSizeByteVal; let aeadChunkSizeByteVal;
let v5KeysVal; let v5KeysVal;
let minRsaBitsVal; let minRSABitsVal;
beforeEach(async function() { beforeEach(async function() {
publicKey = await openpgp.readKey({ armoredKey: pub_key }); publicKey = await openpgp.readKey({ armoredKey: pub_key });
@ -842,20 +842,20 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
privateKeyMismatchingParams = await openpgp.readKey({ armoredKey: mismatchingKeyParams }); privateKeyMismatchingParams = await openpgp.readKey({ armoredKey: mismatchingKeyParams });
aeadProtectVal = openpgp.config.aeadProtect; aeadProtectVal = openpgp.config.aeadProtect;
preferredAeadAlgorithmVal = openpgp.config.preferredAeadAlgorithm; preferredAEADAlgorithmVal = openpgp.config.preferredAEADAlgorithm;
aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte; aeadChunkSizeByteVal = openpgp.config.aeadChunkSizeByte;
v5KeysVal = openpgp.config.v5Keys; v5KeysVal = openpgp.config.v5Keys;
minRsaBitsVal = openpgp.config.minRsaBits; minRSABitsVal = openpgp.config.minRSABits;
openpgp.config.minRsaBits = 512; openpgp.config.minRSABits = 512;
}); });
afterEach(function() { afterEach(function() {
openpgp.config.aeadProtect = aeadProtectVal; openpgp.config.aeadProtect = aeadProtectVal;
openpgp.config.preferredAeadAlgorithm = preferredAeadAlgorithmVal; openpgp.config.preferredAEADAlgorithm = preferredAEADAlgorithmVal;
openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal; openpgp.config.aeadChunkSizeByte = aeadChunkSizeByteVal;
openpgp.config.v5Keys = v5KeysVal; openpgp.config.v5Keys = v5KeysVal;
openpgp.config.minRsaBits = minRsaBitsVal; openpgp.config.minRSABits = minRSABitsVal;
}); });
it('Configuration', async function() { it('Configuration', async function() {
@ -899,14 +899,14 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
privateKey: privateKey, privateKey: privateKey,
passphrase: passphrase passphrase: passphrase
}).then(function(unlocked){ }).then(function(unlocked){
expect(unlocked.getKeyId().toHex()).to.equal(privateKey.getKeyId().toHex()); expect(unlocked.getKeyID().toHex()).to.equal(privateKey.getKeyID().toHex());
expect(unlocked.subKeys[0].getKeyId().toHex()).to.equal(privateKey.subKeys[0].getKeyId().toHex()); expect(unlocked.subKeys[0].getKeyID().toHex()).to.equal(privateKey.subKeys[0].getKeyID().toHex());
expect(unlocked.isDecrypted()).to.be.true; expect(unlocked.isDecrypted()).to.be.true;
expect(unlocked.keyPacket.privateParams).to.not.be.null; expect(unlocked.keyPacket.privateParams).to.not.be.null;
// original key should be unchanged // original key should be unchanged
expect(privateKey.isDecrypted()).to.be.false; expect(privateKey.isDecrypted()).to.be.false;
expect(privateKey.keyPacket.privateParams).to.be.null; expect(privateKey.keyPacket.privateParams).to.be.null;
originalKey.subKeys[0].getKeyId(); // fill in keyid originalKey.subKeys[0].getKeyID(); // fill in keyID
expect(privateKey).to.deep.equal(originalKey); expect(privateKey).to.deep.equal(originalKey);
}); });
}); });
@ -945,7 +945,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
describe('encryptKey', function() { describe('encryptKey', function() {
it('should not change original key', async function() { it('should not change original key', async function() {
const { privateKeyArmored } = await openpgp.generateKey({ userIds: [{ name: 'test', email: 'test@test.com' }] }); const { privateKeyArmored } = await openpgp.generateKey({ userIDs: [{ name: 'test', email: 'test@test.com' }] });
// read both keys from armored data to make sure all fields are exactly the same // read both keys from armored data to make sure all fields are exactly the same
const key = await openpgp.readKey({ armoredKey: privateKeyArmored }); const key = await openpgp.readKey({ armoredKey: privateKeyArmored });
const originalKey = await openpgp.readKey({ armoredKey: privateKeyArmored }); const originalKey = await openpgp.readKey({ armoredKey: privateKeyArmored });
@ -953,20 +953,20 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
privateKey: key, privateKey: key,
passphrase: passphrase passphrase: passphrase
}).then(function(locked){ }).then(function(locked){
expect(locked.getKeyId().toHex()).to.equal(key.getKeyId().toHex()); expect(locked.getKeyID().toHex()).to.equal(key.getKeyID().toHex());
expect(locked.subKeys[0].getKeyId().toHex()).to.equal(key.subKeys[0].getKeyId().toHex()); expect(locked.subKeys[0].getKeyID().toHex()).to.equal(key.subKeys[0].getKeyID().toHex());
expect(locked.isDecrypted()).to.be.false; expect(locked.isDecrypted()).to.be.false;
expect(locked.keyPacket.privateParams).to.be.null; expect(locked.keyPacket.privateParams).to.be.null;
// original key should be unchanged // original key should be unchanged
expect(key.isDecrypted()).to.be.true; expect(key.isDecrypted()).to.be.true;
expect(key.keyPacket.privateParams).to.not.be.null; expect(key.keyPacket.privateParams).to.not.be.null;
originalKey.subKeys[0].getKeyId(); // fill in keyid originalKey.subKeys[0].getKeyID(); // fill in keyID
expect(key).to.deep.equal(originalKey); expect(key).to.deep.equal(originalKey);
}); });
}); });
it('encrypted key can be decrypted', async function() { it('encrypted key can be decrypted', async function() {
const { key } = await openpgp.generateKey({ userIds: [{ name: 'test', email: 'test@test.com' }] }); const { key } = await openpgp.generateKey({ userIDs: [{ name: 'test', email: 'test@test.com' }] });
const locked = await openpgp.encryptKey({ const locked = await openpgp.encryptKey({
privateKey: key, privateKey: key,
passphrase: passphrase passphrase: passphrase
@ -980,7 +980,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
}); });
it('should support multiple passphrases', async function() { it('should support multiple passphrases', async function() {
const { key } = await openpgp.generateKey({ userIds: [{ name: 'test', email: 'test@test.com' }] }); const { key } = await openpgp.generateKey({ userIDs: [{ name: 'test', email: 'test@test.com' }] });
const passphrases = ['123', '456']; const passphrases = ['123', '456'];
const locked = await openpgp.encryptKey({ const locked = await openpgp.encryptKey({
privateKey: key, privateKey: key,
@ -1041,7 +1041,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
if: true, if: true,
beforeEach: function() { beforeEach: function() {
openpgp.config.aeadProtect = true; openpgp.config.aeadProtect = true;
openpgp.config.preferredAeadAlgorithm = openpgp.enums.aead.experimentalGcm; openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.experimentalGCM;
openpgp.config.v5Keys = true; openpgp.config.v5Keys = true;
// Monkey-patch AEAD feature flag // Monkey-patch AEAD feature flag
@ -1068,7 +1068,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
if: !openpgp.config.ci, if: !openpgp.config.ci,
beforeEach: function() { beforeEach: function() {
openpgp.config.aeadProtect = true; openpgp.config.aeadProtect = true;
openpgp.config.preferredAeadAlgorithm = openpgp.enums.aead.ocb; openpgp.config.preferredAEADAlgorithm = openpgp.enums.aead.ocb;
// Monkey-patch AEAD feature flag // Monkey-patch AEAD feature flag
publicKey.users[0].selfCertifications[0].features = [7]; publicKey.users[0].selfCertifications[0].features = [7];
@ -1368,7 +1368,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
return openpgp.encrypt(encOpt).then(async function (encrypted) { return openpgp.encrypt(encOpt).then(async function (encrypted) {
expect(encrypted).to.match(/^-----BEGIN PGP MESSAGE/); expect(encrypted).to.match(/^-----BEGIN PGP MESSAGE/);
decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted });
expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.AEADEncryptedData)).to.equal(false); expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.aeadEncryptedData)).to.equal(false);
return openpgp.decrypt(decOpt); return openpgp.decrypt(decOpt);
}).then(function (decrypted) { }).then(function (decrypted) {
expect(decrypted.data).to.equal(plaintext); expect(decrypted.data).to.equal(plaintext);
@ -1391,7 +1391,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
return openpgp.encrypt(encOpt).then(async function (encrypted) { return openpgp.encrypt(encOpt).then(async function (encrypted) {
expect(encrypted).to.match(/^-----BEGIN PGP MESSAGE/); expect(encrypted).to.match(/^-----BEGIN PGP MESSAGE/);
decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted });
expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.AEADEncryptedData)).to.equal(false); expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.aeadEncryptedData)).to.equal(false);
return openpgp.decrypt(decOpt); return openpgp.decrypt(decOpt);
}).then(function (decrypted) { }).then(function (decrypted) {
expect(decrypted.data).to.equal(plaintext); expect(decrypted.data).to.equal(plaintext);
@ -1410,13 +1410,13 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
}; };
return openpgp.encrypt(encOpt).then(async function (encrypted) { return openpgp.encrypt(encOpt).then(async function (encrypted) {
decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted });
expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.AEADEncryptedData)).to.equal(openpgp.config.aeadProtect); expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.aeadEncryptedData)).to.equal(openpgp.config.aeadProtect);
return openpgp.decrypt(decOpt); return openpgp.decrypt(decOpt);
}).then(async function (decrypted) { }).then(async function (decrypted) {
expect(decrypted.data).to.equal(plaintext); expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].valid).to.be.true;
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(decrypted.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(decrypted.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
@ -1433,20 +1433,20 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
}; };
return openpgp.encrypt(encOpt).then(async function (encrypted) { return openpgp.encrypt(encOpt).then(async function (encrypted) {
decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted });
expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.AEADEncryptedData)).to.equal(false); expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.aeadEncryptedData)).to.equal(false);
return openpgp.decrypt(decOpt); return openpgp.decrypt(decOpt);
}).then(async function (decrypted) { }).then(async function (decrypted) {
expect(decrypted.data).to.equal(plaintext); expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].valid).to.be.true;
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(decrypted.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(decrypted.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
it('should encrypt/sign and decrypt/verify with generated key', function () { it('should encrypt/sign and decrypt/verify with generated key', function () {
const genOpt = { const genOpt = {
userIds: [{ name: 'Test User', email: 'text@example.com' }] userIDs: [{ name: 'Test User', email: 'text@example.com' }]
}; };
return openpgp.generateKey(genOpt).then(async function(newKey) { return openpgp.generateKey(genOpt).then(async function(newKey) {
@ -1464,13 +1464,13 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
}; };
return openpgp.encrypt(encOpt).then(async function (encrypted) { return openpgp.encrypt(encOpt).then(async function (encrypted) {
decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted }); decOpt.message = await openpgp.readMessage({ armoredMessage: encrypted });
expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.AEADEncryptedData)).to.equal(openpgp.config.aeadProtect); expect(!!decOpt.message.packets.findPacket(openpgp.enums.packet.aeadEncryptedData)).to.equal(openpgp.config.aeadProtect);
return openpgp.decrypt(decOpt); return openpgp.decrypt(decOpt);
}).then(async function (decrypted) { }).then(async function (decrypted) {
expect(decrypted.data).to.equal(plaintext); expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].valid).to.be.true;
const signingKey = await newPrivateKey.getSigningKey(); const signingKey = await newPrivateKey.getSigningKey();
expect(decrypted.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(decrypted.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
@ -1478,7 +1478,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
it('should encrypt/sign and decrypt/verify with generated key and detached signatures', async function () { it('should encrypt/sign and decrypt/verify with generated key and detached signatures', async function () {
const newKey = await openpgp.generateKey({ const newKey = await openpgp.generateKey({
userIds: [{ name: 'Test User', email: 'text@example.com' }] userIDs: [{ name: 'Test User', email: 'text@example.com' }]
}); });
const newPublicKey = await openpgp.readKey({ armoredKey: newKey.publicKeyArmored }); const newPublicKey = await openpgp.readKey({ armoredKey: newKey.publicKeyArmored });
const newPrivateKey = await openpgp.readKey({ armoredKey: newKey.privateKeyArmored }); const newPrivateKey = await openpgp.readKey({ armoredKey: newKey.privateKeyArmored });
@ -1493,7 +1493,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
detached: true detached: true
}); });
const message = await openpgp.readMessage({ armoredMessage: encrypted }); const message = await openpgp.readMessage({ armoredMessage: encrypted });
expect(!!message.packets.findPacket(openpgp.enums.packet.AEADEncryptedData)).to.equal(openpgp.config.aeadProtect); expect(!!message.packets.findPacket(openpgp.enums.packet.aeadEncryptedData)).to.equal(openpgp.config.aeadProtect);
const decrypted = await openpgp.decrypt({ const decrypted = await openpgp.decrypt({
message, message,
signature: await openpgp.readSignature({ armoredSignature: signed }), signature: await openpgp.readSignature({ armoredSignature: signed }),
@ -1503,7 +1503,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(decrypted.data).to.equal(plaintext); expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].valid).to.be.true;
const signingKey = await newPrivateKey.getSigningKey(); const signingKey = await newPrivateKey.getSigningKey();
expect(decrypted.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(decrypted.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[0].signature.packets.length).to.equal(1);
}); });
@ -1524,7 +1524,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(decrypted.data).to.equal(''); expect(decrypted.data).to.equal('');
expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].valid).to.be.true;
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(decrypted.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(decrypted.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
@ -1548,7 +1548,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(decrypted.data).to.equal(plaintext); expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].valid).to.be.true;
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(decrypted.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(decrypted.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[0].signature.packets.length).to.equal(1);
}); });
@ -1592,11 +1592,11 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(decrypted.data).to.equal(plaintext); expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].valid).to.be.true;
signingKey = await privateKey.getSigningKey(); signingKey = await privateKey.getSigningKey();
expect(decrypted.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(decrypted.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[0].signature.packets.length).to.equal(1);
expect(decrypted.signatures[1].valid).to.be.true; expect(decrypted.signatures[1].valid).to.be.true;
signingKey = await privKeyDE.getSigningKey(); signingKey = await privKeyDE.getSigningKey();
expect(decrypted.signatures[1].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(decrypted.signatures[1].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(decrypted.signatures[1].signature.packets.length).to.equal(1); expect(decrypted.signatures[1].signature.packets.length).to.equal(1);
}); });
} finally { } finally {
@ -1632,7 +1632,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(signatures[0].valid).to.be.false; expect(signatures[0].valid).to.be.false;
expect(signatures[0].error).to.match(/Could not find signing key/); expect(signatures[0].error).to.match(/Could not find signing key/);
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(signatures[0].signature.packets.length).to.equal(1); expect(signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
@ -1655,7 +1655,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(signatures[0].valid).to.be.false; expect(signatures[0].valid).to.be.false;
expect(signatures[0].error).to.match(/Could not find signing key/); expect(signatures[0].error).to.match(/Could not find signing key/);
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(signatures[0].signature.packets.length).to.equal(1); expect(signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
@ -1678,7 +1678,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(signatures[0].valid).to.be.false; expect(signatures[0].valid).to.be.false;
expect(signatures[0].error).to.match(/Could not find signing key/); expect(signatures[0].error).to.match(/Could not find signing key/);
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(signatures[0].signature.packets.length).to.equal(1); expect(signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
@ -1700,7 +1700,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(signatures[0].valid).to.be.false; expect(signatures[0].valid).to.be.false;
expect(signatures[0].error).to.match(/Could not find signing key/); expect(signatures[0].error).to.match(/Could not find signing key/);
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(signatures[0].signature.packets.length).to.equal(1); expect(signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
@ -1725,7 +1725,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(signatures[0].valid).to.be.false; expect(signatures[0].valid).to.be.false;
expect(signatures[0].error).to.match(/Could not find signing key/); expect(signatures[0].error).to.match(/Could not find signing key/);
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(signatures[0].signature.packets.length).to.equal(1); expect(signatures[0].signature.packets.length).to.equal(1);
}); });
@ -1758,11 +1758,11 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(decrypted.data).to.equal(plaintext); expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].valid).to.be.true;
signingKey = await privateKey.getSigningKey(); signingKey = await privateKey.getSigningKey();
expect(decrypted.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(decrypted.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[0].signature.packets.length).to.equal(1);
expect(decrypted.signatures[1].valid).to.be.true; expect(decrypted.signatures[1].valid).to.be.true;
signingKey = await privKeyDE.getSigningKey(); signingKey = await privKeyDE.getSigningKey();
expect(decrypted.signatures[1].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(decrypted.signatures[1].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(decrypted.signatures[1].signature.packets.length).to.equal(1); expect(decrypted.signatures[1].signature.packets.length).to.equal(1);
}); });
} finally { } finally {
@ -1771,7 +1771,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
}); });
it('should fail to decrypt modified message', async function() { it('should fail to decrypt modified message', async function() {
const { privateKeyArmored } = await openpgp.generateKey({ curve: 'curve25519', userIds: [{ email: 'test@email.com' }] }); const { privateKeyArmored } = await openpgp.generateKey({ curve: 'curve25519', userIDs: [{ email: 'test@email.com' }] });
const key = await openpgp.readKey({ armoredKey: privateKeyArmored }); const key = await openpgp.readKey({ armoredKey: privateKeyArmored });
const data = await openpgp.encrypt({ message: openpgp.Message.fromBinary(new Uint8Array(500)), publicKeys: [key.toPublic()] }); const data = await openpgp.encrypt({ message: openpgp.Message.fromBinary(new Uint8Array(500)), publicKeys: [key.toPublic()] });
let badSumEncrypted = data.replace(/\n=[a-zA-Z0-9/+]{4}/, '\n=aaaa'); let badSumEncrypted = data.replace(/\n=[a-zA-Z0-9/+]{4}/, '\n=aaaa');
@ -1825,7 +1825,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
}); });
it('should fail to decrypt unarmored message with garbage data appended', async function() { it('should fail to decrypt unarmored message with garbage data appended', async function() {
const { key } = await openpgp.generateKey({ userIds: {} }); const { key } = await openpgp.generateKey({ userIDs: {} });
const message = await openpgp.encrypt({ message: openpgp.Message.fromText('test'), publicKeys: key, privateKeys: key, armor: false }); const message = await openpgp.encrypt({ message: openpgp.Message.fromText('test'), publicKeys: key, privateKeys: key, armor: false });
const encrypted = util.concat([message, new Uint8Array([11])]); const encrypted = util.concat([message, new Uint8Array([11])]);
await expect( await expect(
@ -1860,7 +1860,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(decrypted.data).to.equal(plaintext); expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].valid).to.be.true;
const signingKey = await privKeyDE.getSigningKey(); const signingKey = await privKeyDE.getSigningKey();
expect(decrypted.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(decrypted.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(decrypted.signatures[0].signature.packets.length).to.equal(1); expect(decrypted.signatures[0].signature.packets.length).to.equal(1);
}); });
} finally { } finally {
@ -2104,7 +2104,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(verified.data).to.equal(plaintext.replace(/[ \t]+$/mg, '')); expect(verified.data).to.equal(plaintext.replace(/[ \t]+$/mg, ''));
expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].valid).to.be.true;
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(verified.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(verified.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(verified.signatures[0].signature.packets.length).to.equal(1); expect(verified.signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
@ -2134,11 +2134,11 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(verified.data).to.equal(plaintext.replace(/[ \t]+$/mg, '')); expect(verified.data).to.equal(plaintext.replace(/[ \t]+$/mg, ''));
expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].valid).to.be.true;
signingKey = await privateKey.getSigningKey(); signingKey = await privateKey.getSigningKey();
expect(verified.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(verified.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(verified.signatures[0].signature.packets.length).to.equal(1); expect(verified.signatures[0].signature.packets.length).to.equal(1);
expect(verified.signatures[1].valid).to.be.true; expect(verified.signatures[1].valid).to.be.true;
signingKey = await privKeyDE.getSigningKey(); signingKey = await privKeyDE.getSigningKey();
expect(verified.signatures[1].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(verified.signatures[1].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(verified.signatures[1].signature.packets.length).to.equal(1); expect(verified.signatures[1].signature.packets.length).to.equal(1);
}); });
} finally { } finally {
@ -2164,7 +2164,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(verified.data).to.equal(plaintext); expect(verified.data).to.equal(plaintext);
expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].valid).to.be.true;
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(verified.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(verified.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(verified.signatures[0].signature.packets.length).to.equal(1); expect(verified.signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
@ -2186,7 +2186,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(signatures[0].valid).to.be.false; expect(signatures[0].valid).to.be.false;
expect(signatures[0].error).to.match(/Could not find signing key/); expect(signatures[0].error).to.match(/Could not find signing key/);
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(signatures[0].signature.packets.length).to.equal(1); expect(signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
@ -2210,7 +2210,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(signatures[0].valid).to.be.false; expect(signatures[0].valid).to.be.false;
expect(signatures[0].error).to.match(/Could not find signing key/); expect(signatures[0].error).to.match(/Could not find signing key/);
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(signatures[0].signature.packets.length).to.equal(1); expect(signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
@ -2232,7 +2232,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(verified.data).to.equal(plaintext); expect(verified.data).to.equal(plaintext);
expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].valid).to.be.true;
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(verified.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(verified.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(verified.signatures[0].signature.packets.length).to.equal(1); expect(verified.signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
@ -2259,7 +2259,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(+verified.signatures[0].signature.packets[0].created).to.be.gte(+start); expect(+verified.signatures[0].signature.packets[0].created).to.be.gte(+start);
expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].valid).to.be.true;
const signingKey = await privateKey.getSigningKey(); const signingKey = await privateKey.getSigningKey();
expect(verified.signatures[0].keyid.toHex()).to.equal(signingKey.getKeyId().toHex()); expect(verified.signatures[0].keyID.toHex()).to.equal(signingKey.getKeyID().toHex());
expect(verified.signatures[0].signature.packets.length).to.equal(1); expect(verified.signatures[0].signature.packets.length).to.equal(1);
}); });
}); });
@ -2285,7 +2285,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(+verified.signatures[0].signature.packets[0].created).to.equal(+past); expect(+verified.signatures[0].signature.packets[0].created).to.equal(+past);
expect(verified.data).to.equal(plaintext); expect(verified.data).to.equal(plaintext);
expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].valid).to.be.true;
expect(await privateKey_1337.getSigningKey(verified.signatures[0].keyid, past)) expect(await privateKey_1337.getSigningKey(verified.signatures[0].keyID, past))
.to.be.not.null; .to.be.not.null;
expect(verified.signatures[0].signature.packets.length).to.equal(1); expect(verified.signatures[0].signature.packets.length).to.equal(1);
// now check with expiration checking disabled // now check with expiration checking disabled
@ -2295,7 +2295,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(+verified.signatures[0].signature.packets[0].created).to.equal(+past); expect(+verified.signatures[0].signature.packets[0].created).to.equal(+past);
expect(verified.data).to.equal(plaintext); expect(verified.data).to.equal(plaintext);
expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].valid).to.be.true;
expect(await privateKey_1337.getSigningKey(verified.signatures[0].keyid, null)) expect(await privateKey_1337.getSigningKey(verified.signatures[0].keyID, null))
.to.be.not.null; .to.be.not.null;
expect(verified.signatures[0].signature.packets.length).to.equal(1); expect(verified.signatures[0].signature.packets.length).to.equal(1);
}); });
@ -2325,7 +2325,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(+verified.signatures[0].signature.packets[0].created).to.equal(+future); expect(+verified.signatures[0].signature.packets[0].created).to.equal(+future);
expect([].slice.call(verified.data)).to.deep.equal([].slice.call(data)); expect([].slice.call(verified.data)).to.deep.equal([].slice.call(data));
expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].valid).to.be.true;
expect(await privateKey_2038_2045.getSigningKey(verified.signatures[0].keyid, future)) expect(await privateKey_2038_2045.getSigningKey(verified.signatures[0].keyID, future))
.to.be.not.null; .to.be.not.null;
expect(verified.signatures[0].signature.packets.length).to.equal(1); expect(verified.signatures[0].signature.packets.length).to.equal(1);
}); });
@ -2353,7 +2353,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
}).then(async function (verified) { }).then(async function (verified) {
expect([].slice.call(verified.data)).to.deep.equal([].slice.call(data)); expect([].slice.call(verified.data)).to.deep.equal([].slice.call(data));
expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].valid).to.be.true;
expect(await privateKey.getSigningKey(verified.signatures[0].keyid)) expect(await privateKey.getSigningKey(verified.signatures[0].keyID))
.to.be.not.null; .to.be.not.null;
expect(verified.signatures[0].signature.packets.length).to.equal(1); expect(verified.signatures[0].signature.packets.length).to.equal(1);
}); });
@ -2386,7 +2386,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(openpgp.stream.isStream(verified.data)).to.equal(useNativeStream ? 'web' : 'ponyfill'); expect(openpgp.stream.isStream(verified.data)).to.equal(useNativeStream ? 'web' : 'ponyfill');
expect([].slice.call(await openpgp.stream.readToEnd(verified.data))).to.deep.equal([].slice.call(data)); expect([].slice.call(await openpgp.stream.readToEnd(verified.data))).to.deep.equal([].slice.call(data));
expect(await verified.signatures[0].verified).to.be.true; expect(await verified.signatures[0].verified).to.be.true;
expect(await privateKey.getSigningKey(verified.signatures[0].keyid)) expect(await privateKey.getSigningKey(verified.signatures[0].keyID))
.to.be.not.null; .to.be.not.null;
expect((await verified.signatures[0].signature).packets.length).to.equal(1); expect((await verified.signatures[0].signature).packets.length).to.equal(1);
}); });
@ -2454,7 +2454,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(await openpgp.stream.readToEnd(message.getText())).to.equal(plaintext); expect(await openpgp.stream.readToEnd(message.getText())).to.equal(plaintext);
expect(+(await signatures[0].signature).packets[0].created).to.equal(+past); expect(+(await signatures[0].signature).packets[0].created).to.equal(+past);
expect(await signatures[0].verified).to.be.true; expect(await signatures[0].verified).to.be.true;
expect(await privateKey_2000_2008.getSigningKey(signatures[0].keyid, past)) expect(await privateKey_2000_2008.getSigningKey(signatures[0].keyID, past))
.to.be.not.null; .to.be.not.null;
expect((await signatures[0].signature).packets.length).to.equal(1); expect((await signatures[0].signature).packets.length).to.equal(1);
}); });
@ -2483,7 +2483,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(await openpgp.stream.readToEnd(message.getLiteralData())).to.deep.equal(data); expect(await openpgp.stream.readToEnd(message.getLiteralData())).to.deep.equal(data);
expect(+(await signatures[0].signature).packets[0].created).to.equal(+future); expect(+(await signatures[0].signature).packets[0].created).to.equal(+future);
expect(await signatures[0].verified).to.be.true; expect(await signatures[0].verified).to.be.true;
expect(await privateKey_2038_2045.getSigningKey(signatures[0].keyid, future)) expect(await privateKey_2038_2045.getSigningKey(signatures[0].keyID, future))
.to.be.not.null; .to.be.not.null;
expect((await signatures[0].signature).packets.length).to.equal(1); expect((await signatures[0].signature).packets.length).to.equal(1);
}); });
@ -2512,7 +2512,7 @@ module.exports = () => describe('OpenPGP.js public api tests', function() {
expect(await openpgp.stream.readToEnd(message.getLiteralData())).to.deep.equal(data); expect(await openpgp.stream.readToEnd(message.getLiteralData())).to.deep.equal(data);
expect(+(await signatures[0].signature).packets[0].created).to.equal(+future); expect(+(await signatures[0].signature).packets[0].created).to.equal(+future);
expect(await signatures[0].verified).to.be.true; expect(await signatures[0].verified).to.be.true;
expect(await privateKey_2038_2045.getSigningKey(signatures[0].keyid, future)) expect(await privateKey_2038_2045.getSigningKey(signatures[0].keyID, future))
.to.be.not.null; .to.be.not.null;
expect((await signatures[0].signature).packets.length).to.equal(1); expect((await signatures[0].signature).packets.length).to.equal(1);
}); });
@ -2700,7 +2700,7 @@ amnR6g==
message: await openpgp.readMessage({ armoredMessage: encrypted }), message: await openpgp.readMessage({ armoredMessage: encrypted }),
format: 'binary' format: 'binary'
}); });
expect(util.decodeUtf8(decrypted.data)).to.equal('"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nBEGIN:VEVENT\r\nUID:123\r\nDTSTART:20191211T121212Z\r\nDTEND:20191212T121212Z\r\nEND:VEVENT\r\nEND:VCALENDAR"'); expect(util.decodeUTF8(decrypted.data)).to.equal('"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nBEGIN:VEVENT\r\nUID:123\r\nDTSTART:20191211T121212Z\r\nDTEND:20191212T121212Z\r\nEND:VEVENT\r\nEND:VCALENDAR"');
}); });
}); });
@ -2709,7 +2709,7 @@ amnR6g==
curves.forEach(curve => { curves.forEach(curve => {
it(`sign/verify with ${curve}`, async function() { it(`sign/verify with ${curve}`, async function() {
const plaintext = 'short message'; const plaintext = 'short message';
const key = (await openpgp.generateKey({ curve, userIds: { name: 'Alice', email: 'info@alice.com' } })).key; const key = (await openpgp.generateKey({ curve, userIDs: { name: 'Alice', email: 'info@alice.com' } })).key;
const signed = await openpgp.sign({ privateKeys:[key], message: openpgp.CleartextMessage.fromText(plaintext) }); const signed = await openpgp.sign({ privateKeys:[key], message: openpgp.CleartextMessage.fromText(plaintext) });
const verified = await openpgp.verify({ publicKeys:[key], message: await openpgp.readCleartextMessage({ cleartextMessage: signed }) }); const verified = await openpgp.verify({ publicKeys:[key], message: await openpgp.readCleartextMessage({ cleartextMessage: signed }) });
expect(verified.signatures[0].valid).to.be.true; expect(verified.signatures[0].valid).to.be.true;
@ -2837,15 +2837,15 @@ bsZgJWVlAa5eil6J9ePX2xbo1vVAkLQdzE9+1jL+l7PRIZuVBQ==
}); });
describe('Specific encryption/signing key testing', async function () { describe('Specific encryption/signing key testing', async function () {
const encryptionKeyIds = [ const encryptionKeyIDs = [
keyIdType.fromId("87EAE0977B2185EA"), keyIDType.fromID("87EAE0977B2185EA"),
keyIdType.fromId("F94F9B34AF93FA14"), keyIDType.fromID("F94F9B34AF93FA14"),
keyIdType.fromId("08F7D4C7C59545C0") keyIDType.fromID("08F7D4C7C59545C0")
]; ];
const signingKeyIds = [ const signingKeyIDs = [
keyIdType.fromId("663277AF60400638"), keyIDType.fromID("663277AF60400638"),
keyIdType.fromId("BBE14491E6EE6366"), keyIDType.fromID("BBE14491E6EE6366"),
keyIdType.fromId("3E0F20F1A71D6DFD") keyIDType.fromID("3E0F20F1A71D6DFD")
]; ];
const getPrimaryKey = async () => openpgp.readKey({ const getPrimaryKey = async () => openpgp.readKey({
armoredKey: multipleEncryptionAndSigningSubkeys armoredKey: multipleEncryptionAndSigningSubkeys
@ -2855,17 +2855,17 @@ bsZgJWVlAa5eil6J9ePX2xbo1vVAkLQdzE9+1jL+l7PRIZuVBQ==
const primaryKey = await getPrimaryKey(); const primaryKey = await getPrimaryKey();
let m; let m;
let p; let p;
for (let i = 0; i < encryptionKeyIds.length; i++) { for (let i = 0; i < encryptionKeyIDs.length; i++) {
m = await openpgp.readMessage({ m = await openpgp.readMessage({
armoredMessage: await openpgp.encrypt({ armoredMessage: await openpgp.encrypt({
message: openpgp.Message.fromText("Hello World\n"), message: openpgp.Message.fromText("Hello World\n"),
publicKeys: primaryKey, publicKeys: primaryKey,
encryptionKeyIds: [encryptionKeyIds[i]] encryptionKeyIDs: [encryptionKeyIDs[i]]
}) })
}); });
p = m.packets.filterByTag(openpgp.enums.packet.publicKeyEncryptedSessionKey); p = m.packets.filterByTag(openpgp.enums.packet.publicKeyEncryptedSessionKey);
expect(p.length).equals(1); expect(p.length).equals(1);
expect(p[0].publicKeyId.equals(encryptionKeyIds[i])).to.be.true; expect(p[0].publicKeyID.equals(encryptionKeyIDs[i])).to.be.true;
} }
}); });
@ -2873,18 +2873,18 @@ bsZgJWVlAa5eil6J9ePX2xbo1vVAkLQdzE9+1jL+l7PRIZuVBQ==
const primaryKey = await getPrimaryKey(); const primaryKey = await getPrimaryKey();
let s; let s;
let p; let p;
for (let i = 0; i < signingKeyIds.length; i++) { for (let i = 0; i < signingKeyIDs.length; i++) {
s = await openpgp.readSignature({ s = await openpgp.readSignature({
armoredSignature: await openpgp.sign({ armoredSignature: await openpgp.sign({
message: openpgp.Message.fromText("Hello World\n"), message: openpgp.Message.fromText("Hello World\n"),
privateKeys: primaryKey, privateKeys: primaryKey,
signingKeyIds: [signingKeyIds[i]], signingKeyIDs: [signingKeyIDs[i]],
detached: true detached: true
}) })
}); });
p = s.packets.filterByTag(openpgp.enums.packet.signature); p = s.packets.filterByTag(openpgp.enums.packet.signature);
expect(p.length).equals(1); expect(p.length).equals(1);
expect(p[0].issuerKeyId.equals(signingKeyIds[i])).to.be.true; expect(p[0].issuerKeyID.equals(signingKeyIDs[i])).to.be.true;
} }
}); });
@ -2892,26 +2892,26 @@ bsZgJWVlAa5eil6J9ePX2xbo1vVAkLQdzE9+1jL+l7PRIZuVBQ==
const primaryKey = await getPrimaryKey(); const primaryKey = await getPrimaryKey();
const plaintextMessage = openpgp.Message.fromText("Hello World\n"); const plaintextMessage = openpgp.Message.fromText("Hello World\n");
const checkEncryptedPackets = (encryptionKeyIds, pKESKList) => { const checkEncryptedPackets = (encryptionKeyIDs, pKESKList) => {
pKESKList.forEach(({ publicKeyId }, i) => { pKESKList.forEach(({ publicKeyID }, i) => {
expect(publicKeyId.equals(encryptionKeyIds[i])).to.be.true; expect(publicKeyID.equals(encryptionKeyIDs[i])).to.be.true;
}); });
}; };
const checkSignatures = (signingKeyIds, signatures) => { const checkSignatures = (signingKeyIDs, signatures) => {
signatures.forEach(({ keyid }, i) => { signatures.forEach(({ keyID }, i) => {
expect(keyid.equals(signingKeyIds[i])).to.be.true; expect(keyID.equals(signingKeyIDs[i])).to.be.true;
}); });
}; };
const kIds = [encryptionKeyIds[1], encryptionKeyIds[0], encryptionKeyIds[2]]; const kIds = [encryptionKeyIDs[1], encryptionKeyIDs[0], encryptionKeyIDs[2]];
const sIds = [signingKeyIds[2], signingKeyIds[1], signingKeyIds[0]]; const sIds = [signingKeyIDs[2], signingKeyIDs[1], signingKeyIDs[0]];
const message = await openpgp.readMessage({ const message = await openpgp.readMessage({
armoredMessage: await openpgp.encrypt({ armoredMessage: await openpgp.encrypt({
message: plaintextMessage, message: plaintextMessage,
privateKeys: [primaryKey, primaryKey, primaryKey], privateKeys: [primaryKey, primaryKey, primaryKey],
publicKeys: [primaryKey, primaryKey, primaryKey], publicKeys: [primaryKey, primaryKey, primaryKey],
encryptionKeyIds: kIds, encryptionKeyIDs: kIds,
signingKeyIds: sIds signingKeyIDs: sIds
}) })
}); });
const pKESKList = message.packets.filterByTag(openpgp.enums.packet.publicKeyEncryptedSessionKey); const pKESKList = message.packets.filterByTag(openpgp.enums.packet.publicKeyEncryptedSessionKey);

View File

@ -28,6 +28,8 @@ function stringify(array) {
} }
module.exports = () => describe("Packet", function() { module.exports = () => describe("Packet", function() {
const allAllowedPackets = util.constructAllowedPackets([...Object.values(openpgp).filter(packetClass => !!packetClass.tag)]);
const armored_key = const armored_key =
'-----BEGIN PGP PRIVATE KEY BLOCK-----\n' + '-----BEGIN PGP PRIVATE KEY BLOCK-----\n' +
'Version: GnuPG v2.0.19 (GNU/Linux)\n' + 'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
@ -88,7 +90,7 @@ module.exports = () => describe("Packet", function() {
await enc.encrypt(algo, key, undefined, openpgp.config); await enc.encrypt(algo, key, undefined, openpgp.config);
const msg2 = new openpgp.PacketList(); const msg2 = new openpgp.PacketList();
await msg2.read(message.write(), { SymmetricallyEncryptedDataPacket: openpgp.SymmetricallyEncryptedDataPacket }); await msg2.read(message.write(), util.constructAllowedPackets([openpgp.SymmetricallyEncryptedDataPacket]));
await msg2[0].decrypt(algo, key, undefined, openpgp.config); await msg2[0].decrypt(algo, key, undefined, openpgp.config);
expect(await stringify(msg2[0].packets[0].data)).to.equal(stringify(literal.data)); expect(await stringify(msg2[0].packets[0].data)).to.equal(stringify(literal.data));
@ -119,7 +121,7 @@ module.exports = () => describe("Packet", function() {
await enc.encrypt(algo, key, undefined, openpgp.config); await enc.encrypt(algo, key, undefined, openpgp.config);
const msg2 = new openpgp.PacketList(); const msg2 = new openpgp.PacketList();
await msg2.read(message.write(), { SymmetricallyEncryptedDataPacket: openpgp.SymmetricallyEncryptedDataPacket }); await msg2.read(message.write(), util.constructAllowedPackets([openpgp.SymmetricallyEncryptedDataPacket]));
await expect(msg2[0].decrypt(algo, key, undefined, openpgp.config)).to.eventually.be.rejectedWith('Message is not authenticated.'); await expect(msg2[0].decrypt(algo, key, undefined, openpgp.config)).to.eventually.be.rejectedWith('Message is not authenticated.');
} finally { } finally {
openpgp.config.aeadProtect = aeadProtectVal; openpgp.config.aeadProtect = aeadProtectVal;
@ -141,8 +143,7 @@ module.exports = () => describe("Packet", function() {
await enc.encrypt(algo, key, undefined, openpgp.config); await enc.encrypt(algo, key, undefined, openpgp.config);
const msg2 = new openpgp.PacketList(); const msg2 = new openpgp.PacketList();
await msg2.read(msg.write(), openpgp); await msg2.read(msg.write(), allAllowedPackets);
await msg2[0].decrypt(algo, key, undefined, openpgp.config); await msg2[0].decrypt(algo, key, undefined, openpgp.config);
expect(await stringify(msg2[0].packets[0].data)).to.equal(stringify(literal.data)); expect(await stringify(msg2[0].packets[0].data)).to.equal(stringify(literal.data));
@ -167,7 +168,7 @@ module.exports = () => describe("Packet", function() {
const msg2 = new openpgp.PacketList(); const msg2 = new openpgp.PacketList();
return enc.encrypt(algo, key, undefined, openpgp.config).then(async function() { return enc.encrypt(algo, key, undefined, openpgp.config).then(async function() {
await msg2.read(msg.write(), openpgp); await msg2.read(msg.write(), allAllowedPackets);
return msg2[0].decrypt(algo, key); return msg2[0].decrypt(algo, key);
}).then(async function() { }).then(async function() {
expect(await openpgp.stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); expect(await openpgp.stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data);
@ -211,7 +212,7 @@ module.exports = () => describe("Packet", function() {
const literal = new openpgp.LiteralDataPacket(); const literal = new openpgp.LiteralDataPacket();
const enc = new openpgp.AEADEncryptedDataPacket(); const enc = new openpgp.AEADEncryptedDataPacket();
const msg = new openpgp.PacketList(); const msg = new openpgp.PacketList();
enc.aeadAlgorithm = 'experimentalGcm'; enc.aeadAlgorithm = 'experimentalGCM';
msg.push(enc); msg.push(enc);
literal.setText(testText); literal.setText(testText);
@ -221,7 +222,7 @@ module.exports = () => describe("Packet", function() {
try { try {
await enc.encrypt(algo, key, undefined, { ...openpgp.config, aeadChunkSizeByte: 0 }); await enc.encrypt(algo, key, undefined, { ...openpgp.config, aeadChunkSizeByte: 0 });
await msg2.read(msg.write(), openpgp); await msg2.read(msg.write(), allAllowedPackets);
await msg2[0].decrypt(algo, key); await msg2[0].decrypt(algo, key);
expect(await openpgp.stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); expect(await openpgp.stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data);
expect(encryptStub.callCount > 1).to.be.true; expect(encryptStub.callCount > 1).to.be.true;
@ -255,7 +256,7 @@ module.exports = () => describe("Packet", function() {
const msg = new openpgp.PacketList(); const msg = new openpgp.PacketList();
msg.push(enc); msg.push(enc);
literal.setBytes(util.strToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary); literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
literal.filename = ''; literal.filename = '';
enc.packets.push(literal); enc.packets.push(literal);
@ -268,7 +269,7 @@ module.exports = () => describe("Packet", function() {
await enc.encrypt(algo, key, undefined, { ...openpgp.config, aeadChunkSizeByte: 14 }); await enc.encrypt(algo, key, undefined, { ...openpgp.config, aeadChunkSizeByte: 14 });
const data = msg.write(); const data = msg.write();
expect(await openpgp.stream.readToEnd(openpgp.stream.clone(data))).to.deep.equal(packetBytes); expect(await openpgp.stream.readToEnd(openpgp.stream.clone(data))).to.deep.equal(packetBytes);
await msg2.read(data, openpgp); await msg2.read(data, allAllowedPackets);
await msg2[0].decrypt(algo, key); await msg2[0].decrypt(algo, key);
expect(await openpgp.stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data); expect(await openpgp.stream.readToEnd(msg2[0].packets[0].data)).to.deep.equal(literal.data);
} finally { } finally {
@ -276,7 +277,7 @@ module.exports = () => describe("Packet", function() {
} }
}); });
it('Sym encrypted session key with a compressed packet', async function() { it('Sym. encrypted session key with a compressed packet', async function() {
const msg = const msg =
'-----BEGIN PGP MESSAGE-----\n' + '-----BEGIN PGP MESSAGE-----\n' +
'Version: GnuPG v2.0.19 (GNU/Linux)\n' + 'Version: GnuPG v2.0.19 (GNU/Linux)\n' +
@ -289,7 +290,7 @@ module.exports = () => describe("Packet", function() {
const msgbytes = (await openpgp.unarmor(msg)).data; const msgbytes = (await openpgp.unarmor(msg)).data;
const parsed = new openpgp.PacketList(); const parsed = new openpgp.PacketList();
await parsed.read(msgbytes, openpgp); await parsed.read(msgbytes, allAllowedPackets);
return parsed[0].decrypt('test').then(() => { return parsed[0].decrypt('test').then(() => {
const key = parsed[0].sessionKey; const key = parsed[0].sessionKey;
@ -315,11 +316,11 @@ module.exports = () => describe("Packet", function() {
enc.sessionKey = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]); enc.sessionKey = new Uint8Array([1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2]);
enc.publicKeyAlgorithm = 'rsaEncryptSign'; enc.publicKeyAlgorithm = 'rsaEncryptSign';
enc.sessionKeyAlgorithm = 'aes256'; enc.sessionKeyAlgorithm = 'aes256';
enc.publicKeyId.bytes = '12345678'; enc.publicKeyID.bytes = '12345678';
return enc.encrypt({ publicParams, getFingerprintBytes() {} }).then(async () => { return enc.encrypt({ publicParams, getFingerprintBytes() {} }).then(async () => {
msg.push(enc); msg.push(enc);
await msg2.read(msg.write(), openpgp); await msg2.read(msg.write(), allAllowedPackets);
return msg2[0].decrypt({ algorithm: 'rsaEncryptSign', publicParams, privateParams, getFingerprintBytes() {} }).then(() => { return msg2[0].decrypt({ algorithm: 'rsaEncryptSign', publicParams, privateParams, getFingerprintBytes() {} }).then(() => {
expect(stringify(msg2[0].sessionKey)).to.equal(stringify(enc.sessionKey)); expect(stringify(msg2[0].sessionKey)).to.equal(stringify(enc.sessionKey));
@ -353,7 +354,7 @@ module.exports = () => describe("Packet", function() {
'-----END PGP PRIVATE KEY BLOCK-----'; '-----END PGP PRIVATE KEY BLOCK-----';
let key = new openpgp.PacketList(); let key = new openpgp.PacketList();
await key.read((await openpgp.unarmor(armored_key)).data, openpgp); await key.read((await openpgp.unarmor(armored_key)).data, allAllowedPackets);
key = key[0]; key = key[0];
const enc = new openpgp.PublicKeyEncryptedSessionKeyPacket(); const enc = new openpgp.PublicKeyEncryptedSessionKeyPacket();
@ -362,7 +363,7 @@ module.exports = () => describe("Packet", function() {
enc.sessionKey = secret; enc.sessionKey = secret;
enc.publicKeyAlgorithm = 'rsaEncryptSign'; enc.publicKeyAlgorithm = 'rsaEncryptSign';
enc.sessionKeyAlgorithm = 'aes256'; enc.sessionKeyAlgorithm = 'aes256';
enc.publicKeyId.bytes = '12345678'; enc.publicKeyID.bytes = '12345678';
return enc.encrypt(key).then(() => { return enc.encrypt(key).then(() => {
return enc.decrypt(key).then(() => { return enc.decrypt(key).then(() => {
@ -420,11 +421,11 @@ module.exports = () => describe("Packet", function() {
'-----END PGP MESSAGE-----'; '-----END PGP MESSAGE-----';
let key = new openpgp.PacketList(); let key = new openpgp.PacketList();
await key.read((await openpgp.unarmor(armored_key)).data, openpgp); await key.read((await openpgp.unarmor(armored_key)).data, allAllowedPackets);
key = key[3]; key = key[3];
const msg = new openpgp.PacketList(); const msg = new openpgp.PacketList();
await msg.read((await openpgp.unarmor(armored_msg)).data, openpgp); await msg.read((await openpgp.unarmor(armored_msg)).data, allAllowedPackets);
return msg[0].decrypt(key).then(async () => { return msg[0].decrypt(key).then(async () => {
await msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey); await msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
@ -462,7 +463,7 @@ module.exports = () => describe("Packet", function() {
await seip.encrypt(algo, key, undefined, openpgp.config); await seip.encrypt(algo, key, undefined, openpgp.config);
const msg2 = new openpgp.PacketList(); const msg2 = new openpgp.PacketList();
await msg2.read(msg.write(), openpgp); await msg2.read(msg.write(), allAllowedPackets);
await msg2[0].decrypt(passphrase); await msg2[0].decrypt(passphrase);
const key2 = msg2[0].sessionKey; const key2 = msg2[0].sessionKey;
@ -501,7 +502,7 @@ module.exports = () => describe("Packet", function() {
await aeadEnc.encrypt(algo, key, undefined, openpgp.config); await aeadEnc.encrypt(algo, key, undefined, openpgp.config);
const msg2 = new openpgp.PacketList(); const msg2 = new openpgp.PacketList();
await msg2.read(msg.write(), openpgp); await msg2.read(msg.write(), allAllowedPackets);
await msg2[0].decrypt(passphrase); await msg2[0].decrypt(passphrase);
const key2 = msg2[0].sessionKey; const key2 = msg2[0].sessionKey;
@ -567,7 +568,7 @@ module.exports = () => describe("Packet", function() {
const key = skesk.sessionKey; const key = skesk.sessionKey;
literal.setBytes(util.strToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary); literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
literal.filename = ''; literal.filename = '';
encData.packets.push(literal); encData.packets.push(literal);
await encData.encrypt(algo, key, undefined, openpgp.config); await encData.encrypt(algo, key, undefined, openpgp.config);
@ -576,7 +577,7 @@ module.exports = () => describe("Packet", function() {
expect(await openpgp.stream.readToEnd(openpgp.stream.clone(data))).to.deep.equal(packetBytes); expect(await openpgp.stream.readToEnd(openpgp.stream.clone(data))).to.deep.equal(packetBytes);
const msg2 = new openpgp.PacketList(); const msg2 = new openpgp.PacketList();
await msg2.read(data, openpgp); await msg2.read(data, allAllowedPackets);
await msg2[0].decrypt(passphrase); await msg2[0].decrypt(passphrase);
const key2 = msg2[0].sessionKey; const key2 = msg2[0].sessionKey;
@ -646,7 +647,7 @@ module.exports = () => describe("Packet", function() {
const key = key_enc.sessionKey; const key = key_enc.sessionKey;
literal.setBytes(util.strToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary); literal.setBytes(util.stringToUint8Array('Hello, world!\n'), openpgp.enums.literal.binary);
literal.filename = ''; literal.filename = '';
enc.packets.push(literal); enc.packets.push(literal);
await enc.encrypt(algo, key, undefined, openpgp.config); await enc.encrypt(algo, key, undefined, openpgp.config);
@ -655,7 +656,7 @@ module.exports = () => describe("Packet", function() {
expect(await openpgp.stream.readToEnd(openpgp.stream.clone(data))).to.deep.equal(packetBytes); expect(await openpgp.stream.readToEnd(openpgp.stream.clone(data))).to.deep.equal(packetBytes);
const msg2 = new openpgp.PacketList(); const msg2 = new openpgp.PacketList();
await msg2.read(data, openpgp); await msg2.read(data, allAllowedPackets);
await msg2[0].decrypt(passphrase); await msg2[0].decrypt(passphrase);
const key2 = msg2[0].sessionKey; const key2 = msg2[0].sessionKey;
@ -684,12 +685,12 @@ module.exports = () => describe("Packet", function() {
'-----END PGP MESSAGE-----'; '-----END PGP MESSAGE-----';
let key = new openpgp.PacketList(); let key = new openpgp.PacketList();
await key.read((await openpgp.unarmor(armored_key)).data, openpgp); await key.read((await openpgp.unarmor(armored_key)).data, allAllowedPackets);
key = key[3]; key = key[3];
await key.decrypt('test'); await key.decrypt('test');
const msg = new openpgp.PacketList(); const msg = new openpgp.PacketList();
await msg.read((await openpgp.unarmor(armored_msg)).data, openpgp); await msg.read((await openpgp.unarmor(armored_msg)).data, allAllowedPackets);
return msg[0].decrypt(key).then(async () => { return msg[0].decrypt(key).then(async () => {
await msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey); await msg[1].decrypt(msg[0].sessionKeyAlgorithm, msg[0].sessionKey);
@ -702,13 +703,13 @@ module.exports = () => describe("Packet", function() {
it('Secret key reading with signature verification.', async function() { it('Secret key reading with signature verification.', async function() {
const packets = new openpgp.PacketList(); const packets = new openpgp.PacketList();
await packets.read((await openpgp.unarmor(armored_key)).data, openpgp); await packets.read((await openpgp.unarmor(armored_key)).data, allAllowedPackets);
const [keyPacket, userIdPacket, keySigPacket, subkeyPacket, subkeySigPacket] = packets; const [keyPacket, userIDPacket, keySigPacket, subkeyPacket, subkeySigPacket] = packets;
expect(keySigPacket.verified).to.be.null; expect(keySigPacket.verified).to.be.null;
expect(subkeySigPacket.verified).to.be.null; expect(subkeySigPacket.verified).to.be.null;
await keySigPacket.verify( await keySigPacket.verify(
keyPacket, openpgp.enums.signature.certGeneric, { userId: userIdPacket, key: keyPacket } keyPacket, openpgp.enums.signature.certGeneric, { userID: userIDPacket, key: keyPacket }
).then(async () => expect(keySigPacket.verified).to.be.true); ).then(async () => expect(keySigPacket.verified).to.be.true);
await subkeySigPacket.verify( await subkeySigPacket.verify(
keyPacket, openpgp.enums.signature.keyBinding, { key: keyPacket, bind: subkeyPacket } keyPacket, openpgp.enums.signature.keyBinding, { key: keyPacket, bind: subkeyPacket }
@ -733,13 +734,13 @@ module.exports = () => describe("Packet", function() {
'-----END PGP MESSAGE-----'; '-----END PGP MESSAGE-----';
const packets = new openpgp.PacketList(); const packets = new openpgp.PacketList();
await packets.read((await openpgp.unarmor(armored_key)).data, openpgp); await packets.read((await openpgp.unarmor(armored_key)).data, allAllowedPackets);
const keyPacket = packets[0]; const keyPacket = packets[0];
const subkeyPacket = packets[3]; const subkeyPacket = packets[3];
await subkeyPacket.decrypt('test'); await subkeyPacket.decrypt('test');
const msg = new openpgp.PacketList(); const msg = new openpgp.PacketList();
await msg.read((await openpgp.unarmor(armored_msg)).data, openpgp); await msg.read((await openpgp.unarmor(armored_msg)).data, allAllowedPackets);
const [pkesk, encData] = msg; const [pkesk, encData] = msg;
return pkesk.decrypt(subkeyPacket).then(async () => { return pkesk.decrypt(subkeyPacket).then(async () => {
@ -757,7 +758,7 @@ module.exports = () => describe("Packet", function() {
}); });
}); });
it('Reading signersUserId from armored signature', async function() { it('Reading signersUserID from armored signature', async function() {
const armoredSignature = const armoredSignature =
`-----BEGIN PGP SIGNATURE----- `-----BEGIN PGP SIGNATURE-----
@ -773,7 +774,7 @@ kePFjAnu9cpynKXu3usf8+FuBw2zLsg1Id1n7ttxoAte416KjBN9lFBt8mcu
const signature = await openpgp.readSignature({ armoredSignature }); const signature = await openpgp.readSignature({ armoredSignature });
expect(signature.packets[0].signersUserId).to.equal('test-wkd@metacode.biz'); expect(signature.packets[0].signersUserID).to.equal('test-wkd@metacode.biz');
}); });
it('Reading notations from armored key', async function() { it('Reading notations from armored key', async function() {
@ -844,12 +845,12 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
secretKeyPacket.algorithm = "rsaSign"; secretKeyPacket.algorithm = "rsaSign";
secretKeyPacket.isEncrypted = false; secretKeyPacket.isEncrypted = false;
await secretKeyPacket.encrypt('hello', { ...openpgp.config, aeadProtect: true }); await secretKeyPacket.encrypt('hello', { ...openpgp.config, aeadProtect: true });
expect(secretKeyPacket.s2k_usage).to.equal(253); expect(secretKeyPacket.s2kUsage).to.equal(253);
const raw = new openpgp.PacketList(); const raw = new openpgp.PacketList();
raw.push(secretKeyPacket); raw.push(secretKeyPacket);
const packetList = new openpgp.PacketList(); const packetList = new openpgp.PacketList();
await packetList.read(raw.write(), openpgp, undefined, openpgp.config); await packetList.read(raw.write(), allAllowedPackets, undefined, openpgp.config);
const secretKeyPacket2 = packetList[0]; const secretKeyPacket2 = packetList[0];
await secretKeyPacket2.decrypt('hello'); await secretKeyPacket2.decrypt('hello');
@ -866,12 +867,12 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
secretKeyPacket.algorithm = "rsaSign"; secretKeyPacket.algorithm = "rsaSign";
secretKeyPacket.isEncrypted = false; secretKeyPacket.isEncrypted = false;
await secretKeyPacket.encrypt('hello', { ...openpgp.config, aeadProtect: false }); await secretKeyPacket.encrypt('hello', { ...openpgp.config, aeadProtect: false });
expect(secretKeyPacket.s2k_usage).to.equal(254); expect(secretKeyPacket.s2kUsage).to.equal(254);
const raw = new openpgp.PacketList(); const raw = new openpgp.PacketList();
raw.push(secretKeyPacket); raw.push(secretKeyPacket);
const packetList = new openpgp.PacketList(); const packetList = new openpgp.PacketList();
await packetList.read(raw.write(), openpgp, undefined, openpgp.config); await packetList.read(raw.write(), allAllowedPackets, undefined, openpgp.config);
const secretKeyPacket2 = packetList[0]; const secretKeyPacket2 = packetList[0];
await secretKeyPacket2.decrypt('hello'); await secretKeyPacket2.decrypt('hello');
}); });
@ -905,7 +906,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
const raw = signed.write(); const raw = signed.write();
const signed2 = new openpgp.PacketList(); const signed2 = new openpgp.PacketList();
await signed2.read(raw, openpgp); await signed2.read(raw, allAllowedPackets);
signed2.concat(await openpgp.stream.readToEnd(signed2.stream, arr => arr)); signed2.concat(await openpgp.stream.readToEnd(signed2.stream, arr => arr));
await Promise.all([ await Promise.all([

View File

@ -884,8 +884,8 @@ hUhMKMuiM3pRwdIyDOItkUWQmjEEw7/XmhgInkXsCw==
await expect(openpgp.sign({ await expect(openpgp.sign({
message: openpgp.Message.fromText('test'), privateKeys: [priv_key_gnupg_ext], config: { rejectPublicKeyAlgorithms: new Set() } message: openpgp.Message.fromText('test'), privateKeys: [priv_key_gnupg_ext], config: { rejectPublicKeyAlgorithms: new Set() }
})).to.eventually.be.rejectedWith(/Cannot sign with a gnu-dummy key/); })).to.eventually.be.rejectedWith(/Cannot sign with a gnu-dummy key/);
await expect(openpgp.reformatKey({ userIds: { name: 'test' }, privateKey: priv_key_gnupg_ext })).to.eventually.be.rejectedWith(/Cannot reformat a gnu-dummy primary key/); await expect(openpgp.reformatKey({ userIDs: { name: 'test' }, privateKey: priv_key_gnupg_ext })).to.eventually.be.rejectedWith(/Cannot reformat a gnu-dummy primary key/);
await expect(openpgp.reformatKey({ userIds: { name: 'test' }, privateKey: priv_key_gnupg_ext_2, passphrase: 'test' })).to.eventually.be.rejectedWith(/Cannot reformat a gnu-dummy primary key/); await expect(openpgp.reformatKey({ userIDs: { name: 'test' }, privateKey: priv_key_gnupg_ext_2, passphrase: 'test' })).to.eventually.be.rejectedWith(/Cannot reformat a gnu-dummy primary key/);
await priv_key_gnupg_ext.encrypt("abcd"); await priv_key_gnupg_ext.encrypt("abcd");
expect(priv_key_gnupg_ext.isDecrypted()).to.be.false; expect(priv_key_gnupg_ext.isDecrypted()).to.be.false;
const primaryKey_packet2 = priv_key_gnupg_ext.primaryKey.write(); const primaryKey_packet2 = priv_key_gnupg_ext.primaryKey.write();
@ -918,10 +918,10 @@ hUhMKMuiM3pRwdIyDOItkUWQmjEEw7/XmhgInkXsCw==
}); });
it('Verify V4 signature. Hash: SHA1. PK: RSA. Signature Type: 0x00 (binary document)', async function() { it('Verify V4 signature. Hash: SHA1. PK: RSA. Signature Type: 0x00 (binary document)', async function() {
const { rejectMessageHashAlgorithms, minRsaBits } = openpgp.config; const { rejectMessageHashAlgorithms, minRSABits } = openpgp.config;
Object.assign(openpgp.config, { Object.assign(openpgp.config, {
rejectMessageHashAlgorithms: new Set([openpgp.enums.hash.md5, openpgp.enums.hash.ripemd]), rejectMessageHashAlgorithms: new Set([openpgp.enums.hash.md5, openpgp.enums.hash.ripemd]),
minRsaBits: 1024 minRSABits: 1024
}); });
try { try {
const signedArmor = const signedArmor =
@ -945,7 +945,7 @@ hUhMKMuiM3pRwdIyDOItkUWQmjEEw7/XmhgInkXsCw==
expect(await verified[0].verified).to.be.true; expect(await verified[0].verified).to.be.true;
expect((await verified[0].signature).packets.length).to.equal(1); expect((await verified[0].signature).packets.length).to.equal(1);
} finally { } finally {
Object.assign(openpgp.config, { rejectMessageHashAlgorithms, minRsaBits }); Object.assign(openpgp.config, { rejectMessageHashAlgorithms, minRSABits });
} }
}); });
@ -971,9 +971,9 @@ hUhMKMuiM3pRwdIyDOItkUWQmjEEw7/XmhgInkXsCw==
const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 }); const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 });
await Promise.all(esMsg.getEncryptionKeyIds().map(keyId => privKey.decrypt('hello world', keyId))); await Promise.all(esMsg.getEncryptionKeyIDs().map(keyID => privKey.decrypt('hello world', keyID)));
return openpgp.decrypt({ privateKeys: privKey, publicKeys:[pubKey], message:esMsg, config: { minRsaBits: 1024 } }).then(function(decrypted) { return openpgp.decrypt({ privateKeys: privKey, publicKeys:[pubKey], message:esMsg, config: { minRSABits: 1024 } }).then(function(decrypted) {
expect(decrypted.data).to.exist; expect(decrypted.data).to.exist;
expect(decrypted.data).to.equal(plaintext); expect(decrypted.data).to.equal(plaintext);
expect(decrypted.signatures).to.have.length(1); expect(decrypted.signatures).to.have.length(1);
@ -1005,11 +1005,11 @@ hUhMKMuiM3pRwdIyDOItkUWQmjEEw7/XmhgInkXsCw==
const pubKey2 = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const pubKey2 = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const pubKey3 = await openpgp.readKey({ armoredKey: pub_key_arm3 }); const pubKey3 = await openpgp.readKey({ armoredKey: pub_key_arm3 });
const keyids = sMsg.getSigningKeyIds(); const keyIDs = sMsg.getSigningKeyIDs();
expect(pubKey2.getKeys(keyids[1])).to.not.be.empty; expect(pubKey2.getKeys(keyIDs[1])).to.not.be.empty;
expect(pubKey3.getKeys(keyids[0])).to.not.be.empty; expect(pubKey3.getKeys(keyIDs[0])).to.not.be.empty;
const { data, signatures } = await openpgp.verify({ message: sMsg, publicKeys: [pubKey2, pubKey3], config: { minRsaBits: 1024 } }); const { data, signatures } = await openpgp.verify({ message: sMsg, publicKeys: [pubKey2, pubKey3], config: { minRSABits: 1024 } });
expect(data).to.equal(plaintext); expect(data).to.equal(plaintext);
expect(signatures).to.exist; expect(signatures).to.exist;
expect(signatures).to.have.length(2); expect(signatures).to.have.length(2);
@ -1022,7 +1022,7 @@ hUhMKMuiM3pRwdIyDOItkUWQmjEEw7/XmhgInkXsCw==
it('Verify fails with signed message with critical notations', async function() { it('Verify fails with signed message with critical notations', async function() {
const message = await openpgp.readMessage({ armoredMessage: signature_with_critical_notation }); const message = await openpgp.readMessage({ armoredMessage: signature_with_critical_notation });
const key = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const key = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const { signatures: [sig] } = await openpgp.verify({ message, publicKeys: key, config: { minRsaBits: 1024 } }); const { signatures: [sig] } = await openpgp.verify({ message, publicKeys: key, config: { minRSABits: 1024 } });
expect(sig.valid).to.be.false; expect(sig.valid).to.be.false;
expect(sig.error).to.match(/Unknown critical notation: test@example.com/); expect(sig.error).to.match(/Unknown critical notation: test@example.com/);
}); });
@ -1031,7 +1031,7 @@ hUhMKMuiM3pRwdIyDOItkUWQmjEEw7/XmhgInkXsCw==
const message = await openpgp.readMessage({ armoredMessage: signature_with_critical_notation }); const message = await openpgp.readMessage({ armoredMessage: signature_with_critical_notation });
const key = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const key = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const config = { knownNotations: ['test@example.com'], minRsaBits: 1024 }; const config = { knownNotations: ['test@example.com'], minRSABits: 1024 };
const { signatures: [sig] } = await openpgp.verify({ message, publicKeys: key, config }); const { signatures: [sig] } = await openpgp.verify({ message, publicKeys: key, config });
expect(sig.valid).to.be.true; expect(sig.valid).to.be.true;
}); });
@ -1065,12 +1065,12 @@ hUhMKMuiM3pRwdIyDOItkUWQmjEEw7/XmhgInkXsCw==
const pubKey2 = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const pubKey2 = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const pubKey3 = await openpgp.readKey({ armoredKey: pub_key_arm3 }); const pubKey3 = await openpgp.readKey({ armoredKey: pub_key_arm3 });
const keyids = message.getSigningKeyIds(); const keyIDs = message.getSigningKeyIDs();
expect(pubKey2.getKeys(keyids[0])).to.not.be.empty; expect(pubKey2.getKeys(keyIDs[0])).to.not.be.empty;
expect(pubKey3.getKeys(keyids[1])).to.not.be.empty; expect(pubKey3.getKeys(keyIDs[1])).to.not.be.empty;
return openpgp.verify({ publicKeys:[pubKey2, pubKey3], message, config: { minRsaBits: 1024 } }).then(function(cleartextSig) { return openpgp.verify({ publicKeys:[pubKey2, pubKey3], message, config: { minRSABits: 1024 } }).then(function(cleartextSig) {
expect(cleartextSig).to.exist; expect(cleartextSig).to.exist;
expect(cleartextSig.data).to.equal(plaintext); expect(cleartextSig.data).to.equal(plaintext);
expect(cleartextSig.signatures).to.have.length(2); expect(cleartextSig.signatures).to.have.length(2);
@ -1139,14 +1139,14 @@ zmuVOdNuWQqxT9Sqa84=
const message = await openpgp.readCleartextMessage({ cleartextMessage }); const message = await openpgp.readCleartextMessage({ cleartextMessage });
const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const keyids = message.getSigningKeyIds(); const keyIDs = message.getSigningKeyIDs();
expect(pubKey.getKeys(keyids[0])).to.not.be.empty; expect(pubKey.getKeys(keyIDs[0])).to.not.be.empty;
const cleartextSig = await openpgp.verify({ const cleartextSig = await openpgp.verify({
publicKeys:[pubKey], publicKeys:[pubKey],
message, message,
config: { minRsaBits: 1024, rejectMessageHashAlgorithms: new Set() } config: { minRSABits: 1024, rejectMessageHashAlgorithms: new Set() }
}); });
expect(cleartextSig).to.exist; expect(cleartextSig).to.exist;
expect(cleartextSig.data).to.equal(plaintext.replace(/[ \t]+$/mg, '')); expect(cleartextSig.data).to.equal(plaintext.replace(/[ \t]+$/mg, ''));
@ -1174,10 +1174,10 @@ yYDnCgA=
const message = await openpgp.readMessage({ armoredMessage }); const message = await openpgp.readMessage({ armoredMessage });
const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const keyids = message.getSigningKeyIds(); const keyIDs = message.getSigningKeyIDs();
expect(pubKey.getKeys(keyids[0])).to.not.be.empty; expect(pubKey.getKeys(keyIDs[0])).to.not.be.empty;
return openpgp.verify({ publicKeys: [pubKey], message, config: { minRsaBits: 1024 } }).then(({ data, signatures }) => { return openpgp.verify({ publicKeys: [pubKey], message, config: { minRSABits: 1024 } }).then(({ data, signatures }) => {
expect(data).to.equal(plaintext); expect(data).to.equal(plaintext);
expect(signatures).to.have.length(1); expect(signatures).to.have.length(1);
expect(signatures[0].valid).to.equal(!openpgp.config.rejectMessageHashAlgorithms.has(openpgp.enums.hash.sha1)); expect(signatures[0].valid).to.equal(!openpgp.config.rejectMessageHashAlgorithms.has(openpgp.enums.hash.sha1));
@ -1211,10 +1211,10 @@ yYDnCgA=
}); });
const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const keyids = message.getSigningKeyIds(); const keyIDs = message.getSigningKeyIDs();
expect(pubKey.getKeys(keyids[0])).to.not.be.empty; expect(pubKey.getKeys(keyIDs[0])).to.not.be.empty;
return openpgp.verify({ publicKeys: [pubKey], message, config: { minRsaBits: 1024 } }).then(async function(cleartextSig) { return openpgp.verify({ publicKeys: [pubKey], message, config: { minRSABits: 1024 } }).then(async function(cleartextSig) {
expect(cleartextSig).to.exist; expect(cleartextSig).to.exist;
expect(await openpgp.stream.readToEnd(cleartextSig.data)).to.equal(plaintext); expect(await openpgp.stream.readToEnd(cleartextSig.data)).to.equal(plaintext);
expect(cleartextSig.signatures).to.have.length(1); expect(cleartextSig.signatures).to.have.length(1);
@ -1243,10 +1243,10 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
const message = await openpgp.readMessage({ armoredMessage }); const message = await openpgp.readMessage({ armoredMessage });
const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const keyids = message.getSigningKeyIds(); const keyIDs = message.getSigningKeyIDs();
expect(pubKey.getKeys(keyids[0])).to.not.be.empty; expect(pubKey.getKeys(keyIDs[0])).to.not.be.empty;
return openpgp.verify({ publicKeys: [pubKey], message, config: { minRsaBits: 1024 } }).then(async ({ data, signatures }) => { return openpgp.verify({ publicKeys: [pubKey], message, config: { minRSABits: 1024 } }).then(async ({ data, signatures }) => {
expect(data).to.equal(plaintext); expect(data).to.equal(plaintext);
expect(signatures).to.have.length(0); expect(signatures).to.have.length(0);
}); });
@ -1276,10 +1276,10 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
}); });
const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const keyids = message.getSigningKeyIds(); const keyIDs = message.getSigningKeyIDs();
expect(pubKey.getKeys(keyids[0])).to.not.be.empty; expect(pubKey.getKeys(keyIDs[0])).to.not.be.empty;
return openpgp.verify({ publicKeys: [pubKey], message, config: { minRsaBits: 1024 } }).then(async ({ data, signatures }) => { return openpgp.verify({ publicKeys: [pubKey], message, config: { minRSABits: 1024 } }).then(async ({ data, signatures }) => {
expect(await openpgp.stream.readToEnd(data)).to.equal(plaintext); expect(await openpgp.stream.readToEnd(data)).to.equal(plaintext);
expect(signatures).to.have.length(1); expect(signatures).to.have.length(1);
await expect(signatures[0].verified).to.be.rejectedWith('Corresponding signature packet missing'); await expect(signatures[0].verified).to.be.rejectedWith('Corresponding signature packet missing');
@ -1308,7 +1308,7 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 }); const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 });
await privKey.decrypt('hello world'); await privKey.decrypt('hello world');
const config = { minRsaBits: 1024 }; const config = { minRSABits: 1024 };
return openpgp.sign({ privateKeys:[privKey], message: openpgp.CleartextMessage.fromText(plaintext), config }).then(async function(signed) { return openpgp.sign({ privateKeys:[privKey], message: openpgp.CleartextMessage.fromText(plaintext), config }).then(async function(signed) {
const message = await openpgp.readCleartextMessage({ cleartextMessage: signed }); const message = await openpgp.readCleartextMessage({ cleartextMessage: signed });
@ -1328,7 +1328,7 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 }); const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 });
await privKey.decrypt('hello world'); await privKey.decrypt('hello world');
const config = { minRsaBits: 1024 }; const config = { minRSABits: 1024 };
return openpgp.sign({ privateKeys:[privKey], message: openpgp.CleartextMessage.fromText(plaintext), config }).then(async function(signed) { return openpgp.sign({ privateKeys:[privKey], message: openpgp.CleartextMessage.fromText(plaintext), config }).then(async function(signed) {
const message = await openpgp.readCleartextMessage({ cleartextMessage: signed }); const message = await openpgp.readCleartextMessage({ cleartextMessage: signed });
@ -1348,7 +1348,7 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 }); const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 });
await privKey.decrypt('hello world'); await privKey.decrypt('hello world');
const config = { minRsaBits: 1024 }; const config = { minRSABits: 1024 };
return openpgp.sign({ privateKeys:[privKey], message: openpgp.CleartextMessage.fromText(plaintext), config }).then(async function(signed) { return openpgp.sign({ privateKeys:[privKey], message: openpgp.CleartextMessage.fromText(plaintext), config }).then(async function(signed) {
const message = await openpgp.readCleartextMessage({ cleartextMessage: signed }); const message = await openpgp.readCleartextMessage({ cleartextMessage: signed });
@ -1363,12 +1363,12 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
}); });
it('Sign text with openpgp.sign and verify with openpgp.verify leads to same bytes cleartext and valid signatures - armored', async function() { it('Sign text with openpgp.sign and verify with openpgp.verify leads to same bytes cleartext and valid signatures - armored', async function() {
const plaintext = util.strToUint8Array('short message\nnext line \n한국어/조선말'); const plaintext = util.stringToUint8Array('short message\nnext line \n한국어/조선말');
const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 }); const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 });
await privKey.decrypt('hello world'); await privKey.decrypt('hello world');
const config = { minRsaBits: 1024 }; const config = { minRSABits: 1024 };
return openpgp.sign({ privateKeys:[privKey], message: openpgp.Message.fromBinary(plaintext), config }).then(async function(signed) { return openpgp.sign({ privateKeys:[privKey], message: openpgp.Message.fromBinary(plaintext), config }).then(async function(signed) {
const message = await openpgp.readMessage({ armoredMessage: signed }); const message = await openpgp.readMessage({ armoredMessage: signed });
@ -1383,12 +1383,12 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
}); });
it('Sign text with openpgp.sign and verify with openpgp.verify leads to same bytes cleartext and valid signatures - not armored', async function() { it('Sign text with openpgp.sign and verify with openpgp.verify leads to same bytes cleartext and valid signatures - not armored', async function() {
const plaintext = util.strToUint8Array('short message\nnext line \n한국어/조선말'); const plaintext = util.stringToUint8Array('short message\nnext line \n한국어/조선말');
const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 }); const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 });
await privKey.decrypt('hello world'); await privKey.decrypt('hello world');
const config = { minRsaBits: 1024 }; const config = { minRSABits: 1024 };
return openpgp.sign({ privateKeys:[privKey], message: openpgp.Message.fromBinary(plaintext), armor:false, config }).then(async function(signed) { return openpgp.sign({ privateKeys:[privKey], message: openpgp.Message.fromBinary(plaintext), armor:false, config }).then(async function(signed) {
const message = await openpgp.readMessage({ binaryMessage: signed }); const message = await openpgp.readMessage({ binaryMessage: signed });
@ -1408,10 +1408,10 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 }); const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 });
await privKey.decrypt('hello world'); await privKey.decrypt('hello world');
const config = { minRsaBits: 1024 }; const config = { minRSABits: 1024 };
return openpgp.sign({ privateKeys:[privKey], message: openpgp.Message.fromText(plaintext), detached: true, config }).then(async function(armoredSignature) { return openpgp.sign({ privateKeys:[privKey], message: openpgp.Message.fromText(plaintext), detached: true, config }).then(async function(armoredSignature) {
const signature = await openpgp.readSignature({ armoredSignature }); const signature = await openpgp.readSignature({ armoredSignature });
return openpgp.verify({ publicKeys:[pubKey], message: openpgp.Message.fromBinary(util.encodeUtf8(plaintext)), signature, config }); return openpgp.verify({ publicKeys:[pubKey], message: openpgp.Message.fromBinary(util.encodeUTF8(plaintext)), signature, config });
}).then(function({ data, signatures }) { }).then(function({ data, signatures }) {
expect(data).to.equal(plaintext); expect(data).to.equal(plaintext);
expect(signatures).to.have.length(1); expect(signatures).to.have.length(1);
@ -1421,13 +1421,13 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
}); });
it('Should verify cleartext message correctly when using a detached binary signature and text literal data', async function () { it('Should verify cleartext message correctly when using a detached binary signature and text literal data', async function () {
const plaintext = util.encodeUtf8('short message\nnext line \n한국어/조선말'); const plaintext = util.encodeUTF8('short message\nnext line \n한국어/조선말');
const binaryPlaintext = util.encodeUtf8(plaintext); const binaryPlaintext = util.encodeUTF8(plaintext);
const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const pubKey = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 }); const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 });
await privKey.decrypt('hello world'); await privKey.decrypt('hello world');
const config = { minRsaBits: 1024 }; const config = { minRSABits: 1024 };
return openpgp.sign({ privateKeys:[privKey], message:openpgp.Message.fromBinary(binaryPlaintext), detached: true, config }).then(async function(armoredSignature) { return openpgp.sign({ privateKeys:[privKey], message:openpgp.Message.fromBinary(binaryPlaintext), detached: true, config }).then(async function(armoredSignature) {
const signature = await openpgp.readSignature({ armoredSignature }); const signature = await openpgp.readSignature({ armoredSignature });
return openpgp.verify({ publicKeys:[pubKey], message: openpgp.Message.fromText(plaintext), signature, config }); return openpgp.verify({ publicKeys:[pubKey], message: openpgp.Message.fromText(plaintext), signature, config });
@ -1445,10 +1445,10 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 }); const privKey = await openpgp.readKey({ armoredKey: priv_key_arm2 });
await privKey.decrypt('hello world'); await privKey.decrypt('hello world');
const config = { minRsaBits: 1024 }; const config = { minRSABits: 1024 };
return openpgp.sign({ privateKeys:[privKey], message: openpgp.Message.fromText(plaintext), detached: true, config }).then(async function(armoredSignature) { return openpgp.sign({ privateKeys:[privKey], message: openpgp.Message.fromText(plaintext), detached: true, config }).then(async function(armoredSignature) {
const signature = await openpgp.readSignature({ armoredSignature }); const signature = await openpgp.readSignature({ armoredSignature });
return openpgp.encrypt({ message: openpgp.Message.fromBinary(util.encodeUtf8(plaintext)), publicKeys: [pubKey], signature, config }); return openpgp.encrypt({ message: openpgp.Message.fromBinary(util.encodeUTF8(plaintext)), publicKeys: [pubKey], signature, config });
}).then(async armoredMessage => { }).then(async armoredMessage => {
const message = await openpgp.readMessage({ armoredMessage }); const message = await openpgp.readMessage({ armoredMessage });
@ -1567,7 +1567,7 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
const message = openpgp.Message.fromText(content); const message = openpgp.Message.fromText(content);
await message.appendSignature(detachedSig); await message.appendSignature(detachedSig);
const { data, signatures } = await openpgp.verify({ publicKeys:[publicKey], message, config: { minRsaBits: 1024 } }); const { data, signatures } = await openpgp.verify({ publicKeys:[publicKey], message, config: { minRSABits: 1024 } });
expect(data).to.equal(content); expect(data).to.equal(content);
expect(signatures).to.have.length(1); expect(signatures).to.have.length(1);
expect(signatures[0].valid).to.be.true; expect(signatures[0].valid).to.be.true;
@ -1581,18 +1581,18 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
const privKey2 = await openpgp.readKey({ armoredKey: priv_key_arm2 }); const privKey2 = await openpgp.readKey({ armoredKey: priv_key_arm2 });
await privKey2.decrypt('hello world'); await privKey2.decrypt('hello world');
const opt = { rsaBits: 2048, userIds: { name:'test', email:'a@b.com' }, passphrase: null }; const opt = { rsaBits: 2048, userIDs: { name:'test', email:'a@b.com' }, passphrase: null };
const { key: generatedKey } = await openpgp.generateKey(opt); const { key: generatedKey } = await openpgp.generateKey(opt);
const armoredSignature = await openpgp.sign({ privateKeys:[generatedKey, privKey2], message, detached: true, config: { minRsaBits: 1024 } }); const armoredSignature = await openpgp.sign({ privateKeys:[generatedKey, privKey2], message, detached: true, config: { minRSABits: 1024 } });
const signature = await openpgp.readSignature({ armoredSignature }); const signature = await openpgp.readSignature({ armoredSignature });
const { data, signatures } = await openpgp.verify({ publicKeys:[generatedKey.toPublic(), pubKey2], message, signature, config: { minRsaBits: 1024 } }); const { data, signatures } = await openpgp.verify({ publicKeys:[generatedKey.toPublic(), pubKey2], message, signature, config: { minRSABits: 1024 } });
expect(data).to.equal('hello'); expect(data).to.equal('hello');
expect(await signatures[0].verified).to.be.true; expect(await signatures[0].verified).to.be.true;
expect(await signatures[1].verified).to.be.true; expect(await signatures[1].verified).to.be.true;
}); });
it('Sign message with key without password', function() { it('Sign message with key without password', function() {
const opt = { userIds: { name:'test', email:'a@b.com' }, passphrase: null }; const opt = { userIDs: { name:'test', email:'a@b.com' }, passphrase: null };
return openpgp.generateKey(opt).then(function(gen) { return openpgp.generateKey(opt).then(function(gen) {
const key = gen.key; const key = gen.key;
const message = openpgp.Message.fromText('hello world'); const message = openpgp.Message.fromText('hello world');
@ -1632,9 +1632,9 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
const signerKey = await openpgp.readKey({ armoredKey: priv_key_arm1 }); const signerKey = await openpgp.readKey({ armoredKey: priv_key_arm1 });
return signedKey.verifyPrimaryUser([signerKey], undefined, undefined, { ...openpgp.config, rejectPublicKeyAlgorithms: new Set() }).then(signatures => { return signedKey.verifyPrimaryUser([signerKey], undefined, undefined, { ...openpgp.config, rejectPublicKeyAlgorithms: new Set() }).then(signatures => {
expect(signatures[0].valid).to.be.null; expect(signatures[0].valid).to.be.null;
expect(signatures[0].keyid.toHex()).to.equal(signedKey.getKeyId().toHex()); expect(signatures[0].keyID.toHex()).to.equal(signedKey.getKeyID().toHex());
expect(signatures[1].valid).to.be.true; expect(signatures[1].valid).to.be.true;
expect(signatures[1].keyid.toHex()).to.equal(signerKey.getKeyId().toHex()); expect(signatures[1].keyID.toHex()).to.equal(signerKey.getKeyID().toHex());
}); });
}); });
@ -1732,7 +1732,7 @@ oaBUyhCKt8tz6Q==
message: await openpgp.readMessage({ armoredMessage: encrypted }), message: await openpgp.readMessage({ armoredMessage: encrypted }),
publicKeys: key, publicKeys: key,
privateKeys: key, privateKeys: key,
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(decrypted.signatures[0].valid).to.be.true; expect(decrypted.signatures[0].valid).to.be.true;
}); });

View File

@ -184,8 +184,8 @@ function tests() {
dataArrived(); // Do not wait until data arrived. dataArrived(); // Do not wait until data arrived.
const data = new ReadableStream({ const data = new ReadableStream({
async start(controller) { async start(controller) {
controller.enqueue(util.strToUint8Array('hello ')); controller.enqueue(util.stringToUint8Array('hello '));
controller.enqueue(util.strToUint8Array('world')); controller.enqueue(util.stringToUint8Array('world'));
controller.close(); controller.close();
} }
}); });
@ -238,7 +238,7 @@ function tests() {
const signed = await openpgp.sign({ const signed = await openpgp.sign({
message: openpgp.Message.fromBinary(data), message: openpgp.Message.fromBinary(data),
privateKeys: privKey, privateKeys: privKey,
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
const reader = openpgp.stream.getReader(signed); const reader = openpgp.stream.getReader(signed);
expect(await reader.readBytes(1024)).to.match(/^-----BEGIN PGP MESSAGE-----\n/); expect(await reader.readBytes(1024)).to.match(/^-----BEGIN PGP MESSAGE-----\n/);
@ -314,7 +314,7 @@ function tests() {
publicKeys: pubKey, publicKeys: pubKey,
privateKeys: privKey, privateKeys: privKey,
armor: false, armor: false,
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(openpgp.stream.isStream(encrypted)).to.equal(expectedType); expect(openpgp.stream.isStream(encrypted)).to.equal(expectedType);
@ -446,7 +446,7 @@ function tests() {
message: openpgp.Message.fromBinary(data), message: openpgp.Message.fromBinary(data),
publicKeys: pubKey, publicKeys: pubKey,
privateKeys: privKey, privateKeys: privKey,
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(openpgp.stream.isStream(encrypted)).to.equal(expectedType); expect(openpgp.stream.isStream(encrypted)).to.equal(expectedType);
@ -484,7 +484,7 @@ function tests() {
message: openpgp.Message.fromBinary(data), message: openpgp.Message.fromBinary(data),
publicKeys: pubKey, publicKeys: pubKey,
privateKeys: privKey, privateKeys: privKey,
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(openpgp.stream.isStream(encrypted)).to.equal(expectedType); expect(openpgp.stream.isStream(encrypted)).to.equal(expectedType);
@ -518,7 +518,7 @@ function tests() {
const signed = await openpgp.sign({ const signed = await openpgp.sign({
message: openpgp.Message.fromBinary(data), message: openpgp.Message.fromBinary(data),
privateKeys: privKey, privateKeys: privKey,
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(openpgp.stream.isStream(signed)).to.equal(expectedType); expect(openpgp.stream.isStream(signed)).to.equal(expectedType);
@ -535,7 +535,7 @@ function tests() {
message, message,
streaming: expectedType, streaming: expectedType,
format: 'binary', format: 'binary',
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(openpgp.stream.isStream(verified.data)).to.equal(expectedType); expect(openpgp.stream.isStream(verified.data)).to.equal(expectedType);
const reader = openpgp.stream.getReader(verified.data); const reader = openpgp.stream.getReader(verified.data);
@ -574,7 +574,7 @@ function tests() {
const signed = await openpgp.sign({ const signed = await openpgp.sign({
message: openpgp.Message.fromBinary(data), message: openpgp.Message.fromBinary(data),
privateKeys: privKey, privateKeys: privKey,
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(openpgp.stream.isStream(signed)).to.equal(expectedType); expect(openpgp.stream.isStream(signed)).to.equal(expectedType);
@ -583,7 +583,7 @@ function tests() {
publicKeys: pubKey, publicKeys: pubKey,
message, message,
format: 'binary', format: 'binary',
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(openpgp.stream.isStream(verified.data)).to.equal(expectedType); expect(openpgp.stream.isStream(verified.data)).to.equal(expectedType);
const reader = openpgp.stream.getReader(verified.data); const reader = openpgp.stream.getReader(verified.data);
@ -614,7 +614,7 @@ function tests() {
const signed = await openpgp.sign({ const signed = await openpgp.sign({
message: openpgp.Message.fromBinary(data), message: openpgp.Message.fromBinary(data),
privateKeys: privKey, privateKeys: privKey,
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(openpgp.stream.isStream(signed)).to.equal(expectedType); expect(openpgp.stream.isStream(signed)).to.equal(expectedType);
@ -629,7 +629,7 @@ function tests() {
const signed = await openpgp.sign({ const signed = await openpgp.sign({
message: openpgp.Message.fromBinary(data), message: openpgp.Message.fromBinary(data),
privateKeys: privKey, privateKeys: privKey,
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(openpgp.stream.isStream(signed)).to.equal(expectedType); expect(openpgp.stream.isStream(signed)).to.equal(expectedType);
const message = await openpgp.readMessage({ armoredMessage: signed }); const message = await openpgp.readMessage({ armoredMessage: signed });
@ -650,8 +650,8 @@ function tests() {
dataArrived(); // Do not wait until data arrived. dataArrived(); // Do not wait until data arrived.
const data = new ReadableStream({ const data = new ReadableStream({
async start(controller) { async start(controller) {
controller.enqueue(util.strToUint8Array('hello ')); controller.enqueue(util.stringToUint8Array('hello '));
controller.enqueue(util.strToUint8Array('world')); controller.enqueue(util.stringToUint8Array('world'));
controller.close(); controller.close();
} }
}); });
@ -660,7 +660,7 @@ function tests() {
privateKeys: privKey, privateKeys: privKey,
detached: true, detached: true,
streaming: expectedType, streaming: expectedType,
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(openpgp.stream.isStream(signed)).to.equal(expectedType); expect(openpgp.stream.isStream(signed)).to.equal(expectedType);
const armoredSignature = await openpgp.stream.readToEnd(signed); const armoredSignature = await openpgp.stream.readToEnd(signed);
@ -669,7 +669,7 @@ function tests() {
signature, signature,
publicKeys: pubKey, publicKeys: pubKey,
message: openpgp.Message.fromText('hello world'), message: openpgp.Message.fromText('hello world'),
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(verified.data).to.equal('hello world'); expect(verified.data).to.equal('hello world');
expect(verified.signatures).to.exist.and.have.length(1); expect(verified.signatures).to.exist.and.have.length(1);
@ -680,8 +680,8 @@ function tests() {
dataArrived(); // Do not wait until data arrived. dataArrived(); // Do not wait until data arrived.
const data = new ReadableStream({ const data = new ReadableStream({
async start(controller) { async start(controller) {
controller.enqueue(util.strToUint8Array('hello ')); controller.enqueue(util.stringToUint8Array('hello '));
controller.enqueue(util.strToUint8Array('world')); controller.enqueue(util.stringToUint8Array('world'));
controller.close(); controller.close();
} }
}); });
@ -691,7 +691,7 @@ function tests() {
detached: true, detached: true,
streaming: false, streaming: false,
armor: false, armor: false,
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(openpgp.stream.isStream(signed)).to.be.false; expect(openpgp.stream.isStream(signed)).to.be.false;
const signature = await openpgp.readMessage({ binaryMessage: signed }); const signature = await openpgp.readMessage({ binaryMessage: signed });
@ -699,7 +699,7 @@ function tests() {
signature, signature,
publicKeys: pubKey, publicKeys: pubKey,
message: openpgp.Message.fromText('hello world'), message: openpgp.Message.fromText('hello world'),
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(verified.data).to.equal('hello world'); expect(verified.data).to.equal('hello world');
expect(verified.signatures).to.exist.and.have.length(1); expect(verified.signatures).to.exist.and.have.length(1);
@ -710,8 +710,8 @@ function tests() {
dataArrived(); // Do not wait until data arrived. dataArrived(); // Do not wait until data arrived.
const data = new ReadableStream({ const data = new ReadableStream({
async start(controller) { async start(controller) {
controller.enqueue(util.strToUint8Array('hello ')); controller.enqueue(util.stringToUint8Array('hello '));
controller.enqueue(util.strToUint8Array('world')); controller.enqueue(util.stringToUint8Array('world'));
controller.close(); controller.close();
} }
}); });
@ -741,8 +741,8 @@ function tests() {
dataArrived(); // Do not wait until data arrived. dataArrived(); // Do not wait until data arrived.
const data = new ReadableStream({ const data = new ReadableStream({
async start(controller) { async start(controller) {
controller.enqueue(util.strToUint8Array('hello ')); controller.enqueue(util.stringToUint8Array('hello '));
controller.enqueue(util.strToUint8Array('world')); controller.enqueue(util.stringToUint8Array('world'));
controller.close(); controller.close();
} }
}); });
@ -773,7 +773,7 @@ function tests() {
message: openpgp.Message.fromBinary(data), message: openpgp.Message.fromBinary(data),
privateKeys: privKey, privateKeys: privKey,
detached: true, detached: true,
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(openpgp.stream.isStream(signed)).to.equal(expectedType); expect(openpgp.stream.isStream(signed)).to.equal(expectedType);
const reader = openpgp.stream.getReader(signed); const reader = openpgp.stream.getReader(signed);
@ -788,7 +788,7 @@ function tests() {
message: openpgp.Message.fromBinary(data), message: openpgp.Message.fromBinary(data),
privateKeys: privKey, privateKeys: privKey,
detached: true, detached: true,
config: { minRsaBits: 1024 } config: { minRSABits: 1024 }
}); });
expect(openpgp.stream.isStream(signed)).to.equal(expectedType); expect(openpgp.stream.isStream(signed)).to.equal(expectedType);
const reader = openpgp.stream.getReader(signed); const reader = openpgp.stream.getReader(signed);

View File

@ -94,15 +94,15 @@ module.exports = () => describe('Util unit tests', function() {
}); });
}); });
describe('uint8ArrayToMpi', function() { describe('uint8ArrayToMPI', function() {
it('should strip leading zeros', function() { it('should strip leading zeros', function() {
const bytes = new Uint8Array([0, 0, 1, 2]); const bytes = new Uint8Array([0, 0, 1, 2]);
const mpi = util.uint8ArrayToMpi(bytes); const mpi = util.uint8ArrayToMPI(bytes);
expect(mpi).to.deep.equal(new Uint8Array([0, 9, 1, 2])); expect(mpi).to.deep.equal(new Uint8Array([0, 9, 1, 2]));
}); });
it('should throw on array of all zeros', function() { it('should throw on array of all zeros', function() {
const bytes = new Uint8Array([0, 0]); const bytes = new Uint8Array([0, 0]);
expect(() => util.uint8ArrayToMpi(bytes)).to.throw('Zero MPI'); expect(() => util.uint8ArrayToMPI(bytes)).to.throw('Zero MPI');
}); });
}); });

View File

@ -128,7 +128,7 @@ module.exports = () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cr
} }
const pub = await openpgp.readKey({ armoredKey: data[name].pub }); const pub = await openpgp.readKey({ armoredKey: data[name].pub });
expect(pub).to.exist; expect(pub).to.exist;
expect(pub.getKeyId().toHex()).to.equal(data[name].id); expect(pub.getKeyID().toHex()).to.equal(data[name].id);
data[name].pub_key = pub; data[name].pub_key = pub;
return pub; return pub;
} }
@ -139,7 +139,7 @@ module.exports = () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cr
} }
const pk = await openpgp.readKey({ armoredKey: data[name].priv }); const pk = await openpgp.readKey({ armoredKey: data[name].priv });
expect(pk).to.exist; expect(pk).to.exist;
expect(pk.getKeyId().toHex()).to.equal(data[name].id); expect(pk.getKeyID().toHex()).to.equal(data[name].id);
await pk.decrypt(data[name].pass); await pk.decrypt(data[name].pass);
data[name].priv_key = pk; data[name].priv_key = pk;
return pk; return pk;
@ -220,7 +220,7 @@ module.exports = () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cr
const curve = new elliptic.Curve('ed25519'); const curve = new elliptic.Curve('ed25519');
const { publicKey } = nacl.sign.keyPair.fromSeed(util.hexToUint8Array(vector.SECRET_KEY)); const { publicKey } = nacl.sign.keyPair.fromSeed(util.hexToUint8Array(vector.SECRET_KEY));
expect(publicKey).to.deep.equal(util.hexToUint8Array(vector.PUBLIC_KEY)); expect(publicKey).to.deep.equal(util.hexToUint8Array(vector.PUBLIC_KEY));
const data = util.strToUint8Array(vector.MESSAGE); const data = util.stringToUint8Array(vector.MESSAGE);
const privateParams = { const privateParams = {
seed: util.hexToUint8Array(vector.SECRET_KEY) seed: util.hexToUint8Array(vector.SECRET_KEY)
}; };
@ -257,7 +257,7 @@ module.exports = () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cr
return testVector({ return testVector({
SECRET_KEY: '4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb', SECRET_KEY: '4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb',
PUBLIC_KEY: '3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c', PUBLIC_KEY: '3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c',
MESSAGE: util.hexToStr('72'), MESSAGE: util.hexToString('72'),
SIGNATURE: { SIGNATURE: {
R: '92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da', R: '92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da',
S: '085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00' S: '085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00'
@ -269,7 +269,7 @@ module.exports = () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cr
return testVector({ return testVector({
SECRET_KEY: 'c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7', SECRET_KEY: 'c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7',
PUBLIC_KEY: 'fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025', PUBLIC_KEY: 'fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025',
MESSAGE: util.hexToStr('af82'), MESSAGE: util.hexToString('af82'),
SIGNATURE: { SIGNATURE: {
R: '6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac', R: '6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac',
S: '18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a' S: '18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a'
@ -281,7 +281,7 @@ module.exports = () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cr
return testVector({ return testVector({
SECRET_KEY: 'f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5', SECRET_KEY: 'f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5',
PUBLIC_KEY: '278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e', PUBLIC_KEY: '278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e',
MESSAGE: util.hexToStr([ MESSAGE: util.hexToString([
'08b8b2b733424243760fe426a4b54908', '08b8b2b733424243760fe426a4b54908',
'632110a66c2f6591eabd3345e3e4eb98', '632110a66c2f6591eabd3345e3e4eb98',
'fa6e264bf09efe12ee50f8f54e9f77b1', 'fa6e264bf09efe12ee50f8f54e9f77b1',
@ -358,7 +358,7 @@ module.exports = () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cr
return testVector({ return testVector({
SECRET_KEY: '833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42', SECRET_KEY: '833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42',
PUBLIC_KEY: 'ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf', PUBLIC_KEY: 'ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf',
MESSAGE: util.hexToStr([ MESSAGE: util.hexToString([
'ddaf35a193617abacc417349ae204131', 'ddaf35a193617abacc417349ae204131',
'12e6fa4e89a97ea20a9eeee64b55d39a', '12e6fa4e89a97ea20a9eeee64b55d39a',
'2192992a274fc1a836ba3c23a3feebbd', '2192992a274fc1a836ba3c23a3feebbd',
@ -379,7 +379,7 @@ module.exports = () => (openpgp.config.ci ? describe.skip : describe)('X25519 Cr
function omnibus() { function omnibus() {
it('Omnibus Ed25519/Curve25519 Test', function() { it('Omnibus Ed25519/Curve25519 Test', function() {
const options = { const options = {
userIds: { name: "Hi", email: "hi@hel.lo" }, userIDs: { name: "Hi", email: "hi@hel.lo" },
curve: "ed25519" curve: "ed25519"
}; };
return openpgp.generateKey(options).then(async function(firstKey) { return openpgp.generateKey(options).then(async function(firstKey) {
@ -404,7 +404,7 @@ function omnibus() {
const certificate = user.selfCertifications[0]; const certificate = user.selfCertifications[0];
certificate.verified = null; certificate.verified = null;
await certificate.verify( await certificate.verify(
primaryKey, openpgp.enums.signature.certGeneric, { userId: user.userId, key: primaryKey } primaryKey, openpgp.enums.signature.certGeneric, { userID: user.userID, key: primaryKey }
).then(async () => expect(certificate.verified).to.be.true); ).then(async () => expect(certificate.verified).to.be.true);
certificate.verified = null; certificate.verified = null;
@ -413,7 +413,7 @@ function omnibus() {
).then(async () => expect(certificate.verified).to.be.true); ).then(async () => expect(certificate.verified).to.be.true);
const options = { const options = {
userIds: { name: "Bye", email: "bye@good.bye" }, userIDs: { name: "Bye", email: "bye@good.bye" },
curve: "curve25519" curve: "curve25519"
}; };
return openpgp.generateKey(options).then(async function(secondKey) { return openpgp.generateKey(options).then(async function(secondKey) {
@ -428,7 +428,7 @@ function omnibus() {
const certificate = user.selfCertifications[0]; const certificate = user.selfCertifications[0];
certificate.verified = null; certificate.verified = null;
await certificate.verify( await certificate.verify(
bye.primaryKey, openpgp.enums.signature.certGeneric, { userId: user.userId, key: bye.primaryKey } bye.primaryKey, openpgp.enums.signature.certGeneric, { userID: user.userID, key: bye.primaryKey }
).then(async () => expect(certificate.verified).to.be.true); ).then(async () => expect(certificate.verified).to.be.true);
certificate.verified = null; certificate.verified = null;
await user.verifyCertificate( await user.verifyCertificate(
@ -442,7 +442,7 @@ function omnibus() {
expect(hiCertificate.verified).to.be.true; expect(hiCertificate.verified).to.be.true;
hiCertificate.verified = null; hiCertificate.verified = null;
return hiCertificate.verify( return hiCertificate.verify(
primaryKey, openpgp.enums.signature.certGeneric, { userId: user.userId, key: bye.toPublic().primaryKey } primaryKey, openpgp.enums.signature.certGeneric, { userID: user.userID, key: bye.toPublic().primaryKey }
).then(async () => expect(hiCertificate.verified).to.be.true); ).then(async () => expect(hiCertificate.verified).to.be.true);
}), }),
// Signing message // Signing message

View File

@ -9,7 +9,7 @@ const expect = chai.expect;
async function generateTestData() { async function generateTestData() {
const victimPrivKey = (await openpgp.generateKey({ const victimPrivKey = (await openpgp.generateKey({
userIds: [{ name: 'Victim', email: 'victim@example.com' }], userIDs: [{ name: 'Victim', email: 'victim@example.com' }],
type: 'rsa', type: 'rsa',
rsaBits: 2048, rsaBits: 2048,
subkeys: [{ subkeys: [{
@ -19,7 +19,7 @@ async function generateTestData() {
victimPrivKey.revocationSignatures = []; victimPrivKey.revocationSignatures = [];
const attackerPrivKey = (await openpgp.generateKey({ const attackerPrivKey = (await openpgp.generateKey({
userIds: [{ name: 'Attacker', email: 'attacker@example.com' }], userIDs: [{ name: 'Attacker', email: 'attacker@example.com' }],
type: 'rsa', type: 'rsa',
rsaBits: 2048, rsaBits: 2048,
subkeys: [], subkeys: [],
@ -71,7 +71,7 @@ async function testSubkeyTrust() {
publicKeys: fakeKey, publicKeys: fakeKey,
streaming: false streaming: false
}); });
expect(verifyAttackerIsBatman.signatures[0].keyid.equals(victimPubKey.subKeys[0].getKeyId())).to.be.true; expect(verifyAttackerIsBatman.signatures[0].keyID.equals(victimPubKey.subKeys[0].getKeyID())).to.be.true;
expect(verifyAttackerIsBatman.signatures[0].valid).to.be.false; expect(verifyAttackerIsBatman.signatures[0].valid).to.be.false;
expect(verifyAttackerIsBatman.signatures[0].error).to.match(/Could not find valid signing key packet/); expect(verifyAttackerIsBatman.signatures[0].error).to.match(/Could not find valid signing key packet/);
} }

View File

@ -78,7 +78,7 @@ async function makeKeyValid() {
// add key capability // add key capability
fake.keyFlags[0] |= enums.keyFlags.encryptCommunication; fake.keyFlags[0] |= enums.keyFlags.encryptCommunication;
// create modified subpacket data // create modified subpacket data
pusersig.read_sub_packets(fake.write_hashed_sub_packets(), false); pusersig.readSubPackets(fake.writeHashedSubPackets(), false);
// reconstruct the modified key // reconstruct the modified key
const newlist = new PacketList(); const newlist = new PacketList();
newlist.concat([pubkey, puser, pusersig]); newlist.concat([pubkey, puser, pusersig]);

View File

@ -13,7 +13,7 @@ import { expect } from 'chai';
(async () => { (async () => {
// Generate keys // Generate keys
const { publicKeyArmored, key } = await generateKey({ userIds: [{ email: "user@corp.co" }], config: { v5Keys: true } }); const { publicKeyArmored, key } = await generateKey({ userIDs: [{ email: "user@corp.co" }], config: { v5Keys: true } });
expect(key).to.be.instanceOf(Key); expect(key).to.be.instanceOf(Key);
const privateKeys = [key]; const privateKeys = [key];
const publicKeys = [key.toPublic()]; const publicKeys = [key.toPublic()];