Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/test-suite/config.json.template
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"id": "sop-openpgpjs-branch",
"path": "__SOP_OPENPGPJS__",
"env": {
"OPENPGPJS_PATH": "__OPENPGPJS_BRANCH__"
"OPENPGPJS_PATH": "__OPENPGPJS_BRANCH__",
"OPENPGPJS_CUSTOM_PROFILES": "{\"generate-key\": { \"post-quantum\": { \"description\": \"generate post-quantum v6 keys (relying on ML-DSA + ML-KEM)\", \"options\": { \"type\": \"pqc\", \"config\": { \"v6Keys\": true } } } } }"
}
},
{
Expand Down
35 changes: 31 additions & 4 deletions openpgp.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,10 @@ interface Config {
showVersion: boolean;
showComment: boolean;
aeadProtect: boolean;
ignoreSEIPDv2FeatureFlag: boolean;
allowUnauthenticatedMessages: boolean;
allowUnauthenticatedStream: boolean;
allowForwardedMessages: boolean;
minRSABits: number;
passwordCollisionCheck: boolean;
ignoreUnsupportedPackets: boolean;
Expand Down Expand Up @@ -702,7 +704,7 @@ export type EllipticCurveName = 'ed25519Legacy' | 'curve25519Legacy' | 'nistP256
interface GenerateKeyOptions {
userIDs: MaybeArray<UserID>;
passphrase?: string;
type?: 'ecc' | 'rsa' | 'curve25519' | 'curve448';
type?: 'ecc' | 'rsa' | 'curve25519' | 'curve448' | 'pqc';
curve?: EllipticCurveName;
rsaBits?: number;
keyExpirationTime?: number;
Expand All @@ -713,8 +715,9 @@ interface GenerateKeyOptions {
}
export type KeyOptions = GenerateKeyOptions;

export interface SubkeyOptions extends Pick<GenerateKeyOptions, 'type' | 'curve' | 'rsaBits' | 'keyExpirationTime' | 'date' | 'config'> {
export interface SubkeyOptions extends Pick<GenerateKeyOptions, 'type' | 'curve' | 'rsaBits' | 'keyExpirationTime' | 'date' | 'config' > {
sign?: boolean;
forwarding?: boolean;
}

export declare class KeyID {
Expand Down Expand Up @@ -822,7 +825,7 @@ export namespace enums {
aeadEncryptedData = 20
}

export type publicKeyNames = 'rsaEncryptSign' | 'rsaEncrypt' | 'rsaSign' | 'elgamal' | 'dsa' | 'ecdh' | 'ecdsa' | 'eddsaLegacy' | 'aedh' | 'aedsa' | 'ed25519' | 'x25519' | 'ed448' | 'x448';
export type publicKeyNames = 'rsaEncryptSign' | 'rsaEncrypt' | 'rsaSign' | 'elgamal' | 'dsa' | 'ecdh' | 'ecdsa' | 'eddsaLegacy' | 'aedh' | 'aedsa' | 'ed25519' | 'x25519' | 'ed448' | 'x448' | 'pqc_mlkem_x25519' | 'pqc_mldsa_ed25519';
export enum publicKey {
rsaEncryptSign = 1,
rsaEncrypt = 2,
Expand All @@ -837,7 +840,9 @@ export namespace enums {
x25519 = 25,
x448 = 26,
ed25519 = 27,
ed448 = 28
ed448 = 28,
pqc_mlkem_x25519 = 105,
pqc_mldsa_ed25519 = 107
}

export enum curve {
Expand Down Expand Up @@ -891,6 +896,7 @@ export namespace enums {
encryptStorage = 8,
splitPrivateKey = 16,
authentication = 32,
forwardedCommunication = 64,
sharedPrivateKey = 128
}

Expand Down Expand Up @@ -937,3 +943,24 @@ export namespace enums {
gnu = 101
}
}

export declare class Argon2S2K {
static reloadWasmModule(): void;
static ARGON2_WASM_MEMORY_THRESHOLD_RELOAD: number;
constructor(config: Config);
salt: Uint8Array;
/** @throws Argon2OutOfMemoryError */
produceKey(passphrase: string, keySize: number): Promise<Uint8Array>;
}

interface KDFParamsData {
version: number;
hash: enums.hash;
cipher: enums.symmetric;
replacementFingerprint?: Uint8Array;
}

export class KDFParams {
constructor(data: KDFParamsData);
write(forReplacementParams?: boolean): Uint8Array;
}
62 changes: 52 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "openpgp",
"name": "@protontech/openpgp",
"description": "OpenPGP.js is a Javascript implementation of the OpenPGP protocol. This is defined in RFC 4880.",
"version": "6.1.0",
"license": "LGPL-3.0+",
Expand Down Expand Up @@ -63,8 +63,10 @@
},
"devDependencies": {
"@noble/ciphers": "^1.0.0",
"@noble/curves": "^1.6.0",
"@noble/curves": "^1.7.0",
"@noble/ed25519": "^1.7.3",
"@noble/hashes": "^1.5.0",
"@noble/post-quantum": "^0.4.0",
"@openpgp/jsdoc": "^3.6.11",
"@openpgp/seek-bzip": "^1.0.5-git",
"@openpgp/tweetnacl": "^1.0.4-1",
Expand Down Expand Up @@ -114,6 +116,6 @@
},
"repository": {
"type": "git",
"url": "https://github.com/openpgpjs/openpgpjs"
"url": "https://github.com/ProtonMail/openpgpjs"
}
}
31 changes: 26 additions & 5 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ const nodeBuild = {
input: 'src/index.js',
external: nodeBuiltinModules.concat(nodeDependencies),
output: [
{ file: 'dist/node/openpgp.cjs', format: 'cjs', name: pkg.name, banner, intro },
{ file: 'dist/node/openpgp.min.cjs', format: 'cjs', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true },
{ file: 'dist/node/openpgp.cjs', format: 'cjs', name: 'openpgp', banner, intro },
{ file: 'dist/node/openpgp.min.cjs', format: 'cjs', name: 'openpgp', banner, intro, plugins: [terser(terserOptions)], sourcemap: true },
{ file: 'dist/node/openpgp.mjs', format: 'es', banner, intro },
{ file: 'dist/node/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true }
].map(options => ({ ...options, inlineDynamicImports: true })),
Expand All @@ -85,8 +85,8 @@ const fullBrowserBuild = {
input: 'src/index.js',
external: nodeBuiltinModules.concat(nodeDependencies),
output: [
{ file: 'dist/openpgp.js', format: 'iife', name: pkg.name, banner, intro },
{ file: 'dist/openpgp.min.js', format: 'iife', name: pkg.name, banner, intro, plugins: [terser(terserOptions)], sourcemap: true },
{ file: 'dist/openpgp.js', format: 'iife', name: 'openpgp', banner, intro },
{ file: 'dist/openpgp.min.js', format: 'iife', name: 'openpgp', banner, intro, plugins: [terser(terserOptions)], sourcemap: true },
{ file: 'dist/openpgp.mjs', format: 'es', banner, intro },
{ file: 'dist/openpgp.min.mjs', format: 'es', banner, intro, plugins: [terser(terserOptions)], sourcemap: true }
].map(options => ({ ...options, inlineDynamicImports: true })),
Expand All @@ -100,6 +100,13 @@ const fullBrowserBuild = {
commonjs({
ignore: nodeBuiltinModules.concat(nodeDependencies)
}),
replace({
include: 'node_modules/@noble/ed25519/**',
// Rollup ignores the `browser: { crypto: false }` directive in package.json, since `exports` are present,
// hence we need to manually drop it.
"import * as nodeCrypto from 'crypto'": 'const nodeCrypto = null',
delimiters: ['', '']
}),
replace({
'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`,
"import { createRequire } from 'module';": 'const createRequire = () => () => {}',
Expand Down Expand Up @@ -127,6 +134,13 @@ const lightweightBrowserBuild = {
commonjs({
ignore: nodeBuiltinModules.concat(nodeDependencies)
}),
replace({
include: 'node_modules/@noble/ed25519/**',
// Rollup ignores the `browser: { crypto: false }` directive in package.json, since `exports` are present,
// hence we need to manually drop it.
"import * as nodeCrypto from 'crypto'": 'const nodeCrypto = null',
delimiters: ['', '']
}),
replace({
'OpenPGP.js VERSION': `OpenPGP.js ${pkg.version}`,
"import { createRequire } from 'module';": 'const createRequire = () => () => {}',
Expand All @@ -145,7 +159,7 @@ const testBuild = {
plugins: [
alias({
entries: {
openpgp: `./dist/${process.env.npm_config_lightweight ? 'lightweight/' : ''}openpgp.mjs`
'@protontech/openpgp': `./dist/${process.env.npm_config_lightweight ? 'lightweight/' : ''}openpgp.mjs`
}
}),
resolve({
Expand All @@ -158,6 +172,13 @@ const testBuild = {
ignore: nodeBuiltinModules.concat(nodeDependencies),
requireReturnsDefault: 'preferred'
}),
replace({
include: 'node_modules/@noble/ed25519/**',
// Rollup ignores the `browser: { crypto: false }` directive in package.json, since `exports` are present,
// hence we need to manually drop it.
"import * as nodeCrypto from 'crypto'": 'const nodeCrypto = null',
delimiters: ['', '']
}),
replace({
"import { createRequire } from 'module';": 'const createRequire = () => () => {}',
delimiters: ['', '']
Expand Down
15 changes: 15 additions & 0 deletions src/config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ export default {
* @property {Boolean} aeadProtect
*/
aeadProtect: false,
/**
* Whether to disable encrypton using SEIPDv2 even if the encryption keys include the SEIPDv2 feature flag.
* If true, SEIPDv1 (i.e. no AEAD) packets are always used instead.
* SEIPDv2 is a more secure and faster choice, but it is not necessarily compatible with other libs and our mobile apps.
* @memberof module:config
* @property {Boolean} ignoreSEIPDv2FeatureFlag
*/
ignoreSEIPDv2FeatureFlag: false,
/**
* When reading OpenPGP v4 private keys (e.g. those generated in OpenPGP.js when not setting `config.v5Keys = true`)
* which were encrypted by OpenPGP.js v5 (or older) using `config.aeadProtect = true`,
Expand Down Expand Up @@ -149,6 +157,13 @@ export default {
* @property {Boolean} allowUnauthenticatedStream
*/
allowUnauthenticatedStream: false,
/**
* Allow decrypting forwarded messages, using keys with 0x40 ('forwarded communication') flag.
* Note: this is related to a **non-standard feature**.
* @memberof module:config
* @property {Boolean} allowForwardedMessages
*/
allowForwardedMessages: false,
/**
* Minimum RSA key size allowed for key generation and message signing, verification and encryption.
* The default is 2047 since due to a bug, previous versions of OpenPGP.js could generate 2047-bit keys instead of 2048-bit ones.
Expand Down
Loading