Merge pull request #1914

Linter: update to eslint v9
This commit is contained in:
larabr 2025-10-17 17:46:56 +02:00 committed by GitHub
commit c42a42e6f3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
69 changed files with 1246 additions and 1556 deletions

View File

@ -1,4 +0,0 @@
dist
test/lib/
test/typescript/
docs

View File

@ -1,146 +0,0 @@
module.exports = {
'extends': [
'airbnb-base',
'airbnb-typescript/base'
],
'parser': '@typescript-eslint/parser',
'parserOptions': {
'ecmaVersion': 11,
'sourceType': 'module',
'project': 'tsconfig.json'
},
'env': {
'browser': true,
'es6': true,
'node': true
},
'plugins': [
'@typescript-eslint',
'chai-friendly',
'import',
'unicorn'
],
'settings': {
'import/resolver': {
'typescript': {}
}
},
'globals': { // TODO are all these necessary?
'globalThis': true,
'console': true,
'Promise': true,
'importScripts': true,
'process': true,
'Event': true,
'describe': true,
'it': true,
'mocha': true,
'before': true,
'beforeEach': true,
'after': true,
'afterEach': true,
'escape': true,
'unescape': true,
'resolves': true,
'rejects': true,
'TransformStream': true,
'BigInt': true
},
'rules': {
'arrow-body-style': 'off',
'arrow-parens': ['error','as-needed'],
'class-methods-use-this': 'off',
'@typescript-eslint/comma-dangle': ['error', 'never'],
'@typescript-eslint/comma-spacing': 'off',
'consistent-return': 'off',
'default-case': 'off',
'@typescript-eslint/default-param-last': 'off',
'eol-last': ['error', 'always'],
'function-call-argument-newline': 'off',
'func-names': ['error', 'never'],
'function-paren-newline': 'off',
'global-require': 'off',
'key-spacing': 'off',
'keyword-spacing': 'error',
'max-classes-per-file': 'off',
'max-len': 'off',
'newline-per-chained-call': 'off',
'no-bitwise': 'off',
'no-continue': 'off',
'no-else-return': 'off',
'no-empty': ['error', { 'allowEmptyCatch': true }],
'no-multiple-empty-lines': ['error', { 'max': 2, 'maxEOF': 1, 'maxBOF':0 }],
'no-nested-ternary': 'off',
'no-param-reassign': 'off', // TODO get rid of this
'no-plusplus': 'off',
'no-restricted-syntax': ['error', 'ForInStatement', 'LabeledStatement', 'WithStatement'],
'object-curly-newline': 'off',
'@typescript-eslint/no-shadow': 'off', // TODO get rid of this
'object-property-newline': [
'error',
{
'allowMultiplePropertiesPerLine': true
}
],
'object-shorthand': 'off',
'operator-assignment': 'off',
'operator-linebreak': [
'error',
'after'
],
'padded-blocks': 'off',
'prefer-arrow-callback': 'off',
'prefer-destructuring': 'off',
'prefer-rest-params': 'off', // TODO get rid of this
'prefer-spread': 'off', // TODO get rid of this
'prefer-template': 'off',
'quote-props': 'off',
'quotes': ['error', 'single', { 'avoidEscape': true }],
'@typescript-eslint/space-before-function-paren': ['error', { 'anonymous': 'ignore', 'named': 'never', 'asyncArrow': 'always' }],
'spaced-comment': 'off',
'indent': 'off',
'@typescript-eslint/indent': ['error', 2, { 'SwitchCase': 1 }],
'no-unused-vars': 'off',
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_",
}
],
// eslint-plugin-import rules:
'import/named': 'error',
'import/extensions': 'off', // temporary: we use them in tests (ESM compliant), but not in the lib (to limit diff)
'import/first': 'off',
'import/no-extraneous-dependencies': ['error', { 'devDependencies': true, 'optionalDependencies': false, 'peerDependencies': false }],
'import/no-unassigned-import': 'error',
'import/no-unresolved': 'error',
'import/prefer-default-export': 'off',
// Custom silencers:
'no-multi-assign': 'off',
'no-underscore-dangle': 'off',
'no-await-in-loop': 'off',
'camelcase': 'off', // snake_case used in tests, need to fix separately
'@typescript-eslint/naming-convention': 'off', // supersedes 'camelcase' rule
'@typescript-eslint/lines-between-class-members': 'off',
// Custom errors:
'@typescript-eslint/no-use-before-define': ['error', { 'functions': false, 'classes': true, 'variables': false, 'allowNamedExports': true }],
'no-constant-condition': [2, { 'checkLoops': false }],
'new-cap': [2, { 'properties': false, 'capIsNewExceptionPattern': 'EAX|OCB|GCM|CMAC|CBC|OMAC|CTR', 'newIsCapExceptionPattern': 'type|hash*' }],
'max-lines': [2, { 'max': 620, 'skipBlankLines': true, 'skipComments': true }],
'@typescript-eslint/no-unused-expressions': 0,
'chai-friendly/no-unused-expressions': [2, { 'allowShortCircuit': true }],
'unicorn/switch-case-braces': ['error', 'avoid'],
// Custom warnings:
'no-console': 1
}
};

166
eslint.config.js Normal file
View File

@ -0,0 +1,166 @@
// @ts-check
import eslint from '@eslint/js';
import { defineConfig, globalIgnores } from 'eslint/config';
import tseslint from 'typescript-eslint';
import globals from 'globals';
// @ts-expect-error missing types
import pluginChaiFriendly from 'eslint-plugin-chai-friendly';
import pluginImport from 'eslint-plugin-import';
import pluginStylistic from '@stylistic/eslint-plugin';
// @ts-expect-error missing types
import pluginUnicorn from 'eslint-plugin-unicorn';
export default defineConfig(
eslint.configs.recommended,
tseslint.configs.recommendedTypeChecked,
globalIgnores(['dist/', 'test/lib/', 'docs/', '.jsdocrc.cjs']),
{
languageOptions: {
ecmaVersion: 2022,
sourceType: 'module',
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname
},
globals: {
...globals.browser,
...globals.nodeBuiltin,
...globals.mocha
}
},
settings: {
'import/resolver': {
typescript: { alwaysTryTypes: true }
}
},
plugins: {
'chai-friendly': pluginChaiFriendly,
'import': pluginImport,
'@stylistic': pluginStylistic,
'unicorn': pluginUnicorn
},
rules: {
'arrow-body-style': 'off',
'arrow-parens': ['error','as-needed'],
'class-methods-use-this': 'warn',
'comma-dangle': ['error', 'never'],
'@typescript-eslint/comma-spacing': 'off',
'consistent-return': 'off',
'default-case': 'off',
'@typescript-eslint/default-param-last': 'off',
'eol-last': ['error', 'always'],
'function-call-argument-newline': 'off',
'func-names': ['error', 'never'],
'function-paren-newline': 'off',
'global-require': 'off',
'key-spacing': 'off',
'keyword-spacing': 'error',
'max-classes-per-file': 'off',
'max-len': 'off',
'newline-per-chained-call': 'off',
'no-bitwise': 'off',
'no-continue': 'off',
'no-else-return': 'off',
'no-empty': ['error', { 'allowEmptyCatch': true }],
'no-multiple-empty-lines': ['error', { 'max': 2, 'maxEOF': 1, 'maxBOF':0 }],
'no-nested-ternary': 'warn',
'no-param-reassign': 'warn', // TODO get rid of this
'no-plusplus': 'off',
'no-restricted-syntax': ['error', 'ForInStatement', 'LabeledStatement', 'WithStatement'],
'object-curly-newline': 'off',
'@typescript-eslint/no-shadow': 'warn', // TODO get rid of this
'object-property-newline': [
'error',
{
'allowMultiplePropertiesPerLine': true
}
],
'object-shorthand': 'off',
'operator-assignment': 'off',
'operator-linebreak': [
'error',
'after'
],
'padded-blocks': 'off',
'prefer-arrow-callback': 'off',
'prefer-destructuring': 'off',
'prefer-rest-params': 'warn', // TODO get rid of this
'prefer-spread': 'warn', // TODO get rid of this
'prefer-template': 'off',
'quote-props': 'off',
'quotes': 'off', // superseded by @stylistic/quotes
'spaced-comment': 'off',
'indent': 'off',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
'argsIgnorePattern': '^_'
}
],
// eslint-plugin-import rules:
'import/named': 'error',
'import/extensions': 'off', // temporary: we use them in tests (ESM compliant), but not in the lib (to limit diff)
'import/first': 'off',
'import/no-extraneous-dependencies': ['error', { 'devDependencies': true, 'optionalDependencies': false, 'peerDependencies': false }],
'import/no-unassigned-import': 'error',
'import/no-unresolved': 'error',
'import/prefer-default-export': 'off',
'import/newline-after-import': 'error',
// Custom silencers:
'no-multi-assign': 'off',
'no-underscore-dangle': 'off',
'no-await-in-loop': 'off',
'camelcase': 'off', // snake_case used in tests, need to fix separately
'@typescript-eslint/naming-convention': 'off', // supersedes 'camelcase' rule
'@typescript-eslint/lines-between-class-members': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-this-alias': 'off',
// Custom errors:
'@typescript-eslint/no-use-before-define': ['error', { 'functions': false, 'classes': true, 'variables': false, 'allowNamedExports': true }],
'no-constant-condition': [2, { 'checkLoops': false }],
'new-cap': ['error', {
properties: false,
newIsCap: true,
newIsCapExceptions: [],
capIsNew: false
}],
'max-lines': [2, { 'max': 620, 'skipBlankLines': true, 'skipComments': true }],
'@typescript-eslint/no-unused-expressions': 'off',
'chai-friendly/no-unused-expressions': ['error', { 'allowShortCircuit': true }],
'@typescript-eslint/no-empty-object-type': ['error', { allowInterfaces: 'with-single-extends' }],
'no-invalid-this': 'error',
'require-await': 'off', // superseded by @typescript-eslint/require-await
'@typescript-eslint/no-unsafe-call': 'off', // function call to fn with `any` type
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/restrict-template-expressions': 'off',
'prefer-promise-reject-errors': 'off',
'@typescript-eslint/prefer-promise-reject-errors': 'off',
'@stylistic/indent': ['error', 2, { 'SwitchCase': 1 }],
'@stylistic/quotes': ['error', 'single', { avoidEscape: true }],
'@stylistic/space-before-function-paren': ['error', { 'anonymous': 'ignore', 'named': 'never', 'asyncArrow': 'always' }],
'@stylistic/no-mixed-operators': ['error', {
allowSamePrecedence: true,
groups: [
['==', '!=', '===', '!==', '>', '>=', '<', '<='],
['&&', '||']
]
}],
'@stylistic/no-mixed-spaces-and-tabs': 'error',
'@stylistic/eol-last': 'error',
'@stylistic/no-trailing-spaces': 'error',
'@stylistic/no-tabs': 'error',
'unicorn/switch-case-braces': ['error', 'avoid'],
'no-console': 'warn',
'no-process-exit': 'error'
}
}
);

31
openpgp.d.ts vendored
View File

