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