mirror of
https://github.com/openpgpjs/openpgpjs.git
synced 2025-11-23 22:15:52 +00:00
commit
c42a42e6f3
@ -1,4 +0,0 @@
|
||||
dist
|
||||
test/lib/
|
||||
test/typescript/
|
||||
docs
|
||||
146
.eslintrc.cjs
146
.eslintrc.cjs
@ -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
166
eslint.config.js
Normal 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
31
openpgp.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
/* eslint-disable max-lines, @typescript-eslint/indent */
|
||||
/* eslint-disable @stylistic/indent */
|
||||
|
||||
/**
|
||||
* Type definitions for OpenPGP.js http://openpgpjs.org/
|
||||
@ -337,10 +337,9 @@ export class Message<T extends MaybeStream<Data>> {
|
||||
}
|
||||
|
||||
/* ############## PACKET #################### */
|
||||
|
||||
export declare abstract class BasePacket {
|
||||
export declare abstract class BasePacket<AsyncRead extends boolean = false> {
|
||||
static readonly tag: enums.packet;
|
||||
public read(bytes: Uint8Array): void;
|
||||
public read(bytes: Uint8Array): AsyncRead extends true ? Promise<void> : void;
|
||||
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 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 created: Date;
|
||||
public version: number;
|
||||
@ -397,21 +396,21 @@ export class SecretSubkeyPacket extends BaseSecretKeyPacket {
|
||||
protected isSubkey(): true;
|
||||
}
|
||||
|
||||
export class CompressedDataPacket extends BasePacket {
|
||||
export class CompressedDataPacket extends BasePacket<true> {
|
||||
static readonly tag: enums.packet.compressedData;
|
||||
private compress(): void;
|
||||
private decompress(config?: Config): void;
|
||||
}
|
||||
|
||||
export class SymEncryptedIntegrityProtectedDataPacket extends BasePacket {
|
||||
export class SymEncryptedIntegrityProtectedDataPacket extends BasePacket<true> {
|
||||
static readonly tag: enums.packet.symEncryptedIntegrityProtectedData;
|
||||
}
|
||||
|
||||
export class AEADEncryptedDataPacket extends BasePacket {
|
||||
export class AEADEncryptedDataPacket extends BasePacket<true> {
|
||||
static readonly tag: enums.packet.aeadEncryptedData;
|
||||
private decrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): void;
|
||||
private encrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): void;
|
||||
private crypt(fn: Function, sessionKey: Uint8Array, data: MaybeStream<Uint8Array>): MaybeStream<Uint8Array>;
|
||||
private decrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): Promise<void>;
|
||||
private encrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): Promise<void>;
|
||||
private crypt(fn: (block: Uint8Array) => Uint8Array, sessionKey: Uint8Array, data: MaybeStream<Uint8Array>): MaybeStream<Uint8Array>;
|
||||
}
|
||||
|
||||
export class PublicKeyEncryptedSessionKeyPacket extends BasePacket {
|
||||
@ -426,7 +425,7 @@ export class SymEncryptedSessionKeyPacket extends BasePacket {
|
||||
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;
|
||||
private getText(clone?: boolean): MaybeStream<string>;
|
||||
private getBytes(clone?: boolean): MaybeStream<Uint8Array>;
|
||||
@ -439,8 +438,8 @@ export class LiteralDataPacket extends BasePacket {
|
||||
|
||||
export class SymmetricallyEncryptedDataPacket extends BasePacket {
|
||||
static readonly tag: enums.packet.symmetricallyEncryptedData;
|
||||
private decrypt(sessionKeyAlgorithm: enums.symmetric, sessionKey: Uint8Array, config?: Config): void;
|
||||
private encrypt(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): Promise<void>;
|
||||
}
|
||||
|
||||
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.)
|
||||
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`
|
||||
public read(bytes: MaybeStream<Uint8Array>, allowedPackets: AllowedPackets, config?: Config): void;
|
||||
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): Promise<void>;
|
||||
public write(): Uint8Array;
|
||||
public filterByTag(...args: enums.packet[]): PacketList<T>;
|
||||
public indexOfTag(...tags: enums.packet[]): number[];
|
||||
|
||||
1649
package-lock.json
generated
1649
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
14
package.json
14
package.json
@ -63,6 +63,7 @@
|
||||
"postversion": "git push --follow-tags && npm publish"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.36.0",
|
||||
"@noble/ciphers": "^1.3.0",
|
||||
"@noble/curves": "^1.9.6",
|
||||
"@noble/hashes": "^1.8.0",
|
||||
@ -77,10 +78,10 @@
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"@rollup/plugin-typescript": "^12.1.4",
|
||||
"@rollup/plugin-wasm": "^6.2.2",
|
||||
"@stylistic/eslint-plugin": "^5.4.0",
|
||||
"@types/chai": "^4.3.20",
|
||||
"@types/node": "^24.3.1",
|
||||
"@types/sinon": "^17.0.4",
|
||||
"@typescript-eslint/parser": "^7.18.0",
|
||||
"@web/test-runner": "^0.19.0",
|
||||
"@web/test-runner-browserstack": "^0.8.0",
|
||||
"@web/test-runner-mocha": "^0.9.0",
|
||||
@ -92,21 +93,20 @@
|
||||
"chai": "^4.5.0",
|
||||
"chai-as-promised": "^8.0.1",
|
||||
"eckey-utils": "^0.7.14",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-config-airbnb-typescript": "^18.0.0",
|
||||
"eslint-import-resolver-typescript": "^3.10.1",
|
||||
"eslint-plugin-chai-friendly": "^0.7.4",
|
||||
"eslint": "^9.36.0",
|
||||
"eslint-import-resolver-typescript": "^4.4.4",
|
||||
"eslint-plugin-chai-friendly": "^1.1.0",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-unicorn": "^48.0.1",
|
||||
"fflate": "^0.8.2",
|
||||
"globals": "^16.4.0",
|
||||
"mocha": "^11.7.1",
|
||||
"playwright": "^1.56.0",
|
||||
"rollup": "^4.48.1",
|
||||
"sinon": "^21.0.0",
|
||||
"tsx": "^4.20.5",
|
||||
"typescript": "^5.9.2",
|
||||
"typescript-eslint": "^8.44.1",
|
||||
"web-streams-polyfill": "^4.2.0"
|
||||
},
|
||||
"overrides": {
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
/* eslint-disable no-process-env */
|
||||
|
||||
import { builtinModules } from 'module';
|
||||
import { readFileSync } from 'fs';
|
||||
|
||||
|
||||
@ -189,7 +189,7 @@ function verifyHeaders(headers, packetlist) {
|
||||
.map(hashName => {
|
||||
try {
|
||||
return enums.write(enums.hash, hashName.toLowerCase());
|
||||
} catch (e) {
|
||||
} catch {
|
||||
throw new Error('Unknown hash algorithm in armor header: ' + hashName.toLowerCase());
|
||||
}
|
||||
});
|
||||
@ -209,8 +209,9 @@ function verifyHeaders(headers, packetlist) {
|
||||
* @param {Object} options
|
||||
* @param {String} options.text
|
||||
* @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 }) {
|
||||
if (!text) {
|
||||
throw new Error('createCleartextMessage: must pass options object containing `text`');
|
||||
|
||||
@ -31,7 +31,7 @@ const webCrypto = util.getWebCrypto();
|
||||
* @param {enums.symmetric.aes128|enums.symmetric.aes256|enums.symmetric.aes192} algo - AES algo
|
||||
* @param {Uint8Array} key - wrapping key
|
||||
* @param {Uint8Array} dataToWrap
|
||||
* @returns {Uint8Array} wrapped key
|
||||
* @returns {Promise<Uint8Array>} wrapped key
|
||||
*/
|
||||
export async function wrap(algo, key, dataToWrap) {
|
||||
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 {Uint8Array} key - wrapping key
|
||||
* @param {Uint8Array} wrappedData
|
||||
* @returns {Uint8Array} unwrapped data
|
||||
* @returns {Promise<Uint8Array>} unwrapped data
|
||||
*/
|
||||
export async function unwrap(algo, key, wrappedData) {
|
||||
const { keySize } = getCipherParams(algo);
|
||||
|
||||
@ -162,7 +162,7 @@ export function bitLength(x: bigint) {
|
||||
const target = x < _0n ? BigInt(-1) : _0n;
|
||||
let bitlen = 1;
|
||||
let tmp = x;
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
|
||||
while ((tmp >>= _1n) !== target) {
|
||||
bitlen++;
|
||||
}
|
||||
@ -177,7 +177,7 @@ export function byteLength(x: bigint) {
|
||||
const _8n = BigInt(8);
|
||||
let len = 1;
|
||||
let tmp = x;
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
|
||||
while ((tmp >>= _8n) !== target) {
|
||||
len++;
|
||||
}
|
||||
|
||||
@ -1,6 +1,3 @@
|
||||
/* eslint-disable no-mixed-operators, no-fallthrough */
|
||||
|
||||
|
||||
/* Modified by Recurity Labs GmbH
|
||||
*
|
||||
* 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 ashx = [0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7];
|
||||
/** @type {number[][]} */
|
||||
const q = [
|
||||
[],
|
||||
[]
|
||||
@ -158,11 +156,13 @@ function createTwofish() {
|
||||
b = q[0][b] ^ getB(key[3], 1);
|
||||
c = q[0][c] ^ getB(key[3], 2);
|
||||
d = q[1][d] ^ getB(key[3], 3);
|
||||
// eslint-disable-next-line no-fallthrough
|
||||
case 3:
|
||||
a = q[1][a] ^ getB(key[2], 0);
|
||||
b = q[1][b] ^ getB(key[2], 1);
|
||||
c = q[0][c] ^ getB(key[2], 2);
|
||||
d = q[0][d] ^ getB(key[2], 3);
|
||||
// eslint-disable-next-line no-fallthrough
|
||||
case 2:
|
||||
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);
|
||||
@ -222,11 +222,13 @@ function createTwofish() {
|
||||
b = q[0][b] ^ getB(sKey[3], 1);
|
||||
c = q[0][c] ^ getB(sKey[3], 2);
|
||||
d = q[1][d] ^ getB(sKey[3], 3);
|
||||
// eslint-disable-next-line no-fallthrough
|
||||
case 3:
|
||||
a = q[1][a] ^ getB(sKey[2], 0);
|
||||
b = q[1][b] ^ getB(sKey[2], 1);
|
||||
c = q[0][c] ^ getB(sKey[2], 2);
|
||||
d = q[0][d] ^ getB(sKey[2], 3);
|
||||
// eslint-disable-next-line no-fallthrough
|
||||
case 2:
|
||||
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)];
|
||||
|
||||
@ -49,11 +49,10 @@ const nodeAlgos = {
|
||||
* 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
|
||||
* @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 prefixrandom = await getRandomBytes(blockSize);
|
||||
const prefixrandom = getRandomBytes(blockSize);
|
||||
const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]);
|
||||
return util.concat([prefixrandom, repeat]);
|
||||
}
|
||||
@ -156,7 +155,10 @@ class WebCryptoEncryptor {
|
||||
this.zeroBlock = new Uint8Array(this.blockSize);
|
||||
}
|
||||
|
||||
static async isSupported(algo) {
|
||||
/**
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
static isSupported(algo) {
|
||||
const { keySize } = getCipherParams(algo);
|
||||
return webCrypto.importKey('raw', new Uint8Array(keySize), 'aes-cbc', false, ['encrypt'])
|
||||
.then(() => true, () => false);
|
||||
@ -283,6 +285,7 @@ class NobleStreamProcessor {
|
||||
return dst;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
async processChunk(value) {
|
||||
const missing = this.nextBlock.length - this.i;
|
||||
const added = value.subarray(0, missing);
|
||||
@ -321,6 +324,7 @@ class NobleStreamProcessor {
|
||||
return processedBlock;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
async finish() {
|
||||
let result;
|
||||
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);
|
||||
}
|
||||
|
||||
async function aesDecrypt(algo, key, ct, iv) {
|
||||
function aesDecrypt(algo, key, ct, iv) {
|
||||
if (util.isStream(ct)) {
|
||||
const cfb = new NobleStreamProcessor(false, algo, key, iv);
|
||||
return streamTransform(ct, value => cfb.processChunk(value), () => cfb.finish());
|
||||
|
||||
@ -48,6 +48,7 @@ async function OMAC(key) {
|
||||
|
||||
async function CTR(key) {
|
||||
if (util.getNodeCrypto()) { // Node crypto library
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
return async function(pt, iv) {
|
||||
const en = new nodeCrypto.createCipheriv('aes-' + (key.length * 8) + '-ctr', key, iv);
|
||||
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 nobleAesCtr(key, iv).encrypt(pt);
|
||||
};
|
||||
|
||||
@ -48,6 +48,7 @@ async function GCM(cipher, key) {
|
||||
|
||||
if (util.getNodeCrypto()) { // Node crypto library
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
encrypt: async function(pt, iv, adata = new Uint8Array()) {
|
||||
const en = new nodeCrypto.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
|
||||
en.setAAD(adata);
|
||||
@ -55,6 +56,7 @@ async function GCM(cipher, key) {
|
||||
return new Uint8Array(ct);
|
||||
},
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
decrypt: async function(ct, iv, adata = new Uint8Array()) {
|
||||
const de = new nodeCrypto.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
|
||||
de.setAAD(adata);
|
||||
@ -105,10 +107,12 @@ async function GCM(cipher, key) {
|
||||
}
|
||||
|
||||
return {
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
encrypt: async function(pt, iv, adata) {
|
||||
return nobleAesGcm(key, iv, adata).encrypt(pt);
|
||||
},
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
decrypt: async function(ct, iv, adata) {
|
||||
return nobleAesGcm(key, iv, adata).decrypt(ct);
|
||||
}
|
||||
|
||||
@ -61,6 +61,7 @@ const one = new Uint8Array([1]);
|
||||
* @param {enums.symmetric} cipher - The symmetric cipher algorithm to use
|
||||
* @param {Uint8Array} key - The encryption key
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
async function OCB(cipher, key) {
|
||||
const { keySize } = getCipherParams(cipher);
|
||||
// sanity checks
|
||||
@ -240,6 +241,7 @@ async function OCB(cipher, key) {
|
||||
* @param {Uint8Array} adata - Associated data to sign
|
||||
* @returns {Promise<Uint8Array>} The ciphertext output.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
decrypt: async function(ciphertext, nonce, adata) {
|
||||
if (ciphertext.length < tagLength) throw new Error('Invalid OCB ciphertext');
|
||||
|
||||
|
||||
@ -73,6 +73,7 @@ export default async function CMAC(key) {
|
||||
|
||||
async function CBC(key) {
|
||||
if (util.getNodeCrypto()) { // Node crypto library
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
return async function(pt) {
|
||||
const en = new nodeCrypto.createCipheriv('aes-' + (key.length * 8) + '-cbc', key, zeroBlock);
|
||||
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 nobleAesCbc(key, zeroBlock, { disablePadding: true }).encrypt(pt);
|
||||
};
|
||||
|
||||
@ -458,7 +458,7 @@ export function generateSessionKey(algo) {
|
||||
function checkSupportedCurve(oid) {
|
||||
try {
|
||||
oid.getName();
|
||||
} catch (e) {
|
||||
} catch {
|
||||
throw new UnsupportedError('Unknown curve OID');
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ function nodeHash(type) {
|
||||
if (!nodeCrypto || !nodeCryptoHashes.includes(type)) {
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
return async function (data) {
|
||||
const shasum = nodeCrypto.createHash(type);
|
||||
return streamTransform(data, value => {
|
||||
|
||||
@ -35,15 +35,12 @@ class MD5 extends HashMD<MD5> {
|
||||
// Compression function main loop, 64 rounds
|
||||
let { A, B, C, D } = this;
|
||||
for (let i = 0; i < 64; i++) {
|
||||
// eslint-disable-next-line one-var, one-var-declaration-per-line
|
||||
let F, g, s;
|
||||
if (i < 16) {
|
||||
// eslint-disable-next-line new-cap
|
||||
F = Chi(B, C, D);
|
||||
g = i;
|
||||
s = [7, 12, 17, 22];
|
||||
} else if (i < 32) {
|
||||
// eslint-disable-next-line new-cap
|
||||
F = Chi(D, B, C);
|
||||
g = (5 * i + 1) % 16;
|
||||
s = [5, 9, 14, 20];
|
||||
|
||||
@ -44,6 +44,7 @@ const _1n = BigInt(1);
|
||||
* @returns {Promise<{ r: Uint8Array, s: Uint8Array }>}
|
||||
* @async
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export async function sign(hashAlgo, hashed, g, p, q, x) {
|
||||
const _0n = BigInt(0);
|
||||
p = uint8ArrayToBigInt(p);
|
||||
@ -102,6 +103,7 @@ export async function sign(hashAlgo, hashed, g, p, q, x) {
|
||||
* @returns {boolean}
|
||||
* @async
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export async function verify(hashAlgo, r, s, hashed, g, p, q, y) {
|
||||
r = uint8ArrayToBigInt(r);
|
||||
s = uint8ArrayToBigInt(s);
|
||||
@ -135,19 +137,20 @@ export async function verify(hashAlgo, r, s, hashed, g, p, q, y) {
|
||||
|
||||
/**
|
||||
* Validate DSA parameters
|
||||
* @param {Uint8Array} p - DSA prime
|
||||
* @param {Uint8Array} q - DSA group order
|
||||
* @param {Uint8Array} g - DSA sub-group generator
|
||||
* @param {Uint8Array} y - DSA public key
|
||||
* @param {Uint8Array} x - DSA private key
|
||||
* @param {Uint8Array} pBytes - DSA prime
|
||||
* @param {Uint8Array} qBytes - DSA group order
|
||||
* @param {Uint8Array} gBytes - DSA sub-group generator
|
||||
* @param {Uint8Array} yBytes - DSA public key
|
||||
* @param {Uint8Array} xBytes - DSA private key
|
||||
* @returns {Promise<Boolean>} Whether params are valid.
|
||||
* @async
|
||||
*/
|
||||
export async function validateParams(p, q, g, y, x) {
|
||||
p = uint8ArrayToBigInt(p);
|
||||
q = uint8ArrayToBigInt(q);
|
||||
g = uint8ArrayToBigInt(g);
|
||||
y = uint8ArrayToBigInt(y);
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export async function validateParams(pBytes, qBytes, gBytes, yBytes, xBytes) {
|
||||
const p = uint8ArrayToBigInt(pBytes);
|
||||
const q = uint8ArrayToBigInt(qBytes);
|
||||
const g = uint8ArrayToBigInt(gBytes);
|
||||
const y = uint8ArrayToBigInt(yBytes);
|
||||
// Check that 1 < g < p
|
||||
if (g <= _1n || g >= p) {
|
||||
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
|
||||
*/
|
||||
x = uint8ArrayToBigInt(x);
|
||||
const x = uint8ArrayToBigInt(xBytes);
|
||||
const _2n = BigInt(2);
|
||||
const r = getRandomBigInteger(_2n << (qSize - _1n), _2n << qSize); // draw r of same size as q
|
||||
const rqx = q * r + x;
|
||||
|
||||
@ -35,6 +35,7 @@ const _1n = BigInt(1);
|
||||
* @returns {Promise<{ c1: Uint8Array, c2: Uint8Array }>}
|
||||
* @async
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export async function encrypt(data, p, g, y) {
|
||||
p = uint8ArrayToBigInt(p);
|
||||
g = uint8ArrayToBigInt(g);
|
||||
@ -64,6 +65,7 @@ export async function encrypt(data, p, g, y) {
|
||||
* @throws {Error} on decryption error, unless `randomPayload` is given
|
||||
* @async
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export async function decrypt(c1, c2, p, x, randomPayload) {
|
||||
c1 = uint8ArrayToBigInt(c1);
|
||||
c2 = uint8ArrayToBigInt(c2);
|
||||
@ -76,17 +78,18 @@ export async function decrypt(c1, c2, p, x, randomPayload) {
|
||||
|
||||
/**
|
||||
* Validate ElGamal parameters
|
||||
* @param {Uint8Array} p - ElGamal prime
|
||||
* @param {Uint8Array} g - ElGamal group generator
|
||||
* @param {Uint8Array} y - ElGamal public key
|
||||
* @param {Uint8Array} x - ElGamal private exponent
|
||||
* @param {Uint8Array} pBytes - ElGamal prime
|
||||
* @param {Uint8Array} gBytes - ElGamal group generator
|
||||
* @param {Uint8Array} yBytes - ElGamal public key
|
||||
* @param {Uint8Array} xBytes - ElGamal private exponent
|
||||
* @returns {Promise<Boolean>} Whether params are valid.
|
||||
* @async
|
||||
*/
|
||||
export async function validateParams(p, g, y, x) {
|
||||
p = uint8ArrayToBigInt(p);
|
||||
g = uint8ArrayToBigInt(g);
|
||||
y = uint8ArrayToBigInt(y);
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export async function validateParams(pBytes, gBytes, yBytes, xBytes) {
|
||||
const p = uint8ArrayToBigInt(pBytes);
|
||||
const g = uint8ArrayToBigInt(gBytes);
|
||||
const y = uint8ArrayToBigInt(yBytes);
|
||||
|
||||
// Check that 1 < 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
|
||||
*/
|
||||
x = uint8ArrayToBigInt(x);
|
||||
const x = uint8ArrayToBigInt(xBytes);
|
||||
const r = getRandomBigInteger(_2n << (pSize - _1n), _2n << pSize); // draw r of same size as p-1
|
||||
const rqx = (p - _1n) * r + x;
|
||||
if (y !== modExp(g, rqx, p)) {
|
||||
|
||||
@ -4,7 +4,6 @@ import { Field } from '@noble/curves/abstract/modular';
|
||||
|
||||
// brainpoolP256r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.4
|
||||
|
||||
// eslint-disable-next-line new-cap
|
||||
const Fp = Field(BigInt('0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377'));
|
||||
const CURVE_A = Fp.create(BigInt('0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9'));
|
||||
const CURVE_B = BigInt('0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6');
|
||||
|
||||
@ -4,7 +4,6 @@ import { Field } from '@noble/curves/abstract/modular';
|
||||
|
||||
// brainpoolP384 r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.6
|
||||
|
||||
// eslint-disable-next-line new-cap
|
||||
const Fp = Field(BigInt('0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123acd3a729901d1a71874700133107ec53'));
|
||||
const CURVE_A = Fp.create(BigInt('0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f8aa5814a503ad4eb04a8c7dd22ce2826'));
|
||||
const CURVE_B = BigInt('0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d57cb4390295dbc9943ab78696fa504c11');
|
||||
|
||||
@ -4,7 +4,6 @@ import { Field } from '@noble/curves/abstract/modular';
|
||||
|
||||
// brainpoolP512r1: https://datatracker.ietf.org/doc/html/rfc5639#section-3.7
|
||||
|
||||
// eslint-disable-next-line new-cap
|
||||
const Fp = Field(BigInt('0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca703308717d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3'));
|
||||
const CURVE_A = Fp.create(BigInt('0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca'));
|
||||
const CURVE_B = BigInt('0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723');
|
||||
|
||||
@ -336,7 +336,7 @@ async function webPublicEphemeralKey(curve, Q) {
|
||||
* @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
|
||||
* @async
|
||||
*/
|
||||
async function nodePrivateEphemeralKey(curve, V, d) {
|
||||
function nodePrivateEphemeralKey(curve, V, d) {
|
||||
const nodeCrypto = util.getNodeCrypto();
|
||||
const recipient = nodeCrypto.createECDH(curve.node);
|
||||
recipient.setPrivateKey(d);
|
||||
@ -353,7 +353,7 @@ async function nodePrivateEphemeralKey(curve, V, d) {
|
||||
* @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
|
||||
* @async
|
||||
*/
|
||||
async function nodePublicEphemeralKey(curve, Q) {
|
||||
function nodePublicEphemeralKey(curve, Q) {
|
||||
const nodeCrypto = util.getNodeCrypto();
|
||||
const sender = nodeCrypto.createECDH(curve.node);
|
||||
sender.generateKeys();
|
||||
|
||||
@ -88,7 +88,7 @@ export async function validateParams(algo, A, k) {
|
||||
const recomputedSharedSecret = await recomputeSharedSecret(algo, ephemeralPublicKey, A, k);
|
||||
|
||||
return util.equalsUint8Array(sharedSecret, recomputedSharedSecret);
|
||||
} catch (_) {
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed
|
||||
* @param {Uint8Array} message - Message to verify
|
||||
* @param {Uint8Array} publicKey - Public key used to verify the message
|
||||
* @param {Uint8Array} hashed - The hashed message
|
||||
* @returns {Boolean}
|
||||
* @returns {Promise<Boolean>}
|
||||
* @async
|
||||
*/
|
||||
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;
|
||||
case 'node': {
|
||||
const verified = await nodeVerify(curve, hashAlgo, signature, message, publicKey);
|
||||
const verified = nodeVerify(curve, hashAlgo, signature, message, publicKey);
|
||||
return verified || tryFallbackVerificationForOldBug();
|
||||
}
|
||||
}
|
||||
@ -159,9 +159,8 @@ export async function validateParams(oid, Q, d) {
|
||||
const hashed = await computeDigest(hashAlgo, message);
|
||||
try {
|
||||
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);
|
||||
} catch (err) {
|
||||
} catch {
|
||||
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
|
||||
const ecKeyUtils = util.nodeRequire('eckey-utils');
|
||||
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 nodeBuffer = util.getNodeBuffer();
|
||||
const { publicKey: derPublicKey } = ecKeyUtils.generateDer({
|
||||
@ -284,7 +283,7 @@ async function nodeVerify(curve, hashAlgo, { r, s }, message, publicKey) {
|
||||
|
||||
try {
|
||||
return verify.verify({ key: derPublicKey, format: 'der', type: 'spki', dsaEncoding: 'ieee-p1363' }, signature);
|
||||
} catch (err) {
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,6 +70,7 @@ export async function sign(oid, hashAlgo, message, publicKey, privateKey, hashed
|
||||
* @returns {Boolean}
|
||||
* @async
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export async function verify(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
|
||||
const curve = new CurveWithOID(oid);
|
||||
checkPublicPointEnconding(curve, publicKey);
|
||||
|
||||
@ -143,7 +143,7 @@ class CurveWithOID {
|
||||
this.name = oidOrName instanceof OID ?
|
||||
oidOrName.getName() :
|
||||
enums.write(enums.curve,oidOrName);
|
||||
} catch (err) {
|
||||
} catch {
|
||||
throw new UnsupportedError('Unknown curve');
|
||||
}
|
||||
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
|
||||
const ecdh = nodeCrypto.createECDH(nodeCurves[name]);
|
||||
await ecdh.generateKeys();
|
||||
ecdh.generateKeys();
|
||||
return {
|
||||
publicKey: new Uint8Array(ecdh.getPublicKey()),
|
||||
privateKey: new Uint8Array(ecdh.getPrivateKey())
|
||||
|
||||
@ -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} e - RSA public exponent
|
||||
* @param {Uint8Array} hashed - Hashed message
|
||||
* @returns {Boolean}
|
||||
* @returns {Promise<Boolean>}
|
||||
* @async
|
||||
*/
|
||||
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.
|
||||
* @async
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export async function encrypt(data, n, e) {
|
||||
if (util.getNodeCrypto()) {
|
||||
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
|
||||
* @async
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
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,
|
||||
// and we want to avoid checking the error type to decide if the random payload
|
||||
// should indeed be returned.
|
||||
if (util.getNodeCrypto() && !randomPayload) {
|
||||
try {
|
||||
return await nodeDecrypt(data, n, e, d, p, q, u);
|
||||
return nodeDecrypt(data, n, e, d, p, q, u);
|
||||
} catch (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
|
||||
* @param {Integer} bits - RSA bit length
|
||||
* @param {Integer} e - RSA public exponent
|
||||
* @returns {{n, e, d,
|
||||
* p, q ,u: Uint8Array}} RSA public modulus, RSA public exponent, RSA private exponent,
|
||||
* @returns {Promise<{n, e, d,
|
||||
* 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
|
||||
* @async
|
||||
*/
|
||||
@ -231,6 +233,7 @@ export async function generate(bits, e) {
|
||||
* @returns {Promise<Boolean>} Whether params are valid.
|
||||
* @async
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/require-await
|
||||
export async function validateParams(n, e, d, p, q, u) {
|
||||
n = uint8ArrayToBigInt(n);
|
||||
p = uint8ArrayToBigInt(p);
|
||||
@ -269,7 +272,7 @@ export async function validateParams(n, e, d, p, q, u) {
|
||||
return true;
|
||||
}
|
||||
|
||||
async function bnSign(hashAlgo, n, d, hashed) {
|
||||
function bnSign(hashAlgo, n, d, hashed) {
|
||||
n = uint8ArrayToBigInt(n);
|
||||
const m = uint8ArrayToBigInt(emsaEncode(hashAlgo, hashed, byteLength(n)));
|
||||
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
|
||||
* 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 = {
|
||||
name: 'RSASSA-PKCS1-v1_5',
|
||||
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));
|
||||
}
|
||||
|
||||
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));
|
||||
sign.write(data);
|
||||
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' }));
|
||||
}
|
||||
|
||||
async function bnVerify(hashAlgo, s, n, e, hashed) {
|
||||
function bnVerify(hashAlgo, s, n, e, hashed) {
|
||||
n = uint8ArrayToBigInt(n);
|
||||
s = uint8ArrayToBigInt(s);
|
||||
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);
|
||||
}
|
||||
|
||||
async function nodeVerify(hashAlgo, data, s, n, e) {
|
||||
function nodeVerify(hashAlgo, data, s, n, e) {
|
||||
const jwk = publicToJWK(n, e);
|
||||
const key = { key: jwk, format: 'jwk', type: 'pkcs1' };
|
||||
|
||||
@ -333,19 +336,19 @@ async function nodeVerify(hashAlgo, data, s, n, e) {
|
||||
|
||||
try {
|
||||
return verify.verify(key, s);
|
||||
} catch (err) {
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function nodeEncrypt(data, n, e) {
|
||||
function nodeEncrypt(data, n, e) {
|
||||
const jwk = publicToJWK(n, e);
|
||||
const key = { key: jwk, format: 'jwk', type: 'pkcs1', padding: nodeCrypto.constants.RSA_PKCS1_PADDING };
|
||||
|
||||
return new Uint8Array(nodeCrypto.publicEncrypt(key, data));
|
||||
}
|
||||
|
||||
async function bnEncrypt(data, n, e) {
|
||||
function bnEncrypt(data, n, e) {
|
||||
n = uint8ArrayToBigInt(n);
|
||||
data = uint8ArrayToBigInt(emeEncode(data, byteLength(n)));
|
||||
e = uint8ArrayToBigInt(e);
|
||||
@ -355,18 +358,18 @@ async function bnEncrypt(data, n, e) {
|
||||
return bigIntToUint8Array(modExp(data, e, n), 'be', byteLength(n));
|
||||
}
|
||||
|
||||
async function nodeDecrypt(data, n, e, d, p, q, u) {
|
||||
const jwk = await privateToJWK(n, e, d, p, q, u);
|
||||
function nodeDecrypt(data, 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 };
|
||||
|
||||
try {
|
||||
return new Uint8Array(nodeCrypto.privateDecrypt(key, data));
|
||||
} catch (err) {
|
||||
} catch {
|
||||
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);
|
||||
n = uint8ArrayToBigInt(n);
|
||||
e = uint8ArrayToBigInt(e);
|
||||
@ -405,7 +408,7 @@ async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) {
|
||||
* @param {Uint8Array} q
|
||||
* @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 qNum = uint8ArrayToBigInt(q);
|
||||
const dNum = uint8ArrayToBigInt(d);
|
||||
|
||||
@ -227,8 +227,7 @@ function removeChecksum(text) {
|
||||
* @static
|
||||
*/
|
||||
export function unarmor(input) {
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
return new Promise(async (resolve, reject) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const reSplit = /^-----[^-]+-----$/m;
|
||||
const reEmptyLine = /^[ \f\r\t\u00a0\u2000-\u200a\u202f\u205f\u3000]*$/;
|
||||
|
||||
1
src/enums.d.ts
vendored
1
src/enums.d.ts
vendored
@ -1,3 +1,4 @@
|
||||
/* eslint-disable @typescript-eslint/no-duplicate-enum-values */
|
||||
declare namespace enums {
|
||||
export function read(type: typeof armor, e: armor): armorNames;
|
||||
export function read(type: typeof compression, e: compression): compressionNames;
|
||||
|
||||
@ -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
|
||||
* 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 {SecretSubkeyPacket} secretSubkeyPackets
|
||||
* @param {Array<SecretSubkeyPacket>} secretSubkeyPackets
|
||||
* @param {Object} options
|
||||
* @param {Object} config - Full configuration
|
||||
* @returns {PrivateKey}
|
||||
* @returns {Promise<PrivateKey>}
|
||||
*/
|
||||
async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, config) {
|
||||
// set passphrase protection
|
||||
@ -295,12 +295,12 @@ async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, conf
|
||||
secretKeyPacket.clearPrivateParams();
|
||||
}
|
||||
|
||||
await Promise.all(secretSubkeyPackets.map(async function(secretSubkeyPacket, index) {
|
||||
secretSubkeyPackets.map(function(secretSubkeyPacket, index) {
|
||||
const subkeyPassphrase = options.subkeys[index].passphrase;
|
||||
if (subkeyPassphrase) {
|
||||
secretSubkeyPacket.clearPrivateParams();
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
return new PrivateKey(packetlist);
|
||||
}
|
||||
|
||||
@ -357,7 +357,7 @@ export async function isDataRevoked(primaryKey, signatureType, dataToVerify, rev
|
||||
// TODO get an identifier of the revoked object instead
|
||||
revocationKeyIDs.push(revocationSignature.issuerKeyID);
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch {}
|
||||
}));
|
||||
// TODO further verify that this is the signature that should be revoked
|
||||
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`
|
||||
try {
|
||||
options.curve = enums.write(enums.curve, options.curve);
|
||||
} catch (e) {
|
||||
} catch {
|
||||
throw new Error('Unknown curve');
|
||||
}
|
||||
if (options.curve === enums.curve.ed25519Legacy || options.curve === enums.curve.curve25519Legacy ||
|
||||
|
||||
@ -442,7 +442,7 @@ class Key {
|
||||
} else {
|
||||
primaryKeyExpiry = selfSigKeyExpiry < selfSigExpiry ? selfSigKeyExpiry : selfSigExpiry;
|
||||
}
|
||||
} catch (e) {
|
||||
} catch {
|
||||
primaryKeyExpiry = null;
|
||||
}
|
||||
|
||||
@ -510,11 +510,13 @@ class Key {
|
||||
}
|
||||
}
|
||||
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');
|
||||
}
|
||||
await Promise.all(users.map(async function (a) {
|
||||
return a.selfCertification.revoked || a.user.isRevoked(a.selfCertification, null, date, config);
|
||||
// Update `revoked` status, whose value is discarded here but used below;
|
||||
// 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
|
||||
const primaryUser = users.sort(function(a, b) {
|
||||
@ -751,8 +753,7 @@ class Key {
|
||||
}
|
||||
|
||||
['getKeyID', 'getFingerprint', 'getAlgorithmInfo', 'getCreationTime', 'hasSameFingerprintAs'].forEach(name => {
|
||||
Key.prototype[name] =
|
||||
Subkey.prototype[name];
|
||||
Key.prototype[name] = Subkey.prototype[name];
|
||||
});
|
||||
|
||||
export default Key;
|
||||
|
||||
@ -114,7 +114,7 @@ class PrivateKey extends PublicKey {
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
|
||||
@ -168,7 +168,7 @@ class PrivateKey extends PublicKey {
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -112,7 +112,7 @@ class Subkey {
|
||||
let bindingSignature;
|
||||
try {
|
||||
bindingSignature = await helper.getLatestValidSignature(this.bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config);
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
const keyExpiry = helper.getKeyExpirationTime(this.keyPacket, bindingSignature);
|
||||
@ -153,7 +153,7 @@ class Subkey {
|
||||
try {
|
||||
await srcBindSig.verify(primaryKey, enums.signature.subkeyBinding, dataToVerify, date, undefined, config);
|
||||
return true;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
@ -222,7 +222,7 @@ class User {
|
||||
try {
|
||||
await srcSelfSig.verify(primaryKey, enums.signature.certGeneric, dataToVerify, date, false, config);
|
||||
return true;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
@ -220,7 +220,7 @@ export class Message {
|
||||
if (selfCertification.preferredSymmetricAlgorithms) {
|
||||
algos = algos.concat(selfCertification.preferredSymmetricAlgorithms);
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch {}
|
||||
|
||||
await Promise.all(decryptionKeyPackets.map(async function(decryptionKeyPacket) {
|
||||
if (!decryptionKeyPacket.isDecrypted()) {
|
||||
@ -460,7 +460,7 @@ export class Message {
|
||||
try {
|
||||
await keyPacket.decrypt(password);
|
||||
return 1;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
@ -639,9 +639,10 @@ export class Message {
|
||||
* signature: Promise<Signature>,
|
||||
* verified: Promise<true>
|
||||
* }>>} 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 literalDataList = msg.packets.filterByTag(enums.packet.literalData);
|
||||
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 {Boolean} [detached] - Whether to verify detached signature packets
|
||||
* @param {Object} [config] - Full configuration, defaults to openpgp.config
|
||||
* @returns {Promise<{
|
||||
* @returns {{
|
||||
* keyID: module:type/keyid~KeyID,
|
||||
* signature: Promise<Signature>,
|
||||
* verified: Promise<true>
|
||||
* }>} signer's keyID and validity of signature
|
||||
* }} signer's keyID and validity of signature
|
||||
* @async
|
||||
* @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 unverifiedSigningKey;
|
||||
|
||||
@ -831,20 +832,17 @@ async function createVerificationObject(signature, literalDataList, verification
|
||||
* i.e. check signature creation time < date < expiration time
|
||||
* @param {Boolean} [detached] - Whether to verify detached signature packets
|
||||
* @param {Object} [config] - Full configuration, defaults to openpgp.config
|
||||
* @returns {Promise<Array<{
|
||||
* @returns {Array<{
|
||||
* keyID: module:type/keyid~KeyID,
|
||||
* signature: Promise<Signature>,
|
||||
* verified: Promise<true>
|
||||
* }>>} list of signer's keyID and validity of signatures (one entry per signature packet in input)
|
||||
* @async
|
||||
* }>} list of signer's keyID and validity of signatures (one entry per signature packet in input)
|
||||
* @private
|
||||
*/
|
||||
export async function createVerificationObjects(signatureList, literalDataList, verificationKeys, date = new Date(), detached = false, config = defaultConfig) {
|
||||
return Promise.all(signatureList.filter(function(signature) {
|
||||
return ['text', 'binary'].includes(enums.read(enums.signature, signature.signatureType));
|
||||
}).map(async function(signature) {
|
||||
return createVerificationObject(signature, literalDataList, verificationKeys, date, detached, config);
|
||||
}));
|
||||
export function createVerificationObjects(signatureList, literalDataList, verificationKeys, date = new Date(), detached = false, config = defaultConfig) {
|
||||
return signatureList
|
||||
.filter(signature => ['text', 'binary'].includes(enums.read(enums.signature, signature.signatureType)))
|
||||
.map(signature => 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 {'utf8'|'binary'|'text'|'mime'} [options.format='utf8' if text is passed, 'binary' otherwise] - Data packet type
|
||||
* @returns {Promise<Message>} New message object.
|
||||
* @async
|
||||
* @async not necessary, but needed to align with readMessage
|
||||
* @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 }) {
|
||||
const input = text !== undefined ? text : binary;
|
||||
if (input === undefined) {
|
||||
|
||||
@ -186,7 +186,7 @@ function zlib(compressionStreamInstantiator, ZlibStreamedConstructor) {
|
||||
|
||||
return new ReadableStream({
|
||||
async start(controller) {
|
||||
zlibStream.ondata = async (value, isLast) => {
|
||||
zlibStream.ondata = (value, isLast) => {
|
||||
controller.enqueue(value);
|
||||
if (isLast) {
|
||||
controller.close();
|
||||
|
||||
@ -194,8 +194,11 @@ class OnePassSignaturePacket {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
OnePassSignaturePacket.prototype.hash = SignaturePacket.prototype.hash;
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
OnePassSignaturePacket.prototype.toHash = SignaturePacket.prototype.toHash;
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
OnePassSignaturePacket.prototype.toSign = SignaturePacket.prototype.toSign;
|
||||
|
||||
export default OnePassSignaturePacket;
|
||||
|
||||
@ -112,7 +112,7 @@ export function supportsStreaming(tag) {
|
||||
*
|
||||
* @param {Uint8Array | ReadableStream<Uint8Array>} input - Input stream as string
|
||||
* @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) {
|
||||
let writer;
|
||||
@ -155,7 +155,7 @@ export async function readPacket(reader, useStreamType, callback) {
|
||||
writer = streamGetWriter(transform.writable);
|
||||
packet = transform.readable;
|
||||
}
|
||||
// eslint-disable-next-line callback-return
|
||||
|
||||
callbackReturned = callback({ tag, packet });
|
||||
} else {
|
||||
packet = [];
|
||||
@ -244,7 +244,7 @@ export async function readPacket(reader, useStreamType, callback) {
|
||||
await writer.close();
|
||||
} else {
|
||||
packet = util.concatUint8Array(packet);
|
||||
// eslint-disable-next-line callback-return
|
||||
|
||||
await callback({ tag, packet });
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@ -26,7 +26,7 @@ export function newPacketFromTag(tag, allowedPackets) {
|
||||
let packetType;
|
||||
try {
|
||||
packetType = enums.read(enums.packet, tag);
|
||||
} catch (e) {
|
||||
} catch {
|
||||
throw new UnknownPacketError(`Unknown packet type with tag: ${tag}`);
|
||||
}
|
||||
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 {function(enums.packet[], boolean, Object): void} [grammarValidator]
|
||||
* @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
|
||||
* @async
|
||||
*/
|
||||
@ -174,7 +174,7 @@ class PacketList extends Array {
|
||||
// in case there's an MDC error, which should take precedence.
|
||||
if (unauthenticatedError) {
|
||||
await reader.readToEnd();
|
||||
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
||||
// eslint-disable-next-line @typescript-eslint/only-throw-error
|
||||
throw unauthenticatedError;
|
||||
}
|
||||
|
||||
|
||||
@ -53,10 +53,11 @@ class PaddingPacket {
|
||||
* Create random padding.
|
||||
* @param {Number} length - The length of padding to be generated.
|
||||
* @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) {
|
||||
this.padding = await getRandomBytes(length);
|
||||
this.padding = getRandomBytes(length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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}
|
||||
* @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 read(bytes, config = defaultConfig) {
|
||||
@ -284,12 +284,14 @@ class PublicKeyPacket {
|
||||
* Alias of read()
|
||||
* @see PublicKeyPacket#read
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
PublicKeyPacket.prototype.readPublicKey = PublicKeyPacket.prototype.read;
|
||||
|
||||
/**
|
||||
* Alias of write()
|
||||
* @see PublicKeyPacket#write
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
PublicKeyPacket.prototype.writePublicKey = PublicKeyPacket.prototype.write;
|
||||
|
||||
export default PublicKeyPacket;
|
||||
|
||||
@ -53,6 +53,7 @@ class PublicKeyEncryptedSessionKeyPacket {
|
||||
this.publicKeyFingerprint = null;
|
||||
|
||||
// For all versions:
|
||||
/** @type {enums.publicKey | null} */
|
||||
this.publicKeyAlgorithm = null;
|
||||
|
||||
this.sessionKey = null;
|
||||
|
||||
@ -35,7 +35,6 @@ class PublicSubkeyPacket extends PublicKeyPacket {
|
||||
* @param {Date} [date] - Creation date
|
||||
* @param {Object} [config] - Full configuration, defaults to openpgp.config
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
||||
constructor(date, config) {
|
||||
super(date, config);
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
this.isEncrypted = null;
|
||||
/**
|
||||
* S2K usage
|
||||
* @type {enums.symmetric}
|
||||
* @type {number}
|
||||
*/
|
||||
this.s2kUsage = 0;
|
||||
/**
|
||||
@ -481,7 +481,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
try {
|
||||
const { privateParams } = parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
|
||||
this.privateParams = privateParams;
|
||||
} catch (err) {
|
||||
} catch {
|
||||
throw new Error('Error reading MPIs');
|
||||
}
|
||||
this.isEncrypted = false;
|
||||
@ -515,7 +515,7 @@ class SecretKeyPacket extends PublicKeyPacket {
|
||||
try {
|
||||
// this can throw if some parameters are undefined
|
||||
validParams = await validateParams(this.algorithm, this.publicParams, this.privateParams);
|
||||
} catch (_) {
|
||||
} catch {
|
||||
validParams = false;
|
||||
}
|
||||
if (!validParams) {
|
||||
|
||||
@ -97,6 +97,7 @@ class SignaturePacket {
|
||||
this.keyFlags = null;
|
||||
this.signersUserID = null;
|
||||
this.reasonForRevocationFlag = null;
|
||||
/** @type {String | null} */
|
||||
this.reasonForRevocationString = null;
|
||||
this.features = null;
|
||||
this.signatureTargetPublicKeyAlgorithm = null;
|
||||
|
||||
@ -321,7 +321,6 @@ export async function runAEAD(packet, fn, key, data) {
|
||||
done = true;
|
||||
}
|
||||
cryptedBytes += chunk.length - tagLengthIfDecrypting;
|
||||
// eslint-disable-next-line @typescript-eslint/no-loop-func
|
||||
latestPromise = latestPromise.then(() => cryptedPromise).then(async crypted => {
|
||||
await writer.ready;
|
||||
await writer.write(crypted);
|
||||
|
||||
18
src/util.js
18
src/util.js
@ -29,8 +29,8 @@ import defaultConfig from './config';
|
||||
|
||||
const debugMode = (() => {
|
||||
try {
|
||||
return process.env.NODE_ENV === 'development'; // eslint-disable-line no-process-env
|
||||
} catch (e) {}
|
||||
return process.env.NODE_ENV === 'development';
|
||||
} catch {}
|
||||
return false;
|
||||
})();
|
||||
|
||||
@ -255,7 +255,7 @@ const util = {
|
||||
*/
|
||||
encodeUTF8: function (str) {
|
||||
const encoder = new TextEncoder('utf-8');
|
||||
// eslint-disable-next-line no-inner-declarations
|
||||
|
||||
function process(value, lastChunk = false) {
|
||||
return encoder.encode(value, { stream: !lastChunk });
|
||||
}
|
||||
@ -269,7 +269,7 @@ const util = {
|
||||
*/
|
||||
decodeUTF8: function (utf8) {
|
||||
const decoder = new TextDecoder('utf-8');
|
||||
// eslint-disable-next-line no-inner-declarations
|
||||
|
||||
function process(value, lastChunk = false) {
|
||||
return decoder.decode(value, { stream: !lastChunk });
|
||||
}
|
||||
@ -606,7 +606,7 @@ const util = {
|
||||
try {
|
||||
error.message += ': ' + cause.message;
|
||||
error.cause = cause;
|
||||
} catch (e) {}
|
||||
} catch {}
|
||||
return error;
|
||||
}
|
||||
return new Error(error + ': ' + cause.message, { cause });
|
||||
@ -638,18 +638,18 @@ const util = {
|
||||
* or rejected with the Error of the last resolved Promise (if all promises are rejected)
|
||||
*/
|
||||
anyPromise: function(promises) {
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
return new Promise(async (resolve, reject) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let exception;
|
||||
await Promise.all(promises.map(async promise => {
|
||||
void Promise.all(promises.map(async promise => {
|
||||
try {
|
||||
resolve(await promise);
|
||||
} catch (e) {
|
||||
exception = e;
|
||||
}
|
||||
}));
|
||||
})).then(() => {
|
||||
reject(exception);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
/* global require */
|
||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||
/* eslint-disable no-console */
|
||||
|
||||
import assert from 'assert';
|
||||
import path from 'path';
|
||||
import { writeFileSync, unlinkSync } from 'fs';
|
||||
@ -105,7 +108,7 @@ class MemoryBenchamrkSuite {
|
||||
* Memory usage tests.
|
||||
* All the necessary variables must be declared inside the test function.
|
||||
*/
|
||||
(async () => {
|
||||
void (async () => {
|
||||
const suite = new MemoryBenchamrkSuite();
|
||||
|
||||
suite.add('empty test (baseline)', () => {});
|
||||
|
||||
@ -23,7 +23,7 @@ const onError = err => {
|
||||
* Time benchmark tests.
|
||||
* 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 { armoredKey, privateKey, publicKey, armoredEncryptedMessage, armoredSignedMessage } = await getTestData();
|
||||
function* largeDataGenerator({ chunk, numberOfChunks }) {
|
||||
|
||||
@ -4,7 +4,7 @@ import BN from 'bn.js';
|
||||
import { bigIntToUint8Array, bitLength, byteLength, gcd, getBit, modExp, modInv } from '../../src/crypto/biginteger';
|
||||
import { getRandomBytes } from '../../src/crypto/random';
|
||||
|
||||
async function getRandomBN(min, max) {
|
||||
function getRandomBN(min, max) {
|
||||
if (max.cmp(min) <= 0) {
|
||||
throw new Error('Illegal parameter value: max <= min');
|
||||
}
|
||||
|
||||
@ -112,6 +112,7 @@ export default () => describe('ECC signatures', function () {
|
||||
});
|
||||
it('Creating KeyPair', function () {
|
||||
if (!config.useEllipticFallback && !util.getNodeCrypto()) {
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
this.skip();
|
||||
}
|
||||
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 () {
|
||||
if (!config.useEllipticFallback && !util.getNodeCrypto()) {
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
this.skip(); // webcrypto does not implement secp256k1: JS fallback tested instead
|
||||
}
|
||||
await expect(verify_signature(
|
||||
@ -249,6 +251,7 @@ export default () => describe('ECC signatures', function () {
|
||||
});
|
||||
it('secp256k1 - Invalid signature', function (done) {
|
||||
if (!config.useEllipticFallback && !util.getNodeCrypto()) {
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
this.skip(); // webcrypto does not implement secp256k1: JS fallback tested instead
|
||||
}
|
||||
expect(verify_signature(
|
||||
|
||||
@ -346,7 +346,7 @@ NJCB6+LWtabSoVIjNVgKwyKqyTLaESNwC2ogZwkdE8qPGiDFEHo4Gg9zuRof
|
||||
`;
|
||||
|
||||
const { type, data } = await openpgp.unarmor(pubKey);
|
||||
const armor = await openpgp.armor(type, data);
|
||||
const armor = openpgp.armor(type, data);
|
||||
expect(
|
||||
armor
|
||||
.replace(/^(Version|Comment): .*$\n/mg, '')
|
||||
|
||||
@ -11,7 +11,7 @@ import * as input from './testInputs.js';
|
||||
|
||||
export default () => (openpgp.config.ci ? describe.skip : describe)('Brainpool Cryptography @lightweight', function () {
|
||||
let rejectCurvesVal;
|
||||
before(function() {
|
||||
before(() => {
|
||||
//only x25519 crypto is fully functional in lightbuild
|
||||
if (!openpgp.config.useEllipticFallback && !util.getNodeCrypto()) {
|
||||
this.skip(); // eslint-disable-line no-invalid-this
|
||||
|
||||
@ -456,7 +456,7 @@ c1HGHD56KA0Mu4eQksKNEugotEyBuWiZCVO+LBrDUFztC1IwXaNPL3bCjYaD
|
||||
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 fnNames = ['generateKey', 'encryptKey', 'decryptKey', 'reformatKey', 'revokeKey', 'sign', 'encrypt', 'verify', 'decrypt', 'generateSessionKey', 'encryptSessionKey', 'decryptSessionKeys'];
|
||||
fnNames.forEach(name => it(`openpgp.${name}`, async function() {
|
||||
|
||||
@ -2272,7 +2272,7 @@ function versionSpecificTests() {
|
||||
expect(selfSignature.features).to.eql([expectedFeatures]);
|
||||
};
|
||||
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(publicKey);
|
||||
});
|
||||
@ -3023,8 +3023,8 @@ export default () => describe('Key', function() {
|
||||
// ssb cv25519 2019-03-20 [E]
|
||||
// E4557C2B02FFBF4B04F87401EC336AF7133D0F85BE7FD09BAEFD9CAEB8C93965
|
||||
const key = await openpgp.readKey({ armoredKey: v5_sample_key, config: { enableParsingV5Entities: true } });
|
||||
expect(await key.keyPacket.getFingerprint()).to.equal('19347bc9872464025f99df3ec2e0000ed9884892e1f7b3ea4c94009159569b54');
|
||||
expect(await key.subkeys[0].getFingerprint()).to.equal('e4557c2b02ffbf4b04f87401ec336af7133d0f85be7fd09baefd9caeb8c93965');
|
||||
expect(key.keyPacket.getFingerprint()).to.equal('19347bc9872464025f99df3ec2e0000ed9884892e1f7b3ea4c94009159569b54');
|
||||
expect(key.subkeys[0].getFingerprint()).to.equal('e4557c2b02ffbf4b04f87401ec336af7133d0f85be7fd09baefd9caeb8c93965');
|
||||
await key.verifyPrimaryKey();
|
||||
});
|
||||
|
||||
@ -3482,7 +3482,7 @@ PzIEeL7UH3trraFmi+Gq8u4kAA==
|
||||
expect(pubKeyV4).to.exist;
|
||||
|
||||
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() {
|
||||
@ -3503,7 +3503,7 @@ PzIEeL7UH3trraFmi+Gq8u4kAA==
|
||||
);
|
||||
|
||||
const subkeyPackets = [packetlist[8], packetlist[11]];
|
||||
const subkeys = await pubKey.getSubkeys();
|
||||
const subkeys = pubKey.getSubkeys();
|
||||
expect(subkeys).to.exist;
|
||||
expect(subkeys).to.have.length(2);
|
||||
expect(subkeys[0].getKeyID().equals(subkeyPackets[0].getKeyID())).to.be.true;
|
||||
|
||||
@ -1116,7 +1116,7 @@ PIQe3UJEj7ReaAd2LBkk3XXkg74zfts7GAGdNtWgXQEAwYQJdVChJFU3LRNh
|
||||
curve: 'curve25519',
|
||||
format: 'object'
|
||||
};
|
||||
return openpgp.generateKey(opt).then(async function({ privateKey: key }) {
|
||||
return openpgp.generateKey(opt).then(({ privateKey: key }) => {
|
||||
expect(key).to.exist;
|
||||
expect(key.getAlgorithmInfo().rsaBits).to.equal(undefined);
|
||||
expect(key.getAlgorithmInfo().algorithm).to.equal('eddsaLegacy');
|
||||
@ -1454,7 +1454,7 @@ VFBLG8uc9IiaKann/DYBAJcZNZHRSfpDoV2pUA5EAEi2MdjxkRysFQnYPRAu
|
||||
describe('decrypt - unit tests', function() {
|
||||
let minRSABitsVal;
|
||||
|
||||
beforeEach(async function() {
|
||||
beforeEach(() => {
|
||||
minRSABitsVal = openpgp.config.minRSABits;
|
||||
openpgp.config.minRSABits = 1024;
|
||||
});
|
||||
@ -1821,7 +1821,7 @@ BdPq
|
||||
describe('verify - unit tests', function() {
|
||||
let minRSABitsVal;
|
||||
|
||||
beforeEach(async function() {
|
||||
beforeEach(() => {
|
||||
minRSABitsVal = openpgp.config.minRSABits;
|
||||
openpgp.config.minRSABits = 512;
|
||||
});
|
||||
@ -4533,7 +4533,7 @@ bsZgJWVlAa5eil6J9ePX2xbo1vVAkLQdzE9+1jL+l7PRIZuVBQ==
|
||||
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 () {
|
||||
// x25519 key (v4) with cast5 as preferred cipher
|
||||
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 () {
|
||||
// X448 key (v4) with cast5 as preferred cipher
|
||||
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 = [
|
||||
keyIDType.fromID('87EAE0977B2185EA'),
|
||||
keyIDType.fromID('F94F9B34AF93FA14'),
|
||||
|
||||
@ -157,7 +157,7 @@ export default () => describe('Packet', function() {
|
||||
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) {
|
||||
const symmetricAlgo = openpgp.enums.symmetric.aes256;
|
||||
const key = random.getRandomBytes(crypto.getCipherParams(symmetricAlgo).keySize);
|
||||
@ -237,7 +237,7 @@ export default () => describe('Packet', function() {
|
||||
cryptStub.onCall(0).callsFake(async function() {
|
||||
cryptCallsActive++;
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/return-await
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
return await crypt.apply(this, arguments);
|
||||
} finally {
|
||||
cryptCallsActive--;
|
||||
@ -249,6 +249,7 @@ export default () => describe('Packet', function() {
|
||||
// Chromium disabled some async WebCrypto operations in v141 .
|
||||
// Context: https://github.com/w3c/webcrypto/issues/389#issuecomment-3136298597 .
|
||||
expect(cryptCallsActive).to.equal(isChromeV141OrAbove() ? 0 : 1);
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
return crypt.apply(this, arguments);
|
||||
});
|
||||
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 = [{
|
||||
// from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.9
|
||||
algoLabel: 'EAX',
|
||||
@ -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 = [{
|
||||
// from https://datatracker.ietf.org/doc/html/rfc9580#appendix-A.9.1
|
||||
algoLabel: 'EAX',
|
||||
@ -1016,8 +1017,7 @@ export default () => describe('Packet', function() {
|
||||
});
|
||||
|
||||
it('Reading signersUserID from armored signature', async function() {
|
||||
const armoredSignature =
|
||||
`-----BEGIN PGP SIGNATURE-----
|
||||
const armoredSignature = `-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQFKBAEBCgA0FiEEdOyNPagqedqiXfEMa6Ve2Dq64bsFAlszXwQWHHRlc3Qtd2tk
|
||||
QG1ldGFjb2RlLmJpegAKCRBrpV7YOrrhuw1PB/9KhFRR/M3OR6NmIent6ri1ekWn
|
||||
@ -1035,8 +1035,7 @@ kePFjAnu9cpynKXu3usf8+FuBw2zLsg1Id1n7ttxoAte416KjBN9lFBt8mcu
|
||||
});
|
||||
|
||||
it('Reading notations from armored key', async function() {
|
||||
const pubkey =
|
||||
`-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
const pubkey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQENBFzQOToBCADd0Pwh8edZ6gR3x49L1PaBPtiAQUr1QDUDWeNes8co5MTFl5hG
|
||||
lHzptt+VD0JGucuIkvi34f5z2ZbInAV/xYDX3kSYefy6LB8XJD527I/o9bqY1P7T
|
||||
@ -1114,7 +1113,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
|
||||
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();
|
||||
packet.version = 5;
|
||||
packet.privateParams = { key: new Uint8Array([1, 2, 3]) };
|
||||
@ -1142,7 +1141,7 @@ V+HOQJQxXJkVRYa3QrFUehiMzTeqqMdgC6ZqJy7+
|
||||
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;
|
||||
openpgp.config.v6Keys = true;
|
||||
|
||||
@ -1378,7 +1377,7 @@ kePFjAnu9cpynKXu3usf8+FuBw2zLsg1Id1n7ttxoAte416KjBN9lFBt8mcu
|
||||
expect(otherPackets[0].constructor.tag).to.equal(openpgp.enums.packet.userID);
|
||||
});
|
||||
|
||||
describe('Grammar validation', async function () {
|
||||
describe('Grammar validation', () => {
|
||||
describe('MessageGrammarValidator - unit tests', () => {
|
||||
it('valid nested signed messages should be valid', () => {
|
||||
// Sig | OPS | Literal | Sig
|
||||
|
||||
@ -706,7 +706,7 @@ hUhMKMuiM3pRwdIyDOItkUWQmjEEw7/XmhgInkXsCw==
|
||||
config: { minRSABits: 1024 }
|
||||
});
|
||||
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());
|
||||
});
|
||||
|
||||
@ -1180,7 +1180,7 @@ Fk7EflUZzngwY4lBzYAfnNBjEjc30xD/ddo+rwE=
|
||||
const sMsg = await openpgp.readMessage({ armoredMessage: signedArmor });
|
||||
const pub_key = await openpgp.readKey({ armoredKey: pub_key_arm2 });
|
||||
const verified = await sMsg.verify([pub_key]);
|
||||
stream.readToEnd(sMsg.getLiteralData());
|
||||
await stream.readToEnd(sMsg.getLiteralData());
|
||||
expect(verified).to.exist;
|
||||
expect(verified).to.have.length(1);
|
||||
expect(await verified[0].verified).to.be.true;
|
||||
@ -1574,7 +1574,7 @@ I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg==
|
||||
const latin1Binary = util.hexToUint8Array('48e46c6cf62057e86c74');
|
||||
const message = await openpgp.createMessage({ binary: latin1Binary });
|
||||
|
||||
message.appendSignature(`-----BEGIN PGP SIGNATURE-----
|
||||
await message.appendSignature(`-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iQIzBAEBCAAdFiEET5+J9VBawdGiYGMc2xGHud1faTsFAl5lE/AACgkQ2xGHud1f
|
||||
aTtIuw//YWrVaXLyP8sGBc0uUSLxQbmfQQYV8Oq8Vsg+jV4orc73wmEy8+Nj5m2g
|
||||
@ -1842,7 +1842,7 @@ hkJiXopCSWKSlQInL1devkJJUWJmTmZeugJYlpdLAagQJM0JpsCqIQZwKgAA
|
||||
const keyIDs = message.getSigningKeyIDs();
|
||||
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(signatures).to.have.length(0);
|
||||
});
|
||||
|
||||
@ -789,7 +789,7 @@ function tests() {
|
||||
|
||||
it('Detached sign small message using curve25519 keys (legacy format)', async function() {
|
||||
const data = new globalThis.ReadableStream({
|
||||
async start(controller) {
|
||||
start(controller) {
|
||||
controller.enqueue(util.stringToUint8Array('hello '));
|
||||
controller.enqueue(util.stringToUint8Array('world'));
|
||||
controller.close();
|
||||
@ -1016,7 +1016,7 @@ export default () => describe('Streaming', function() {
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
|
||||
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 encrypted = await openpgp.encrypt({
|
||||
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() {
|
||||
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 encrypted = await openpgp.encrypt({
|
||||
message: await openpgp.createMessage({ binary: data }),
|
||||
|
||||
@ -84,12 +84,12 @@ async function fakeSignature() {
|
||||
});
|
||||
// read the standalone signature packet
|
||||
const tmp = new SignaturePacket();
|
||||
await tmp.read(STANDALONE_PKT);
|
||||
tmp.read(STANDALONE_PKT);
|
||||
|
||||
// replace the "text" signature with the
|
||||
// "standalone" signature
|
||||
fake.signature.packets[0] = tmp;
|
||||
const faked_armored = await fake.armor();
|
||||
const faked_armored = fake.armor();
|
||||
// re-read the message to eliminate any
|
||||
// behaviour due to cached values.
|
||||
fake = await readCleartextMessage({ cleartextMessage: faked_armored });
|
||||
|
||||
@ -60,7 +60,7 @@ export default () => it('Does not trust subkeys without Primary Key Binding Sign
|
||||
fakeBindingSignature // faked key binding
|
||||
);
|
||||
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({
|
||||
message: await readCleartextMessage({ cleartextMessage: signed }),
|
||||
verificationKeys: fakeKey
|
||||
|
||||
@ -61,7 +61,7 @@ async function makeKeyValid() {
|
||||
encryptionKeys: k
|
||||
});
|
||||
return false;
|
||||
} catch (e) {
|
||||
} catch {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -84,7 +84,7 @@ async function makeKeyValid() {
|
||||
let modifiedkey = new PrivateKey(newlist);
|
||||
// re-read the message to eliminate any
|
||||
// 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(modifiedkey)).to.be.true;
|
||||
|
||||
@ -16,7 +16,7 @@ import {
|
||||
encrypt, decrypt, sign, verify, config, enums,
|
||||
generateSessionKey, encryptSessionKey, decryptSessionKeys,
|
||||
LiteralDataPacket, PacketList, CompressedDataPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, CleartextMessage,
|
||||
WebStream, NodeWebStream,
|
||||
WebStream, NodeWebStream
|
||||
} from 'openpgp';
|
||||
|
||||
(async () => {
|
||||
@ -47,7 +47,7 @@ import {
|
||||
const parsedBinaryPrivateKey: PrivateKey = await readPrivateKey({ binaryKey: privateKeyBinary });
|
||||
expect(parsedBinaryPrivateKey.isPrivate()).to.be.true;
|
||||
// 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;
|
||||
|
||||
// Check PrivateKey type inference
|
||||
@ -55,23 +55,23 @@ import {
|
||||
expect(parsedKey.isDecrypted()).to.be.true;
|
||||
} else {
|
||||
// @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.toPublic().update(privateKey)).isDecrypted();
|
||||
// @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
|
||||
await revokeKey({ key: privateKey });
|
||||
// @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' });
|
||||
expect(revokedPrivateKey).to.be.instanceOf(PrivateKey);
|
||||
expect(revokedPublicKey).to.be.instanceOf(PublicKey);
|
||||
const revokedKeyPair = await revokeKey({ key: publicKey, revocationCertificate, format: 'object' });
|
||||
// @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.publicKey).to.be.instanceOf(PublicKey);
|
||||
|
||||
@ -123,16 +123,16 @@ import {
|
||||
const verifiedCleartextData: string = verificationResult.data;
|
||||
expect(verifiedCleartextData).to.equal(cleartextMessage.getText());
|
||||
// @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 });
|
||||
expect(clearSignedArmor).to.include('-----BEGIN PGP SIGNED MESSAGE-----');
|
||||
const clearSignedObject: CleartextMessage = await sign({ signingKeys: privateKeys, message: cleartextMessage, format: 'object' });
|
||||
expect(clearSignedObject).to.be.instanceOf(CleartextMessage);
|
||||
// @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
|
||||
try { await sign({ signingKeys: parsedKey, message: cleartextMessage }); } catch (e) {}
|
||||
try { await sign({ signingKeys: parsedKey, message: cleartextMessage }); } catch {}
|
||||
|
||||
// Sign text message (armored)
|
||||
const textSignedArmor: string = await sign({ signingKeys: privateKeys, message: textMessage });
|
||||
@ -147,7 +147,10 @@ import {
|
||||
expect(textSignedObject).to.be.instanceOf(Message);
|
||||
|
||||
// Sign text message (armored)
|
||||
const textSignedWithNotations: string = await sign({ signingKeys: privateKeys, message: textMessage, signatureNotations: [{
|
||||
const textSignedWithNotations: string = await sign({
|
||||
signingKeys: privateKeys,
|
||||
message: textMessage,
|
||||
signatureNotations: [{
|
||||
name: 'test@example.org',
|
||||
value: new TextEncoder().encode('test'),
|
||||
humanReadable: true,
|
||||
@ -176,7 +179,7 @@ import {
|
||||
// @ts-expect-error for unsafe downcasting
|
||||
packets.map((packet: LiteralDataPacket) => packet.getText());
|
||||
// @ts-expect-error for non-packet element
|
||||
try { new PacketList().push(1); } catch (e) {}
|
||||
try { new PacketList().push(1); } catch {}
|
||||
|
||||
// Packetlist of specific type
|
||||
const literalPackets = new PacketList<LiteralDataPacket>();
|
||||
@ -215,10 +218,12 @@ import {
|
||||
try {
|
||||
const nodeTextStream = NodeNativeReadableStream.toWeb(createReadStream('non-existent-file', { encoding: 'utf8' }));
|
||||
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>;
|
||||
} catch (err) {}
|
||||
} catch {}
|
||||
const webTextStream = new WebReadableStream<string>();
|
||||
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>;
|
||||
messageFromWebTextStream.getText() as WebStream<string>;
|
||||
messageFromWebTextStream.getLiteralData() as WebStream<Uint8Array>;
|
||||
@ -227,10 +232,12 @@ import {
|
||||
try {
|
||||
const nodeBinaryStream = NodeNativeReadableStream.toWeb(createReadStream('non-existent-file'));
|
||||
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>;
|
||||
} catch (err) {}
|
||||
} catch {}
|
||||
const webBinaryStream = new WebReadableStream<Uint8Array>();
|
||||
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>;
|
||||
messageFromWebBinaryStream.getText() as WebStream<string>;
|
||||
messageFromWebBinaryStream.getLiteralData() as WebStream<Uint8Array>;
|
||||
@ -239,5 +246,6 @@ import {
|
||||
})().catch(e => {
|
||||
console.error('TypeScript definitions tests failed by throwing the following error');
|
||||
console.error(e);
|
||||
// eslint-disable-next-line no-process-exit
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
@ -53,8 +53,8 @@ describe('Unit Tests', function () {
|
||||
if (key && key !== 'grep') {
|
||||
openpgp.config[key] = decodeURIComponent(value);
|
||||
try {
|
||||
openpgp.config[key] = window.eval(openpgp.config[key]); // eslint-disable-line no-eval
|
||||
} catch (e) {}
|
||||
openpgp.config[key] = window.eval(openpgp.config[key]);
|
||||
} catch {}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* globals openpgp */
|
||||
/* globals openpgp, importScripts */
|
||||
|
||||
importScripts('../../dist/openpgp.js');
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user