Age | Commit message (Collapse) | Author |
|
- Cert::into_packet is problematic because it does not protect from
accidentally leaking secret key material. The documentation even
warns about that, but it still happened. Hence, this is a
violation of our safe-by-default principle guiding the API, and we
should fix it.
- The replacement, Cert::into_packets2, strips secret key material
just as serializing a cert does. To convert to a sequence of
packets while keeping the secret key material, a new function is
added: TSK::into_packets, analogous to how TSK serializes secret
key material.
|
|
|
|
|
|
- Previously, the filter operated on references with the lifetime 'a
only, which is the lifetime associated with the Cert the TSK
object references. Change the signature to take a reference with
an anonymous lifetime instead.
- This makes the filter more general, but it can no longer rely on
the fact that the references are live for 'a. However, the
function is a Fn, not a FnMut, and returns a bool, so the function
cannot store the reference anywhere, so this shouldn't make a
difference in practice.
- Annoyingly, there is a wrinkle. If a closure bound to an
identifier is given to TSK::set_filter, the Rust compiler
incorrectly (or over eagerly?) specializes the function in a way
that it doesn't match the callback's prototype:
error[E0308]: mismatched types
--> openpgp/src/serialize/cert.rs:946:16
|
946 | check!(tsk_0.as_tsk().set_filter(no_secrets),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected trait `for<'a> Fn<(&'a packet::Key<packet::key::SecretParts, packet::key::UnspecifiedRole>,)>`
found trait `Fn<(&packet::Key<packet::key::SecretParts, packet::key::UnspecifiedRole>,)>`
note: this closure does not fulfill the lifetime requirements
--> openpgp/src/serialize/cert.rs:940:26
|
940 | let no_secrets = |_| false;
| ^^^
note: the lifetime requirement is introduced here
--> openpgp/src/serialize/cert.rs:318:23
|
318 | where P: 'a + Fn(&key::UnspecifiedSecret) -> bool
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: implementation of `FnOnce` is not general enough
--> openpgp/src/serialize/cert.rs:946:16
|
946 | check!(tsk_0.as_tsk().set_filter(no_secrets),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 packet::Key<packet::key::SecretParts, packet::key::UnspecifiedRole>) -> bool` must implement `FnOnce<(&'1 packet::Key<packet::key::SecretParts, packet::key::UnspecifiedRole>,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 packet::Key<packet::key::SecretParts, packet::key::UnspecifiedRole>,)>`, for some specific lifetime `'2`
This is easily fixed by providing a partial type for the
callback's argument. This commit includes a tweak for our test.
|
|
- When parsing a key ID string, reject short key IDs.
- Note: we can't reject short key IDs in `KeyID::from_bytes`,
because that function in infallible. But, that function does return
`KeyID::Invalid` when presented with a short key ID.
- Fixes #388.
|
|
- Simplify initialization.
- Use `KeyHandle::aliases` to compare two `KeyHandle`s.
|
|
- Add references to related functions.
|
|
- When checking for an issuer subpacket, `SubpacketAreas::issuers`,
not `SubpacketAreas::get_issuers`.
|
|
- When checking of a list of issuers contains a fingerprint, use
`KeyHandle::aliases`, don't search for the fingerprint, and then the
key ID.
|
|
- Add `UserID::from_static_bytes`, which is equivalent to
`UserID::from` for a byte slice, but is a constant function.
|
|
- When creating a `UserID`, avoid unnecessary heap allocations by
making better use of what we have. For example, we can directly
convert a `String` to a `Vec<u8>` without allocating a `Vec<u8>`,
and copying the contents.
|
|
- See !1592.
|
|
- Previously, the if let was infallible, and rightfully flagged by
rustc.
|
|
- Currently, we are careful to not export components (user IDs, and
subkeys) if they don't have any exportable self signatures,
however, we still export the primary key. Further, the primary
user ID is leaked when the output is armored.
- When exporting a certificate, correctly check if the certificate
is exportable. If it isn't, don't export anything.
|
|
- Add `Cert::exportable` to return whether a certificate is
exportable or not.
- A certificate should only be exported if it has at least one
exportable direct key signature, or there is at least one user ID
or user attribute with at least one exportable self-signature.
|
|
- Add `CertBuilder::set_exportable`, which sets the exportable flag
accordingly on all generated signatures.
- This allows the easy creation of non-exportable certificates,
which is recommended by the OpenPGP Certificate Directory
specification for the local trust root:
> The trust root is an OpenPGP certificate that is stored under
> the special name trust-root.
>
> The certificate:
>
> SHOULD use direct key signatures or binding signatures that are marked as non-exportable.
https://www.ietf.org/archive/id/draft-nwjw-openpgp-cert-d-00.html#section-3.5.1
- Fixes #1082.
|
|
- Ed25519 keys use the EdDSA signature algorithm, but the
documentation mentions parameters for ECDH.
- It appears that the documentation was copied from
`Key4::import_public_cv25519`, and not adjusted.
- Fix it.
|
|
- Ed25519 keys use the EdDSA signature algorithm, but the
documentation mentions parameters for ECDH.
- It appears that the documentation was copied from
`Key4::import_secret_cv25519`, and not adjusted.
- Fix it.
|
|
- Add a buffered-reader-based function to trait Parse. This allows
us to manipulate the buffered reader stack before and after
parsing, e.g. to parse several armored objects in one stream. The
CertParser also does this, but uses internal interfaces for that.
|
|
- This is an internal interface that uses our reader stack's
cookie. We need this to traverse the buffered reader stack. We
did not, however, expose it as an external interface, because we
didn't want to bake in the cookie type into the API.
- Having a public API that operates on buffered readers is
convenient: the current Parser::from_reader operates on
io::Readers, and will most likely construct a
buffered_reader::Generic from it. This will eagerly buffer some
data, making this interface unsuitable if you want to read in one
artifact (e.g. an MPI) without consuming more data.
- Renaming the internal functions gives us a chance to add a more
general buffered reader interface.
|
|
|
|
- Previously, we emitted the PRIVATE KEY label when armoring TSKs
that don't in fact contain secrets, confusing users.
- See https://gitlab.com/sequoia-pgp/sequoia-sq/-/issues/14
- Fixes #1075.
|
|
|
|
- The public ABI has a bug.
- The documentation for `Key` says that a `Key<SecretParts, R>`
must have secret key material:
> If P is key::SecretParts, then the key definitely contains
> secret key material (although it is not guaranteed that the secret
> key material is valid), and methods that require secret key
> material are available.
https://gitlab.com/sequoia-pgp/sequoia/-/blob/a9982139/openpgp/src/packet/mod.rs#L1249-1256
- Unfortunately, we accidentally provided infallible conversions from
`Key<PublicParts, R1>` to `Key<SecretsParts, R2>` and
`Key<UnspecifiedParts, R1>` to `Key<SecretsParts, R2>` where
`R1 != R2`.
- These conversions are wrong, and useless: attempting to use a
method on a `Key<SecretsParts, R2>` that expects the `Key` to have
secret key material, but doesn't results in a panic.
- Removing these methods converts run-time errors into compile-time
errors. As such, we do not consider this change to result in a
change to the semantic version.
- Make the conversions to `Key<key::SecretsParts, R>` fallible.
- Fixes #740.
|
|
- Change `UserID::from_address` to wrap a bare address in angle
brackets. That is, change `UserID::from_address` so that
`UserID::from_address(None, None, "alice@example.org")` maps to
`<alice@example.org>` not `alice@example.org`. This has the
advantage that the standard regular expression for scoping CAs can
match bare email addresses, see:
https://docs.sequoia-pgp.org/sequoia_openpgp/regex/index.html#caveat-emptor
- Fixes #1076.
|
|
- Add `UserIDAmalgamation::valid_third_party_revocations_by_key` and
`KeyAmalgamation::valid_third_party_revocations_by_key`, which
return third-party revocations that were made by a particular key at
a particular time, i.e., they also verify that the signatures are
valid.
|
|
- Add `UserIDAmalgamation::valid_certifications_by_key` and
`KeyAmalgamation::valid_certifications_by_key`, which return
third-party certifications that were made by a particular key at a
particular time, i.e., they also verify that the signatures are
valid.
- Add `UserIDAmalgamation::active_certifications_by_key` and
`KeyAmalgamation::active_certifications_by_key`, which return the
active certifications made by a particular key at a particular time.
|
|
- Add `ComponentAmalgamation::certifications_by_key`, which returns
third-party certifications that appear to be made by a particular
key. Specifically, this function only checks that the
certificates include a matching issuer or issuer fingerprint
subpacket; the certifications are not verified.
|
|
- Also, disable the default features and enable only what we need.
|
|
- Previously, all optional dependencies created implicit features.
This is unnecessary in our case, and may cause friction for
packagers. See
https://doc.rust-lang.org/cargo/reference/features.html
|
|
- This allows the use of `Into::into(e)` in `VerificationHandler` to
transform the error into an `anyhow::Error`.
|
|
- anyhow::Error isn't Clone, so we cannot, in general, duplicate the
error without losing information. We can try to downcast to the
most likely errors, and clone them, but this can never cover all
possibilities.
- Further, the error wrapped in std::io::Error isn't clone, so we
necessarily lose information when cloning this, even after we
changed Sequoia to return concrete errors.
- I think this is the best we can do, at least for now.
- Fixes #1068.
|
|
- See #1068.
|
|
- The proposal that once thought would end up as the next revision
of OpenPGP does not have the backing of the IETF OpenPGP working
group. We should not support it for the following reasons:
- Accepting it risks proliferation of a proprietary format.
- It is less scrutinized, and interactions with other versions
or features of the OpenPGP standard is not well understood.
Notably, as the "v5" Signature packets use an 8 octet length
counter in the footer, the hashed data streams alias with v3
Signatures. See also
https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/220
- Rejecting "v5" Signature Packets addresses these risks.
|
|
- The proposal that once thought would end up as the next revision
of OpenPGP does not have the backing of the IETF OpenPGP working
group. We should not support it for the following reasons:
- Accepting it risks proliferation of a proprietary format.
- It is less scrutinized, and interactions with other versions
or features of the OpenPGP standard is not well understood.
Notably, as the "v5" AEAD encrypted data packet doesn't use key
space separation, it cannot protect against cross-algorithm
attacks, so now the question of which algorithms are safe to use
depends on which packet they are used with.
- Rejecting "v5" AEAD Encrypted Data Packets addresses these risks.
|
|
- Fixes #878.
|
|
- This is safe, as it is not possible to change the shape of the
data through a mutable reference (e.g. it is not possible to take
the secret key material away).
|
|
|
|
- Tests that an inline-signed message using two different hash
algorithms verifies correctly.
|
|
|
|
- This triggers a warning in rustc 1.73, and thus is an error for
us.
|
|
|
|
- `openpgp` uses features that are only present in version 1.3.0 of
buffered reader. Adjust the dependency.
|
|
|
|
- Fixes #1060.
|
|
|
|
- Use `cipher`'s reexport of `generic-array` instead of directly
depending on `generic-array` and having to worry about synchronizing
the versions.
|
|
|
|
|
|
|