Top Related Projects
Quick Overview
The libsignal-protocol-c
repository is a C implementation of the Signal Protocol, a cryptographic protocol designed for end-to-end encrypted messaging. It provides a secure and efficient way to exchange encrypted messages between clients, ensuring the confidentiality and integrity of the communication.
Pros
- Cross-Platform Compatibility: The library is written in C, making it highly portable and suitable for a wide range of platforms, including mobile devices, servers, and embedded systems.
- Security-Focused: The Signal Protocol is widely regarded as one of the most secure and privacy-preserving messaging protocols available, and the
libsignal-protocol-c
implementation adheres to these high standards. - Actively Maintained: The project is actively maintained by the Signal team, ensuring regular updates, bug fixes, and security improvements.
- Extensive Documentation: The project's documentation is comprehensive, providing detailed instructions and examples for integrating the library into various applications.
Cons
- Complexity: Integrating the
libsignal-protocol-c
library into an application may require a significant amount of development effort, as it involves understanding the underlying cryptographic concepts and the library's API. - Limited Language Support: While the library is written in C, it may not be as widely adopted or supported in certain programming languages or ecosystems compared to other cryptographic libraries.
- Dependency Management: Depending on the project's requirements, the
libsignal-protocol-c
library may have additional dependencies that need to be managed, which can add complexity to the integration process. - Performance Overhead: The cryptographic operations performed by the library may introduce some performance overhead, which may be a concern for applications with strict performance requirements.
Code Examples
Here are a few code examples demonstrating the usage of the libsignal-protocol-c
library:
- Initializing the Signal Protocol Context:
signal_context *context;
signal_protocol_initialize(&context, NULL, NULL, NULL, NULL, NULL);
This code initializes the Signal Protocol context, which is the main entry point for using the library.
- Generating a New Identity Key Pair:
signal_protocol_key_helper_generate_identity_key_pair(&identity_key_pair, context);
This code generates a new identity key pair, which is used for establishing secure communication channels between clients.
- Encrypting a Message:
signal_message *encrypted_message;
signal_protocol_session_encrypt(session, message, message_len, &encrypted_message, context);
This code encrypts a message using the Signal Protocol session, ensuring the confidentiality of the communication.
- Decrypting a Message:
signal_message *decrypted_message;
signal_protocol_session_decrypt(session, encrypted_message, &decrypted_message, context);
This code decrypts a message received from the remote client, verifying its integrity and authenticity.
Getting Started
To get started with the libsignal-protocol-c
library, follow these steps:
- Clone the repository:
git clone https://github.com/signalapp/libsignal-protocol-c.git
- Build the library:
cd libsignal-protocol-c
mkdir build && cd build
cmake ..
make
- Install the library:
sudo make install
- Include the library in your C project and start using the Signal Protocol APIs:
#include <signal_protocol.h>
// Initialize the Signal Protocol context
signal_context *context;
signal_protocol_initialize(&context, NULL, NULL, NULL, NULL, NULL);
// Use the Signal Protocol APIs to encrypt/decrypt messages
// See the code examples above for more details
By following these steps, you can integrate the libsignal-protocol-c
library into your C-based application and leverage the secure messaging capabilities provided by the Signal Protocol.
Competitor Comparisons
Pros of libsignal-protocol-java
- Provides a Java implementation of the Signal Protocol, making it easier to integrate into Java-based applications.
- Offers a more object-oriented and idiomatic Java API, which can be more intuitive for Java developers.
- Includes additional features and utilities specific to the Java ecosystem, such as support for Android platforms.
Cons of libsignal-protocol-java
- May have a larger codebase and dependencies compared to the C implementation, potentially leading to a larger footprint in some applications.
- The Java implementation may not be as performant as the C version, especially in resource-constrained environments.
- Developers working in non-Java environments may find the C implementation more suitable for their needs.
Code Comparison
libsignal-protocol-c
int signal_protocol_session_cipher_encrypt(
signal_protocol_session_cipher *cipher,
const uint8_t *plaintext, size_t plaintext_len,
signal_buffer **ciphertext)
{
return signal_protocol_cipher_encrypt(
cipher->session_record,
plaintext, plaintext_len,
ciphertext);
}
libsignal-protocol-java
public CiphertextMessage encrypt(byte[] paddedPlaintext) throws InvalidMessageException {
try {
SessionCipher sessionCipher = new SessionCipher(this.sessionStore, this.identityKeyStore, this.recipientId, this.deviceId);
return sessionCipher.encrypt(paddedPlaintext);
} catch (UntrustedIdentityException e) {
throw new InvalidMessageException(e);
}
}
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Overview
This is a ratcheting forward secrecy protocol that works in synchronous and asynchronous messaging environments. See the Java library for more details.
Building libsignal-protocol-c
Development host setup
Build dependencies
- CMake 2.8.4 or higher
- Check *1
- OpenSSL *1 1.0 or higher
- On MacOS X, Common Crypto is used instead of OpenSSL
- LCOV *2
Most of these dependencies are required just for the unit test suite and development of the library itself. When integrating into actual applications, you should not need anything beyond CMake. Alternatively, you may integrate the code using a build system of your choice. Items marked with *1 are required for tests, with *2 are additionally required for code coverage.
Setting up a fresh source tree
$ cd /path/to/libsignal-protocol-c
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Debug ..
$ make
Running the unit tests
$ cd /path/to/libsignal-protocol-c/build
$ cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=1 ..
$ cd tests
$ make
$ cd ..
$ ctest
Creating the code coverage report
$ cd /path/to/libsignal-protocol-c/build
$ cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=1 -DCOVERAGE=1 ..
$ make coverage
The generated code coverage report can be found in:
/path/to/libsignal-protocol-c/build/coverage
Eclipse project setup
CMake provides a tutorial on Eclipse project setup here: https://cmake.org/Wiki/CMake:Eclipse_UNIX_Tutorial
It is recommended to follow the more manual "Option 2," since the Eclipse project generator built into CMake tends to be outdated and leads you toward a very awkward and occasionally broken project configuration.
Protocol Buffers compiler
This project uses serialization code based on Protocol Buffers. Since the official library does not support C, the protobuf-c generator is used instead. For the sake of convenience, the generated code and its dependencies are included in the source tree. The generated code can be regenerated at any time by installing the two mentioned packages and running "make" in the "protobuf/" subdirectory.
Target platforms
CMake toolchain files have been included from the following sources:
Using libsignal-protocol-c
Library initialization
Before using the library, a libsignal-protocol-c client needs to initialize a global context. This global context is used to provide callbacks for implementations of functions used across the library that need client-specific implementations. Refer to "signal_protocol.h" for detailed documentation on these functions, and the unit tests for example implementations.
signal_context *global_context;
signal_context_create(&global_context, user_data);
signal_context_set_crypto_provider(global_context, &provider);
signal_context_set_locking_functions(global_context, lock_function, unlock_function);
Client install time
At install time, a libsignal-protocol-c client needs to generate its identity keys, registration id, and prekeys.
ratchet_identity_key_pair *identity_key_pair;
uint32_t registration_id;
signal_protocol_key_helper_pre_key_list_node *pre_keys_head;
session_signed_pre_key *signed_pre_key;
signal_protocol_key_helper_generate_identity_key_pair(&identity_key_pair, global_context);
signal_protocol_key_helper_generate_registration_id(®istration_id, 0, global_context);
signal_protocol_key_helper_generate_pre_keys(&pre_keys_head, start_id, 100, global_context);
signal_protocol_key_helper_generate_signed_pre_key(&signed_pre_key, identity_key_pair, 5, timestamp, global_context);
/* Store identity_key_pair somewhere durable and safe. */
/* Store registration_id somewhere durable and safe. */
/* Store pre keys in the pre key store. */
/* Store signed pre key in the signed pre key store. */
The above example is simplified for the sake of clarity. All of these functions return errors on failure, and those errors should be checked for in real usage.
There are also iteration and serialization methods for the above types that should be used as appropriate.
Building a session
A libsignal-protocol-c client needs to implement four data store callback interfaces:
signal_protocol_identity_key_store
, signal_protocol_pre_key_store
,
signal_protocol_signed_pre_key_store
, and signal_protocol_session_store
.
These will manage loading and storing of identity, prekeys, signed prekeys,
and session state.
These callback interfaces are designed such that implementations should treat all data flowing through them as opaque binary blobs. Anything necessary for referencing that data will be provided as separate function arguments to those callbacks. If it is ever necessary for clients to directly access stored data in terms of library data structures, they should use the accessor functions declared in "signal_protocol.h" for these data stores.
Once the callbacks for these data stores are implemented, building a session is fairly straightforward:
/* Create the data store context, and add all the callbacks to it */
signal_protocol_store_context *store_context;
signal_protocol_store_context_create(&store_context, context);
signal_protocol_store_context_set_session_store(store_context, &session_store);
signal_protocol_store_context_set_pre_key_store(store_context, &pre_key_store);
signal_protocol_store_context_set_signed_pre_key_store(store_context, &signed_pre_key_store);
signal_protocol_store_context_set_identity_key_store(store_context, &identity_key_store);
/* Instantiate a session_builder for a recipient address. */
signal_protocol_address address = {
"+14159998888", 12, 1
};
session_builder *builder;
session_builder_create(&builder, store_context, &address, global_context);
/* Build a session with a pre key retrieved from the server. */
session_builder_process_pre_key_bundle(builder, retrieved_pre_key);
/* Create the session cipher and encrypt the message */
session_cipher *cipher;
session_cipher_create(&cipher, store_context, &address, global_context);
ciphertext_message *encrypted_message;
session_cipher_encrypt(cipher, message, message_len, &encrypted_message);
/* Get the serialized content and deliver it */
signal_buffer *serialized = ciphertext_message_get_serialized(encrypted_message);
deliver(signal_buffer_data(serialized), signal_buffer_len(serialized));
/* Cleanup */
SIGNAL_UNREF(encrypted_message);
session_cipher_free(cipher);
session_builder_free(builder);
signal_protocol_store_context_destroy(store_context);
The above example is simplified for the sake of clarity. All of these functions return errors on failure, and those errors should be checked for in real usage.
Memory management notes
For every custom data type that the libsignal-protocol-c library can allocate and return, a corresponding way of deallocating an instance of that data type is provided.
The more basic and higher level data types provide a type-specific free or
destroy function. These types include signal_context
,
signal_protocol_store_context
, signal_buffer
, signal_buffer_list
,
signal_int_list
, signal_protocol_key_helper_pre_key_list_node
, session_builder
,
session_cipher
, group_session_builder
, group_cipher
, and
fingerprint_generator
.
Most of the other data types, including everything internal, use a reference
counting mechanism. If you are going to hold onto a reference to one of these
types, use the SIGNAL_REF(x)
macro to increment its count. If you are done
with a reference, use SIGNAL_UNREF(x)
to decrement its count. When the count
reaches 0, the type's destructor function is called.
Legal things
Cryptography Notice
This distribution includes cryptographic software. The country in which you currently reside may have restrictions on the import, possession, use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check your country's laws, regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. See http://www.wassenaar.org/ for more information.
The U.S. Government Department of Commerce, Bureau of Industry and Security (BIS), has classified this software as Export Commodity Control Number (ECCN) 5D002.C.1, which includes information security software using or performing cryptographic functions with asymmetric algorithms. The form and manner of this distribution makes it eligible for export under the License Exception ENC Technology Software Unrestricted (TSU) exception (see the BIS Export Administration Regulations, Section 740.13) for both object code and source code.
License
Copyright 2015-2016 Open Whisper Systems
Licensed under the GPLv3: http://www.gnu.org/licenses/gpl-3.0.html
Additional Permissions For Submission to Apple App Store: Provided that you are otherwise in compliance with the GPLv3 for each covered work you convey (including without limitation making the Corresponding Source available in compliance with Section 6 of the GPLv3), Open Whisper Systems also grants you the additional permission to convey through the Apple App Store non-source executable versions of the Program as incorporated into each applicable covered work as Executable Versions only under the Mozilla Public License version 2.0 (https://www.mozilla.org/en-US/MPL/2.0/).
Top Related Projects
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot