Optimize presentation of credentials (AuthCredentialPresentationV2, ProfileKeyCredentialPresentationV2, PniCredentialPresentationV2). Server will accept V1 or V2 presentations. Clients will produce V2.
Various improvements to FFI to support this, and some minor optimizations (in particular "lazy statics" to avoid redundant loading of SystemParams).
Similar to the previous commit, this would make sense if we lazily
deserialized these types, but we don't. It's faster to clone them
structurally in Rust than to serialize and deserialize them.
At one point we experimented with Java's SignalProtocolAddress only
wrapping a String + integer, rather than a boxed Rust handle, but we
gave that up because it was more difficult to pass them across the
bridge. That means there's no longer a need to go through
SignalProtocolAddress's main constructor when trying to box one from
Rust.
This was previously necessary because the Linux implementation of
SwiftPM+XCTest didn't support automatic test discovery, but that's no
longer a problem with newer versions of Swift.
The main advantage here is that we don't need any dependencies from
the unstable repo, which means we can be sure that the glibc version
we build against is suitable for Buster instead of being pulled in
from a later train. (We can't do this for Stretch because Stretch is
too old for all our build tools.)
While here, simplify the build a little bit: we're already using
snapshots of the Debian repo, so drop the separate file for pinned
dependencies.
Previously the project would error out during the configuration stage,
since the Android Gradle plugin requires JDK 11 to even load. Now it
throws an error if you try to build a top-level task or a task in the
Android subproject, but allows you to build, e.g. 'client:test' with
no problems.
This helper task was supposed to only execute when publishing the
client or server artifacts, but at the point where that was checked
the task graph *hasn't been built yet*. Instead, add the task to the
task graph unconditionally, but disable it by default, and have its
dependents enable it only when publishing.
In Java these are subclasses of IllegalStateException, a
RuntimeException, so that every session operation isn't annotated as
throwing InvalidSessionException. Swift and TypeScript don't have
typed errors, so they're just additional specific cases that can be
caught.
Similar to the previous commit, this makes crate-internal operations
use a dedicated error type, or not produce an error at all, in order
to make sure that errors for invalid sessions always have the
distribution ID attached.
Anything that stays within the crate gets a dedicated error type, or
no error at all if the operation cannot actually fail. The "defensive"
signatures remain for public operations.
Apart from making 'Result' more meaningful, this also keeps from
propagating low-level errors out that really indicate a corrupt
session.
The former was used for errors in the protobuf format itself, while
the latter was used when the decoded protobuf failed some higher-level
precondition. But apps can't really distinguish those cases, and
neither one "should" happen in a reliable system, so this is just
defending against rare or malicious inputs.
This commit mechanically turns every prost::DecodeError into
InvalidProtobufEncoding, but the next commit will make more of a
distinction of these errors.
All our bridges translate panics to platform-specific errors anyway;
there's no advantage in using a dedicated error for things that should
*really* never happen.
Pros:
- Linux executors are cheaper on GitHub's CI, when running in the
private repository.
- Checks that the Swift package can still be built and tested on
Linux, even though that's not a primary goal.
Cons:
- Removed the code coverage report. It's possible to do this on Linux
as well, but we haven't been using this as a primary tool, and it's
still possible to check locally (particularly by running in Xcode).
The coverage of the Rust tests is more interesting anyway, and we
haven't had an automated report for *that*.
Neutral:
- Moved the SwiftLint run to the "Swift CocoaPod" job, since SwiftLint
isn't installed on GitHub's Linux images by default. Even though
"Swift CocoaPod" is the longest job at the moment and we may want to
shorten it, the SwiftLint action is quick anyway.
- Provide a fallback for generating random data that doesn't use
Security.framework.
- Fix package unsafe linker settings for ld.gold compatibility.
- Don't depend on the UUID_NULL constant.
The main purpose of this is to distinguish new-session PreKey message
failures from established-session Whisper message failures.
In some cases this meant *not* using InvalidMessage, because the error
wasn't for a particular CiphertextMessage.
This is returned as a SessionNotFound error so that the recipient's
address can be included, but it's important to clarify that it's the
identity key that's missing.
Originally InvalidCiphertext meant something structurally wrong, while
InvalidMessage meant it wasn't decryptable. But distinguishing those
isn't really important except for debugging purposes, so using a
string description is sufficient.
A SenderCertificate object stores both the serialized bytes and the
deserialized fields that make up the certificate, which means that
converting from an in-memory protobuf representation requires
serializing back to bytes. Avoid that extra step by delaying the
deserialization of the SenderCertificate protobuf.