This is a pretty mechanical translation *except* for
- moving the RANDOM_LENGTH constant out of the obsolete Native class
(libsignal-client has its own) into a new Constants class
- replacing the mocked SecureRandom with a custom subclass; Mockito
was refusing to mock SecureRandom and honestly that's fair
- removing unused classes UUIDUtil and ZkGroupError
- updating to JUnit 4, which zkgroup's tests rely on
These APIs are designed to match the generated "simpleapi" entry
points in the original zkgroup repository, to make it easier to adapt
the existing Java, Swift, and TypeScript code to libsignal-client.
The cbindgen-generated signal_ffi.h now includes constants, so that
the fixed-size arrays used to serialize zkgroup types can use named
constants in Rust. This meant filtering out some constants that were
getting picked up but that should not be included.
Note that this commit makes references to Java exception types that
will be added in a later commit.
This is like signal-client-java, but also contains dylibs for Mac and
Windows for testing purposes. Gradle will automatically fetch these
artifacts from the corresponding GitHub release.
This will be used to build a "testable" signal-client-java.jar that
includes native libraries for macOS and Windows in addition to Linux.
This is something zkgroup already has; in particular it allows
developers working on the server to use the zkgroup APIs even if they
run macOS or Windows on their individual machines.
Previously, we had HKDF-for-session-version-3, which matches RFC 5869,
and HKDF-for-session-version-2, which produced slightly different
results. However, nothing in the current versions of Signal uses
anything but the RFC-compliant version. Therefore, this commit removes
support for version 2 and deprecates the entry points that take a
version:
- Java: The HKDFv3 class is deprecated in favor of static methods on
the HKDF class.
- Swift: The hkdf function that takes a 'version' parameter is
deprecated in favor of a new overload that does not.
- TypeScript: The HKDF class is deprecated in favor of a top-level
hkdf function.
- Rust: The libsignal-protocol implementation of HKDF has been removed
entirely in favor of the hkdf crate.
There are no significant benchmark deltas from this change, and a
minimal code size increase that's the cost for removing our own
implementation of HKDF. The deprecations can be removed as a later
breaking change.
If garbage collection happens at exactly the wrong time, the Java
wrapper around a Rust object (such as SessionRecord) can be finalized
while the Rust object is being used, via its opaque 'nativeHandle'
(address cast as integer). Avoid this by adding a NativeHandleGuard
type that keeps the wrapper alive, as well as a low-level entry point
`Native.keepAlive(...)` that does nothing but serve as a sort of GC
guard, similar to `Reference.reachabilityFence()` in Java 9.
This knocks about 10% off of the built binary for Android (per slice),
to balance out the increased size from the new toolchain and stdlib.
Applying the same `opt-level=s` option for `cargo bench` (on desktop)
gives a roughly 1% slowdown, a trade-off that's worth it.
This dedicated error is thrown when a recipient has a registration ID
that's out of the range used by Signal [0, 0x3FFF]. These IDs cannot
be encoded in the sealed sender v2 format and are not supported, even
though they don't cause any problems for 1:1 messages.
This is useful for PlaintextContent messages (just
DecryptionErrorMessage for now), which can't include a group ID when
sent outside of sealed sender because it would reveal group
membership.
That is, when there's an error decrypting the inner payload of a
sealed sender message, instead of just saving the sender (and more
recently the content hint and group ID), save the whole decrypted
contents of the sealed sender message. This is necessary so that the
app can make a DecryptedErrorMessage from that failed payload.
This is complicated somewhat by the fact that the app also uses the
"short" constructor for the various Protocol*Exceptions, so we have to
keep those working.
This allows a device to know whether it's the one that sent a bad
message, and take action accordingly.
We could have a slightly more typesafe API here by using
ProtocolAddress and extracting the device ID, but that doesn't match
up with getting the device ID out of a sealed sender certificate.