Commit e9081dcd authored by johan's avatar johan

Add a C89 FFI

parent 4f006cf2
......@@ -26,7 +26,7 @@ include(CMakePushCheckState)
include(CMakePackageConfigHelpers)
cmake_minimum_required(VERSION 3.0)
project(lime VERSION 0.0.1 LANGUAGES CXX)
project(lime VERSION 0.0.1 LANGUAGES CXX C)
set(LIME_SO_VERSION "0")
......@@ -37,6 +37,7 @@ option(ENABLE_CURVE25519 "Enable support of Curve 25519." YES)
option(ENABLE_CURVE448 "Enable support of Curve 448(goldilock)." YES)
option(ENABLE_UNIT_TESTS "Enable compilation of unit tests." YES)
option(ENABLE_PROFILING "Enable profiling, GCC only" NO)
option(ENABLE_C_INTERFACE "Enable support of C function foreign interface" NO)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
......@@ -77,6 +78,7 @@ if(LIME_CPPFLAGS)
endif()
add_definitions("-DLIME_EXPORTS")
set(STRICT_OPTIONS_C)
set(STRICT_OPTIONS_CPP )
set(STRICT_OPTIONS_CXX )
set(STRICT_OPTIONS_OBJC )
......@@ -91,6 +93,9 @@ else()
list(APPEND STRICT_OPTIONS_CXX "-std=c++11")
#list(APPEND STRICT_OPTIONS_CPP "-Wall" "-Wuninitialized" "-Wno-error=deprecated-declarations") # turn off deprecated-declaration warning to avoid being flooded by soci.h
list(APPEND STRICT_OPTIONS_CPP "-Wall" "-Wuninitialized" "-Wno-deprecated-declarations" "-Wno-missing-field-initializers")
if(ENABLE_C_INTERFACE)
list(APPEND STRICT_OPTIONS_C "-std=c99")
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
list(APPEND STRICT_OPTIONS_CPP "-Qunused-arguments" "-Wno-array-bounds")
endif()
......@@ -121,6 +126,11 @@ if (ENABLE_CURVE448)
message(STATUS "Support Curve 448")
endif()
if(ENABLE_C_INTERFACE)
add_definitions("-DFFI_ENABLED")
message(STATUS "Provide C89 interface")
endif()
add_subdirectory(include)
add_subdirectory(src)
if(ENABLE_UNIT_TESTS AND BCTOOLBOX_TESTER_FOUND)
......
......@@ -44,7 +44,7 @@ PROJECT_NUMBER =
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF =
PROJECT_BRIEF = "Lime is a C++ library implementing Open Whisper System Signal protocol"
# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
# the documentation. The maximum height of the logo should not exceed 55 pixels
......@@ -449,7 +449,7 @@ EXTRACT_LOCAL_METHODS = NO
# are hidden.
# The default value is: NO.
EXTRACT_ANON_NSPACES = NO
EXTRACT_ANON_NSPACES = YES
# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
# undocumented members inside documented classes or files. If set to NO these
......
......@@ -47,7 +47,13 @@ Testing
Library settings
----------------
Some mostly harmless settings are available in src/lime_settings.hpp
Some mostly harmless settings are available in *src/lime_settings.hpp*
Library API
-----------
The C++11 API is available in *include/lime/lime.hpp*
if enabled (see Options), a C89 FFI is provided by *include/lime/lime_ffi.h*
Options
......@@ -62,6 +68,7 @@ Options
- `ENABLE_Curve25519` : Enable support of Curve 25519.
- `ENABLE_Curve448` : Enable support of Curve 448.
- `ENABLE_PROFILING` : Enable code profiling for GCC
- `ENABLE_C_INTERFACE` : Enable support of C89 function foreign interface
------------------
......
......@@ -24,6 +24,10 @@ set(HEADER_FILES
lime.hpp
)
if (ENABLE_C_INTERFACE)
set(HEADER_FILES ${HEADER_FILES} lime_ffi.h)
endif()
set(LIME_HEADER_FILES )
foreach(HEADER_FILE ${HEADER_FILES})
list(APPEND LIME_HEADER_FILES "${CMAKE_CURRENT_LIST_DIR}/lime/${HEADER_FILE}")
......
This diff is collapsed.
......@@ -33,7 +33,6 @@ set(LIME_HEADER_FILES
lime_crypto_primitives.hpp
lime_log.hpp
)
set(LIME_SOURCE_FILES_C )
set(LIME_SOURCE_FILES_CXX
lime.cpp
lime_crypto_primitives.cpp
......@@ -45,11 +44,14 @@ set(LIME_SOURCE_FILES_CXX
lime_manager.cpp
)
bc_apply_compile_flags(LIME_SOURCE_FILES_C STRICT_OPTIONS_CPP STRICT_OPTIONS_C)
if (ENABLE_C_INTERFACE)
set(LIME_SOURCE_FILES_CXX ${LIME_SOURCE_FILES_CXX} lime_ffi.cpp)
endif()
bc_apply_compile_flags(LIME_SOURCE_FILES_CXX STRICT_OPTIONS_CPP STRICT_OPTIONS_CXX)
if(ENABLE_STATIC)
add_library(lime-static STATIC ${LIME_HEADER_FILES} ${LIME_SOURCE_FILES_C} ${LIME_SOURCE_FILES_CXX})
add_library(lime-static STATIC ${LIME_HEADER_FILES} ${LIME_SOURCE_FILES_CXX})
set_target_properties(lime-static PROPERTIES OUTPUT_NAME lime)
target_include_directories(lime-static PUBLIC ${BCTOOLBOX_INCLUDE_DIRS} ${SOCI_INCLUDE_DIRS} ${SOCI_INCLUDE_DIRS}/soci)
target_link_libraries(lime-static INTERFACE ${BCTOOLBOX_CORE_LIBRARIES} ${SOCI_LIBRARIES} ${SOCI_sqlite3_PLUGIN})
......@@ -58,7 +60,7 @@ if(ENABLE_STATIC)
endif()
endif()
if(ENABLE_SHARED)
add_library(lime SHARED ${LIME_HEADER_FILES} ${LIME_SOURCE_FILES_C} ${LIME_SOURCE_FILES_CXX})
add_library(lime SHARED ${LIME_HEADER_FILES} ${LIME_SOURCE_FILES_CXX})
set_target_properties(lime PROPERTIES VERSION ${LIME_SO_VERSION})
target_include_directories(lime PUBLIC ${BCTOOLBOX_INCLUDE_DIRS} ${SOCI_INCLUDE_DIRS} ${SOCI_INCLUDE_DIRS}/soci)
target_link_libraries(lime PRIVATE ${BCTOOLBOX_CORE_LIBRARIES} ${SOCI_LIBRARIES} ${SOCI_sqlite3_PLUGIN})
......
......@@ -62,17 +62,7 @@ namespace lime {
namespace double_ratchet_protocol {
/**
* @brief return the size of the double ratchet packet header
*
* header is: Protocol Version Number<1 byte> || Message Type <1 byte> || curveId <1 byte> || [X3DH Init message < variable >] || Ns<2 bytes> || PN<2 bytes> || DHs<...>
*
* @return the header size without optionnal X3DH init packet
*/
template <typename Curve>
constexpr size_t headerSize() {
return 7 + X<Curve, lime::Xtype::publicKey>::ssize();
}
/**
* @brief build an X3DH init message to insert in DR header
......@@ -177,11 +167,12 @@ namespace lime {
if (message[2] != static_cast<uint8_t>(Curve::curveId()) || !(message[1]&static_cast<uint8_t>(DR_message_type::X3DH_init_flag))) {
return false;
}
// check length
size_t x3dh_initMessageSize = 1 + DSA<Curve, lime::DSAtype::publicKey>::ssize() + X<Curve, lime::Xtype::publicKey>::ssize() + 4; // size of X3DH init message without OPk
if (message[3] == 1) { // there is an OPk
x3dh_initMessageSize += 4;
}
// check length, message[3] holds the OPk flag of the X3DH init message
size_t x3dh_initMessageSize = X3DHinitSize<Curve>(message[3] == 1);
// size_t x3dh_initMessageSize = 1 + DSA<Curve, lime::DSAtype::publicKey>::ssize() + X<Curve, lime::Xtype::publicKey>::ssize() + 4; // size of X3DH init message without OPk
// if (message[3] == 1) { // there is an OPk
// x3dh_initMessageSize += 4;
// }
//header shall be actually longer because buffer passed is the whole message
if (message.size() < x3dh_initMessageSize + headerSize<Curve>()) {
......@@ -319,6 +310,8 @@ namespace lime {
/* Instanciate templated functions */
#ifdef EC25519_ENABLED
//template size_t headerSize<C255>() noexcept;
//template size_t X3DHinitSize<C255>(bool haveOPk) noexcept;
template void buildMessage_X3DHinit<C255>(std::vector<uint8_t> &message, const DSA<C255, lime::DSAtype::publicKey> &Ik, const X<C255, lime::Xtype::publicKey> &Ek, const uint32_t SPk_id, const uint32_t OPk_id, const bool OPk_flag) noexcept;
template void parseMessage_X3DHinit<C255>(const std::vector<uint8_t>message, DSA<C255, lime::DSAtype::publicKey> &Ik, X<C255, lime::Xtype::publicKey> &Ek, uint32_t &SPk_id, uint32_t &OPk_id, bool &OPk_flag) noexcept;
template bool parseMessage_get_X3DHinit<C255>(const std::vector<uint8_t> &message, std::vector<uint8_t> &X3DH_initMessage) noexcept;
......@@ -327,6 +320,8 @@ namespace lime {
#endif
#ifdef EC448_ENABLED
//template size_t headerSize<C448>() noexcept;
//template size_t X3DHinitSize<C448>(bool haveOPk) noexcept;
template void buildMessage_X3DHinit<C448>(std::vector<uint8_t> &message, const DSA<C448, lime::DSAtype::publicKey> &Ik, const X<C448, lime::Xtype::publicKey> &Ek, const uint32_t SPk_id, const uint32_t OPk_id, const bool OPk_flag) noexcept;
template void parseMessage_X3DHinit<C448>(const std::vector<uint8_t>message, DSA<C448, lime::DSAtype::publicKey> &Ik, X<C448, lime::Xtype::publicKey> &Ek, uint32_t &SPk_id, uint32_t &OPk_id, bool &OPk_flag) noexcept;
template bool parseMessage_get_X3DHinit<C448>(const std::vector<uint8_t> &message, std::vector<uint8_t> &X3DH_initMessage) noexcept;
......
......@@ -24,6 +24,31 @@
namespace lime {
namespace double_ratchet_protocol {
/**
* @brief return the size of the double ratchet packet header
*
* header is: Protocol Version Number<1 byte> || Message Type <1 byte> || curveId <1 byte> || [X3DH Init message < variable >] || Ns<2 bytes> || PN<2 bytes> || DHs< DH public key size >
*
* @return the header size without optionnal X3DH init packet
*/
template <typename Curve>
constexpr size_t headerSize() noexcept {
return 7 + X<Curve, lime::Xtype::publicKey>::ssize();
}
/**
* @brief return the size of the X3DH init packet included in the double ratchet packet header
*
* X3DH init packet is : OPk flag<1 byte> || Ik < DSA public key size > || Ek < DH public key size > || SPk Id <4 bytes> || [OPk Id <4 bytes>]
*
* @return the header size without optionnal X3DH init packet
*/
template <typename Curve>
constexpr size_t X3DHinitSize(bool haveOPk) noexcept {
return 1 + DSA<Curve, lime::DSAtype::publicKey>::ssize() + X<Curve, lime::Xtype::publicKey>::ssize() + 4 // size of X3DH init message without OPk
+ (haveOPk?4:0); // if there is an OPk, we must add 4 for the OPk id
}
template <typename Curve>
void buildMessage_X3DHinit(std::vector<uint8_t> &message, const DSA<Curve, lime::DSAtype::publicKey> &Ik, const X<Curve, lime::Xtype::publicKey> &Ek, const uint32_t SPk_id, const uint32_t OPk_id, const bool OPk_flag) noexcept;
template <typename Curve>
......
This diff is collapsed.
......@@ -42,10 +42,15 @@ set(SOURCE_FILES_CXX
lime_massive_group-tester.cpp
)
set(SOURCE_FILES_C
lime_ffi-tester.c
)
bc_apply_compile_flags(SOURCE_FILES_C STRICT_OPTIONS_CPP STRICT_OPTIONS_C)
bc_apply_compile_flags(SOURCE_FILES_CXX STRICT_OPTIONS_CPP STRICT_OPTIONS_CXX)
if(ANDROID OR IOS)
add_library(limetester SHARED ${HEADER_FILES_CXX} ${SOURCE_FILES_CXX})
add_library(limetester SHARED ${HEADER_FILES_CXX} ${SOURCE_FILES_CXX} ${SOURCE_FILES_C} )
target_include_directories(limetester PUBLIC ${BCTOOLBOX_TESTER_INCLUDE_DIRS} ${BELLESIP_INCLUDE_DIRS})
target_link_libraries(limetester ${LIME_LIBRARIES_FOR_TESTER} ${BCTOOLBOX_LIBRARIES} ${BCTOOLBOX_TESTER_LIBRARIES} ${BELLESIP_LIBRARIES} ${SOCI_LIBRARIES} ${SOCI_sqlite3_PLUGIN})
if(IOS)
......@@ -68,7 +73,7 @@ if(ANDROID OR IOS)
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
)
else()
add_executable(lime_tester ${SOURCE_FILES_CXX} ${HEADER_FILES_CXX})
add_executable(lime_tester ${SOURCE_FILES_CXX} ${HEADER_FILES_CXX} ${SOURCE_FILES_C} )
set_target_properties(lime_tester PROPERTIES LINKER_LANGUAGE CXX)
target_include_directories(lime_tester PUBLIC ${BCTOOLBOX_TESTER_INCLUDE_DIRS} ${BELLESIP_INCLUDE_DIRS})
target_link_libraries(lime_tester ${LIME_LIBRARIES_FOR_TESTER} ${BCTOOLBOX_LIBRARIES} ${BCTOOLBOX_TESTER_LIBRARIES} ${BELLESIP_LIBRARIES} ${SOCI_LIBRARIES} ${SOCI_sqlite3_PLUGIN})
......
......@@ -53,6 +53,7 @@ void lime_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list
bc_tester_add_suite(&lime_lime_test_suite);
bc_tester_add_suite(&lime_massive_group_test_suite);
bc_tester_add_suite(&lime_helloworld_test_suite);
bc_tester_add_suite(&lime_ffi_test_suite);
}
void lime_tester_uninit(void) {
......
......@@ -35,6 +35,7 @@ extern test_suite_t lime_lime_test_suite;
extern test_suite_t lime_helloworld_test_suite;
extern test_suite_t lime_crypto_test_suite;
extern test_suite_t lime_massive_group_test_suite;
extern test_suite_t lime_ffi_test_suite;
void lime_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list args));
void lime_tester_uninit(void);
......
This diff is collapsed.
......@@ -253,7 +253,7 @@ static void helloworld_basic_test(const lime::CurveId curve, const std::string &
// encrypt, parameters are:
// - localDeviceId to select which of the users managed by the LimeManager we shall use to perform the encryption (in our example we have only one local device). This one doesn't need to be a shared pointer.
// - recipientUser: an id of the recipient user (which can hold several devices), typically its sip:uri
// - RecipientData vector (see above), list all recipient devices, will hold their cipher header
// - RecipientData vector (see above), list all recipient devices, will hold their DR message
// - plain message
// - cipher message (this one must then be distributed to all recipients devices)
// - a callback (prototype: void(lime::CallbackReturn, std::string))
......@@ -487,7 +487,7 @@ static void helloworld_verifyIdentity_test(const lime::CurveId curve, const std:
// encrypt, parameters are:
// - localDeviceId to select which of the users managed by the LimeManager we shall use to perform the encryption (in our example we have only one local device). This one doesn't need to be a shared pointer.
// - recipientUser: an id of the recipient user (which can hold several devices), typically its sip:uri
// - RecipientData vector (see above), list all recipient devices, will hold their cipher header
// - RecipientData vector (see above), list all recipient devices, will hold their DR message
// - plain message
// - cipher message (this one must then be distributed to all recipients devices)
// - a callback (prototype: void(lime::CallbackReturn, std::string))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment