Commit Graph

477 Commits

Author SHA1 Message Date
larabr
4b6189b91b
Rename config.tolerant to config.ignoreUnsupportedPackets, add config.ignoreMalformedPackets (#1386)
Configuration options related to parsing have been changed to make it possible
to try to read messages containing malformed packets. Changes:
- rename `config.tolerant` to `config.ignoreUnsupportedPackets`. This still
defaults to `true`.
- Add `config.ignoreMalformedPackets` to ignore packets that fail to parse
(when possible). This option was not available before and it defaults to `false`.
2021-07-23 13:22:18 +02:00
larabr
ab22fe86da
Lint: enforce single quotes and do not error on class methods without this (#1341) 2021-06-24 22:58:15 +02:00
larabr
b76236755a
Ignore Trust and Marker packets on parsing and always throw on unexpected packets (#1340)
- When parsing, throw on unexpected packets even if `config.tolerant = true`
(e.g. if a Public Key packet is found when reading a signature).
- Always ignore Trust and Marker packets on parsing.
- Fix #1145: correctly verify signatures that include Marker packets when
`config.tolerant = false`.
2021-06-23 12:17:29 +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
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
Daniel Huigens
1836c40468 Fix JSDoc type 2021-05-28 17:34:59 +02:00
larabr
f028026217
Replace Key with PrivateKey and PublicKey classes (#1300)
- Add `PrivateKey` and `PublicKey` classes. A `PrivateKey` can always
  be passed where a `PublicKey` key is expected, but not vice versa.
- Unexport `Key`, and export `PrivateKey` and `PublicKey`. 
- Rename `Key.packetlist2structure` to `Key.packetListToStructure`.
- Change `Key.update` to return a new updated key, rather than
  modifying the destination one in place.
- Add `openpgp.readPrivateKey` and `openpgp.readPrivateKeys` to avoid
  having to downcast the result of `readKey(s)` in TypeScript.
2021-05-25 19:18:47 +02:00
larabr
31fe960261
Only ignore unsupported packets when config.tolerant is set (#1298)
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.
2021-05-05 19:51:33 +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
larabr
247ad58344
Add PacketList.fromBinary and add missing config param in some functions (#1294)
- Add `PacketList.fromBinary` which parses binary data and returns a
  `PacketList`. Using it instead of `PacketList.read` avoids being left
  with partially read data in case of errors.
- Rename `toPacketlist` to `toPacketList` in `Key`, `Subkey` and `User`
  classes
- In `readMessage`, pass down `config` to `PacketList.read`
- Add `config` param to `CompressedDataPacket.decompress`,
  `AEADEncryptedDataPacket.decrypt` and `Message.appendSignature`
2021-05-05 16:56:11 +02:00
larabr
aeddac438e
Make PacketList a valid subtype of Array and update Packet.tag types (#1289)
Changes:
- Implementation:
  - Remove `PacketList.prototype.concat` and `push`
    (we solely rely on `Array.push` instead)
  - Fix https://github.com/openpgpjs/openpgpjs/issues/907 by
    correctly handling result of `filterByTag`
  - Implement `write()` method for `Trust` and `Marker` packets,
    to make them compatible with the `BasePacket` interface
- Types:
  - Simplify and updated `PacketList` type definitions
  - Fix types for `Packet.tag`, which is `static` since
    https://github.com/openpgpjs/openpgpjs/pull/1268
  - Prevent passing SubkeyPackets where KeyPackets are expected,
    and vice versa
2021-04-29 17:18:39 +02:00
larabr
0654bbe505
Remove Key.prototype.encrypt() and Key.prototype.decrypt() (#1285)
To encrypt/decrypt a key, the top-level functions `openpgp.encryptKey` and
`openpgp.decryptKey` should be used instead: these don't mutate the key;
instead, they either return a new encrypted/decrypted key object or throw an
error.

With `Key.prototype.encrypt` and `decrypt`, which mutated the key, it was
possible to end up in an inconsistent state if some (sub)keys could be
decrypted but others couldn't, they would both mutate the key and throw an
error, which is unexpected.

Note that the `keyID` parameter is not supported by `encryptKey`/`decryptKey`,
since partial key decryption is not recommended. If you still need to decrypt
a single subkey or primary key `k`, you can call `k.keyPacket.decrypt(...)`,
followed by `k.keyPacket.validate(...)`. Similarly, for encryption, call
`k.keyPacket.encrypt(...)`.

Additionally, `openpgp.generateKey` now requires `options.userIDs` again,
since otherwise the key is basically unusable. This was a regression from v4,
since we now allow parsing keys without user IDs (but still not using them).
2021-04-23 15:43:38 +02:00
Kostis Andrikopoulos
39aa742c7a
Fix encoded length in unencrypted v5 secret key packets (#1278)
When unencrypted secret key packets are serialized, a 2-byte checksum is
appended after the key material. According to rfc4880bis, these 2 bytes are
not included in the length of the key material (this encoded length is a new
addition of rfc4880bis, specific to v5 keys). We erroneously included them,
causing other implementations to fail to parse unencrypted v5 private keys
generated by OpenPGP.js.
2021-04-06 15:00:45 +02:00
Daniel Huigens
5299561aa3 Clean up async function JSDocs 2021-03-28 16:07:56 +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
e599cee6c8 Remove top-level streaming options
Only return a stream if a stream was passed.
2021-03-26 10:56:02 +01:00
Daniel Huigens
18ec54bf4b Fetch Streams ponyfill on demand in lightweight build 2021-03-26 10:56:02 +01:00
Daniel Huigens
06aef92752 Remove internal streaming parameters 2021-03-25 19:23:58 +01:00
Daniel Huigens
ff8d274b4d Use ArrayStreams 2021-03-25 18:57:29 +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
b9134ed161
Fix unhandled promise rejection when stream-decrypting non-MDC messages (#1260)
Also, add some tests.
2021-03-03 19:38:58 +01:00
larabr
6e2a787ff8
Rename config.ignoreMdcError, drop config.integrityProtect and allow V4 keys to be AEAD-encrypted (#1261)
* Rename `config.ignoreMdcError` to `config.allowUnauthenticatedMessages`

* Do not support creating sym. enc. messages without integrity protection

* Use `config.aeadProtect` to determine SKESK encryption mode
2021-03-03 18:05:40 +01:00
larabr
f41412a5a2
Check critical notations during signature verification instead of parsing (#1259) 2021-03-03 18:03:45 +01:00
Daniel Huigens
e959602a94 Switch packages installed from git to @openpgp scope 2021-02-28 21:45:21 +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
174086a011 Default to empty filename 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
Daniel Huigens
b6edfe646b Lint all tests (#1235) 2021-02-12 23:00:22 +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
c23ed58387 Require User IDs to be objects; refactor UserIDPacket (#1187)
- `openpgp.generateKey` now expects `userIds` in object format
  (strings are no longer supported)
- Remove `util.parseUserId` and `util.formatUserId`
- Replace `UserIDPacket#format` with `UserIDPacket.fromObject`
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
Dan Ristea
d5dd247b2c Store named session key parameters (#1157)
Change session key parameter handling to mirror key parameters.
Parameters are stored as an object rather than an array. MPIs are
always stored as Uint8Arrays.
2021-02-09 19:25:20 +01:00
Daniel Huigens
b3e08fdc26 Don't export default objects / namespaces
Import individual functions, instead.
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
larabr
8854b097b4 Use native BigInt when available instead of bn.js (#1119)
In the lightweight build, lazily load bn.js only when necessary.

Also, use Uint8Arrays instead of strings in PKCS1 padding functions, and
check that the leading zero is present when decoding EME-PKCS1 padding.
2021-02-09 19:25:20 +01:00
Dan Ristea
10aa1aa5cb JSdoc types & ESLint fixes (#1132) 2021-02-09 19:25:20 +01:00
larabr
f6ee6e959e Finish merging key validation 2021-02-09 19:25:20 +01:00
Dan Ristea
b9afd26912 Fix comments on symmetric- and public-key encrypted session keys (#1120) 2021-02-09 19:25:20 +01:00
Daniel Huigens
6a607c7567 Rename SymEncryptedAEADProtectedDataPacket to AEADEncryptedDataPacket 2021-02-09 19:25:20 +01:00
Daniel Huigens
17fc32ba51 Appease linter 2021-02-09 19:25:20 +01:00
Daniel Huigens
aea7aa953a Use ES6 classes 2021-02-09 19:25:20 +01:00
Daniel Huigens
fb3d23427d Allow dead code elimination 2021-02-09 19:25:20 +01:00
Daniel Huigens
5b148089c3 Switch to ES8 build of asmcrypto.js 2021-02-09 19:25:20 +01:00