The Babel plugin `@babel/plugin-transform-regenerator` used in the web-app Jest tests
(as part of @babel/preset-env) introduces a bug when transforming this specific minified
lightweight built.
The issue is that the mangled `ArrayStream` class name (`n` in the specific case) gets wrongly
reused and shadowed by a local variable in the `readPacket` function.
As a workaround for the problem, and to not have to amend the babel config for each monorepo workspace,
we disable mangling the specific class name.
Implements Draft 6
(https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/06/).
Also, chunk ML-KEM and ML-DSA together in lightweight bundle.
Noble-curves had to be updated to v1.7.0 to ensure the same
version of noble-hashes is used as noble-post-quantum,
making it possible to reuse the sha3 code/chunk across libs.
Much faster than tweetnacl, and no constant-timeness required.
We are not using v2 for now, despite being smaller, because it relies on
bigint literals, and it requires polyfilling the WebCrypto lib
manually in Node < 19.
SEIPDv2 is a more secure and faster choice, but it is
not necessarily compatible with other libs and our mobile apps.
Co-authored-by: Daniel Huigens <d.huigens@protonmail.com>
These subkeys must not have the standard encryption flags (EtEr) set,
as they are not supposed to be used for direct messages.
Also:
- preserve 'forwarded communication' key flag when reformatting
- fix bug allowing to decrypt forwarded messages by setting
`config.allowInsecureDecryptionWithSigningKeys` instead of
`config.allowForwardedMessages`
- add TS definition for `config.allowForwardedMessages`
To enable stored messages to be protected using symmetric key encryption and validated
using message authentication codes, this set of changes adds support for storing
symmetric key material as Secret Key Packets, symmetric key encrypted session keys as
Public Key Encrypted Session Key Packets, and MAC tags as Signature Packets.
Co-authored-by: Konstantinos Andrikopoulos <kandrikopoulos@proton.ch>
Co-authored-by: Daniel Huigens <d.huigens@protonmail.com>
To avoid issues with the lightweight build:
for now it works fine, but it could mess up chunking in the future,
and it already results in a circular import.
The existing md5 module brought in the util module,
which messed up the chunking structure in the lightweight build;
inlining those functions is an option, but the noble-hashes code
is also more modern and readable.
Every submodule under the 'crypto' directory was exported-imported
even if a handful of functions where actually needed.
We now only export entire modules behind default exports if it makes
sense for readability and if the different submodules would be
imported together anyway (e.g. `cipherMode` exports are all needed
by the SEIPD class).
We've also dropped exports that are not used outside of the crypto modules,
e.g. pkcs5 helpers.
This adds back support for decrypting password-protected messages which
were encrypted in OpenPGP.js v5 with custom config settings
`config.aeadProtect = true` together with
`config.preferredAEADAlgorithm = openpgp.enums.aead.experimentalGCM`.
Public-key-encrypted messages are affected if they were encrypted using the same config, while also providing `encryptionKeys` that declared `experimentalGCM` in their AEAD prefs.
Such keys could be generated in OpenPGP.js v5 by setting the aforementioned config values.
`experimentalGCM` should not be used anymore,
as a different a different algorithm ID was standardized
for GCM, and using the experimental value could give
interoperability issues with e.g. SEIPDv2 and AEAD-encrypted keys.
We could also drop the browser's directive `"./dist/node/openpgp.min.cjs": "./dist/openpgp.min.js"`,
since that build cannot be used with `require()`, and it's instead meant
to be the target of <script> tags.
But we keep it around for now to avoid potentially breaking changes, in case it's
used in some setups.
The `expect().to.not.throw` check as written is a no-op.
In fact, `throw` should have been called as a function.
We drop the relevant check altogether since if the wrapped
operation throws, the test will naturally fail due to the
unexpected error.
This affects the preferences of newly generated keys, which by default will
have SHA512 as first hash algo preference.
SHA512 will also be used when signing, as long as the recipient keys declare
support for the algorithm.
If given, the signature will be generated using the preferred hash algo from the recipient keys.
Otherwise, the signing key preferences are used (this was also the existing behavior).
Note: when signing through `openpgp.encrypt`, the `encryptionKeys` are automatically used as recipient keys.
In `openpgp.sign`, the signing key preferences are considered instead,
since no "recipient keys" are available.
The hash algo selection logic has been reworked as follows:
if `config.preferredHashAlgo` appears in the prefs of all recipients, we pick it;
otherwise, we use the strongest supported algo (note: SHA256 is always implicitly supported by all keys),
as long as it is compatible with the signing key (e.g. ECC keys require minimum digest sizes).
Previously, only the preferences of the signing key were used to determine the hash algo to use,
but this is in contrast to the RFC: https://www.rfc-editor.org/rfc/rfc9580.html#section-5.2.3.16-2 .
Also, an algo stronger than `config.preferredHashAlgo` would be used, if the signing key
declared it as first preference.
With this change, `config.preferredHashAlgo` is picked even if it's weaker than the
preferences of the recipient keys.