@ -1,4 +1,4 @@
/* eslint-disable max-lines, @typescript-eslint/indent */ /* eslint-disable @stylistic/indent */
/** /**
* Type definitions for OpenPGP.js http://openpgpjs.org/ * Type definitions for OpenPGP.js http://openpgpjs.org/
@ -337,10 +337,9 @@ export class Message<T extends MaybeStream<Data>> {
} }
/* ############## PACKET #################### */ /* ############## PACKET #################### */
export declare abstract class BasePacket<AsyncRead extends boolean = false> {
export declare abstract class BasePacket {
static readonly tag: enums.packet; static readonly tag: enums.packet;
public read(bytes: Uint8Array): void; public read(bytes: Uint8Array): AsyncRead extends true ? Promise<void> : void;
public write(): Uint8Array; public write(): Uint8Array;
} }
@ -349,7 +348,7 @@ export declare abstract class BasePacket {
* - A Secret (Sub)Key Packet can always be used when a Public one is expected. * - A Secret (Sub)Key Packet can always be used when a Public one is expected.
* - A Subkey Packet cannot always be used when a Primary Key Packet is expected (and vice versa). * - A Subkey Packet cannot always be used when a Primary Key Packet is expected (and vice versa).
*/ */
declare abstract class BasePublicKeyPacket extends BasePacket { declare abstract class BasePublicKeyPacket extends BasePacket<true> {
public algorithm: enums.publicKey; public algorithm: enums.publicKey;
public created: Date; public created: Date;
public version: number; public version: number;
@ -397,21 +396,21 @@ export class SecretSubkeyPacket extends BaseSecretKeyPacket {
protected isSubkey(): true; protected isSubkey(): true;
} }
export class CompressedDataPacket extends BasePacket { export class CompressedDataPacket extends BasePacket<true> {
static readonly tag: enums.packet.compressedData; static readonly tag: enums.packet.compressedData;
private compress(): void; private compress(): void;
private decompress(config?: Config): void; private decompress(config?: Config): void;
} }
export class SymEncryptedIntegrityProtectedDataPacket extends BasePacket { export class SymEncryptedIntegrityProtectedDataPacket extends BasePacket<true> {
static readonly tag: enums.packet.symEncryptedIntegrityProtectedData; static readonly tag: enums.packet.symEncryptedIntegrityProtectedData;
} }
export class AEADEncryptedDataPacket extends BasePacket { export class AEADEncryptedDataPacket extends BasePacket<true> {
static readonly tag: enums.packet.aeadEncryptedData; static readonly tag: enums.packet.aeadEncryptedData;
private decrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): void; private decrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): Promise<void>;
private encrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): void; private encrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): Promise<void>;
private crypt(fn: Function, sessionKey: Uint8Array, data: MaybeStream<Uint8Array>): MaybeStream<Uint8Array>; private crypt(fn: (block: Uint8Array) => Uint8Array, sessionKey: Uint8Array, data: MaybeStream<Uint8Array>): MaybeStream<Uint8Array>;
} }
export class PublicKeyEncryptedSessionKeyPacket extends BasePacket { export class PublicKeyEncryptedSessionKeyPacket extends BasePacket {
@ -426,7 +425,7 @@ export class SymEncryptedSessionKeyPacket extends BasePacket {
private encrypt(passphrase: string, config?: Config): Promise<void>; private encrypt(passphrase: string, config?: Config): Promise<void>;
} }
export class LiteralDataPacket extends BasePacket { export class LiteralDataPacket extends BasePacket<true> {
static readonly tag: enums.packet.literalData; static readonly tag: enums.packet.literalData;
private getText(clone?: boolean): MaybeStream<string>; private getText(clone?: boolean): MaybeStream<string>;
private getBytes(clone?: boolean): MaybeStream<Uint8Array>; private getBytes(clone?: boolean): MaybeStream<Uint8Array>;
@ -439,8 +438,8 @@ export class LiteralDataPacket extends BasePacket {
export class SymmetricallyEncryptedDataPacket extends BasePacket { export class SymmetricallyEncryptedDataPacket extends BasePacket {
static readonly tag: enums.packet.symmetricallyEncryptedData; static readonly tag: enums.packet.symmetricallyEncryptedData;
private decrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): void; private decrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): Promise<void>;
private encrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): void; private encrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): Promise<void>;
} }
export class MarkerPacket extends BasePacket { export class MarkerPacket extends BasePacket {
@ -547,8 +546,8 @@ export type AnyKeyPacket = BasePublicKeyPacket;
type AllowedPackets = Map<enums.packet, object>; // mapping to Packet classes (i.e. typeof LiteralDataPacket etc.) type AllowedPackets = Map<enums.packet, object>; // mapping to Packet classes (i.e. typeof LiteralDataPacket etc.)
export class PacketList<T extends AnyPacket> extends Array<T> { export class PacketList<T extends AnyPacket> extends Array<T> {
static fromBinary(bytes: MaybeStream<Uint8Array>, allowedPackets: AllowedPackets, config?: Config): PacketList<AnyPacket>; // the packet types depend on`allowedPackets` static fromBinary(bytes: MaybeStream<Uint8Array>, allowedPackets: AllowedPackets, config?: Config): Promise<PacketList<AnyPacket>>; // the packet types depend on`allowedPackets`
public read(bytes: MaybeStream<Uint8Array>, allowedPackets: AllowedPackets, config?: Config): void; public read(bytes: MaybeStream<Uint8Array>, allowedPackets: AllowedPackets, config?: Config): Promise<void>;
public write(): Uint8Array; public write(): Uint8Array;
public filterByTag(...args: enums.packet[]): PacketList<T>; public filterByTag(...args: enums.packet[]): PacketList<T>;
public indexOfTag(...tags: enums.packet[]): number[]; public indexOfTag(...tags: enums.packet[]): number[];

1651
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -63,6 +63,7 @@
"postversion": "git push --follow-tags && npm publish" "postversion": "git push --follow-tags && npm publish"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.36.0",
"@noble/ciphers": "^1.3.0", "@noble/ciphers": "^1.3.0",
"@noble/curves": "^1.9.6", "@noble/curves": "^1.9.6",
"@noble/hashes": "^1.8.0", "@noble/hashes": "^1.8.0",
@ -77,10 +78,10 @@
"@rollup/plugin-terser": "^0.4.4", "@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.1.4", "@rollup/plugin-typescript": "^12.1.4",
"@rollup/plugin-wasm": "^6.2.2", "@rollup/plugin-wasm": "^6.2.2",
"@stylistic/eslint-plugin": "^5.4.0",
"@types/chai": "^4.3.20", "@types/chai": "^4.3.20",
"@types/node": "^24.3.1", "@types/node": "^24.3.1",
"@types/sinon": "^17.0.4", "@types/sinon": "^17.0.4",
"@typescript-eslint/parser": "^7.18.0",
"@web/test-runner": "^0.19.0", "@web/test-runner": "^0.19.0",
"@web/test-runner-browserstack": "^0.8.0", "@web/test-runner-browserstack": "^0.8.0",
"@web/test-runner-mocha": "^0.9.0", "@web/test-runner-mocha": "^0.9.0",
@ -92,21 +93,20 @@
"chai": "^4.5.0", "chai": "^4.5.0",
"chai-as-promised": "^8.0.1", "chai-as-promised": "^8.0.1",
"eckey-utils": "^0.7.14", "eckey-utils": "^0.7.14",
"eslint": "^8.57.1", "eslint": "^9.36.0",
"eslint-config-airbnb": "^19.0.4", "eslint-import-resolver-typescript": "^4.4.4",
"eslint-config-airbnb-base": "^15.0.0", "eslint-plugin-chai-friendly": "^1.1.0",
"eslint-config-airbnb-typescript": "^18.0.0",
"eslint-import-resolver-typescript": "^3.10.1",
"eslint-plugin-chai-friendly": "^0.7.4",
"eslint-plugin-import": "^2.32.0", "eslint-plugin-import": "^2.32.0",
"eslint-plugin-unicorn": "^48.0.1", "eslint-plugin-unicorn": "^48.0.1",
"fflate": "^0.8.2", "fflate": "^0.8.2",
"globals": "^16.4.0",
"mocha": "^11.7.1", "mocha": "^11.7.1",
"playwright": "^1.56.0", "playwright": "^1.56.0",
"rollup": "^4.48.1", "rollup": "^4.48.1",
"sinon": "^21.0.0", "sinon": "^21.0.0",
"tsx": "^4.20.5", "tsx": "^4.20.5",
"typescript": "^5.9.2", "typescript": "^5.9.2",
"typescript-eslint": "^8.44.1",
"web-streams-polyfill": "^4.2.0" "web-streams-polyfill": "^4.2.0"
}, },
"overrides": { "overrides": {

View File

@ -1,5 +1,3 @@
/* eslint-disable no-process-env */
import { builtinModules } from 'module'; import { builtinModules } from 'module';
import { readFileSync } from 'fs'; import { readFileSync } from 'fs';

View File

@ -189,7 +189,7 @@ function verifyHeaders(headers, packetlist) {
.map(hashName => { .map(hashName => {
try { try {
return enums.write(enums.hash, hashName.toLowerCase()); return enums.write(enums.hash, hashName.toLowerCase());
} catch (e) { } catch {
throw new Error('Unknown hash algorithm in armor header: ' + hashName.toLowerCase()); throw new Error('Unknown hash algorithm in armor header: ' + hashName.toLowerCase());
} }
}); });
@ -209,8 +209,9 @@ function verifyHeaders(headers, packetlist) {
* @param {Object} options * @param {Object} options
* @param {String} options.text * @param {String} options.text
* @static * @static
* @async * @async not necessary, but needed to align with createMessage
*/ */
// eslint-disable-next-line @typescript-eslint/require-await
export async function createCleartextMessage({ text, ...rest }) { export async function createCleartextMessage({ text, ...rest }) {
if (!text) { if (!text) {
throw new Error('createCleartextMessage: must pass options object containing `text`'); throw new Error('createCleartextMessage: must pass options object containing `text`');

View File

@ -31,7 +31,7 @@ const webCrypto = util.getWebCrypto();
* @param {enums.symmetric.aes128|enums.symmetric.aes256|enums.symmetric.aes192} algo - AES algo * @param {enums.symmetric.aes128|enums.symmetric.aes256|enums.symmetric.aes192} algo - AES algo
* @param {Uint8Array} key - wrapping key * @param {Uint8Array} key - wrapping key
* @param {Uint8Array} dataToWrap * @param {Uint8Array} dataToWrap
* @returns {Uint8Array} wrapped key * @returns {Promise<Uint8Array>} wrapped key
*/ */
export async function wrap(algo, key, dataToWrap) { export async function wrap(algo, key, dataToWrap) {
const { keySize } = getCipherParams(algo); const { keySize } = getCipherParams(algo);
@ -63,7 +63,7 @@ export async function wrap(algo, key, dataToWrap) {
* @param {enums.symmetric.aes128|enums.symmetric.aes256|enums.symmetric.aes192} algo - AES algo * @param {enums.symmetric.aes128|enums.symmetric.aes256|enums.symmetric.aes192} algo - AES algo
* @param {Uint8Array} key - wrapping key * @param {Uint8Array} key - wrapping key
* @param {Uint8Array} wrappedData * @param {Uint8Array} wrappedData
* @returns {Uint8Array} unwrapped data * @returns {Promise<Uint8Array>} unwrapped data
*/ */
export async function unwrap(algo, key, wrappedData) { export async function unwrap(algo, key, wrappedData) {
const { keySize } = getCipherParams(algo); const { keySize } = getCipherParams(algo);

View File

@ -162,7 +162,7 @@ export function bitLength(x: bigint) {
const target = x < _0n ? BigInt(-1) : _0n; const target = x < _0n ? BigInt(-1) : _0n;
let bitlen = 1; let bitlen = 1;
let tmp = x; let tmp = x;
// eslint-disable-next-line no-cond-assign
while ((tmp >>= _1n) !== target) { while ((tmp >>= _1n) !== target) {
bitlen++; bitlen++;
} }
@ -177,7 +177,7 @@ export function byteLength(x: bigint) {
const _8n = BigInt(8); const _8n = BigInt(8);
let len = 1; let len = 1;
let tmp = x; let tmp = x;
// eslint-disable-next-line no-cond-assign
while ((tmp >>= _8n) !== target) { while ((tmp >>= _8n) !== target) {
len++; len++;
} }

View File

@ -1,6 +1,3 @@
/* eslint-disable no-mixed-operators, no-fallthrough */
/* Modified by Recurity Labs GmbH /* Modified by Recurity Labs GmbH
* *
* Cipher.js * Cipher.js
@ -98,6 +95,7 @@ function createTwofish() {
]; ];
const ror4 = [0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15]; const ror4 = [0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15];
const ashx = [0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7]; const ashx = [0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7];
/** @type {number[][]} */
const q = [ const q = [
[], [],
[] []
@ -158,11 +156,13 @@ function createTwofish() {
b = q[0][b] ^ getB(key[3], 1); b = q[0][b] ^ getB(key[3], 1);
c = q[0][c] ^ getB(key[3], 2); c = q[0][c] ^ getB(key[3], 2);
d = q[1][d] ^ getB(key[3], 3); d = q[1][d] ^ getB(key[3], 3);
// eslint-disable-next-line no-fallthrough
case 3: case 3:
a = q[1][a] ^ getB(key[2], 0); a = q[1][a] ^ getB(key[2], 0);
b = q[1][b] ^ getB(key[2], 1); b = q[1][b] ^ getB(key[2], 1);
c = q[0][c] ^ getB(key[2], 2); c = q[0][c] ^ getB(key[2], 2);
d = q[0][d] ^ getB(key[2], 3); d = q[0][d] ^ getB(key[2], 3);
// eslint-disable-next-line no-fallthrough
case 2: case 2:
a = q[0][q[0][a] ^ getB(key[1], 0)] ^ getB(key[0], 0); a = q[0][q[0][a] ^ getB(key[1], 0)] ^ getB(key[0], 0);
b = q[0][q[1][b] ^ getB(key[1], 1)] ^ getB(key[0], 1); b = q[0][q[1][b] ^ getB(key[1], 1)] ^ getB(key[0], 1);
@ -222,11 +222,13 @@ function createTwofish() {
b = q[0][b] ^ getB(sKey[3], 1); b = q[0][b] ^ getB(sKey[3], 1);
c = q[0][c] ^ getB(sKey[3], 2); c = q[0][c] ^ getB(sKey[3], 2);
d = q[1][d] ^ getB(sKey[3], 3); d = q[1][d] ^ getB(sKey[3], 3);
// eslint-disable-next-line no-fallthrough
case 3: case 3:
a = q[1][a] ^ getB(sKey[2], 0); a = q[1][a] ^ getB(sKey[2], 0);
b = q[1][b] ^ getB(sKey[2], 1); b = q[1][b] ^ getB(sKey[2], 1);
c = q[0][c] ^ getB(sKey[2], 2); c = q[0][c] ^ getB(sKey[2], 2);
d = q[0][d] ^ getB(sKey[2], 3); d = q[0][d] ^ getB(sKey[2], 3);
// eslint-disable-next-line no-fallthrough
case 2: case 2:
tfsM[0][i] = m[0][q[0][q[0][a] ^ getB(sKey[1], 0)] ^ getB(sKey[0], 0)]; tfsM[0][i] = m[0][q[0][q[0][a] ^ getB(sKey[1], 0)] ^ getB(sKey[0], 0)];
tfsM[1][i] = m[1][q[0][q[1][b] ^ getB(sKey[1], 1)] ^ getB(sKey[0], 1)]; tfsM[1][i] = m[1][q[0][q[1][b] ^ getB(sKey[1], 1)] ^ getB(sKey[0], 1)];

View File

@ -49,11 +49,10 @@ const nodeAlgos = {
* See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms. * See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
* @param {module:enums.symmetric} algo - Symmetric encryption algorithm * @param {module:enums.symmetric} algo - Symmetric encryption algorithm
* @returns {Promise<Uint8Array>} Random bytes with length equal to the block size of the cipher, plus the last two bytes repeated. * @returns {Promise<Uint8Array>} Random bytes with length equal to the block size of the cipher, plus the last two bytes repeated.
* @async
*/ */
export async function getPrefixRandom(algo) { export function getPrefixRandom(algo) {
const { blockSize } = getCipherParams(algo); const { blockSize } = getCipherParams(algo);
const prefixrandom = await getRandomBytes(blockSize); const prefixrandom = getRandomBytes(blockSize);
const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]); const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]);
return util.concat([prefixrandom, repeat]); return util.concat([prefixrandom, repeat]);
} }
@ -156,7 +155,10 @@ class WebCryptoEncryptor {
this.zeroBlock = new Uint8Array(this.blockSize); this.zeroBlock = new Uint8Array(this.blockSize);
} }
static async isSupported(algo) { /**
* @returns {Promise<boolean>}
*/
static isSupported(algo) {
const { keySize } = getCipherParams(algo); const { keySize } = getCipherParams(algo);
return webCrypto.importKey('raw', new Uint8Array(keySize), 'aes-cbc', false, ['encrypt']) return webCrypto.importKey('raw', new Uint8Array(keySize), 'aes-cbc', false, ['encrypt'])
.then(() => true, () => false); .then(() => true, () => false);
@ -283,6 +285,7 @@ class NobleStreamProcessor {
return dst; return dst;
} }
// eslint-disable-next-line @typescript-eslint/require-await
async processChunk(value) { async processChunk(value) {
const missing = this.nextBlock.length - this.i; const missing = this.nextBlock.length - this.i;
const added = value.subarray(0, missing); const added = value.subarray(0, missing);
@ -321,6 +324,7 @@ class NobleStreamProcessor {
return processedBlock; return processedBlock;
} }
// eslint-disable-next-line @typescript-eslint/require-await
async finish() { async finish() {
let result; let result;
if (this.i === 0) { // nothing more to encrypt if (this.i === 0) { // nothing more to encrypt
@ -354,7 +358,7 @@ async function aesEncrypt(algo, key, pt, iv) {
return nobleAesCfb(key, iv).encrypt(pt); return nobleAesCfb(key, iv).encrypt(pt);
} }
async function aesDecrypt(algo, key, ct, iv) { function aesDecrypt(algo, key, ct, iv) {
if (util.isStream(ct)) { if (util.isStream(ct)) {
const cfb = new NobleStreamProcessor(false, algo, key, iv); const cfb = new NobleStreamProcessor(false, algo, key, iv);
return streamTransform(ct, value => cfb.processChunk(value), () => cfb.finish()); return streamTransform(ct, value => cfb.processChunk(value), () => cfb.finish());

View File

@ -48,6 +48,7 @@ async function OMAC(key) {
async function CTR(key) { async function CTR(key) {
if (util.getNodeCrypto()) { // Node crypto library if (util.getNodeCrypto()) { // Node crypto library
// eslint-disable-next-line @typescript-eslint/require-await
return async function(pt, iv) { return async function(pt, iv) {
const en = new nodeCrypto.createCipheriv('aes-' + (key.length * 8) + '-ctr', key, iv); const en = new nodeCrypto.createCipheriv('aes-' + (key.length * 8) + '-ctr', key, iv);
const ct = Buffer.concat([en.update(pt), en.final()]); const ct = Buffer.concat([en.update(pt), en.final()]);
@ -72,6 +73,7 @@ async function CTR(key) {
} }
} }
// eslint-disable-next-line @typescript-eslint/require-await
return async function(pt, iv) { return async function(pt, iv) {
return nobleAesCtr(key, iv).encrypt(pt); return nobleAesCtr(key, iv).encrypt(pt);
}; };

View File

@ -48,6 +48,7 @@ async function GCM(cipher, key) {
if (util.getNodeCrypto()) { // Node crypto library if (util.getNodeCrypto()) { // Node crypto library
return { return {
// eslint-disable-next-line @typescript-eslint/require-await
encrypt: async function(pt, iv, adata = new Uint8Array()) { encrypt: async function(pt, iv, adata = new Uint8Array()) {
const en = new nodeCrypto.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv); const en = new nodeCrypto.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
en.setAAD(adata); en.setAAD(adata);
@ -55,6 +56,7 @@ async function GCM(cipher, key) {
return new Uint8Array(ct); return new Uint8Array(ct);
}, },
// eslint-disable-next-line @typescript-eslint/require-await
decrypt: async function(ct, iv, adata = new Uint8Array()) { decrypt: async function(ct, iv, adata = new Uint8Array()) {
const de = new nodeCrypto.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv); const de = new nodeCrypto.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
de.setAAD(adata); de.setAAD(adata);
@ -105,10 +107,12 @@ async function GCM(cipher, key) {
} }
return { return {
// eslint-disable-next-line @typescript-eslint/require-await
encrypt: async function(pt, iv, adata) { encrypt: async function(pt, iv, adata) {
return nobleAesGcm(key, iv, adata).encrypt(pt); return nobleAesGcm(key, iv, adata).encrypt(pt);
}, },
// eslint-disable-next-line @typescript-eslint/require-await
decrypt: async function(ct, iv, adata) { decrypt: async function(ct, iv, adata) {
return nobleAesGcm(key, iv, adata).decrypt(ct); return nobleAesGcm(key, iv, adata).decrypt(ct);
} }

View File

@ -61,6 +61,7 @@ const one = new Uint8Array([1]);
* @param {enums.symmetric} cipher - The symmetric cipher algorithm to use * @param {enums.symmetric} cipher - The symmetric cipher algorithm to use
* @param {Uint8Array} key - The encryption key * @param {Uint8Array} key - The encryption key
*/ */
// eslint-disable-next-line @typescript-eslint/require-await
async function OCB(cipher, key) { async function OCB(cipher, key) {
const { keySize } = getCipherParams(cipher); const { keySize } = getCipherParams(cipher);
// sanity checks // sanity checks
@ -240,6 +241,7 @@ async function OCB(cipher, key) {
* @param {Uint8Array} adata - Associated data to sign * @param {Uint8Array} adata - Associated data to sign
* @returns {Promise<Uint8Array>} The ciphertext output. * @returns {Promise<Uint8Array>} The ciphertext output.
*/ */
// eslint-disable-next-line @typescript-eslint/require-await
decrypt: async function(ciphertext, nonce, adata) { decrypt: async function(ciphertext, nonce, adata) {
if (ciphertext.length < tagLength) throw new Error('Invalid OCB ciphertext'); if (ciphertext.length < tagLength) throw new Error('Invalid OCB ciphertext');

View File

@ -73,6 +73,7 @@ export default async function CMAC(key) {
async function CBC(key) { async function CBC(key) {
if (util.getNodeCrypto()) { // Node crypto library if (util.getNodeCrypto()) { // Node crypto library
// eslint-disable-next-line @typescript-eslint/require-await
return async function(pt) { return async function(pt) {
const en = new nodeCrypto.createCipheriv('aes-' + (key.length * 8) + '-cbc', key, zeroBlock); const en = new nodeCrypto.createCipheriv('aes-' + (key.length * 8) + '-cbc', key, zeroBlock);
const ct = en.update(pt); const ct = en.update(pt);
@ -97,6 +98,7 @@ async function CBC(key) {
} }
} }
// eslint-disable-next-line @typescript-eslint/require-await
return async function(pt) { return async function(pt) {
return nobleAesCbc(key, zeroBlock, { disablePadding: true }).encrypt(pt); return nobleAesCbc(key, zeroBlock, { disablePadding: true }).encrypt(pt);
}; };

View File

@ -458,7 +458,7 @@ export function generateSessionKey(algo) {
function checkSupportedCurve(oid) { function checkSupportedCurve(oid) {
try { try {
oid.getName(); oid.getName();
} catch (e) { } catch {
throw new UnsupportedError('Unknown curve OID'); throw new UnsupportedError('Unknown curve OID');
} }
} }

View File

@ -17,6 +17,7 @@ function nodeHash(type) {
if (!nodeCrypto || !nodeCryptoHashes.includes(type)) { if (!nodeCrypto || !nodeCryptoHashes.includes(type)) {
return; return;
} }
// eslint-disable-next-line @typescript-eslint/require-await
return async function (data) { return async function (data) {
const shasum = nodeCrypto.createHash(type); const shasum = nodeCrypto.createHash(type);
return streamTransform(data, value => { return streamTransform(data, value => {

View File

@ -35,15 +35,12 @@ class MD5 extends HashMD<MD5> {
// Compression function main loop, 64 rounds // Compression function main loop, 64 rounds
let { A, B, C, D } = this; let { A, B, C, D } = this;
for (let i = 0; i < 64; i++) { for (let i = 0; i < 64; i++) {
// eslint-disable-next-line one-var, one-var-declaration-per-line
let F, g, s; let F, g, s;
if (i < 16) { if (i < 16) {
// eslint-disable-next-line new-cap
F = Chi(B, C, D); F = Chi(B, C, D);
g = i; g = i;
s = [7, 12, 17, 22]; s = [7, 12, 17, 22];
} else if (i < 32) { } else if (i < 32) {
// eslint-disable-next-line new-cap
F = Chi(D, B, C); F = Chi(D, B, C);
g = (5 * i + 1) % 16; g = (5 * i + 1) % 16;
s = [5, 9, 14, 20]; s = [5, 9, 14, 20];

View File

@ -44,6 +44,7 @@ const _1n = BigInt(1);
* @returns {Promise<{ r: Uint8Array, s: Uint8Array }>} * @returns {Promise<{ r: Uint8Array, s: Uint8Array }>}
* @async * @async
*/ */
// eslint-disable-next-line @typescript-eslint/require-await
export async function sign(hashAlgo, hashed, g, p, q, x) { export async function sign(hashAlgo, hashed, g, p, q, x) {
const _0n = BigInt(0); const _0n = BigInt(0);
p = uint8ArrayToBigInt(p); p = uint8ArrayToBigInt(p);
@ -102,6 +103,7 @@ export async function sign(hashAlgo, hashed, g, p, q, x) {
* @returns {boolean} * @returns {boolean}
* @async * @async
*/ */
// eslint-disable-next-line @typescript-eslint/require-await
export async function verify(hashAlgo, r, s, hashed, g, p, q, y) { export async function verify(hashAlgo, r, s, hashed, g, p, q, y) {
r = uint8ArrayToBigInt(r); r = uint8ArrayToBigInt(r);
s = uint8ArrayToBigInt(s); s = uint8ArrayToBigInt(s);
@ -135,19 +137,20 @@ export async function verify(hashAlgo, r, s, hashed, g, p, q, y) {
/** /**
* Validate DSA parameters * Validate DSA parameters
* @param {Uint8Array} p - DSA prime * @param {Uint8Array} pBytes - DSA prime
* @param {Uint8Array} q - DSA group order * @param {Uint8Array} qBytes - DSA group order
* @param {Uint8Array} g - DSA sub-group generator * @param {Uint8Array} gBytes - DSA sub-group generator
* @param {Uint8Array} y - DSA public key * @param {Uint8Array} yBytes - DSA public key
* @param {Uint8Array} x - DSA private key * @param {Uint8Array} xBytes - DSA private key
* @returns {Promise<Boolean>} Whether params are valid. * @returns {Promise<Boolean>} Whether params are valid.
* @async * @async
*/ */
export async function validateParams(p, q, g, y, x) { // eslint-disable-next-line @typescript-eslint/require-await
p = uint8ArrayToBigInt(p); export async function validateParams(pBytes, qBytes, gBytes, yBytes, xBytes) {
q = uint8ArrayToBigInt(q); const p = uint8ArrayToBigInt(pBytes);
g = uint8ArrayToBigInt(g); const q = uint8ArrayToBigInt(qBytes);
y = uint8ArrayToBigInt(y); const g = uint8ArrayToBigInt(gBytes);
const y = uint8ArrayToBigInt(yBytes);
// Check that 1 < g < p // Check that 1 < g < p
if (g <= _1n || g >= p) { if (g <= _1n || g >= p) {
return false; return false;
@ -183,7 +186,7 @@ export async function validateParams(p, q, g, y, x) {
* *
* Blinded exponentiation computes g**{rq + x} to compare to y * Blinded exponentiation computes g**{rq + x} to compare to y
*/ */
x = uint8ArrayToBigInt(x); const x = uint8ArrayToBigInt(xBytes);
const _2n = BigInt(2); const _2n = BigInt(2);
const r = getRandomBigInteger(_2n << (qSize - _1n), _2n << qSize); // draw r of same size as q const r = getRandomBigInteger(_2n << (qSize - _1n), _2n << qSize); // draw r of same size as q
const rqx = q * r + x; const rqx = q * r + x;

View File

@ -35,6 +35,7 @@ const _1n = BigInt(1);
* @returns {Promise<{ c1: Uint8Array, c2: Uint8Array }>} * @returns {Promise<{ c1: Uint8Array, c2: Uint8Array }>}
* @async * @async
*/ */
// eslint-disable-next-line @typescript-eslint/require-await
export async function encrypt(data, p, g, y) { export async function encrypt(data, p, g, y) {
p = uint8ArrayToBigInt(p); p = uint8ArrayToBigInt(p);
g = uint8ArrayToBigInt(g); g = uint8ArrayToBigInt(g);
@ -64,6 +65,7 @@ export async function encrypt(data, p, g, y) {
* @throws {Error} on decryption error, unless `randomPayload` is given * @throws {Error} on decryption error, unless `randomPayload` is given
* @async * @async
*/ */
// eslint-disable-next-line @typescript-eslint/require-await
export async function decrypt(c1, c2, p, x, randomPayload) { export async function decrypt(c1, c2, p, x, randomPayload) {
c1 = uint8ArrayToBigInt(c1); c1 = uint8ArrayToBigInt(c1);
c2 = uint8ArrayToBigInt(c2); c2 = uint8ArrayToBigInt(c2);
@ -76,17 +78,18 @@ export async function decrypt(c1, c2, p, x, randomPayload) {
/** /**
* Validate ElGamal parameters * Validate ElGamal parameters
* @param {Uint8Array} p - ElGamal prime * @param {Uint8Array} pBytes - ElGamal prime
* @param {Uint8Array} g - ElGamal group generator * @param {Uint8Array} gBytes - ElGamal group generator
* @param {Uint8Array} y - ElGamal public key * @param {Uint8Array} yBytes - ElGamal public key
* @param {Uint8Array} x - ElGamal private exponent * @param {Uint8Array} xBytes - ElGamal private exponent
* @returns {Promise<Boolean>} Whether params are valid. * @returns {Promise<Boolean>} Whether params are valid.
* @async * @async
*/ */
export async function validateParams(p, g, y, x) { // eslint-disable-next-line @typescript-eslint/require-await
p = uint8ArrayToBigInt(p); export async function validateParams(pBytes, gBytes, yBytes, xBytes) {
g = uint8ArrayToBigInt(g); const p = uint8ArrayToBigInt(pBytes);
y = uint8ArrayToBigInt(y); const g = uint8ArrayToBigInt(gBytes);
const y = uint8ArrayToBigInt(yBytes);
// Check that 1 < g < p // Check that 1 < g < p
if (g <= _1n || g >= p) { if (g <= _1n || g >= p) {
@ -132,7 +135,7 @@ export async function validateParams(p, g, y, x) {
* *
* Blinded exponentiation computes g**{r(p-1) + x} to compare to y * Blinded exponentiation computes g**{r(p-1) + x} to compare to y
*/ */
x = uint8ArrayToBigInt(x); const x = uint8ArrayToBigInt(xBytes);
const r = getRandomBigInteger(_2n << (pSize - _1n), _2n << pSize); // draw r of same size as p-1 const r = getRandomBigInteger(_2n << (pSize - _1n), _2n << pSize); // draw r of same size as p-1
const rqx = (p - _1n) * r + x; const rqx = (p - _1n) * r + x;
if (y !== modExp(g, rqx, p)) { if (y !== modExp(g, rqx, p)) {

View File

@ -4,7 +4,6 @@ import { Field } from '@noble/curves/abstract/modular';
// brainpoolP256r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.4 // brainpoolP256r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.4
// eslint-disable-next-line new-cap
const Fp = Field(BigInt('0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377')); const Fp = Field(BigInt('0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377'));
const CURVE_A = Fp.create(BigInt('0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9')); const CURVE_A = Fp.create(BigInt('0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9'));
const CURVE_B = BigInt('0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6'); const CURVE_B = BigInt('0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6');

View File

@ -4,7 +4,6 @@ import { Field } from '@noble/curves/abstract/modular';
// brainpoolP384 r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.6 // brainpoolP384 r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.6
// eslint-disable-next-line new-cap
const Fp = Field(BigInt('0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a71874700133107ec53')); const Fp = Field(BigInt('0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a71874700133107ec53'));
const CURVE_A = Fp.create(BigInt('0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f8aa5814a503ad4eb04a8c7dd22ce2826')); const CURVE_A = Fp.create(BigInt('0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f8aa5814a503ad4eb04a8c7dd22ce2826'));
const CURVE_B = BigInt('0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d57cb4390295dbc9943ab78696fa504c11'); const CURVE_B = BigInt('0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d57cb4390295dbc9943ab78696fa504c11');

View File

@ -4,7 +4,6 @@ import { Field } from '@noble/curves/abstract/modular';
// brainpoolP512r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.7 // brainpoolP512r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.7
// eslint-disable-next-line new-cap
const Fp = Field(BigInt('0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3')); const Fp = Field(BigInt('0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3'));
const CURVE_A = Fp.create(BigInt('0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca')); const CURVE_A = Fp.create(BigInt('0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca'));
const CURVE_B = BigInt('0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723'); const CURVE_B = BigInt('0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723');

View File

@ -336,7 +336,7 @@ async function webPublicEphemeralKey(curve, Q) {
* @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>} * @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
* @async * @async
*/ */
async function nodePrivateEphemeralKey(curve, V, d) { function nodePrivateEphemeralKey(curve, V, d) {
const nodeCrypto = util.getNodeCrypto(); const nodeCrypto = util.getNodeCrypto();
const recipient = nodeCrypto.createECDH(curve.node); const recipient = nodeCrypto.createECDH(curve.node);
recipient.setPrivateKey(d); recipient.setPrivateKey(d);
@ -353,7 +353,7 @@ async function nodePrivateEphemeralKey(curve, V, d) {
* @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>} * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
* @async * @async
*/ */
async function nodePublicEphemeralKey(curve, Q) { function nodePublicEphemeralKey(curve, Q) {
const nodeCrypto = util.getNodeCrypto(); const nodeCrypto = util.getNodeCrypto();
const sender = nodeCrypto.createECDH(curve.node); const sender = nodeCrypto.createECDH(curve.node);
sender.generateKeys(); sender.generateKeys();

View File

@ -88,7 +88,7 @@ export async function validateParams(algo, A, k) {
const recomputedSharedSecret = await recomputeSharedSecret(algo, ephemeralPublicKey, A, k); const recomputedSharedSecret = await recomputeSharedSecret(algo, ephemeralPublicKey, A, k);
return util.equalsUint8Array(sharedSecret, recomputedSharedSecret); return util.equalsUint8Array(sharedSecret, recomputedSharedSecret);
} catch (_) { } catch {
return false; return false;
} }

View File

@ -88,7 +88,7 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed
* @param {Uint8Array} message - Message to verify * @param {Uint8Array} message - Message to verify
* @param {Uint8Array} publicKey - Public key used to verify the message * @param {Uint8Array} publicKey - Public key used to verify the message
* @param {Uint8Array} hashed - The hashed message * @param {Uint8Array} hashed - The hashed message
* @returns {Boolean} * @returns {Promise<Boolean>}
* @async * @async
*/ */
export async function verify(oid, hashAlgo, signature, message, publicKey, hashed) { export async function verify(oid, hashAlgo, signature, message, publicKey, hashed) {
@ -124,7 +124,7 @@ export async function verify(oid, hashAlgo, signature, message, publicKey, hashe
} }
break; break;
case 'node': { case 'node': {
const verified = await nodeVerify(curve, hashAlgo, signature, message, publicKey); const verified = nodeVerify(curve, hashAlgo, signature, message, publicKey);
return verified || tryFallbackVerificationForOldBug(); return verified || tryFallbackVerificationForOldBug();
} }
} }
@ -159,9 +159,8 @@ export async function validateParams(oid, Q, d) {
const hashed = await computeDigest(hashAlgo, message); const hashed = await computeDigest(hashAlgo, message);
try { try {
const signature = await sign(oid, hashAlgo, message, Q, d, hashed); const signature = await sign(oid, hashAlgo, message, Q, d, hashed);
// eslint-disable-next-line @typescript-eslint/return-await
return await verify(oid, hashAlgo, signature, message, Q, hashed); return await verify(oid, hashAlgo, signature, message, Q, hashed);
} catch (err) { } catch {
return false; return false;
} }
} }
@ -246,7 +245,7 @@ async function webVerify(curve, hashAlgo, { r, s }, message, publicKey) {
); );
} }
async function nodeSign(curve, hashAlgo, message, privateKey) { function nodeSign(curve, hashAlgo, message, privateKey) {
// JWT encoding cannot be used for now, as Brainpool curves are not supported // JWT encoding cannot be used for now, as Brainpool curves are not supported
const ecKeyUtils = util.nodeRequire('eckey-utils'); const ecKeyUtils = util.nodeRequire('eckey-utils');
const nodeBuffer = util.getNodeBuffer(); const nodeBuffer = util.getNodeBuffer();
@ -268,7 +267,7 @@ async function nodeSign(curve, hashAlgo, message, privateKey) {
}; };
} }
async function nodeVerify(curve, hashAlgo, { r, s }, message, publicKey) { function nodeVerify(curve, hashAlgo, { r, s }, message, publicKey) {
const ecKeyUtils = util.nodeRequire('eckey-utils'); const ecKeyUtils = util.nodeRequire('eckey-utils');
const nodeBuffer = util.getNodeBuffer(); const nodeBuffer = util.getNodeBuffer();
const { publicKey: derPublicKey } = ecKeyUtils.generateDer({ const { publicKey: derPublicKey } = ecKeyUtils.generateDer({
@ -284,7 +283,7 @@ async function nodeVerify(curve, hashAlgo, { r, s }, message, publicKey) {
try { try {
return verify.verify({ key: derPublicKey, format: 'der', type: 'spki', dsaEncoding: 'ieee-p1363' }, signature); return verify.verify({ key: derPublicKey, format: 'der', type: 'spki', dsaEncoding: 'ieee-p1363' }, signature);
} catch (err) { } catch {
return false; return false;
} }
} }

View File

@ -70,6 +70,7 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed
* @returns {Boolean} * @returns {Boolean}
* @async * @async
*/ */
// eslint-disable-next-line @typescript-eslint/require-await
export async function verify(oid, hashAlgo, { r, s }, m, publicKey, hashed) { export async function verify(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
const curve = new CurveWithOID(oid); const curve = new CurveWithOID(oid);
checkPublicPointEnconding(curve, publicKey); checkPublicPointEnconding(curve, publicKey);

View File

@ -143,7 +143,7 @@ class CurveWithOID {
this.name = oidOrName instanceof OID ? this.name = oidOrName instanceof OID ?
oidOrName.getName() : oidOrName.getName() :
enums.write(enums.curve,oidOrName); enums.write(enums.curve,oidOrName);
} catch (err) { } catch {
throw new UnsupportedError('Unknown curve'); throw new UnsupportedError('Unknown curve');
} }
const params = curves[this.name]; const params = curves[this.name];
@ -315,10 +315,10 @@ async function webGenKeyPair(name, wireFormatLeadingByte) {
}; };
} }
async function nodeGenKeyPair(name) { function nodeGenKeyPair(name) {
// Note: ECDSA and ECDH key generation is structurally equivalent // Note: ECDSA and ECDH key generation is structurally equivalent
const ecdh = nodeCrypto.createECDH(nodeCurves[name]); const ecdh = nodeCrypto.createECDH(nodeCurves[name]);
await ecdh.generateKeys(); ecdh.generateKeys();
return { return {
publicKey: new Uint8Array(ecdh.getPublicKey()), publicKey: new Uint8Array(ecdh.getPublicKey()),
privateKey: new Uint8Array(ecdh.getPrivateKey()) privateKey: new Uint8Array(ecdh.getPrivateKey())

View File

@ -76,7 +76,7 @@ export async function sign(hashAlgo, data, n, e, d, p, q, u, hashed) {
* @param {Uint8Array} n - RSA public modulus * @param {Uint8Array} n - RSA public modulus
* @param {Uint8Array} e - RSA public exponent * @param {Uint8Array} e - RSA public exponent
* @param {Uint8Array} hashed - Hashed message * @param {Uint8Array} hashed - Hashed message
* @returns {Boolean} * @returns {Promise<Boolean>}
* @async * @async
*/ */
export async function verify(hashAlgo, data, s, n, e, hashed) { export async function verify(hashAlgo, data, s, n, e, hashed) {
@ -102,6 +102,7 @@ export async function verify(hashAlgo, data, s, n, e, hashed) {
* @returns {Promise<Uint8Array>} RSA Ciphertext. * @returns {Promise<Uint8Array>} RSA Ciphertext.
* @async * @async
*/ */
// eslint-disable-next-line @typescript-eslint/require-await
export async function encrypt(data, n, e) { export async function encrypt(data, n, e) {
if (util.getNodeCrypto()) { if (util.getNodeCrypto()) {
return nodeEncrypt(data, n, e); return nodeEncrypt(data, n, e);
@ -124,13 +125,14 @@ export async function encrypt(data, n, e) {
* @throws {Error} on decryption error, unless `randomPayload` is given * @throws {Error} on decryption error, unless `randomPayload` is given
* @async * @async
*/ */
// eslint-disable-next-line @typescript-eslint/require-await
export async function decrypt(data, n, e, d, p, q, u, randomPayload) { export async function decrypt(data, n, e, d, p, q, u, randomPayload) {
// Node v18.19.1, 20.11.1 and 21.6.2 have disabled support for PKCS#1 decryption, // Node v18.19.1, 20.11.1 and 21.6.2 have disabled support for PKCS#1 decryption,
// and we want to avoid checking the error type to decide if the random payload // and we want to avoid checking the error type to decide if the random payload
// should indeed be returned. // should indeed be returned.
if (util.getNodeCrypto() && !randomPayload) { if (util.getNodeCrypto() && !randomPayload) {
try { try {
return await nodeDecrypt(data, n, e, d, p, q, u); return nodeDecrypt(data, n, e, d, p, q, u);
} catch (err) { } catch (err) {
util.printDebugError(err); util.printDebugError(err);
} }
@ -146,8 +148,8 @@ export async function decrypt(data, n, e, d, p, q, u, randomPayload) {
* @see module:crypto/public_key/prime * @see module:crypto/public_key/prime
* @param {Integer} bits - RSA bit length * @param {Integer} bits - RSA bit length
* @param {Integer} e - RSA public exponent * @param {Integer} e - RSA public exponent
* @returns {{n, e, d, * @returns {Promise<{n, e, d,
* p, q ,u: Uint8Array}} RSA public modulus, RSA public exponent, RSA private exponent, * p, q ,u: Uint8Array}>} RSA public modulus, RSA public exponent, RSA private exponent,
* RSA private prime p, RSA private prime q, u = p ** -1 mod q * RSA private prime p, RSA private prime q, u = p ** -1 mod q
* @async * @async
*/ */
@ -231,6 +233,7 @@ export async function generate(bits, e) {
* @returns {Promise<Boolean>} Whether params are valid. * @returns {Promise<Boolean>} Whether params are valid.
* @async * @async
*/ */
// eslint-disable-next-line @typescript-eslint/require-await
export async function validateParams(n, e, d, p, q, u) { export async function validateParams(n, e, d, p, q, u) {
n = uint8ArrayToBigInt(n); n = uint8ArrayToBigInt(n);
p = uint8ArrayToBigInt(p); p = uint8ArrayToBigInt(p);
@ -269,7 +272,7 @@ export async function validateParams(n, e, d, p, q, u) {
return true; return true;
} }
async function bnSign(hashAlgo, n, d, hashed) { function bnSign(hashAlgo, n, d, hashed) {
n = uint8ArrayToBigInt(n); n = uint8ArrayToBigInt(n);
const m = uint8ArrayToBigInt(emsaEncode(hashAlgo, hashed, byteLength(n))); const m = uint8ArrayToBigInt(emsaEncode(hashAlgo, hashed, byteLength(n)));
d = uint8ArrayToBigInt(d); d = uint8ArrayToBigInt(d);
@ -284,7 +287,7 @@ async function webSign(hashName, data, n, e, d, p, q, u) {
* does if the underlying Web Crypto does so (though the tested implementations * does if the underlying Web Crypto does so (though the tested implementations
* don't do so). * don't do so).
*/ */
const jwk = await privateToJWK(n, e, d, p, q, u); const jwk = privateToJWK(n, e, d, p, q, u);
const algo = { const algo = {
name: 'RSASSA-PKCS1-v1_5', name: 'RSASSA-PKCS1-v1_5',
hash: { name: hashName } hash: { name: hashName }
@ -293,16 +296,16 @@ async function webSign(hashName, data, n, e, d, p, q, u) {
return new Uint8Array(await webCrypto.sign('RSASSA-PKCS1-v1_5', key, data)); return new Uint8Array(await webCrypto.sign('RSASSA-PKCS1-v1_5', key, data));
} }
async function nodeSign(hashAlgo, data, n, e, d, p, q, u) { function nodeSign(hashAlgo, data, n, e, d, p, q, u) {
const sign = nodeCrypto.createSign(enums.read(enums.hash, hashAlgo)); const sign = nodeCrypto.createSign(enums.read(enums.hash, hashAlgo));
sign.write(data); sign.write(data);
sign.end(); sign.end();
const jwk = await privateToJWK(n, e, d, p, q, u); const jwk = privateToJWK(n, e, d, p, q, u);
return new Uint8Array(sign.sign({ key: jwk, format: 'jwk', type: 'pkcs1' })); return new Uint8Array(sign.sign({ key: jwk, format: 'jwk', type: 'pkcs1' }));
} }
async function bnVerify(hashAlgo, s, n, e, hashed) { function bnVerify(hashAlgo, s, n, e, hashed) {
n = uint8ArrayToBigInt(n); n = uint8ArrayToBigInt(n);
s = uint8ArrayToBigInt(s); s = uint8ArrayToBigInt(s);
e = uint8ArrayToBigInt(e); e = uint8ArrayToBigInt(e);
@ -323,7 +326,7 @@ async function webVerify(hashName, data, s, n, e) {
return webCrypto.verify('RSASSA-PKCS1-v1_5', key, s, data); return webCrypto.verify('RSASSA-PKCS1-v1_5', key, s, data);
} }
async function nodeVerify(hashAlgo, data, s, n, e) { function nodeVerify(hashAlgo, data, s, n, e) {
const jwk = publicToJWK(n, e); const jwk = publicToJWK(n, e);
const key = { key: jwk, format: 'jwk', type: 'pkcs1' }; const key = { key: jwk, format: 'jwk', type: 'pkcs1' };
@ -333,19 +336,19 @@ async function nodeVerify(hashAlgo, data, s, n, e) {
try { try {
return verify.verify(key, s); return verify.verify(key, s);
} catch (err) { } catch {
return false; return false;
} }
} }
async function nodeEncrypt(data, n, e) { function nodeEncrypt(data, n, e) {
const jwk = publicToJWK(n, e); const jwk = publicToJWK(n, e);
const key = { key: jwk, format: 'jwk', type: 'pkcs1', padding: nodeCrypto.constants.RSA_PKCS1_PADDING }; const key = { key: jwk, format: 'jwk', type: 'pkcs1', padding: nodeCrypto.constants.RSA_PKCS1_PADDING };
return new Uint8Array(nodeCrypto.publicEncrypt(key, data)); return new Uint8Array(nodeCrypto.publicEncrypt(key, data));
} }
async function bnEncrypt(data, n, e) { function bnEncrypt(data, n, e) {
n = uint8ArrayToBigInt(n); n = uint8ArrayToBigInt(n);
data = uint8ArrayToBigInt(emeEncode(data, byteLength(n))); data = uint8ArrayToBigInt(emeEncode(data, byteLength(n)));
e = uint8ArrayToBigInt(e); e = uint8ArrayToBigInt(e);
@ -355,18 +358,18 @@ async function bnEncrypt(data, n, e) {
return bigIntToUint8Array(modExp(data, e, n), 'be', byteLength(n)); return bigIntToUint8Array(modExp(data, e, n), 'be', byteLength(n));
} }
async function nodeDecrypt(data, n, e, d, p, q, u) { function nodeDecrypt(data, n, e, d, p, q, u) {
const jwk = await privateToJWK(n, e, d, p, q, u); const jwk = privateToJWK(n, e, d, p, q, u);
const key = { key: jwk, format: 'jwk' , type: 'pkcs1', padding: nodeCrypto.constants.RSA_PKCS1_PADDING }; const key = { key: jwk, format: 'jwk' , type: 'pkcs1', padding: nodeCrypto.constants.RSA_PKCS1_PADDING };
try { try {
return new Uint8Array(nodeCrypto.privateDecrypt(key, data)); return new Uint8Array(nodeCrypto.privateDecrypt(key, data));
} catch (err) { } catch {
throw new Error('Decryption error'); throw new Error('Decryption error');
} }
} }
async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) { function bnDecrypt(data, n, e, d, p, q, u, randomPayload) {
data = uint8ArrayToBigInt(data); data = uint8ArrayToBigInt(data);
n = uint8ArrayToBigInt(n); n = uint8ArrayToBigInt(n);
e = uint8ArrayToBigInt(e); e = uint8ArrayToBigInt(e);
@ -405,7 +408,7 @@ async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) {
* @param {Uint8Array} q * @param {Uint8Array} q
* @param {Uint8Array} u * @param {Uint8Array} u
*/ */
async function privateToJWK(n, e, d, p, q, u) { function privateToJWK(n, e, d, p, q, u) {
const pNum = uint8ArrayToBigInt(p); const pNum = uint8ArrayToBigInt(p);
const qNum = uint8ArrayToBigInt(q); const qNum = uint8ArrayToBigInt(q);
const dNum = uint8ArrayToBigInt(d); const dNum = uint8ArrayToBigInt(d);

View File

@ -227,8 +227,7 @@ function removeChecksum(text) {
* @static * @static
*/ */
export function unarmor(input) { export function unarmor(input) {
// eslint-disable-next-line no-async-promise-executor return new Promise((resolve, reject) => {
return new Promise(async (resolve, reject) => {
try { try {
const reSplit = /^-----[^-]+-----$/m; const reSplit = /^-----[^-]+-----$/m;
const reEmptyLine = /^[ \f\r\t\u00a0\u2000-\u200a\u202f\u205f\u3000]*$/; const reEmptyLine = /^[ \f\r\t\u00a0\u2000-\u200a\u202f\u205f\u3000]*$/;

1
src/enums.d.ts vendored
View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-duplicate-enum-values */
declare namespace enums { declare namespace enums {
export function read(type: typeof armor, e: armor): armorNames; export function read(type: typeof armor, e: armor): armorNames;
export function read(type: typeof compression, e: compression): compressionNames; export function read(type: typeof compression, e: compression): compressionNames;

View File

@ -167,10 +167,10 @@ export async function reformat(options, config) {
* Construct PrivateKey object from the given key packets, add certification signatures and set passphrase protection * Construct PrivateKey object from the given key packets, add certification signatures and set passphrase protection
* The new key includes a revocation certificate that must be removed before returning the key, otherwise the key is considered revoked. * The new key includes a revocation certificate that must be removed before returning the key, otherwise the key is considered revoked.
* @param {SecretKeyPacket} secretKeyPacket * @param {SecretKeyPacket} secretKeyPacket
* @param {SecretSubkeyPacket} secretSubkeyPackets * @param {Array<SecretSubkeyPacket>} secretSubkeyPackets
* @param {Object} options * @param {Object} options
* @param {Object} config - Full configuration * @param {Object} config - Full configuration
* @returns {PrivateKey} * @returns {Promise<PrivateKey>}
*/ */
async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, config) { async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, config) {
// set passphrase protection // set passphrase protection
@ -295,12 +295,12 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
secretKeyPacket.clearPrivateParams(); secretKeyPacket.clearPrivateParams();
} }
await Promise.all(secretSubkeyPackets.map(async function(secretSubkeyPacket, index) { secretSubkeyPackets.map(function(secretSubkeyPacket, index) {
const subkeyPassphrase = options.subkeys[index].passphrase; const subkeyPassphrase = options.subkeys[index].passphrase;
if (subkeyPassphrase) { if (subkeyPassphrase) {
secretSubkeyPacket.clearPrivateParams(); secretSubkeyPacket.clearPrivateParams();
} }
})); });
return new PrivateKey(packetlist); return new PrivateKey(packetlist);
} }

View File

@ -357,7 +357,7 @@ export async function isDataRevoked(primaryKey, signatureType, dataToVerify, rev
// 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 {}
})); }));
// 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) {
@ -398,7 +398,7 @@ export function sanitizeKeyOptions(options, subkeyDefaults = {}) {
case 'ecc': // NB: this case also handles legacy eddsa and x25519 keys, based on `options.curve` case 'ecc': // NB: this case also handles legacy eddsa and x25519 keys, based on `options.curve`
try { try {
options.curve = enums.write(enums.curve, options.curve); options.curve = enums.write(enums.curve, options.curve);
} catch (e) { } catch {
throw new Error('Unknown curve'); throw new Error('Unknown curve');
} }
if (options.curve === enums.curve.ed25519Legacy || options.curve === enums.curve.curve25519Legacy || if (options.curve === enums.curve.ed25519Legacy || options.curve === enums.curve.curve25519Legacy ||

View File

@ -442,7 +442,7 @@ class Key {
} else { } else {
primaryKeyExpiry = selfSigKeyExpiry < selfSigExpiry ? selfSigKeyExpiry : selfSigExpiry; primaryKeyExpiry = selfSigKeyExpiry < selfSigExpiry ? selfSigKeyExpiry : selfSigExpiry;
} }
} catch (e) { } catch {
primaryKeyExpiry = null; primaryKeyExpiry = null;
} }
@ -510,11 +510,13 @@ class Key {
} }
} }
if (!users.length) { if (!users.length) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal // eslint-disable-next-line @typescript-eslint/only-throw-error
throw exception || new Error('Could not find primary user'); throw exception || new Error('Could not find primary user');
} }
await Promise.all(users.map(async function (a) { // Update `revoked` status, whose value is discarded here but used below;
return a.selfCertification.revoked || a.user.isRevoked(a.selfCertification, null, date, config); // see https://github.com/openpgpjs/openpgpjs/issues/880 for Promise.all motivation
await Promise.all(users.map(async a => {
a.selfCertification.revoked || await a.user.isRevoked(a.selfCertification, null, date, config);
})); }));
// sort by primary user flag and signature creation time // sort by primary user flag and signature creation time
const primaryUser = users.sort(function(a, b) { const primaryUser = users.sort(function(a, b) {
@ -751,8 +753,7 @@ 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

@ -114,7 +114,7 @@ class PrivateKey extends PublicKey {
} }
if (keys.length === 0) { if (keys.length === 0) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal // eslint-disable-next-line @typescript-eslint/only-throw-error
throw exception || new Error('No decryption key packets found'); throw exception || new Error('No decryption key packets found');
} }
@ -168,7 +168,7 @@ class PrivateKey extends PublicKey {
throw new Error('Cannot validate an all-gnu-dummy key'); throw new Error('Cannot validate an all-gnu-dummy key');
} }
return Promise.all(keys.map(async key => key.keyPacket.validate())); return Promise.all(keys.map(key => key.keyPacket.validate()));
} }
} }

View File

@ -112,7 +112,7 @@ class Subkey {
let bindingSignature; let bindingSignature;
try { try {
bindingSignature = await helper.getLatestValidSignature(this.bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config); bindingSignature = await helper.getLatestValidSignature(this.bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config);
} catch (e) { } catch {
return null; return null;
} }
const keyExpiry = helper.getKeyExpirationTime(this.keyPacket, bindingSignature); const keyExpiry = helper.getKeyExpirationTime(this.keyPacket, bindingSignature);
@ -153,7 +153,7 @@ class Subkey {
try { try {
await srcBindSig.verify(primaryKey, enums.signature.subkeyBinding, dataToVerify, date, undefined, config); await srcBindSig.verify(primaryKey, enums.signature.subkeyBinding, dataToVerify, date, undefined, config);
return true; return true;
} catch (e) { } catch {
return false; return false;
} }
}); });

View File

@ -222,7 +222,7 @@ class User {
try { try {
await srcSelfSig.verify(primaryKey, enums.signature.certGeneric, dataToVerify, date, false, config); await srcSelfSig.verify(primaryKey, enums.signature.certGeneric, dataToVerify, date, false, config);
return true; return true;
} catch (e) { } catch {
return false; return false;
} }
}); });

View File

@ -220,7 +220,7 @@ export class Message {
if (selfCertification.preferredSymmetricAlgorithms) { if (selfCertification.preferredSymmetricAlgorithms) {
algos = algos.concat(selfCertification.preferredSymmetricAlgorithms); algos = algos.concat(selfCertification.preferredSymmetricAlgorithms);
} }
} catch (e) {} } catch {}
await Promise.all(decryptionKeyPackets.map(async function(decryptionKeyPacket) { await Promise.all(decryptionKeyPackets.map(async function(decryptionKeyPacket) {
if (!decryptionKeyPacket.isDecrypted()) { if (!decryptionKeyPacket.isDecrypted()) {
@ -460,7 +460,7 @@ export class Message {
try { try {
await keyPacket.decrypt(password); await keyPacket.decrypt(password);
return 1; return 1;
} catch (e) { } catch {
return 0; return 0;
} }
}; };
@ -639,9 +639,10 @@ export class Message {
* signature: Promise<Signature>, * signature: Promise<Signature>,
* verified: Promise<true> * verified: Promise<true>
* }>>} List of signer's keyID and validity of signature. * }>>} List of signer's keyID and validity of signature.
* @async * @async needed to avoid breaking change until next major release
*/ */
verifyDetached(signature, verificationKeys, date = new Date(), config = defaultConfig) { // eslint-disable-next-line @typescript-eslint/require-await
async verifyDetached(signature, verificationKeys, date = new Date(), config = defaultConfig) {
const msg = this.unwrapCompressed(); const msg = this.unwrapCompressed();
const literalDataList = msg.packets.filterByTag(enums.packet.literalData); const literalDataList = msg.packets.filterByTag(enums.packet.literalData);
if (literalDataList.length !== 1) { if (literalDataList.length !== 1) {
@ -751,15 +752,15 @@ export async function createSignaturePackets(literalDataPacket, signingKeys, rec
* @param {Date} [date] - Check signature validity with respect to the given date * @param {Date} [date] - Check signature validity with respect to the given date
* @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 {Promise<{ * @returns {{
* keyID: module:type/keyid~KeyID, * keyID: module:type/keyid~KeyID,
* signature: Promise<Signature>, * signature: Promise<Signature>,
* verified: Promise<true> * verified: Promise<true>
* }>} signer's keyID and validity of signature * }} signer's keyID and validity of signature
* @async * @async
* @private * @private
*/ */
async function createVerificationObject(signature, literalDataList, verificationKeys, date = new Date(), detached = false, config = defaultConfig) { function createVerificationObject(signature, literalDataList, verificationKeys, date = new Date(), detached = false, config = defaultConfig) {
let primaryKey; let primaryKey;
let unverifiedSigningKey; let unverifiedSigningKey;
@ -831,20 +832,17 @@ async function createVerificationObject(signature, literalDataList, verification
* 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 {Promise<Array<{ * @returns {Array<{
* keyID: module:type/keyid~KeyID, * keyID: module:type/keyid~KeyID,
* signature: Promise<Signature>, * signature: Promise<Signature>,
* verified: Promise<true> * verified: Promise<true>
* }>>} list of signer's keyID and validity of signatures (one entry per signature packet in input) * }>} list of signer's keyID and validity of signatures (one entry per signature packet in input)
* @async
* @private * @private
*/ */
export async function createVerificationObjects(signatureList, literalDataList, verificationKeys, date = new Date(), detached = false, config = defaultConfig) { export function createVerificationObjects(signatureList, literalDataList, verificationKeys, date = new Date(), detached = false, config = defaultConfig) {
return Promise.all(signatureList.filter(function(signature) { return signatureList
return ['text', 'binary'].includes(enums.read(enums.signature, signature.signatureType)); .filter(signature => ['text', 'binary'].includes(enums.read(enums.signature, signature.signatureType)))
}).map(async function(signature) { .map(signature => createVerificationObject(signature, literalDataList, verificationKeys, date, detached, config));
return createVerificationObject(signature, literalDataList, verificationKeys, date, detached, config);
}));
} }
/** /**
@ -894,9 +892,10 @@ export async function readMessage({ armoredMessage, binaryMessage, config, ...re
* @param {Date} [options.date=current date] - Date of the message, or modification date of the file * @param {Date} [options.date=current date] - Date of the message, or modification date of the file
* @param {'utf8'|'binary'|'text'|'mime'} [options.format='utf8' if text is passed, 'binary' otherwise] - Data packet type * @param {'utf8'|'binary'|'text'|'mime'} [options.format='utf8' if text is passed, 'binary' otherwise] - Data packet type
* @returns {Promise<Message>} New message object. * @returns {Promise<Message>} New message object.
* @async * @async not necessary, but needed to align with readMessage
* @static * @static
*/ */
// eslint-disable-next-line @typescript-eslint/require-await
export async function createMessage({ text, binary, filename, date = new Date(), format = text !== undefined ? 'utf8' : 'binary', ...rest }) { export async function createMessage({ text, binary, filename, date = new Date(), format = text !== undefined ? 'utf8' : 'binary', ...rest }) {
const input = text !== undefined ? text : binary; const input = text !== undefined ? text : binary;
if (input === undefined) { if (input === undefined) {

View File

@ -186,7 +186,7 @@ function zlib(compressionStreamInstantiator, ZlibStreamedConstructor) {
return new ReadableStream({ return new ReadableStream({
async start(controller) { async start(controller) {
zlibStream.ondata = async (value, isLast) => { zlibStream.ondata = (value, isLast) => {
controller.enqueue(value); controller.enqueue(value);
if (isLast) { if (isLast) {
controller.close(); controller.close();

View File

@ -194,8 +194,11 @@ class OnePassSignaturePacket {
} }
} }
// eslint-disable-next-line @typescript-eslint/unbound-method
OnePassSignaturePacket.prototype.hash = SignaturePacket.prototype.hash; OnePassSignaturePacket.prototype.hash = SignaturePacket.prototype.hash;
// eslint-disable-next-line @typescript-eslint/unbound-method
OnePassSignaturePacket.prototype.toHash = SignaturePacket.prototype.toHash; OnePassSignaturePacket.prototype.toHash = SignaturePacket.prototype.toHash;
// eslint-disable-next-line @typescript-eslint/unbound-method
OnePassSignaturePacket.prototype.toSign = SignaturePacket.prototype.toSign; OnePassSignaturePacket.prototype.toSign = SignaturePacket.prototype.toSign;
export default OnePassSignaturePacket; export default OnePassSignaturePacket;

View File

@ -112,7 +112,7 @@ export function supportsStreaming(tag) {
* *
* @param {Uint8Array | ReadableStream<Uint8Array>} input - Input stream as string * @param {Uint8Array | ReadableStream<Uint8Array>} input - Input stream as string
* @param {Function} callback - Function to call with the parsed packet * @param {Function} callback - Function to call with the parsed packet
* @returns {Boolean} Returns false if the stream was empty and parsing is done, and true otherwise. * @returns {Promise<Boolean>} Returns false if the stream was empty and parsing is done, and true otherwise.
*/ */
export async function readPacket(reader, useStreamType, callback) { export async function readPacket(reader, useStreamType, callback) {
let writer; let writer;
@ -155,7 +155,7 @@ export async function readPacket(reader, useStreamType, callback) {
writer = streamGetWriter(transform.writable); writer = streamGetWriter(transform.writable);
packet = transform.readable; packet = transform.readable;
} }
// eslint-disable-next-line callback-return
callbackReturned = callback({ tag, packet }); callbackReturned = callback({ tag, packet });
} else { } else {
packet = []; packet = [];
@ -244,7 +244,7 @@ export async function readPacket(reader, useStreamType, callback) {
await writer.close(); await writer.close();
} else { } else {
packet = util.concatUint8Array(packet); packet = util.concatUint8Array(packet);
// eslint-disable-next-line callback-return
await callback({ tag, packet }); await callback({ tag, packet });
} }
} catch (e) { } catch (e) {

View File

@ -26,7 +26,7 @@ export function newPacketFromTag(tag, allowedPackets) {
let packetType; let packetType;
try { try {
packetType = enums.read(enums.packet, tag); packetType = enums.read(enums.packet, tag);
} catch (e) { } catch {
throw new UnknownPacketError(`Unknown packet type with tag: ${tag}`); throw new UnknownPacketError(`Unknown packet type with tag: ${tag}`);
} }
throw new Error(`Packet not allowed in this context: ${packetType}`); throw new Error(`Packet not allowed in this context: ${packetType}`);
@ -49,7 +49,7 @@ class PacketList extends Array {
* @param {Object} [config] - full configuration, defaults to openpgp.config * @param {Object} [config] - full configuration, defaults to openpgp.config
* @param {function(enums.packet[], boolean, Object): void} [grammarValidator] * @param {function(enums.packet[], boolean, Object): void} [grammarValidator]
* @param {Boolean} [delayErrors] - delay errors until the input stream has been read completely * @param {Boolean} [delayErrors] - delay errors until the input stream has been read completely
* @returns {PacketList} parsed list of packets * @returns {Promise<PacketList>} parsed list of packets
* @throws on parsing errors * @throws on parsing errors
* @async * @async
*/ */
@ -174,7 +174,7 @@ class PacketList extends Array {
// in case there's an MDC error, which should take precedence. // in case there's an MDC error, which should take precedence.
if (unauthenticatedError) { if (unauthenticatedError) {
await reader.readToEnd(); await reader.readToEnd();
// eslint-disable-next-line @typescript-eslint/no-throw-literal // eslint-disable-next-line @typescript-eslint/only-throw-error
throw unauthenticatedError; throw unauthenticatedError;
} }

View File

@ -53,10 +53,11 @@ class PaddingPacket {
* Create random padding. * Create random padding.
* @param {Number} length - The length of padding to be generated. * @param {Number} length - The length of padding to be generated.
* @throws {Error} if padding generation was not successful * @throws {Error} if padding generation was not successful
* @async * @async needed to avoid breaking change until next major release
*/ */
// eslint-disable-next-line @typescript-eslint/require-await
async createPadding(length) { async createPadding(length) {
this.padding = await getRandomBytes(length); this.padding = getRandomBytes(length);
} }
} }

View File

@ -101,7 +101,7 @@ class PublicKeyPacket {
/** /**
* Internal Parser for public keys as specified in {@link https://tools.ietf.org/html/rfc4880#section-5.5.2|RFC 4880 section 5.5.2 Public-Key Packet Formats} * Internal Parser for public keys as specified in {@link https://tools.ietf.org/html/rfc4880#section-5.5.2|RFC 4880 section 5.5.2 Public-Key Packet Formats}
* @param {Uint8Array} bytes - Input array to read the packet from * @param {Uint8Array} bytes - Input array to read the packet from
* @returns {Object} This object with attributes set by the parser * @returns {Promise<number>} The number of bytes read from `bytes`
* @async * @async
*/ */
async read(bytes, config = defaultConfig) { async read(bytes, config = defaultConfig) {
@ -284,12 +284,14 @@ class PublicKeyPacket {
* Alias of read() * Alias of read()
* @see PublicKeyPacket#read * @see PublicKeyPacket#read
*/ */
// eslint-disable-next-line @typescript-eslint/unbound-method
PublicKeyPacket.prototype.readPublicKey = PublicKeyPacket.prototype.read; PublicKeyPacket.prototype.readPublicKey = PublicKeyPacket.prototype.read;
/** /**
* Alias of write() * Alias of write()
* @see PublicKeyPacket#write * @see PublicKeyPacket#write
*/ */
// eslint-disable-next-line @typescript-eslint/unbound-method
PublicKeyPacket.prototype.writePublicKey = PublicKeyPacket.prototype.write; PublicKeyPacket.prototype.writePublicKey = PublicKeyPacket.prototype.write;
export default PublicKeyPacket; export default PublicKeyPacket;

View File

@ -53,6 +53,7 @@ class PublicKeyEncryptedSessionKeyPacket {
this.publicKeyFingerprint = null; this.publicKeyFingerprint = null;
// For all versions: // For all versions:
/** @type {enums.publicKey | null} */
this.publicKeyAlgorithm = null; this.publicKeyAlgorithm = null;
this.sessionKey = null; this.sessionKey = null;

View File

@ -35,7 +35,6 @@ class PublicSubkeyPacket extends PublicKeyPacket {
* @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 @typescript-eslint/no-useless-constructor
constructor(date, config) { constructor(date, config) {
super(date, config); super(date, config);
} }

View File

@ -51,7 +51,7 @@ class SecretKeyPacket extends PublicKeyPacket {
this.isEncrypted = null; this.isEncrypted = null;
/** /**
* S2K usage * S2K usage
* @type {enums.symmetric} * @type {number}
*/ */
this.s2kUsage = 0; this.s2kUsage = 0;
/** /**
@ -481,7 +481,7 @@ class SecretKeyPacket extends PublicKeyPacket {
try { try {
const { privateParams } = parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams); const { privateParams } = parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
this.privateParams = privateParams; this.privateParams = privateParams;
} catch (err) { } catch {
throw new Error('Error reading MPIs'); throw new Error('Error reading MPIs');
} }
this.isEncrypted = false; this.isEncrypted = false;
@ -515,7 +515,7 @@ class SecretKeyPacket extends PublicKeyPacket {
try { try {
// this can throw if some parameters are undefined // this can throw if some parameters are undefined
validParams = await validateParams(this.algorithm, this.publicParams, this.privateParams); validParams = await validateParams(this.algorithm, this.publicParams, this.privateParams);
} catch (_) { } catch {
validParams = false; validParams = false;
} }
if (!validParams) { if (!validParams) {

View File

@ -97,6 +97,7 @@ class SignaturePacket {
this.keyFlags = null; this.keyFlags = null;
this.signersUserID = null; this.signersUserID = null;
this.reasonForRevocationFlag = null; this.reasonForRevocationFlag = null;
/** @type {String | null} */
this.reasonForRevocationString = null; this.reasonForRevocationString = null;
this.features = null; this.features = null;
this.signatureTargetPublicKeyAlgorithm = null; this.signatureTargetPublicKeyAlgorithm = null;

View File

@ -321,7 +321,6 @@ export async function runAEAD(packet, fn, key, data) {
done = true; done = true;
} }
cryptedBytes += chunk.length - tagLengthIfDecrypting; cryptedBytes += chunk.length - tagLengthIfDecrypting;
// eslint-disable-next-line @typescript-eslint/no-loop-func
latestPromise = latestPromise.then(() => cryptedPromise).then(async crypted => { latestPromise = latestPromise.then(() => cryptedPromise).then(async crypted => {
await writer.ready; await writer.ready;
await writer.write(crypted); await writer.write(crypted);

View File

@ -29,8 +29,8 @@ import defaultConfig from './config';
const debugMode = (() => { const debugMode = (() => {
try { try {
return process.env.NODE_ENV === 'development'; // eslint-disable-line no-process-env return process.env.NODE_ENV === 'development';
} catch (e) {} } catch {}
return false; return false;
})(); })();
@ -255,7 +255,7 @@ const util = {
*/ */
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
function process(value, lastChunk = false) { function process(value, lastChunk = false) {
return encoder.encode(value, { stream: !lastChunk }); return encoder.encode(value, { stream: !lastChunk });
} }
@ -269,7 +269,7 @@ const util = {
*/ */
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
function process(value, lastChunk = false) { function process(value, lastChunk = false) {
return decoder.decode(value, { stream: !lastChunk }); return decoder.decode(value, { stream: !lastChunk });
} }
@ -606,7 +606,7 @@ const util = {
try { try {
error.message += ': ' + cause.message; error.message += ': ' + cause.message;
error.cause = cause; error.cause = cause;
} catch (e) {} } catch {}
return error; return error;
} }
return new Error(error + ': ' + cause.message, { cause }); return new Error(error + ': ' + cause.message, { cause });
@ -638,17 +638,17 @@ const util = {
* or rejected with the Error of the last resolved Promise (if all promises are rejected) * or rejected with the Error of the last resolved Promise (if all promises are rejected)
*/ */
anyPromise: function(promises) { anyPromise: function(promises) {
// eslint-disable-next-line no-async-promise-executor return new Promise((resolve, reject) => {
return new Promise(async (resolve, reject) => {
let exception; let exception;
await Promise.all(promises.map(async promise => { void Promise.all(promises.map(async promise => {
try { try {
resolve(await promise); resolve(await promise);
} catch (e) { } catch (e) {
exception = e; exception = e;
} }
})); })).then(() => {
reject(exception); reject(exception);
});
}); });
}, },

View File

@ -1,4 +1,7 @@
/* global require */
/* eslint-disable @typescript-eslint/no-require-imports */
/* eslint-disable no-console */ /* eslint-disable no-console */
import assert from 'assert'; import assert from 'assert';
import path from 'path'; import path from 'path';
import { writeFileSync, unlinkSync } from 'fs'; import { writeFileSync, unlinkSync } from 'fs';
@ -105,7 +108,7 @@ class MemoryBenchamrkSuite {
* Memory usage tests. * Memory usage tests.
* All the necessary variables must be declared inside the test function. * All the necessary variables must be declared inside the test function.
*/ */
(async () => { void (async () => {
const suite = new MemoryBenchamrkSuite(); const suite = new MemoryBenchamrkSuite();
suite.add('empty test (baseline)', () => {}); suite.add('empty test (baseline)', () => {});

View File

@ -23,7 +23,7 @@ const onError = err => {
* Time benchmark tests. * Time benchmark tests.
* NB: each test will be run multiple times, so any input must be consumable multiple times. * NB: each test will be run multiple times, so any input must be consumable multiple times.
*/ */
(async () => { void (async () => {
const suite = new Benchmark.Suite(); const suite = new Benchmark.Suite();
const { armoredKey, privateKey, publicKey, armoredEncryptedMessage, armoredSignedMessage } = await getTestData(); const { armoredKey, privateKey, publicKey, armoredEncryptedMessage, armoredSignedMessage } = await getTestData();
function* largeDataGenerator({ chunk, numberOfChunks }) { function* largeDataGenerator({ chunk, numberOfChunks }) {

View File

@ -4,7 +4,7 @@ import BN from 'bn.js';
import { bigIntToUint8Array, bitLength, byteLength, gcd, getBit, modExp, modInv } from '../../src/crypto/biginteger'; import { bigIntToUint8Array, bitLength, byteLength, gcd, getBit, modExp, modInv } from '../../src/crypto/biginteger';
import { getRandomBytes } from '../../src/crypto/random'; import { getRandomBytes } from '../../src/crypto/random';
async function getRandomBN(min, max) { function getRandomBN(min, max) {
if (max.cmp(min) <= 0) { if (max.cmp(min) <= 0) {
throw new Error('Illegal parameter value: max <= min'); throw new Error('Illegal parameter value: max <= min');
} }

View File

@ -112,6 +112,7 @@ export default () => describe('ECC signatures', function () {
}); });
it('Creating KeyPair', function () { it('Creating KeyPair', function () {
if (!config.useEllipticFallback && !util.getNodeCrypto()) { if (!config.useEllipticFallback && !util.getNodeCrypto()) {
// eslint-disable-next-line no-invalid-this
this.skip(); this.skip();
} }
const names = config.useEllipticFallback ? ['nistP256', 'nistP384', 'nistP521', 'secp256k1', 'curve25519Legacy', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1'] : const names = config.useEllipticFallback ? ['nistP256', 'nistP384', 'nistP521', 'secp256k1', 'curve25519Legacy', 'brainpoolP256r1', 'brainpoolP384r1', 'brainpoolP512r1'] :
@ -235,6 +236,7 @@ export default () => describe('ECC signatures', function () {
}); });
it('secp256k1 - Invalid public key', async function () { it('secp256k1 - Invalid public key', async function () {
if (!config.useEllipticFallback && !util.getNodeCrypto()) { if (!config.useEllipticFallback && !util.getNodeCrypto()) {
// eslint-disable-next-line no-invalid-this
this.skip(); // webcrypto does not implement secp256k1: JS fallback tested instead this.skip(); // webcrypto does not implement secp256k1: JS fallback tested instead
} }
await expect(verify_signature( await expect(verify_signature(
@ -249,6 +251,7 @@ export default () => describe('ECC signatures', function () {
}); });
it('secp256k1 - Invalid signature', function (done) { it('secp256k1 - Invalid signature', function (done) {
if (!config.useEllipticFallback && !util.getNodeCrypto()) { if (!config.useEllipticFallback && !util.getNodeCrypto()) {
// eslint-disable-next-line no-invalid-this
this.skip(); // webcrypto does not implement secp256k1: JS fallback tested instead this.skip(); // webcrypto does not implement secp256k1: JS fallback tested instead
} }
expect(verify_signature( expect(verify_signature(

View File

@ -346,7 +346,7 @@ NJCB6+LWtabSoVIjNVgKwyKqyTLaESNwC2ogZwkdE8qPGiDFEHo4Gg9zuRof
`; `;
const { type, data } = await openpgp.unarmor(pubKey); const { type, data } = await openpgp.unarmor(pubKey);
const armor = await openpgp.armor(type, data); const armor = openpgp.armor(type, data);
expect( expect(
armor armor
.replace(/^(Version|Comment): .*$\n/mg, '') .replace(/^(Version|Comment): .*$\n/mg, '')

View File

@ -11,7 +11,7 @@ import * as input from './testInputs.js';
export default () => (openpgp.config.ci ? describe.skip : describe)('Brainpool Cryptography @lightweight', function () { export default () => (openpgp.config.ci ? describe.skip : describe)('Brainpool Cryptography @lightweight', function () {
let rejectCurvesVal; let rejectCurvesVal;
before(function() { before(() => {
//only x25519 crypto is fully functional in lightbuild //only x25519 crypto is fully functional in lightbuild
if (!openpgp.config.useEllipticFallback && !util.getNodeCrypto()) { if (!openpgp.config.useEllipticFallback && !util.getNodeCrypto()) {
this.skip(); // eslint-disable-line no-invalid-this this.skip(); // eslint-disable-line no-invalid-this

View File

@ -456,7 +456,7 @@ c1HGHD56KA0Mu4eQksKNEugotEyBuWiZCVO+LBrDUFztC1IwXaNPL3bCjYaD
await expect(sig5.verified).to.be.eventually.rejectedWith(/Support for eddsaLegacy keys using curve ed25519Legacy is disabled/); await expect(sig5.verified).to.be.eventually.rejectedWith(/Support for eddsaLegacy keys using curve ed25519Legacy is disabled/);
}); });
describe('detects unknown config property', async function() { describe('detects unknown config property', function() {
const invalidConfig = { invalidProp: false }; const invalidConfig = { invalidProp: false };
const fnNames = ['generateKey', 'encryptKey', 'decryptKey', 'reformatKey', 'revokeKey', 'sign', 'encrypt', 'verify', 'decrypt', 'generateSessionKey', 'encryptSessionKey', 'decryptSessionKeys']; const fnNames = ['generateKey', 'encryptKey', 'decryptKey', 'reformatKey', 'revokeKey', 'sign', 'encrypt', 'verify', 'decrypt', 'generateSessionKey', 'encryptSessionKey', 'decryptSessionKeys'];
fnNames.forEach(name => it(`openpgp.${name}`, async function() { fnNames.forEach(name => it(`openpgp.${name}`, async function() {

View File

@ -216,180 +216,180 @@ PepQmgsu
-----END PGP PUBLIC KEY BLOCK-----`; -----END PGP PUBLIC KEY BLOCK-----`;
const pub_revoked_subkeys = const pub_revoked_subkeys =
['-----BEGIN PGP PUBLIC KEY BLOCK-----', ['-----BEGIN PGP PUBLIC KEY BLOCK-----',
'Version: GnuPG v2.0.19 (GNU/Linux)', 'Version: GnuPG v2.0.19 (GNU/Linux)',
'', '',
'mQENBFKpincBCADhZjIihK15f3l+j87JgeLp9eUTSbn+g3gOFSR73TOMyBHMPt8O', 'mQENBFKpincBCADhZjIihK15f3l+j87JgeLp9eUTSbn+g3gOFSR73TOMyBHMPt8O',
'KwuA+TN2sM86AooOR/2B2MjHBUZqrgeJe+sk5411yXezyYdQGZ8vlq/FeLeNF70D', 'KwuA+TN2sM86AooOR/2B2MjHBUZqrgeJe+sk5411yXezyYdQGZ8vlq/FeLeNF70D',
'JrvIC6tsEe2F9F7ICO7o7G+k5yveLaYQNU/okiP8Gj79XW3wN77+yAMwpQzBsrwa', 'JrvIC6tsEe2F9F7ICO7o7G+k5yveLaYQNU/okiP8Gj79XW3wN77+yAMwpQzBsrwa',
'UO/X4mDV59h1DdrTuN4g8SZhAmY/JfT7YCZuQ8ivOs9n7xPdbGpIQWGWjJLVWziC', 'UO/X4mDV59h1DdrTuN4g8SZhAmY/JfT7YCZuQ8ivOs9n7xPdbGpIQWGWjJLVWziC',
'7uvxN4eFOlCqvc6JwmS/xyYGKL2B3RcQuY+OlvQ3wxKFEGDfG73HtWBd2soB7/7p', '7uvxN4eFOlCqvc6JwmS/xyYGKL2B3RcQuY+OlvQ3wxKFEGDfG73HtWBd2soB7/7p',
'w53mVcz5sLhkOWjMTj+VDDZ3jas+7VznaAbVABEBAAGJAToEIAECACQFAlKpj3od', 'w53mVcz5sLhkOWjMTj+VDDZ3jas+7VznaAbVABEBAAGJAToEIAECACQFAlKpj3od',
'HQNUZXN0aW5nIHJldm9rZSBjb21wbGV0ZSBrZXkACgkQO+K1SH0WBbOtJgf/XqJF', 'HQNUZXN0aW5nIHJldm9rZSBjb21wbGV0ZSBrZXkACgkQO+K1SH0WBbOtJgf/XqJF',
'dfWJjXBPEdfDbnXW+OZcvVgUMEEKEKsS1MiB21BEQpsTiuOLLgDOnEKRDjT1Z9H/', 'dfWJjXBPEdfDbnXW+OZcvVgUMEEKEKsS1MiB21BEQpsTiuOLLgDOnEKRDjT1Z9H/',
'6owkb1+iLOZRGcJIdXxxAi2W0hNwx3qSiYkJIaYIm6dhoTy77lAmrPGwjoBETflU', '6owkb1+iLOZRGcJIdXxxAi2W0hNwx3qSiYkJIaYIm6dhoTy77lAmrPGwjoBETflU',
'CdWWgYFUGQVNPnpCi0AizoHXX2S4zaVlLnDthss+/FtIiuiYAIbMzB902nhF0oKH', 'CdWWgYFUGQVNPnpCi0AizoHXX2S4zaVlLnDthss+/FtIiuiYAIbMzB902nhF0oKH',
'v5PTrm1IpbstchjHITtrRi4tdbyvpAmZFC6a+ydylijNyKkMeoMy0S+6tIAyaTym', 'v5PTrm1IpbstchjHITtrRi4tdbyvpAmZFC6a+ydylijNyKkMeoMy0S+6tIAyaTym',
'V5UthMH/Kk2n3bWNY4YnjDcQpIPlPF1cEnqq2c47nYxHuYdGJsw9l1F88J0enL72', 'V5UthMH/Kk2n3bWNY4YnjDcQpIPlPF1cEnqq2c47nYxHuYdGJsw9l1F88J0enL72',
'56LWk5waecsz6XOYXrQTVjMgS2V5IDx2M0BrZXkuY29tPokBMQQwAQIAGwUCUqmP', '56LWk5waecsz6XOYXrQTVjMgS2V5IDx2M0BrZXkuY29tPokBMQQwAQIAGwUCUqmP',
'BRQdIFRlc3RpbmcgcmV2b2RlIHVpZAAKCRA74rVIfRYFszHUB/oCAV+IMzZF6uad', 'BRQdIFRlc3RpbmcgcmV2b2RlIHVpZAAKCRA74rVIfRYFszHUB/oCAV+IMzZF6uad',
'v0Gi+Z2qCY1Eqshdxv4i7J2G3174YGF9+0hMrHwsxBkVQ/oLZKBFjfP7Z1RZXxso', 'v0Gi+Z2qCY1Eqshdxv4i7J2G3174YGF9+0hMrHwsxBkVQ/oLZKBFjfP7Z1RZXxso',
'ts0dBho3XWZr3mrEk6Au6Ss+pbGNqq2XytV+CB3xY0DKX1Q0BJOEhgcSNn187jqd', 'ts0dBho3XWZr3mrEk6Au6Ss+pbGNqq2XytV+CB3xY0DKX1Q0BJOEhgcSNn187jqd',
'XoKLuK/hy0Bk6YkXe1lv6HqkFxYGNB2MW0wSPjrfnjjHkM29bM0Q/JNVY4o/osmY', 'XoKLuK/hy0Bk6YkXe1lv6HqkFxYGNB2MW0wSPjrfnjjHkM29bM0Q/JNVY4o/osmY',
'zoY/hc59fKBm5uBBL7kEtSkMO0KPVzqhvMCi5qW9/V9+vNn//WWOY+fAXYKa1cBo', 'zoY/hc59fKBm5uBBL7kEtSkMO0KPVzqhvMCi5qW9/V9+vNn//WWOY+fAXYKa1cBo',
'aMykBfE2gGf/alIV9dFpHl+TkIT8lD8sY5dBmiKHN4D38PhuLdFWHXLe4ww7kqXt', 'aMykBfE2gGf/alIV9dFpHl+TkIT8lD8sY5dBmiKHN4D38PhuLdFWHXLe4ww7kqXt',
'JrD0bchKiQE/BBMBAgApBQJSqYp3AhsDBQkJZgGABwsJCAcDAgEGFQgCCQoLBBYC', 'JrD0bchKiQE/BBMBAgApBQJSqYp3AhsDBQkJZgGABwsJCAcDAgEGFQgCCQoLBBYC',
'AwECHgECF4AACgkQO+K1SH0WBbOOAwgAx9Qr6UciDbN2Bn1254YH6j5HZbVXGTA/', 'AwECHgECF4AACgkQO+K1SH0WBbOOAwgAx9Qr6UciDbN2Bn1254YH6j5HZbVXGTA/',
'uQhZZGAYE/wDuZ5u8Z2U4giEZ3dwtblqRZ6WROmtELXn+3bGGbYjczHEFOKt4D/y', 'uQhZZGAYE/wDuZ5u8Z2U4giEZ3dwtblqRZ6WROmtELXn+3bGGbYjczHEFOKt4D/y',
'HtrjCtQX04eS+FfL453n7aaQbpmHou22UvV0hik+iagMbIrYnB6nqaui9k8HrGzE', 'HtrjCtQX04eS+FfL453n7aaQbpmHou22UvV0hik+iagMbIrYnB6nqaui9k8HrGzE',
'1HE1AeC5UTlopEHb/KQRGLUmAlr8oJEhDVXLEq41exNTArJWa9QlimFZeaG+vcbz', '1HE1AeC5UTlopEHb/KQRGLUmAlr8oJEhDVXLEq41exNTArJWa9QlimFZeaG+vcbz',
'2QarcmIXmZ3o+1ARwZKTK/20oCpF6/gUGnY3KMvpLYdW88Qznsp+7yWhpC1nchfW', '2QarcmIXmZ3o+1ARwZKTK/20oCpF6/gUGnY3KMvpLYdW88Qznsp+7yWhpC1nchfW',
'7frQmuQa94yb5PN7kBJ83yF/SZiDggZ8YfcCf1DNcbw8bjPYyFNW3bkBDQRSqYp3', '7frQmuQa94yb5PN7kBJ83yF/SZiDggZ8YfcCf1DNcbw8bjPYyFNW3bkBDQRSqYp3',
'AQgA1Jgpmxwr2kmP2qj8FW9sQceylHJr4gUfSQ/4KPZbGFZhzK+xdEluBJOzxNbf', 'AQgA1Jgpmxwr2kmP2qj8FW9sQceylHJr4gUfSQ/4KPZbGFZhzK+xdEluBJOzxNbf',
'LQXhQOHbWFmlNrGpoVDawZbA5FL7w5WHYMmNY1AADmmP0uHbHqdOvOyz/boo3fU0', 'LQXhQOHbWFmlNrGpoVDawZbA5FL7w5WHYMmNY1AADmmP0uHbHqdOvOyz/boo3fU0',
'dcl0wOjo06vsUqLf8/3skQstUFjwLzjI2ebXWHXj5OSqZsoFvj+/P/NaOeVuAwFx', 'dcl0wOjo06vsUqLf8/3skQstUFjwLzjI2ebXWHXj5OSqZsoFvj+/P/NaOeVuAwFx',
'50vfUK19o40wsRoprgxmZOIL4uMioQ/V/QUr++ziahwqFwDQmqmj0bAzV/bIklSJ', '50vfUK19o40wsRoprgxmZOIL4uMioQ/V/QUr++ziahwqFwDQmqmj0bAzV/bIklSJ',
'jrLfs7amX8qiGPn8K5UyWzYMa2q9r0Srt/9wx+FoSRbqRvsqLFYoU3d745zX1W7o', 'jrLfs7amX8qiGPn8K5UyWzYMa2q9r0Srt/9wx+FoSRbqRvsqLFYoU3d745zX1W7o',
'dFcDddGMv5LMPnvNR+Qm7PUlowARAQABiQE0BCgBAgAeBQJSqY5XFx0DVGVzdGlu', 'dFcDddGMv5LMPnvNR+Qm7PUlowARAQABiQE0BCgBAgAeBQJSqY5XFx0DVGVzdGlu',
'ZyBzdWJrZXkgcmV2b2tlAAoJEDvitUh9FgWzsUoH/1MrYYo7aQErScnhbIVQ5qpB', 'ZyBzdWJrZXkgcmV2b2tlAAoJEDvitUh9FgWzsUoH/1MrYYo7aQErScnhbIVQ5qpB',
'qnqBTiyVGa3cqSPKUkT552dRs6TwsjFKnOs68MIZQ6qfliZE/ApKPQhxaHgmfWKI', 'qnqBTiyVGa3cqSPKUkT552dRs6TwsjFKnOs68MIZQ6qfliZE/ApKPQhxaHgmfWKI',
'Q09Qv04SKHqo9njX6E3q257DnvmQiv6c9PRA3G/p2doBrj3joaOVm/ZioiCZdf2W', 'Q09Qv04SKHqo9njX6E3q257DnvmQiv6c9PRA3G/p2doBrj3joaOVm/ZioiCZdf2W',
'l6akAf7j5DbcVRh8BQigM4EUhsVjBvGPYxqVNIM4aWHMTG62CaREa9g1PWOobASU', 'l6akAf7j5DbcVRh8BQigM4EUhsVjBvGPYxqVNIM4aWHMTG62CaREa9g1PWOobASU',
'jX47B7/FFP4zCLkeb+znDMwc8jKWeUBp5sUGhWo74wFiD5Dp2Zz50qRi1u05nJXg', 'jX47B7/FFP4zCLkeb+znDMwc8jKWeUBp5sUGhWo74wFiD5Dp2Zz50qRi1u05nJXg',
'bIib7pwmH2CeDwmPRi/HRUrKBcqFzSYG5QVggQ5KMIU9M7zmvd8mDYE8MQbTLbaJ', 'bIib7pwmH2CeDwmPRi/HRUrKBcqFzSYG5QVggQ5KMIU9M7zmvd8mDYE8MQbTLbaJ',
'ASUEGAECAA8FAlKpincCGwwFCQlmAYAACgkQO+K1SH0WBbPbnQgAxcYAS3YplyBI', 'ASUEGAECAA8FAlKpincCGwwFCQlmAYAACgkQO+K1SH0WBbPbnQgAxcYAS3YplyBI',
'ddNJQNvyrWnnuGXoGGKgkE8+LUR3rX3NK/c4pF7EFgrNxKIPrWZoIu7m1XNqoK3g', 'ddNJQNvyrWnnuGXoGGKgkE8+LUR3rX3NK/c4pF7EFgrNxKIPrWZoIu7m1XNqoK3g',
'PwRXJfPPQWalVrhhOajtYipXumQVAe+q8DyxAZ5YJGrUvR9b96GRel9G+HsRlR1M', 'PwRXJfPPQWalVrhhOajtYipXumQVAe+q8DyxAZ5YJGrUvR9b96GRel9G+HsRlR1M',
'NV62ZXFdXVgg9FZJHDR8fa1Zy93xC0JSKu4ZoCrH5ybw+DPCngogDl4KwgdV5y4e', 'NV62ZXFdXVgg9FZJHDR8fa1Zy93xC0JSKu4ZoCrH5ybw+DPCngogDl4KwgdV5y4e',
'EAZpGDSq7PrdsgZTiSuepwVw116GWJm1zecmh6FdpZL/ZrE6EfYcCGJqJiVfDiCR', 'EAZpGDSq7PrdsgZTiSuepwVw116GWJm1zecmh6FdpZL/ZrE6EfYcCGJqJiVfDiCR',
'jgvGbcTzxnvrRmDevmJUdXBSAE11OYQuDGlhgFCU0o9cdX+k+QqP5wNycXhoJ+yk', 'jgvGbcTzxnvrRmDevmJUdXBSAE11OYQuDGlhgFCU0o9cdX+k+QqP5wNycXhoJ+yk',
'pMiJM+NJAQ==', 'pMiJM+NJAQ==',
'=ok+o', '=ok+o',
'-----END PGP PUBLIC KEY BLOCK-----'].join('\n'); '-----END PGP PUBLIC KEY BLOCK-----'].join('\n');
const pub_revoked_with_cert = const pub_revoked_with_cert =
['-----BEGIN PGP PUBLIC KEY BLOCK-----', ['-----BEGIN PGP PUBLIC KEY BLOCK-----',
'Comment: GPGTools - https://gpgtools.org', 'Comment: GPGTools - https://gpgtools.org',
'', '',
'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',
'onCOcv4DKguN2w==', 'onCOcv4DKguN2w==',
'=OqO3', '=OqO3',
'-----END PGP PUBLIC KEY BLOCK-----'].join('\n'); '-----END PGP PUBLIC KEY BLOCK-----'].join('\n');
const pub_sig_test = const pub_sig_test =
['-----BEGIN PGP PUBLIC KEY BLOCK-----', ['-----BEGIN PGP PUBLIC KEY BLOCK-----',
'Version: GnuPG v2.0.19 (GNU/Linux)', 'Version: GnuPG v2.0.19 (GNU/Linux)',
'', '',
'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',
'yeSTTh8ZnzRiwuUH1t90E7w=', 'yeSTTh8ZnzRiwuUH1t90E7w=',
'=e8xo', '=e8xo',
'-----END PGP PUBLIC KEY BLOCK-----'].join('\n'); '-----END PGP PUBLIC KEY BLOCK-----'].join('\n');
const priv_key_rsa = const priv_key_rsa =
['-----BEGIN PGP PRIVATE KEY BLOCK-----', ['-----BEGIN PGP PRIVATE KEY BLOCK-----',
@ -842,7 +842,7 @@ const wrong_key =
'-----END PGP PUBLIC KEY BLOCK-----'].join('\n'); '-----END PGP PUBLIC KEY BLOCK-----'].join('\n');
const expiredKey = const expiredKey =
`-----BEGIN PGP PRIVATE KEY BLOCK----- `-----BEGIN PGP PRIVATE KEY BLOCK-----
xcA4BAAAAAEBAgCgONc0J8rfO6cJw5YTP38x1ze2tAYIO7EcmRCNYwMkXngb xcA4BAAAAAEBAgCgONc0J8rfO6cJw5YTP38x1ze2tAYIO7EcmRCNYwMkXngb
0Qdzg34Q5RW0rNiR56VB6KElPUhePRPVklLFiIvHABEBAAEAAf9qabYMzsz/ 0Qdzg34Q5RW0rNiR56VB6KElPUhePRPVklLFiIvHABEBAAEAAf9qabYMzsz/
@ -857,7 +857,7 @@ DECl1Qu4QyeXin29uEXWiekMpNlZVsEuc8icCw6ABhIZ
-----END PGP PRIVATE KEY BLOCK-----`; -----END PGP PRIVATE KEY BLOCK-----`;
const multipleBindingSignatures = const multipleBindingSignatures =
`-----BEGIN PGP PUBLIC KEY BLOCK----- `-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2 Version: GnuPG v2
mQINBFQNRrkBEAChLrYuYjiy1jq7smQtYPln6XGJjMiJ1PbZwGK2CKQaIW6u4EUJ mQINBFQNRrkBEAChLrYuYjiy1jq7smQtYPln6XGJjMiJ1PbZwGK2CKQaIW6u4EUJ
@ -2272,7 +2272,7 @@ function versionSpecificTests() {
expect(selfSignature.features).to.eql([expectedFeatures]); expect(selfSignature.features).to.eql([expectedFeatures]);
}; };
const opt = { userIDs: { name: 'test', email: 'a@b.com' }, passphrase: 'hello', format: 'object' }; const opt = { userIDs: { name: 'test', email: 'a@b.com' }, passphrase: 'hello', format: 'object' };
return openpgp.generateKey(opt).then(async function({ privateKey, publicKey }) { return openpgp.generateKey(opt).then(({ privateKey, publicKey }) => {
testPref(privateKey); testPref(privateKey);
testPref(publicKey); testPref(publicKey);
}); });
@ -3023,8 +3023,8 @@ export default () => describe('Key', function() {
// ssb cv25519 2019-03-20 [E] // ssb cv25519 2019-03-20 [E]
// E4557C2B02FFBF4B04F87401EC336AF7133D0F85BE7FD09BAEFD9CAEB8C93965 // E4557C2B02FFBF4B04F87401EC336AF7133D0F85BE7FD09BAEFD9CAEB8C93965
const key = await openpgp.readKey({ armoredKey: v5_sample_key, config: { enableParsingV5Entities: true } }); const key = await openpgp.readKey({ armoredKey: v5_sample_key, config: { enableParsingV5Entities: true } });
expect(await key.keyPacket.getFingerprint()).to.equal('19347bc9872464025f99df3ec2e0000ed9884892e1f7b3ea4c94009159569b54'); expect(key.keyPacket.getFingerprint()).to.equal('19347bc9872464025f99df3ec2e0000ed9884892e1f7b3ea4c94009159569b54');
expect(await key.subkeys[0].getFingerprint()).to.equal('e4557c2b02ffbf4b04f87401ec336af7133d0f85be7fd09baefd9caeb8c93965'); expect(key.subkeys[0].getFingerprint()).to.equal('e4557c2b02ffbf4b04f87401ec336af7133d0f85be7fd09baefd9caeb8c93965');
await key.verifyPrimaryKey(); await key.verifyPrimaryKey();
}); });
@ -3482,7 +3482,7 @@ PzIEeL7UH3trraFmi+Gq8u4kAA==
expect(pubKeyV4).to.exist; expect(pubKeyV4).to.exist;
expect(pubKeyV4.getKeyID().toHex()).to.equal('4a63613a4d6e4094'); expect(pubKeyV4.getKeyID().toHex()).to.equal('4a63613a4d6e4094');
expect(await pubKeyV4.getFingerprint()).to.equal('f470e50dcb1ad5f1e64e08644a63613a4d6e4094'); expect(pubKeyV4.getFingerprint()).to.equal('f470e50dcb1ad5f1e64e08644a63613a4d6e4094');
}); });
it('Create new key ID with fromID()', async function() { it('Create new key ID with fromID()', async function() {
@ -3503,7 +3503,7 @@ PzIEeL7UH3trraFmi+Gq8u4kAA==
); );
const subkeyPackets = [packetlist[8], packetlist[11]]; const subkeyPackets = [packetlist[8], packetlist[11]];
const subkeys = await pubKey.getSubkeys(); const subkeys = pubKey.getSubkeys();
expect(subkeys).to.exist; expect(subkeys).to.exist;
expect(subkeys).to.have.length(2); expect(subkeys).to.have.length(2);
expect(subkeys[0].getKeyID().equals(subkeyPackets[0].getKeyID())).to.be.true; expect(subkeys[0].getKeyID().equals(subkeyPackets[0].getKeyID())).to.be.true;

View File

@ -1116,7 +1116,7 @@ PIQe3UJEj7ReaAd2LBkk3XXkg74zfts7GAGdNtWgXQEAwYQJdVChJFU3LRNh
curve: 'curve25519', curve: 'curve25519',
format: 'object' format: 'object'
}; };
return openpgp.generateKey(opt).then(async function({ privateKey: key }) { return openpgp.generateKey(opt).then(({ privateKey: key }) => {
expect(key).to.exist; expect(key).to.exist;
expect(key.getAlgorithmInfo().rsaBits).to.equal(undefined); expect(key.getAlgorithmInfo().rsaBits).to.equal(undefined);
expect(key.getAlgorithmInfo().algorithm).to.equal('eddsaLegacy'); expect(key.getAlgorithmInfo().algorithm).to.equal('eddsaLegacy');
@ -1454,7 +1454,7 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu
describe('decrypt - unit tests', function() { describe('decrypt - unit tests', function() {
let minRSABitsVal; let minRSABitsVal;
beforeEach(async function() { beforeEach(() => {
minRSABitsVal = openpgp.config.minRSABits; minRSABitsVal = openpgp.config.minRSABits;
openpgp.config.minRSABits = 1024; openpgp.config.minRSABits = 1024;
}); });
@ -1821,7 +1821,7 @@ BdPq
describe('verify - unit tests', function() { describe('verify - unit tests', function() {
let minRSABitsVal; let minRSABitsVal;
beforeEach(async function() { beforeEach(() => {
minRSABitsVal = openpgp.config.minRSABits; minRSABitsVal = openpgp.config.minRSABits;
openpgp.config.minRSABits = 512; openpgp.config.minRSABits = 512;
}); });
@ -4533,7 +4533,7 @@ bsZgJWVlAa5eil6J9ePX2xbo1vVAkLQdzE9+1jL+l7PRIZuVBQ==
expect(data).to.equal('test'); expect(data).to.equal('test');
}); });
describe('X25519/Ed25519 (new format)', async function () { describe('X25519/Ed25519 (new format)', () => {
it('should enforce using AES session keys with x25519 keys (v4 key)', async function () { it('should enforce using AES session keys with x25519 keys (v4 key)', async function () {
// x25519 key (v4) with cast5 as preferred cipher // x25519 key (v4) with cast5 as preferred cipher
const privateKeyCast5 = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- const privateKeyCast5 = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK-----
@ -4667,7 +4667,7 @@ k0mXubZvyl4GBg==
}); });
}); });
describe('X448/Ed448', async function () { describe('X448/Ed448', () => {
it('should enforce using AES session keys with x448 keys (v4 key)', async function () { it('should enforce using AES session keys with x448 keys (v4 key)', async function () {
// X448 key (v4) with cast5 as preferred cipher // X448 key (v4) with cast5 as preferred cipher
const privateKeyCast5 = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK----- const privateKeyCast5 = await openpgp.readKey({ armoredKey: `-----BEGIN PGP PRIVATE KEY BLOCK-----
@ -5093,7 +5093,7 @@ sEj+v9LKoMTYZGMfp3qDVFLtkBE88eVmVjgJOoLhrsv7yh0PAA==
}); });
describe('Specific encryption/signing key testing', async function () { describe('Specific encryption/signing key testing', () => {
const encryptionKeyIDs = [ const encryptionKeyIDs = [
keyIDType.fromID('87EAE0977B2185EA'), keyIDType.fromID('87EAE0977B2185EA'),
keyIDType.fromID('F94F9B34AF93FA14'), keyIDType.fromID('F94F9B34AF93FA14'),

View File

@ -35,7 +35,7 @@ export default () => describe('Packet', function() {
const allAllowedPackets = util.constructAllowedPackets([...Object.values(openpgp).filter(packetClass => !!packetClass.tag)]); 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' +
'\n' + '\n' +
'lQH+BFF79J8BBADDhRUOMUSGdYM1Kq9J/vVS3qLfaZHweycAKm9SnpLGLJE+Qbki\n' + 'lQH+BFF79J8BBADDhRUOMUSGdYM1Kq9J/vVS3qLfaZHweycAKm9SnpLGLJE+Qbki\n' +
@ -157,7 +157,7 @@ export default () => describe('Packet', function() {
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));
}); });
describe('Sym. encrypted integrity protected packet - throw on unexpected session key size', async () => { describe('Sym. encrypted integrity protected packet - throw on unexpected session key size', () => {
async function testSEIPD(packetOptions) { async function testSEIPD(packetOptions) {
const symmetricAlgo = openpgp.enums.symmetric.aes256; const symmetricAlgo = openpgp.enums.symmetric.aes256;
const key = random.getRandomBytes(crypto.getCipherParams(symmetricAlgo).keySize); const key = random.getRandomBytes(crypto.getCipherParams(symmetricAlgo).keySize);
@ -237,7 +237,7 @@ export default () => describe('Packet', function() {
cryptStub.onCall(0).callsFake(async function() { cryptStub.onCall(0).callsFake(async function() {
cryptCallsActive++; cryptCallsActive++;
try { try {
// eslint-disable-next-line @typescript-eslint/return-await // eslint-disable-next-line no-invalid-this
return await crypt.apply(this, arguments); return await crypt.apply(this, arguments);
} finally { } finally {
cryptCallsActive--; cryptCallsActive--;
@ -249,6 +249,7 @@ export default () => describe('Packet', function() {
// Chromium disabled some async WebCrypto operations in v141 . // Chromium disabled some async WebCrypto operations in v141 .
// Context: https://github.com/w3c/webcrypto/issues/389#issuecomment-3136298597 . // Context: https://github.com/w3c/webcrypto/issues/389#issuecomment-3136298597 .
expect(cryptCallsActive).to.equal(isChromeV141OrAbove() ? 0 : 1); expect(cryptCallsActive).to.equal(isChromeV141OrAbove() ? 0 : 1);
// eslint-disable-next-line no-invalid-this
return crypt.apply(this, arguments); return crypt.apply(this, arguments);
}); });
cryptStub.callThrough(); cryptStub.callThrough();
@ -336,7 +337,7 @@ export default () => describe('Packet', function() {
}); });
describe('Sym. encrypted integrity protected packet reading/writing test vector (SEIPDv2)', async function () { describe('Sym. encrypted integrity protected packet reading/writing test vector (SEIPDv2)', () => {
const testVectors = [{ const testVectors = [{
// from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.9 // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.9
algoLabel: 'EAX', algoLabel: 'EAX',
@ -434,7 +435,7 @@ export default () => 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' +
'\n' + '\n' +
'jA0ECQMCpo7I8WqsebTJ0koBmm6/oqdHXJU9aPe+Po+nk/k4/PZrLmlXwz2lhqBg\n' + 'jA0ECQMCpo7I8WqsebTJ0koBmm6/oqdHXJU9aPe+Po+nk/k4/PZrLmlXwz2lhqBg\n' +
@ -520,7 +521,7 @@ export default () => describe('Packet', function() {
it('Secret key packet (reading, unencrypted)', async function() { it('Secret key packet (reading, unencrypted)', async function() {
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' +
'\n' + '\n' +
'lQHYBFF33iMBBAC9YfOYahJlWrVj2J1TjQiZLunWljI4G9e6ARTyD99nfOkV3swh\n' + 'lQHYBFF33iMBBAC9YfOYahJlWrVj2J1TjQiZLunWljI4G9e6ARTyD99nfOkV3swh\n' +
@ -563,7 +564,7 @@ export default () => describe('Packet', function() {
it('Public key encrypted packet (reading, GPG)', async function() { it('Public key encrypted packet (reading, GPG)', async function() {
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' +
'\n' + '\n' +
'lQHYBFF6gtkBBADKUOWZK6/V75MNwBS+hLYicoS0Sojbo3qWXXpS7eM+uhiDm4bP\n' + 'lQHYBFF6gtkBBADKUOWZK6/V75MNwBS+hLYicoS0Sojbo3qWXXpS7eM+uhiDm4bP\n' +
@ -598,7 +599,7 @@ export default () => describe('Packet', function() {
'-----END PGP PRIVATE KEY BLOCK-----'; '-----END PGP PRIVATE KEY BLOCK-----';
const armored_msg = const armored_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' +
'\n' + '\n' +
'hIwDFYET+7bfx/ABA/95Uc9942Tg8oqpO0vEu2eSKwPALM3a0DrVdAiFOIK/dJmZ\n' + 'hIwDFYET+7bfx/ABA/95Uc9942Tg8oqpO0vEu2eSKwPALM3a0DrVdAiFOIK/dJmZ\n' +
@ -837,7 +838,7 @@ export default () => describe('Packet', function() {
})); }));
}); });
describe('Sym. encrypted session key reading/writing test vector (SKESK v6)', async function () { describe('Sym. encrypted session key reading/writing test vector (SKESK v6)', () => {
const testVectors = [{ const testVectors = [{
// from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.9.1 // from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.9.1
algoLabel: 'EAX', algoLabel: 'EAX',
@ -934,7 +935,7 @@ export default () => describe('Packet', function() {
it('Secret key encryption/decryption test', async function() { it('Secret key encryption/decryption test', async function() {
const armored_msg = const armored_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' +
'\n' + '\n' +
'hIwD95D9aHS5fxEBA/98CwH54XZmwobOmHUcvWcDDQysBEC4uf7wASiGcRbejDaO\n' + 'hIwD95D9aHS5fxEBA/98CwH54XZmwobOmHUcvWcDDQysBEC4uf7wASiGcRbejDaO\n' +
@ -976,7 +977,7 @@ export default () => describe('Packet', function() {
it('Reading a signed, encrypted message.', async function() { it('Reading a signed, encrypted message.', async function() {
const armored_msg = const armored_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' +
'\n' + '\n' +
'hIwD95D9aHS5fxEBA/4/X4myvH+jB1HYNeZvdK+WsBNDMfLsBGOf205Rxr3vSob/\n' + 'hIwD95D9aHS5fxEBA/4/X4myvH+jB1HYNeZvdK+WsBNDMfLsBGOf205Rxr3vSob/\n' +
@ -1016,8 +1017,7 @@ export default () => 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-----
iQFKBAEBCgA0FiEEdOyNPagqedqiXfEMa6Ve2Dq64bsFAlszXwQWHHRlc3Qtd2tk iQFKBAEBCgA0FiEEdOyNPagqedqiXfEMa6Ve2Dq64bsFAlszXwQWHHRlc3Qtd2tk
QG1ldGFjb2RlLmJpegAKCRBrpV7YOrrhuw1PB/9KhFRR/M3OR6NmIent6ri1ekWn QG1ldGFjb2RlLmJpegAKCRBrpV7YOrrhuw1PB/9KhFRR/M3OR6NmIent6ri1ekWn
@ -1035,8 +1035,7 @@ kePFjAnu9cpynKXu3usf8+FuBw2zLsg1Id1n7ttxoAte416KjBN9lFBt8mcu
}); });
it('Reading notations from armored key', async function() { it('Reading notations from armored key', async function() {
const pubkey = const pubkey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
`-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFzQOToBCADd0Pwh8edZ6gR3x49L1PaBPtiAQUr1QDUDWeNes8co5MTFl5hG mQENBFzQOToBCADd0Pwh8edZ6gR3x49L1PaBPtiAQUr1QDUDWeNes8co5MTFl5hG
lHzptt+VD0JGucuIkvi34f5z2ZbInAV/xYDX3kSYefy6LB8XJD527I/o9bqY1P7T lHzptt+VD0JGucuIkvi34f5z2ZbInAV/xYDX3kSYefy6LB8XJD527I/o9bqY1P7T
@ -1114,7 +1113,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
expect(secretKeyPacket2.publicParams).to.deep.equal(secretKeyPacket.publicParams); expect(secretKeyPacket2.publicParams).to.deep.equal(secretKeyPacket.publicParams);
}); });
it('Writing of unencrypted v5 secret key packet', async function() { it('Writing of unencrypted v5 secret key packet', () => {
const packet = new openpgp.SecretKeyPacket(); const packet = new openpgp.SecretKeyPacket();
packet.version = 5; packet.version = 5;
packet.privateParams = { key: new Uint8Array([1, 2, 3]) }; packet.privateParams = { key: new Uint8Array([1, 2, 3]) };
@ -1142,7 +1141,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
expect(written[25]).to.equal(3); expect(written[25]).to.equal(3);
}); });
it('Writing of unencrypted v6 secret key packet', async function() { it('Writing of unencrypted v6 secret key packet', () => {
const originalv6KeysSetting = openpgp.config.v6Keys; const originalv6KeysSetting = openpgp.config.v6Keys;
openpgp.config.v6Keys = true; openpgp.config.v6Keys = true;
@ -1378,7 +1377,7 @@ kePFjAnu9cpynKXu3usf8+FuBw2zLsg1Id1n7ttxoAte416KjBN9lFBt8mcu
expect(otherPackets[0].constructor.tag).to.equal(openpgp.enums.packet.userID); expect(otherPackets[0].constructor.tag).to.equal(openpgp.enums.packet.userID);
}); });
describe('Grammar validation', async function () { describe('Grammar validation', () => {
describe('MessageGrammarValidator - unit tests', () => { describe('MessageGrammarValidator - unit tests', () => {
it('valid nested signed messages should be valid', () => { it('valid nested signed messages should be valid', () => {
// Sig | OPS | Literal | Sig // Sig | OPS | Literal | Sig

View File

@ -706,7 +706,7 @@ hUhMKMuiM3pRwdIyDOItkUWQmjEEw7/XmhgInkXsCw==
config: { minRSABits: 1024 } config: { minRSABits: 1024 }
}); });
const signature = await openpgp.readSignature({ armoredSignature }); const signature = await openpgp.readSignature({ armoredSignature });
expect(signature.getSigningKeyIDs).to.exist; expect(signature.getSigningKeyIDs()).to.exist;
expect(signature.getSigningKeyIDs().map(x => x.toHex())).to.include(publicKey.getKeyID().toHex()); expect(signature.getSigningKeyIDs().map(x => x.toHex())).to.include(publicKey.getKeyID().toHex());
}); });
@ -1180,7 +1180,7 @@ Fk7EflUZzngwY4lBzYAfnNBjEjc30xD/ddo+rwE=
const sMsg = await openpgp.readMessage({ armoredMessage: signedArmor }); const sMsg = await openpgp.readMessage({ armoredMessage: signedArmor });
const pub_key = await openpgp.readKey({ armoredKey: pub_key_arm2 }); const pub_key = await openpgp.readKey({ armoredKey: pub_key_arm2 });
const verified = await sMsg.verify([pub_key]); const verified = await sMsg.verify([pub_key]);
stream.readToEnd(sMsg.getLiteralData()); await stream.readToEnd(sMsg.getLiteralData());
expect(verified).to.exist; expect(verified).to.exist;
expect(verified).to.have.length(1); expect(verified).to.have.length(1);
expect(await verified[0].verified).to.be.true; expect(await verified[0].verified).to.be.true;
@ -1574,7 +1574,7 @@ I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg==
const latin1Binary = util.hexToUint8Array('48e46c6cf62057e86c74'); const latin1Binary = util.hexToUint8Array('48e46c6cf62057e86c74');
const message = await openpgp.createMessage({ binary: latin1Binary }); const message = await openpgp.createMessage({ binary: latin1Binary });
message.appendSignature(`-----BEGIN PGP SIGNATURE----- await message.appendSignature(`-----BEGIN PGP SIGNATURE-----
iQIzBAEBCAAdFiEET5+J9VBawdGiYGMc2xGHud1faTsFAl5lE/AACgkQ2xGHud1f iQIzBAEBCAAdFiEET5+J9VBawdGiYGMc2xGHud1faTsFAl5lE/AACgkQ2xGHud1f
aTtIuw//YWrVaXLyP8sGBc0uUSLxQbmfQQYV8Oq8Vsg+jV4orc73wmEy8+Nj5m2g aTtIuw//YWrVaXLyP8sGBc0uUSLxQbmfQQYV8Oq8Vsg+jV4orc73wmEy8+Nj5m2g
@ -1842,7 +1842,7 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
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({ verificationKeys: [pubKey], message, config: { minRSABits: 1024 } }).then(async ({ data, signatures }) => { return openpgp.verify({ verificationKeys: [pubKey], message, config: { minRSABits: 1024 } }).then(({ data, signatures }) => {
expect(data).to.equal(plaintext); expect(data).to.equal(plaintext);
expect(signatures).to.have.length(0); expect(signatures).to.have.length(0);
}); });

View File

@ -789,7 +789,7 @@ function tests() {
it('Detached sign small message using curve25519 keys (legacy format)', async function() { it('Detached sign small message using curve25519 keys (legacy format)', async function() {
const data = new globalThis.ReadableStream({ const data = new globalThis.ReadableStream({
async start(controller) { start(controller) {
controller.enqueue(util.stringToUint8Array('hello ')); controller.enqueue(util.stringToUint8Array('hello '));
controller.enqueue(util.stringToUint8Array('world')); controller.enqueue(util.stringToUint8Array('world'));
controller.close(); controller.close();
@ -1016,7 +1016,7 @@ export default () => describe('Streaming', function() {
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
it('Node: Encrypt and decrypt text message roundtrip', async function() { it('Node: Encrypt and decrypt text message roundtrip', async function() {
const plaintext = fs.readFileSync(__filename.replace('streaming.js', 'openpgp.js'), 'utf8'); // eslint-disable-line no-sync const plaintext = fs.readFileSync(__filename.replace('streaming.js', 'openpgp.js'), 'utf8');
const data = NodeReadableStream.toWeb(fs.createReadStream(__filename.replace('streaming.js', 'openpgp.js'), { encoding: 'utf8' })); const data = NodeReadableStream.toWeb(fs.createReadStream(__filename.replace('streaming.js', 'openpgp.js'), { encoding: 'utf8' }));
const encrypted = await openpgp.encrypt({ const encrypted = await openpgp.encrypt({
message: await openpgp.createMessage({ text: data }), message: await openpgp.createMessage({ text: data }),
@ -1034,7 +1034,7 @@ export default () => describe('Streaming', function() {
}); });
it('Node: Encrypt and decrypt binary message roundtrip', async function() { it('Node: Encrypt and decrypt binary message roundtrip', async function() {
const plaintext = fs.readFileSync(__filename.replace('streaming.js', 'openpgp.js')); // eslint-disable-line no-sync const plaintext = fs.readFileSync(__filename.replace('streaming.js', 'openpgp.js'));
const data = NodeReadableStream.toWeb(fs.createReadStream(__filename.replace('streaming.js', 'openpgp.js'))); const data = NodeReadableStream.toWeb(fs.createReadStream(__filename.replace('streaming.js', 'openpgp.js')));
const encrypted = await openpgp.encrypt({ const encrypted = await openpgp.encrypt({
message: await openpgp.createMessage({ binary: data }), message: await openpgp.createMessage({ binary: data }),

View File

@ -84,12 +84,12 @@ async function fakeSignature() {
}); });
// read the standalone signature packet // read the standalone signature packet
const tmp = new SignaturePacket(); const tmp = new SignaturePacket();
await tmp.read(STANDALONE_PKT); tmp.read(STANDALONE_PKT);
// replace the "text" signature with the // replace the "text" signature with the
// "standalone" signature // "standalone" signature
fake.signature.packets[0] = tmp; fake.signature.packets[0] = tmp;
const faked_armored = await fake.armor(); const faked_armored = fake.armor();
// re-read the message to eliminate any // re-read the message to eliminate any
// behaviour due to cached values. // behaviour due to cached values.
fake = await readCleartextMessage({ cleartextMessage: faked_armored }); fake = await readCleartextMessage({ cleartextMessage: faked_armored });

View File

@ -60,7 +60,7 @@ export default () => it('Does not trust subkeys without Primary Key Binding Sign
fakeBindingSignature // faked key binding fakeBindingSignature // faked key binding
); );
let fakeKey = new PublicKey(newList); let fakeKey = new PublicKey(newList);
fakeKey = await readKey({ armoredKey: await fakeKey.toPublic().armor() }); fakeKey = await readKey({ armoredKey: fakeKey.toPublic().armor() });
const verifyAttackerIsBatman = await openpgp.verify({ const verifyAttackerIsBatman = await openpgp.verify({
message: await readCleartextMessage({ cleartextMessage: signed }), message: await readCleartextMessage({ cleartextMessage: signed }),
verificationKeys: fakeKey verificationKeys: fakeKey

View File

@ -61,7 +61,7 @@ async function makeKeyValid() {
encryptionKeys: k encryptionKeys: k
}); });
return false; return false;
} catch (e) { } catch {
return true; return true;
} }
} }
@ -84,7 +84,7 @@ async function makeKeyValid() {
let modifiedkey = new PrivateKey(newlist); let modifiedkey = new PrivateKey(newlist);
// re-read the message to eliminate any // re-read the message to eliminate any
// behaviour due to cached values. // behaviour due to cached values.
modifiedkey = await readKey({ armoredKey: await modifiedkey.armor() }); modifiedkey = await readKey({ armoredKey: modifiedkey.armor() });
expect(await encryptFails(invalidkey)).to.be.true; expect(await encryptFails(invalidkey)).to.be.true;
expect(await encryptFails(modifiedkey)).to.be.true; expect(await encryptFails(modifiedkey)).to.be.true;

View File

@ -16,7 +16,7 @@ import {
encrypt, decrypt, sign, verify, config, enums, encrypt, decrypt, sign, verify, config, enums,
generateSessionKey, encryptSessionKey, decryptSessionKeys, generateSessionKey, encryptSessionKey, decryptSessionKeys,
LiteralDataPacket, PacketList, CompressedDataPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, CleartextMessage, LiteralDataPacket, PacketList, CompressedDataPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, CleartextMessage,
WebStream, NodeWebStream, WebStream, NodeWebStream
} from 'openpgp'; } from 'openpgp';
(async () => { (async () => {
@ -47,7 +47,7 @@ import {
const parsedBinaryPrivateKey: PrivateKey = await readPrivateKey({ binaryKey: privateKeyBinary }); const parsedBinaryPrivateKey: PrivateKey = await readPrivateKey({ binaryKey: privateKeyBinary });
expect(parsedBinaryPrivateKey.isPrivate()).to.be.true; expect(parsedBinaryPrivateKey.isPrivate()).to.be.true;
// a generic Key can be directly used as PublicKey, since both classes have the same properties // a generic Key can be directly used as PublicKey, since both classes have the same properties
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const unusedPublicKey: PublicKey = parsedKey; const unusedPublicKey: PublicKey = parsedKey;
// Check PrivateKey type inference // Check PrivateKey type inference
@ -55,23 +55,23 @@ import {
expect(parsedKey.isDecrypted()).to.be.true; expect(parsedKey.isDecrypted()).to.be.true;
} else { } else {
// @ts-expect-error isDecrypted is not defined for public keys // @ts-expect-error isDecrypted is not defined for public keys
try { parsedKey.isDecrypted(); } catch (e) {} try { parsedKey.isDecrypted(); } catch {}
} }
(await privateKey.update(privateKey)).isDecrypted(); (await privateKey.update(privateKey)).isDecrypted();
(await privateKey.toPublic().update(privateKey)).isDecrypted(); (await privateKey.toPublic().update(privateKey)).isDecrypted();
// @ts-expect-error isDecrypted is not defined for public keys // @ts-expect-error isDecrypted is not defined for public keys
try { (await privateKey.toPublic().update(privateKey.toPublic())).isDecrypted(); } catch (e) {} try { (await privateKey.toPublic().update(privateKey.toPublic())).isDecrypted(); } catch {}
// Revoke keys // Revoke keys
await revokeKey({ key: privateKey }); await revokeKey({ key: privateKey });
// @ts-expect-error for missing revocation certificate // @ts-expect-error for missing revocation certificate
try { await revokeKey({ key: publicKey }); } catch (e) {} try { await revokeKey({ key: publicKey }); } catch {}
const { privateKey: revokedPrivateKey, publicKey: revokedPublicKey } = await revokeKey({ key: privateKey, revocationCertificate, format: 'object' }); const { privateKey: revokedPrivateKey, publicKey: revokedPublicKey } = await revokeKey({ key: privateKey, revocationCertificate, format: 'object' });
expect(revokedPrivateKey).to.be.instanceOf(PrivateKey); expect(revokedPrivateKey).to.be.instanceOf(PrivateKey);
expect(revokedPublicKey).to.be.instanceOf(PublicKey); expect(revokedPublicKey).to.be.instanceOf(PublicKey);
const revokedKeyPair = await revokeKey({ key: publicKey, revocationCertificate, format: 'object' }); const revokedKeyPair = await revokeKey({ key: publicKey, revocationCertificate, format: 'object' });
// @ts-expect-error for null private key // @ts-expect-error for null private key
try { revokedKeyPair.privateKey.armor(); } catch (e) {} try { revokedKeyPair.privateKey.armor(); } catch {}
expect(revokedKeyPair.privateKey).to.be.null; expect(revokedKeyPair.privateKey).to.be.null;
expect(revokedKeyPair.publicKey).to.be.instanceOf(PublicKey); expect(revokedKeyPair.publicKey).to.be.instanceOf(PublicKey);
@ -123,16 +123,16 @@ import {
const verifiedCleartextData: string = verificationResult.data; const verifiedCleartextData: string = verificationResult.data;
expect(verifiedCleartextData).to.equal(cleartextMessage.getText()); expect(verifiedCleartextData).to.equal(cleartextMessage.getText());
// @ts-expect-error Binary output not available for cleartext messages // @ts-expect-error Binary output not available for cleartext messages
try { await verify({ message: cleartextMessage, verificationKeys: publicKey, format: 'binary' }) } catch (e) {} try { await verify({ message: cleartextMessage, verificationKeys: publicKey, format: 'binary' }) } catch {}
const clearSignedArmor = await sign({ signingKeys: privateKeys, message: cleartextMessage }); const clearSignedArmor = await sign({ signingKeys: privateKeys, message: cleartextMessage });
expect(clearSignedArmor).to.include('-----BEGIN PGP SIGNED MESSAGE-----'); expect(clearSignedArmor).to.include('-----BEGIN PGP SIGNED MESSAGE-----');
const clearSignedObject: CleartextMessage = await sign({ signingKeys: privateKeys, message: cleartextMessage, format: 'object' }); const clearSignedObject: CleartextMessage = await sign({ signingKeys: privateKeys, message: cleartextMessage, format: 'object' });
expect(clearSignedObject).to.be.instanceOf(CleartextMessage); expect(clearSignedObject).to.be.instanceOf(CleartextMessage);
// @ts-expect-error PublicKey not assignable to PrivateKey // @ts-expect-error PublicKey not assignable to PrivateKey
try { await sign({ signingKeys: publicKeys, message: cleartextMessage }); } catch (e) {} try { await sign({ signingKeys: publicKeys, message: cleartextMessage }); } catch {}
// @ts-expect-error Key not assignable to PrivateKey // @ts-expect-error Key not assignable to PrivateKey
try { await sign({ signingKeys: parsedKey, message: cleartextMessage }); } catch (e) {} try { await sign({ signingKeys: parsedKey, message: cleartextMessage }); } catch {}
// Sign text message (armored) // Sign text message (armored)
const textSignedArmor: string = await sign({ signingKeys: privateKeys, message: textMessage }); const textSignedArmor: string = await sign({ signingKeys: privateKeys, message: textMessage });
@ -147,12 +147,15 @@ import {
expect(textSignedObject).to.be.instanceOf(Message); expect(textSignedObject).to.be.instanceOf(Message);
// Sign text message (armored) // Sign text message (armored)
const textSignedWithNotations: string = await sign({ signingKeys: privateKeys, message: textMessage, signatureNotations: [{ const textSignedWithNotations: string = await sign({
name: 'test@example.org', signingKeys: privateKeys,
value: new TextEncoder().encode('test'), message: textMessage,
humanReadable: true, signatureNotations: [{
critical: false name: 'test@example.org',
}] }); value: new TextEncoder().encode('test'),
humanReadable: true,
critical: false
}] });
expect(textSignedWithNotations).to.include('-----BEGIN PGP MESSAGE-----'); expect(textSignedWithNotations).to.include('-----BEGIN PGP MESSAGE-----');
// Verify signed text message (armored) // Verify signed text message (armored)
@ -176,7 +179,7 @@ import {
// @ts-expect-error for unsafe downcasting // @ts-expect-error for unsafe downcasting
packets.map((packet: LiteralDataPacket) => packet.getText()); packets.map((packet: LiteralDataPacket) => packet.getText());
// @ts-expect-error for non-packet element // @ts-expect-error for non-packet element
try { new PacketList().push(1); } catch (e) {} try { new PacketList().push(1); } catch {}
// Packetlist of specific type // Packetlist of specific type
const literalPackets = new PacketList<LiteralDataPacket>(); const literalPackets = new PacketList<LiteralDataPacket>();
@ -210,15 +213,17 @@ import {
await createMessage({ binary: new WebReadableStream<string>() }); await createMessage({ binary: new WebReadableStream<string>() });
// @ts-expect-error for passing binary stream as text data // @ts-expect-error for passing binary stream as text data
await createMessage({ text: new WebReadableStream<Uint8Array>() }); await createMessage({ text: new WebReadableStream<Uint8Array>() });
// Streaming - encrypt text message (armored output) // Streaming - encrypt text message (armored output)
try { try {
const nodeTextStream = NodeNativeReadableStream.toWeb(createReadStream('non-existent-file', { encoding: 'utf8' })); const nodeTextStream = NodeNativeReadableStream.toWeb(createReadStream('non-existent-file', { encoding: 'utf8' }));
const messageFromNodeTextStream = await createMessage({ text: nodeTextStream }); const messageFromNodeTextStream = await createMessage({ text: nodeTextStream });
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
(await encrypt({ message: messageFromNodeTextStream, passwords: 'password', format: 'armored' })) as NodeWebStream<string>; (await encrypt({ message: messageFromNodeTextStream, passwords: 'password', format: 'armored' })) as NodeWebStream<string>;
} catch (err) {} } catch {}
const webTextStream = new WebReadableStream<string>(); const webTextStream = new WebReadableStream<string>();
const messageFromWebTextStream = await createMessage({ text: webTextStream }); const messageFromWebTextStream = await createMessage({ text: webTextStream });
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
(await encrypt({ message: messageFromWebTextStream, passwords: 'password', format: 'armored' })) as WebStream<string>; (await encrypt({ message: messageFromWebTextStream, passwords: 'password', format: 'armored' })) as WebStream<string>;
messageFromWebTextStream.getText() as WebStream<string>; messageFromWebTextStream.getText() as WebStream<string>;
messageFromWebTextStream.getLiteralData() as WebStream<Uint8Array>; messageFromWebTextStream.getLiteralData() as WebStream<Uint8Array>;
@ -227,10 +232,12 @@ import {
try { try {
const nodeBinaryStream = NodeNativeReadableStream.toWeb(createReadStream('non-existent-file')); const nodeBinaryStream = NodeNativeReadableStream.toWeb(createReadStream('non-existent-file'));
const messageFromNodeBinaryStream = await createMessage({ binary: nodeBinaryStream }); const messageFromNodeBinaryStream = await createMessage({ binary: nodeBinaryStream });
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
(await encrypt({ message: messageFromNodeBinaryStream, passwords: 'password', format: 'binary' })) as NodeWebStream<Uint8Array>; (await encrypt({ message: messageFromNodeBinaryStream, passwords: 'password', format: 'binary' })) as NodeWebStream<Uint8Array>;
} catch (err) {} } catch {}
const webBinaryStream = new WebReadableStream<Uint8Array>(); const webBinaryStream = new WebReadableStream<Uint8Array>();
const messageFromWebBinaryStream = await createMessage({ binary: webBinaryStream }); const messageFromWebBinaryStream = await createMessage({ binary: webBinaryStream });
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
(await encrypt({ message: messageFromWebBinaryStream, passwords: 'password', format: 'binary' })) as WebStream<Uint8Array>; (await encrypt({ message: messageFromWebBinaryStream, passwords: 'password', format: 'binary' })) as WebStream<Uint8Array>;
messageFromWebBinaryStream.getText() as WebStream<string>; messageFromWebBinaryStream.getText() as WebStream<string>;
messageFromWebBinaryStream.getLiteralData() as WebStream<Uint8Array>; messageFromWebBinaryStream.getLiteralData() as WebStream<Uint8Array>;
@ -239,5 +246,6 @@ import {
})().catch(e => { })().catch(e => {
console.error('TypeScript definitions tests failed by throwing the following error'); console.error('TypeScript definitions tests failed by throwing the following error');
console.error(e); console.error(e);
// eslint-disable-next-line no-process-exit
process.exit(1); process.exit(1);
}); });

View File

@ -53,8 +53,8 @@ describe('Unit Tests', function () {
if (key && key !== 'grep') { if (key && key !== 'grep') {
openpgp.config[key] = decodeURIComponent(value); openpgp.config[key] = decodeURIComponent(value);
try { try {
openpgp.config[key] = window.eval(openpgp.config[key]); // eslint-disable-line no-eval openpgp.config[key] = window.eval(openpgp.config[key]);
} catch (e) {} } catch {}
} }
}); });
} else { } else {

View File

@ -1,4 +1,4 @@
/* globals openpgp */ /* globals openpgp, importScripts */
importScripts('../../dist/openpgp.js'); importScripts('../../dist/openpgp.js');