0
0
mirror of https://github.com/signalapp/libsignal.git synced 2024-09-20 20:03:07 +02:00
Commit Graph

153 Commits

Author SHA1 Message Date
Trevor Perrin
7e12a71889
zkgroup: Optimize credential presentation and FFI cleanup
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).
2022-04-06 11:07:08 -07:00
Jordan Rose
df2d4ae9fa swift: Remove unnecessary Tests/LinuxMain.swift
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.
2022-03-25 12:04:17 -07:00
Jordan Rose
0542686e70 Update artifact/package/module names across all three app languages
- Java: org.whispersystems:signal-client-java ->
    org.signal:libsignal-client
- Java: org.whispersystems:signal-client-android ->
    org.signal:libsignal-android
- Java: org.whispersystems:libsignal-server ->
    org.signal:libsignal-server
- Swift: SignalClient -> LibSignalClient
- NPM: @signalapp/signal-client -> @signalapp/libsignal-client
- Repository: github.com/signalapp/libsignal-client ->
    github.com/signalapp/libsignal
2022-03-23 10:49:09 -07:00
Jordan Rose
d26cf8b46d Add dedicated error types for invalid 1:1 and Sender Key sessions
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.
2022-03-21 14:12:04 -07:00
Jordan Rose
ee26c7f269 Swift: restore Linux compatibility (testing only)
- 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.
2022-03-17 16:11:43 -07:00
Jordan Rose
0f5744a712 protocol: Remove the ability to create an empty SenderKeyRecord 2022-03-16 14:09:08 -07:00
Jordan Rose
d2ab3dd09f protocol: Collapse InvalidCiphertext error into InvalidMessage
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.
2022-03-14 14:59:39 -07:00
Jordan Rose
674acdf653 ffi: Remove special-casing for slice inputs
Previously slice inputs expanded to two parameters in the C bridge: a
pointer and a length. This required extra support in the bridge_fn
macro and still needed Swift callers to pass the length explicitly
(with the potential for typos). Now, the Rust side uses a new
BorrowedSliceOf struct, which cbindgen monomorphizes to names like
'SignalBorrowedSliceOfProtocolAddress', plus and a special-case for
bytes: 'SignalBorrowedBuffer'. Together with some conveniences on the
Swift side, this makes calls safer and simpler with fewer special
cases. (In particular, we can now have variable-length input types
that aren't written syntactically as slices.)

Outputs still have the special bridge_fn_buffer mode, which provides
separate pointer and length output parameters. We can revisit this in
the future, but bridge_fn_buffer can save a copy in the Java and Node
bridges, and bridge_fn_void also exists today (for zero output
parameters in the C bridge when Rust has a Result return type).
2022-03-10 16:18:55 -08:00
Jordan Rose
b6740b7647 Swift: split store-related FFI utilities out to their own file 2022-03-10 16:18:55 -08:00
Michelle Linington
a7a874d819 Fix broken tests 2022-02-11 14:14:15 -08:00
Michelle Linington
e2fe069d38 Tweaks the Swift interface for HSM Enclave Client
- Fixes an issue where a call to decrypt would instead re-encrypt the
  ciphertext.
- Tweaks the interface for the initializer to instead take raw public
  key bytes. This matches the java interface. Framework clients have no
  way to construct a PublicKey from raw bytes.
2022-02-10 15:56:17 -08:00
Jordan Rose
600b9070c1
Merge pull request #435 from signalapp/jrose/signAlternateIdentity
Add signAlternateIdentity and verifyAlternateIdentity operations
2021-12-20 11:06:54 -08:00
Jordan Rose
66c65cda86 Expose signAlternateIdentity and verifyAlternateIdentity
- Java: on IdentityKeyPair and IdentityKey, respectively
- Swift: on IdentityKeyPair and IdentityKey, respectively
- Node: on IdentityKeyPair and PublicKey; Node doesn't have a separate
  IdentityKey API

For convenience, exposes IdentityKeyPair.generate() in Java and Node
as well. (This API already existed in Swift.)
2021-12-20 10:30:42 -08:00
Jordan Rose
71fdd6566e Expose SessionRecord.needsPniSignature/.setNeedsPniSignature 2021-12-20 10:21:31 -08:00
Jordan Rose
315fe1963f Remove unused FFI-only error code 'InsufficientOutputSize' 2021-12-10 18:08:39 -08:00
Jordan Rose
5a67a4bf0a Remove unused error FingerprintIdentifierMismatch
Fingerprint checks are done with a boolean-returning method; the error
is never thrown. Android and iOS aren't using the exception / error
case either.
2021-12-10 18:08:39 -08:00
Jordan Rose
145ba7f47c Expose PniCredential operations to app languages 2021-11-15 10:27:57 -08:00
Jordan Rose
8cf56835ef zkgroup: Move blob padding/unpadding into Rust
Previously this was defined in the app layers, because zkgroup's
original codegen didn't support custom exception types. However, we
can now move it to a common implementation in Rust.
2021-11-08 11:06:32 -08:00
Jordan Rose
4186b4a506 swift: Improve zkgroup's ByteArray helper class
Don't validate sizes explicitly; they're already provided in the
signatures of the *_check_valid_contents functions exposed in the FFI
layer.
2021-11-08 11:06:32 -08:00
Jordan Rose
bd248f715f swift: Eliminate ZKGUuid type in favor of Foundation.UUID 2021-11-08 11:06:32 -08:00
Jordan Rose
2198447164 swiftlint: allow the term "master" (for GroupMasterKey) 2021-11-08 11:06:32 -08:00
Jordan Rose
ed24ddf8c5 swift: Update zkgroup license headers, remove codegen warnings
And format with swiftlint and remove the extra space after 'throws'
(from Swift having untyped errors).
2021-11-08 11:06:32 -08:00
Jordan Rose
51dd9db22d swift: Get zkgroup to work (and pass its tests)
This is a pretty mechanical translation *except* for

- changes to the ByteArray class to account for libsignal-client
  supporting fixed-size arrays in the bridge layer

- introducing the Randomness wrapper struct to manage the 32 bytes of
  randomness zkgroup uses

- removing ZkGroupException in favor of SignalError, which has a new
  'verificationFailed' case

Everything else replaces zkgroup's generated "ffiapi" entry points with
libsignal-client's bridge_fn entry points.
2021-11-08 11:06:32 -08:00
Jordan Rose
9174837432 swift: Add zkgroup Swift sources verbatim (does not compile) 2021-11-08 11:06:32 -08:00
Jordan Rose
852069bdc9 bridge: Add zkgroup APIs
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.
2021-11-08 11:04:41 -08:00
Jordan Rose
0f27f82890
Merge pull request #400 from signalapp/jrose/standardize-license-headers
Standardize license headers
2021-10-28 17:48:45 -07:00
Jordan Rose
9a569f2ffe Standardize license headers
...to have a period after "Signal Messenger, LLC."

...except for the Java sources, which still need a cleanup pass.
2021-10-28 17:27:30 -07:00
Jordan Rose
c58ebfe4ee bridge: Support UUID return values in the FFI bridge
This was already present in the Java and Node bridges; I'm not sure
why it was considered a problem in the FFI bridge.
2021-10-28 16:21:14 -07:00
Jim Gustafson
4b9348475c Implement swift interfaces for HsmEnclave 2021-10-26 18:34:27 -07:00
Jordan Rose
ed2e5bce3a bridge: Update generated decls 2021-10-25 15:19:47 -07:00
Jordan Rose
26ebba20ab bridge: Restrict bridge_deserialize! to only the most common case
Unlike bridge_get or bridge_get_bytearray, bridge_deserialize doesn't
do any complicated transformation of the return value to accept
optional or non-optional, failable and non-failable results alike. At
the same time, its syntax has been subtly different from the other
bridge_fn macros, dating from when we were first setting up this
library. Since the extra parameters to rename or disable a particular
bridge's entry point were rarely used, this commit removes them and
replaces those use sites with spelled-out bridge_fns. This in turn
allows removing the custom per-bridge implementations of
bridge_deserialize in favor of a bridge_fn-based implementation like
bridge_get already has.
2021-10-25 13:18:11 -07:00
Jordan Rose
64ad39c54d Remove support for HKDF "versions"
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.
2021-10-14 16:02:56 -07:00
Jordan Rose
6fa8678426 Swift: ensure deinitializers don't run until Rust calls complete
The Swift version of the NativeHandleGuard change for Java. This one's
mostly being proactive, since the Swift compiler will not optimize
across modules at this time without explicitly marking code as
inlinable, but it's possible that an operation that creates and
destroys an object entirely within the SignalClient module could have
the deinitialization of the Swift wrapper happen before the Rust
object pointer's final use. withExtendedLifetime protects against
this, and withNativeHandle wraps that up to access the native object
pointer at the same time.
2021-10-14 15:07:25 -07:00
Jordan Rose
9db55642ce Swift: Standardize native handle management with NativeHandleOwner
Previously some classes used ClonableHandleOwner and some managed
native handles manually. Breaking out the non-cloning parts of
ClonableHandleOwner into a superclass and consistently using inherited
initializers allows us to handle wrappers of Rust objects more
uniformly.
2021-10-14 15:05:36 -07:00
Jordan Rose
d6fc73b27a Update dependencies
- cargo update
- But stay on our fork of curve25519-dalek (pinned at 3.0.0)
- Update x25519-dalek from 1.0 to 1.1 (instead of 1.2) to stay
  compatible with curve25519-dalek
- Update cpufeatures to 2.1 to match our dependencies
- Note that updating picky* resulted in more duplicate crates (rand*)
- Pin num-bigint-dig to a build that supports Cargo's -Zbuild-std,
  because xargo + autocfg has stopped working with the new toolchain
- Remove xargo in favor of -Zbuild-std
2021-10-06 10:58:44 -07:00
Jordan Rose
f441c6c559 Update build instructions for Java and for Swift
Adjusts for recent changes and to clarify issues raised by the
community.
2021-09-24 16:31:08 -07:00
Jordan Rose
5d99e87e2c Swift: Add an error message for missing rust-src when using xargo
xargo does print a reasonably nice error for this, but it doesn't
mention which toolchain to install rust-src for. Check ourselves so
that CocoaPods clients don't have to do something weird like "cd into
the package and run rustup there".
2021-09-24 16:31:08 -07:00
Jordan Rose
8c5b6af3fa Sealed sender v2: add an InvalidRegistrationId exception/error
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.
2021-08-31 13:11:10 -07:00
Jordan Rose
1f477c860c swiftlint: Allow test files to be longer than library files 2021-08-31 13:11:10 -07:00
Jordan Rose
92a40ce1c3 crypto: Use RustCrypto's AES and AES-CTR implementations
The signal-crypto struct Aes256Ctr32 is still useful because we use a
different nonce size than RustCrypto's "full block", and we provide a
convenience constructor to specify an initial counter value.
2021-07-01 13:48:04 -07:00
Jordan Rose
7905bd7a5a FFI: remove clone capability from AES bridge objects
This was never exposed in Swift, so there's no effective change.
2021-07-01 13:46:20 -07:00
Jordan Rose
d72047a245 Bridge: expose RustCrypto's AES-GCM-SIV instead of our own
Same as before, but for the wrapper exposed to the app languages.
2021-07-01 13:46:20 -07:00
Nora Trapp
720d796f76 Add support for M1 and Catalyst architectures via cocoapods 2021-06-10 11:34:10 -07:00
Jordan Rose
b780409c1b Add a deviceId field to DecryptionErrorMessage
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.
2021-05-26 17:23:42 -07:00
Jordan Rose
4c0141c31f Fix merge conflict in Java and Swift tests too. 2021-05-26 16:43:11 -07:00
Jordan Rose
2491447ee7
Merge pull request #316 from signalapp/jrose/DecryptionErrorMessage-and-PlaintextContent-2
Add DecryptionErrorMessage and PlaintextContent (alternate)
2021-05-26 16:27:49 -07:00
Jordan Rose
51dd86a1db Finalize ContentHint design
- Default: sender will not resend; an error should be shown
  immediately
- Resendable: sender will try to resend; delay any error UI if
  possible
- Implicit: don't show any error UI at all; this is something sent
  implicitly like a typing message or a receipt
2021-05-26 15:57:45 -07:00
Jordan Rose
f7acf9005e Add SessionRecord.currentRatchetKeyMatches
This checks if there is an active sender state using the given ratchet
key, for use with decryption error messages. In this case, the app may
choose to archive the current session, or take even stronger actions
such as fetching new prekeys for the recipient.
2021-05-26 15:41:04 -07:00
Jordan Rose
3f3a6e1aca Expose DecryptionErrorMessage and PlaintextContent to Java/Swift/TS 2021-05-26 15:41:04 -07:00
Jordan Rose
6f9083175e Get registration IDs from sessions for Sealed Sender v2
The app-visible change is that sealedSenderMultiRecipientEncrypt now
takes a SessionStore as well. Sessions will be looked up in bulk using
a new SessionStore API, 'loadExistingSessions' or
'getExistingSessions`. The registration ID is then loaded from each
session and included in the resulting SSv2 payload.

The implementation is a bit of a divergence from some other APIs in
libsignal-client in that the "look up in bulk" step is performed in
the Java, Swift, or TypeScript layer, with the resulting sessions
passed down to Rust. Why? Because otherwise we'd pass a list of
addresses into Rust, which would have to turn them back into a Java,
Swift, or TypeScript array to call the SessionStore method. This would
be (1) a bunch of extra work to implement, and (2) a waste of CPU when
we already /have/ a list of addresses in the correct format: the
argument to sealedSenderMultiRecipientEncrypt.

This is an example of "the boundaries between the Rust and
Java/Swift/TypeScript parts of the library don't have to be perfect;
they're internal to the overall product". In this case, we've taken
that a little further than usual: usually we try to make the
libsignal-protocol API as convenient as possible as well, but here it
had to be a bit lower-level to satisfy the needs of the app language
wrappers. (Specifically, callers need to fetch the list of
SessionRecords themselves.)

P.S. Why doesn't v1 of sealed sender include registration IDs? Because
for SSv1, libsignal-client isn't producing the entire request body to
upload to the server; it's only producing the message content that
will be decrypted by the recipient. With SSv2, the serialized message
the recipient downloads has both shared and per-recipient data in it,
which the server must assemble from the uploaded request. Because of
this, SSv2's encrypt API might as well produce the entire request.
2021-05-20 18:04:03 -07:00