Commit Graph

35 Commits

Author SHA1 Message Date
Daniel Huigens
71fef439ed
Add support for creating critical signature subpackets (#1599)
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.
2023-02-17 12:21:03 +01:00
Daniel Huigens
809deee3a6 Add signatureNotations option to sign and encrypt
This allows adding Notation Data signature subpackets when signing or
encrypting a message.
2023-02-15 19:42:45 +01:00
larabr
ef066183dd
Throw UnsupportedError on unknown algorithm in keys, signatures and encrypted session keys (#1523)
The relevant packets will be considered unsupported instead of malformed.
Hence, parsing them will succeed by default (based on
`config.ignoreUnsupportedPackets`).
2022-06-07 13:51:58 +02:00
larabr
6da1c53de7
Replace strings with integer algorithm identifiers in packet classes (#1410)
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`
2021-11-22 11:51:27 +01:00
larabr
3fa778abe2
Add config.rejectCurves and prevent generating keys using blacklisted algorithms (#1395)
Breaking changes:
- throw error on key generation if the requested public key algorithm is
included in `config.rejectPublicKeyAlgorithms`;
- add `config.rejectCurves` to blacklist a set of ECC curves, to prevent keys
using those curves from being generated, or being used to
encrypt/decrypt/sign/verify messages.
By default, `config.rejectCurves` includes the brainpool curves
(`brainpoolP256r1`, `brainpoolP384r1`, `brainpoolP512r1`) and the Bitcoin curve
(`secp256k1`). This is because it's unclear whether these curves will be
standardised[1], and we prefer to blacklist them already, rather than introduce
a breaking change after release.

[1] https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/47#note_634199141
2021-08-19 17:58:16 +02:00
larabr
619d02d78c
Drop capabilities, keyID args in Key.getExpirationTime() and consider direct-key sigs (#1319)
- 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)`
2021-06-15 19:16:52 +02:00
larabr
1166de205c
Remove primaryKey argument from User methods, rename User.sign to User.certify (#1329)
- Add `User.mainKey` field to store a reference to the corresponding `Key`,
allowing to simplify calling some `User` methods.
- Rename `User.sign` to `User.certify`, since it's used for third-party
certifications and not as a counterpart of `User.verify`, which deals with
self-signatures.
- Change `Key.update` behaviour to store a copy of newly added users and
subkeys. Pointing to the same instance could give issues as the lists of
certifications and signatures could be altered by both the source key and the
updated one.

Breaking changes in `User` methods:
- `User.constructor(userPacket)` -> `constructor(userPacket, mainKey)`
- `User.sign(primaryKey, signingKeys, date, config)` -> `.certify(signingKeys,
date, config)`
- `User.verify(primaryKey, date = new Date(), config)` -> `.verify(date = new
Date(), config)`
- `User.verifyCertificate(primaryKey, certificate, verificationKeys, date = new
Date(), config)` -> `.verifyCertificate(certificate, verificationKeys, date =
new Date(), config)`
- `User.verifyAllCertifications(primaryKey, verificationKeys, date = new
Date(), config)` -> `.verifyAllCertifications(verificationKeys, date = new
Date(), config)`
- `User.isRevoked(primaryKey, certificate, keyPacket, date = new Date(),
config)` -> `.isRevoked(certificate, keyPacket, date = new Date(), config)`
- `User.update(sourceUser, primaryKey, date, config)` -> `.update(sourceUser,
date, config)`
2021-06-15 17:42:00 +02:00
larabr
e785df4c8f
Require keys in openpgp.sign and make all top-level functions fully async (#1318)
- `openpgp.sign` throws if no signing keys are given, instead of returning a
non-signed literal packet.
- Any top-level function error will cause Promise rejection, and can thus be
handled with `.catch()`.
2021-06-15 17:21:18 +02:00
Daniel Huigens
df2240ba08
CI: Check that JSDoc comments are valid (#1328)
Also, fix a JSDoc comment.
2021-06-14 11:15:37 +02:00
larabr
0e088aec28
Fix various signature verification issues (#1302)
- 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)`
2021-06-08 18:12:48 +02:00
larabr
02a1ed2d78
Make key fingerprint computation async (#1297)
- Make fingerprint and key ID computation async, and rely on Web Crypto
  for hashing if available
- Always set fingerprint and keyID on key parsing / generation
- Introduce `*KeyPacket.computeFingerprint()` and
  `*KeyPacket.computeFingerprintAndKeyID()` 
- Change `getKeyID` and `getFingerprint*` functions to return the
  pre-computed key ID and fingerprint, respectively
- Make `PublicKeyPacket.read` async
2021-05-05 17:39:19 +02:00
Daniel Huigens
e3cfa4f9dd Revert "Don't mark async function as returning a Promise explicitly"
This reverts commit 9e85f75519.

It made VS Code / TypeScript complain about unnecessary `await`s.
2021-03-28 15:39:19 +02:00
Daniel Huigens
06aef92752 Remove internal streaming parameters 2021-03-25 19:23:58 +01:00
larabr
6cff19c44a
Use consistent name casing (#1268)
- 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`.
2021-03-25 19:56:59 +01:00
larabr
8a57246ec4
Add config.rejectPublicKeyAlgorithms (#1264)
- 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.
2021-03-25 15:08:49 +01:00
larabr
43fb58404d
Simplify algorithm preference selection and normalize config names (#1262)
- Rename `config.compression` to `config.preferredCompressionAlgorithm`
- Rename `config.encryptionCipher` to `config.preferredSymmetricAlgorithm`
- Rename `config.preferHashAlgorithm` to `config.preferredHashAlgorithm`
- Rename `config.aeadMode` to `config.preferredAeadAlgorithm`
- When encrypting to public keys, the compression/aead/symmetric algorithm is selected by:
  - taking the preferred algorithm specified in config, if it is supported by all recipients
  - otherwise, taking the "MUST implement" algorithm specified by rfc4880bis
- When encrypting to passphrases only (no public keys), the preferred algorithms from `config` are always used
- EdDSA signing with a hash algorithm weaker than sha256 is explicitly disallowed (https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2)
2021-03-10 18:06:03 +01:00
Daniel Huigens
9e85f75519 Don't mark async function as returning a Promise explicitly
It seems redundant.
2021-02-28 01:47:48 +01:00
Daniel Huigens
21e3ba4653 Clean up JSDocs 2021-02-28 00:32:02 +01:00
Daniel Huigens
e2eadd09e4 Fix documentation of top-level function parameters 2021-02-27 23:37:41 +01:00
Daniel Huigens
636c7cf529 Update documentation 2021-02-27 01:22:13 +01:00
larabr
7f37a8aaca
Add config parameter to top-level functions (#1241)
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
2021-02-26 20:04:54 +01:00
larabr
66c06dab3e Check if any (sub)key is decrypted in Key.prototype.isDecrypted (#1182)
`key.isDecrypted()` now returns true if either the primary key or any subkey
is decrypted.

Additionally, implement `SecretKeyPacket.prototype.makeDummy` for encrypted
keys.
2021-02-09 19:25:20 +01:00
larabr
724775816f Add explicit key type parameter in openpgp.generateKey (#1179)
- Changes `openpgp.generateKey` to accept an explicit `type` parameter,
  instead of inferring its value from the `curve` or `rsaBits` params
- Introduces `config.minRsaBits` to set minimum key size of RSA key generation
2021-02-09 19:25:20 +01:00
larabr
2ee36c2984 Drop inconsistent boolean returns and fix type definitions (#1191)
- 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
2021-02-09 19:25:20 +01:00
Dan Ristea
331a0c27a9 Store named signature parameters (#1158)
Also, remove the now-unnecessary MPI type.
2021-02-09 19:25:20 +01:00
larabr
3a75eadaa0 Store named key params in key objects (#1141)
- 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
2021-02-09 19:25:20 +01:00
Daniel Huigens
fb3d23427d Allow dead code elimination 2021-02-09 19:25:20 +01:00
Ilya Chesnokov
6e648b1cbc Rename enums to use camelCase (#1093) 2021-02-09 19:25:20 +01:00
Ilya Chesnokov
d415bc2546 Rename config option names to camelCase (#1088) 2021-02-09 19:25:20 +01:00
larabr
2eab8a1ebc
Add config option to allow insecure decryption with RSA signing keys (#1148) 2020-08-28 16:09:56 +02:00
larabr
cc1bdcbae8
Allow decryption with revoked keys (#1135)
However, when decrypting session keys, check that the public key
algorithm matches that of the decryption key.
2020-08-18 15:49:27 +02:00
Daniel Huigens
8c3bcd1f21 Reject signatures using insecure hash algorithms
Also, switch from returning false to throwing errors in most verify*()
functions, as well as in `await signatures[*].verified`, in order to be
able to show more informative error messages.
2020-02-25 15:06:15 +01:00
Alexandre Perrin
0a32f4d5e7 Comment typo fixes (#1022) 2019-12-27 12:47:37 +01:00
Daniel Huigens
3d75efc1dc
Only throw on authorized revocation key when verifying self-signatures (#1017)
This also has the effect that we only throw on them when trying to use
the key, instead of when parsing it, and that we don't throw when the
authorized revocation key is specified in a separate direct-key
signature instead of a User ID self-signature (the spec only specifies
including it in a direct-key signature, so that means that we
effectively don't reject them anymore. This is because users that
wanted to use the key, could remove this separate signature, anyway.)
2019-12-20 17:21:35 +01:00
Ilya Chesnokov
114184c6f2 Split up key.js (#972) 2019-10-15 18:42:14 +02:00