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.
Parsing of v5 keys, v5 signatures and AEAD-encrypted data packets now requires turning on
the corresponding config flag.
The affected entities are non-standard, and in the crypto-refresh RFC they have been superseded by
v6 keys, v6 signatures and SEIPDv2 encrypted data, respectively.
However, generation of v5 entities was supported behind config flag in OpenPGP.js v5, and some other libraries,
hence parsing them might be necessary in some cases.
EdDSA is known to be vulnerable to fault attacks which can lead to secret key
extraction if two signatures over the same data can be collected. Randomly
occurring bitflips in specific parts of the computation might in principle
result in vulnerable faulty signatures being generated.
To protect signatures generated using v4 and v5 keys from this possibility, we
randomise each signature by adding a custom notation with a random value,
functioning as a salt.
For simplicity, we add the salt to all algos, not just EdDSA, as it may also
serve as protection in case of weaknesses in the hash algo, potentially
hindering e.g. some chosen-prefix attacks.
v6 signatures do not need to rely on this, as they are non-deterministic by
design.
While this notation solution is interoperable, it will reveal that the
signature has been generated using OpenPGP.js, which may not be desirable in
some cases.
For this reason, the option `config.nonDeterministicSignaturesViaNotation`
(defaulting to true) has been added to turn off the feature.
Introduces v6 one-pass signature packets required for v6 signatures.
Includes the changes from !305 of the crypto refresh:
https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/305
Also, introduce `OnePassSignaturePacket.fromSignaturePacket` to simplify
OPS generation.
This subpacket replaces both symmetric algorithm preferences and
AEAD algorithm preferences when AEAD is supported, by providing
sets of preferred symmetric and AEAD algorithm pairs.
We still keep the symmetric algorithm preferences in case AEAD is
not supported.
Assign most signature subpacket types a criticality based on whether
failing to interpret their meaning would negatively impact security.
For Notation Data subpackets, let the user indicate their criticality
using the `signatureNotations[*].critical` property.
Move the Issuer, Issuer Fingerprint, and Embedded Signature subpackets
to the hashed subpackets for new signatures. While we allow these to be
unhashed, it's safer to hash them, and this simplifies the code as well.
When re-serializing a signature packet, don't add Issuer, Issuer
Fingerprint, and Embedded Signature subpackets to the unhashed
subpackets if they weren't already there.
Also, store all unhashed subpackets in `signature.unhashedSubpackets`,
not just the "disallowed" ones.
In several packet classes, we used to store string identifiers for public-key,
aead, cipher or hash algorithms. To make the code consistent and to avoid
having to convert to/from string values, we now always store integer values
instead, e.g. `enums.symmetric.aes128` is used instead of `'aes128'`.
This is not expected to be a breaking change for most library users. Note that
the type of `Key.getAlgorithmInfo()` and of the session key objects returned
and accepted by top-level functions remain unchanged.
Affected classes (type changes for some properties and method's arguments):
- `PublicKeyPacket`, `PublicSubkeyPacket`, `SecretKeyPacket`,
`SecretSubkeyPacket`
- `SymEncryptedIntegrityProtectedDataPacket`, `AEADEncryptedDataPacket`,
`SymmetricallyEncryptedDataPacket`
- `LiteralDataPacket`, `CompressedDataPacket`
- `PublicKeyEncryptedSessionKey`, `SymEncryptedSessionKeyPacket`
- `SignaturePacket`
Other potentially breaking changes:
- Removed property `AEADEncryptedDataPacket.aeadAlgo`, since it was redudant
given `.aeadAlgorithm`.
- Renamed `AEADEncryptedDataPacket.cipherAlgo` -> `.cipherAlgorithm`
- Fix#1159: `Key.verifyPrimaryKey` considers expiration time subpackets in
direct-key signatures to determine whether the key is expired.
- `Key.getExpirationTime()` does not take the `capabilities` and `keyID` arguments
anymore, and simply returns the expiration date of the primary key. Also, like
for `verifyPrimaryKey`, direct-key signatures are now taken into account.
- Keys and signatures are considered expired at the time of expiry, instead of
one second later.
Breaking change:
`Key.getExpirationTime(capabilities, keyID, userID, config)` ->
`.getExpirationTime(userID, config)`
- Throw on signature parsing (e.g. in `openpgp.readSignature`) if the
creation time subpacket is missing
- `SignaturePacket.verify` now directly checks for signature creation
and expiration times. This makes it easier to thoroughly check the
validity of signatures. Also:
- `openpgp.revokeKey` now takes a `date` to check the provided
revocation certificate
- `openpgp.decryptSessionKeys` now takes a `date` to check the
validity of the provided private keys
- whenever a `date` is used internally, the function accepts a
`date` param to allow passing the correct date
- Add tests for all of the above
- Like `openpgp.generateKey`, `openpgp.reformatKey` now also requires
`options.userIDs`
- Simplify calling `SubKey.isRevoked/update/getExpirationTime` by
adding the `SubKey.mainKey` field to hold the reference of the
corresponding `Key`
Breaking changes in low-level functions:
- Added/removed `date` params:
- `Key.update(key, config)` -> `update(key, date, config)`
- `Key.applyRevocationCertificate(revocationCertificate, config)` ->
`applyRevocationCertificate(revocationCertificate, date, config)`
- `Key.signAllUsers(privateKeys, config)` ->
`signAllUsers(privateKeys, date, config)`
- `Key.verifyAllUsers(keys, config)` ->
`verifyAllUsers(keys, date, config)`
- `new SignaturePacket(date)` -> `new SignaturePacket()`
- `SignaturePacket.sign(key, data, detached)` ->
`sign(key, data, date, detached)`
- `Message.sign(primaryKey, privateKeys, config)` ->
`sign(primaryKey, privateKeys, date, config)`
- `Message.decrypt(privateKeys, passwords, sessionKeys, config)` ->
`decrypt(privateKeys, passwords, sessionKeys, date, config)`
- `Message.decryptSessionKeys(privateKeys, passwords, config)` ->
`decryptSessionKeys(privateKeys, passwords, date, config)`
- Removed `primaryKey` params:
- `SubKey.isRevoked(primaryKey, signature, key, date, config)` ->
`isRevoked(signature, key, date, config)`
- `SubKey.update(subKey, primaryKey, date, config)` ->
`update(subKey, date, config)`
- `SubKey.getExpirationTime(primaryKey, date, config)` ->
`getExpirationTime(date, config)`
Don't ignore parse errors if `config.tolerant` is enabled. This leads to
more useful error messages in most cases, as ignoring these errors will
most likely still lead to an error down the line (e.g. if a key binding
signature is missing). Unsupported and unknown packets and packets with
an unsupported or unknown version are still ignored, for forward
compatibility.
Also, make `PKESK.encrypt`/`decrypt` void.
- Use PascalCase for classes, with uppercase acronyms.
- Use camelCase for function and variables. First word/acronym is always
lowercase, otherwise acronyms are uppercase.
Also, make the packet classes' `tag` properties `static`.
- Add `config.rejectPublicKeyAlgorithms` to disallow using the given algorithms
to verify, sign or encrypt new messages or third-party certifications.
- Consider `config.minRsaBits` when signing, verifying and encrypting messages
and third-party certifications, not just on key generation.
- When verifying a message, if the verification key is not found (i.e. not
provided or too weak), the corresponding `signature` will have
`signature.valid=false` (used to be `signature.valid=null`).
`signature.error` will detail whether the key is missing/too weak/etc.
Generating and verifying key certification signatures is still permitted in all cases.
Refactor functions to take the configuration as a parameter.
This allows setting a config option for a single function call, whereas
setting `openpgp.config` could lead to concurrency-related issues when
multiple async function calls are made at the same time.
`openpgp.config` is used as default for unset config values in top-level
functions.
`openpgp.config` is used as default config object in low-level functions
(i.e., when calling a low-level function, it may be required to pass
`{ ...openpgp.config, modifiedConfig: modifiedValue }`).
Also,
- remove `config.rsaBlinding`: blinding is now always applied to RSA decryption
- remove `config.debug`: debugging mode can be enabled by setting
`process.env.NODE_ENV = 'development'`
- remove `config.useNative`: native crypto is always used when available
- Remove the boolean return value of various internal functions that throw on
error (the returned value was unused in most cases)
- Update and fix type definitions
- Store private and public params separately and by name in objects,
instead of as an array
- Do not keep params in MPI form, but convert them to Uint8Arrays when
generating/parsing the key
- Modify low-level crypto functions to always accept and return
Uint8Arrays instead of BigIntegers
- Move PKCS1 padding to lower level functions
This change adds support for binary (non-human-readable) values in
signature notations through `rawNotations` property on signature objects.
Human-readable notations will additionally appear in `notations` object
where the value of the notation will be deserialized into a string.
Additionally the check for human-readable flag was modified to check the
existence of the flag instead of comparison with the whole value.