Compare commits
2 commits
master
...
rav/simple
Author | SHA1 | Date | |
---|---|---|---|
|
06a1b66ea9 | ||
|
2ac6177f9c |
43 changed files with 430 additions and 542 deletions
|
@ -1,33 +1,3 @@
|
|||
Changes in `3.2.16 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.16>`_
|
||||
===========================================================================
|
||||
|
||||
This release includes the following changes since 3.2.15:
|
||||
|
||||
* Fix and modernize the Python packaging (thanks to Alfred Wingate)
|
||||
|
||||
Changes in `3.2.15 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.15>`_
|
||||
===========================================================================
|
||||
|
||||
This release includes the following changes since 3.2.14:
|
||||
|
||||
* Improvements to Python packaging
|
||||
* No longer depend on ``future`` since Python 2 is no longer supported.
|
||||
* Improve compatibility with tox 4.
|
||||
* Add support for making standalone sdist.
|
||||
* Improvements to Nix flake (Thanks to Jon Ringer)
|
||||
* Improve structure.
|
||||
* Enable Darwin builds.
|
||||
* Typescript type fix.
|
||||
|
||||
Changes in `3.2.14 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.14>`_
|
||||
===========================================================================
|
||||
|
||||
This release includes the following changes since 3.2.13:
|
||||
|
||||
* TypeScript type improvements.
|
||||
* Improvements to Python packaging
|
||||
* Documentation improvements.
|
||||
|
||||
Changes in `3.2.13 <https://gitlab.matrix.org/matrix-org/olm/tags/3.2.13>`_
|
||||
===========================================================================
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
project(olm VERSION 3.2.16 LANGUAGES CXX C)
|
||||
project(olm VERSION 3.2.13 LANGUAGES CXX C)
|
||||
|
||||
option(OLM_TESTS "Build tests" ON)
|
||||
option(BUILD_SHARED_LIBS "Build as a shared library" ON)
|
||||
|
|
7
Makefile
7
Makefile
|
@ -8,6 +8,7 @@ RELEASE_OPTIMIZE_FLAGS ?= -O3
|
|||
DEBUG_OPTIMIZE_FLAGS ?= -g -O0 -U_FORTIFY_SOURCE
|
||||
JS_OPTIMIZE_FLAGS ?= -O3
|
||||
FUZZER_OPTIMIZE_FLAGS ?= -O3
|
||||
CC = gcc
|
||||
EMCC = emcc
|
||||
EMAR = emar
|
||||
AR = ar
|
||||
|
@ -30,7 +31,7 @@ JS_ASMJS_TARGET := javascript/olm_legacy.js
|
|||
WASM_TARGET := $(BUILD_DIR)/wasm/libolm.a
|
||||
|
||||
JS_EXPORTED_FUNCTIONS := javascript/exported_functions.json
|
||||
JS_EXPORTED_RUNTIME_METHODS := [ALLOC_STACK,writeAsciiToMemory,intArrayFromString,UTF8ToString,stringToUTF8]
|
||||
JS_EXPORTED_RUNTIME_METHODS := [ALLOC_STACK,writeAsciiToMemory,intArrayFromString]
|
||||
JS_EXTERNS := javascript/externs.js
|
||||
|
||||
PUBLIC_HEADERS := include/olm/olm.h include/olm/outbound_group_session.h include/olm/inbound_group_session.h include/olm/pk.h include/olm/sas.h include/olm/error.h include/olm/olm_export.h
|
||||
|
@ -93,7 +94,7 @@ LDFLAGS += -Wall -Werror
|
|||
CFLAGS_NATIVE = -fPIC
|
||||
CXXFLAGS_NATIVE = -fPIC
|
||||
|
||||
EMCCFLAGS = --closure 1 --memory-init-file 0 -s NO_FILESYSTEM=1 -s INVOKE_RUN=0 -s MODULARIZE=1 -Wno-error=closure
|
||||
EMCCFLAGS = --closure 1 --memory-init-file 0 -s NO_FILESYSTEM=1 -s INVOKE_RUN=0 -s MODULARIZE=1
|
||||
|
||||
# Olm generally doesn't need a lot of memory to encrypt / decrypt its usual
|
||||
# payloads (ie. Matrix messages), but we do need about 128K of heap to encrypt
|
||||
|
@ -105,7 +106,7 @@ EMCCFLAGS = --closure 1 --memory-init-file 0 -s NO_FILESYSTEM=1 -s INVOKE_RUN=0
|
|||
# we don't use this for the legacy build.)
|
||||
EMCCFLAGS_WASM += -s TOTAL_STACK=65536 -s TOTAL_MEMORY=262144 -s ALLOW_MEMORY_GROWTH
|
||||
|
||||
EMCCFLAGS_ASMJS += -s WASM=0
|
||||
EMCCFLAGS_ASMJS += -s WASM=0 -Wno-error=closure
|
||||
|
||||
EMCC.c = $(EMCC) $(CFLAGS) $(CPPFLAGS) -c -DNDEBUG -DOLM_STATIC_DEFINE=1
|
||||
EMCC.cc = $(EMCC) $(CXXFLAGS) $(CPPFLAGS) -c -DNDEBUG -DOLM_STATIC_DEFINE=1
|
||||
|
|
|
@ -3,7 +3,7 @@ Pod::Spec.new do |s|
|
|||
# The libolm version
|
||||
MAJOR = 3
|
||||
MINOR = 2
|
||||
PATCH = 16
|
||||
PATCH = 13
|
||||
|
||||
s.name = "OLMKit"
|
||||
s.version = "#{MAJOR}.#{MINOR}.#{PATCH}"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import PackageDescription
|
||||
|
||||
let major = 3, minor = 2, patch = 16
|
||||
let major = 3, minor = 2, patch = 13
|
||||
|
||||
let package = Package(
|
||||
name: "Olm",
|
||||
|
|
17
README.md
17
README.md
|
@ -52,16 +52,13 @@ You can use pre-built npm packages, available at
|
|||
|
||||
#### Python
|
||||
|
||||
A Python source package and pre-built packages for certain architectures from
|
||||
<https://pypi.org/project/python-olm/>. If a pre-built package is not
|
||||
available for your architecture, you will need:
|
||||
Pre-built packages for Python are available for certain architectures at
|
||||
<https://gitlab.matrix.org/matrix-org/olm/-/packages?type=PyPI>. They can be
|
||||
installed by running
|
||||
|
||||
- cmake (recommended) or GNU make
|
||||
- a C/C++ compiler
|
||||
|
||||
to build the source package.
|
||||
|
||||
You can then run `pip install python-olm`.
|
||||
```bash
|
||||
pip install python-olm --extra-index-url https://gitlab.matrix.org/api/v4/projects/27/packages/pypi/simple
|
||||
```
|
||||
|
||||
Currently, we try to provide packages for all supported versions of Python on
|
||||
x86-64, i686, and aarch64, but we cannot guarantee that packages for all
|
||||
|
@ -206,7 +203,7 @@ endorsed by the Matrix.org Foundation C.I.C.
|
|||
## Release process
|
||||
|
||||
First: bump version numbers in ``common.mk``, ``CMakeLists.txt``,
|
||||
``javascript/package.json``, ``python/pyproject.toml``, ``OLMKit.podspec``,
|
||||
``javascript/package.json``, ``python/olm/__version__.py``, ``OLMKit.podspec``,
|
||||
``Package.swift``, and ``android/gradle.properties``.
|
||||
|
||||
Also, ensure the changelog is up to date, and that everything is committed to
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
|
||||
# which compilers to use for C and C++
|
||||
SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc-posix)
|
||||
SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++-posix)
|
||||
SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
|
||||
SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
|
||||
SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
|
||||
|
||||
# here is the target environment located
|
||||
|
|
|
@ -26,7 +26,7 @@ org.gradle.configureondemand=false
|
|||
# Ref: https://github.com/vanniktech/gradle-maven-publish-plugin
|
||||
GROUP=org.matrix.android
|
||||
POM_ARTIFACT_ID=olm
|
||||
VERSION_NAME=3.2.16
|
||||
VERSION_NAME=3.2.13
|
||||
|
||||
POM_PACKAGING=aar
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
MAJOR := 3
|
||||
MINOR := 2
|
||||
PATCH := 16
|
||||
PATCH := 13
|
||||
|
|
|
@ -28,56 +28,18 @@ channels. Provided that peer-to-peer channel provides authenticity of the
|
|||
messages to the participants and deniability of the messages to third parties,
|
||||
the Megolm session will inherit those properties.
|
||||
|
||||
## The Megolm ratchet algorithm
|
||||
## The Megolm V2 ratchet algorithm
|
||||
|
||||
The Megolm ratchet $`R_i`$ consists of four parts, $`R_{i,j}`$ for
|
||||
$`j \in {0,1,2,3}`$. The length of each part depends on the hash function
|
||||
in use (256 bits for this version of Megolm).
|
||||
The Megolm V2 ratchet $`R_i`$ is based on a single key whose length depends
|
||||
on the hash function in use (256 bits for this version of Megolm).
|
||||
|
||||
The ratchet is initialised with cryptographically-secure random data, and
|
||||
advanced as follows:
|
||||
The key is initialised with cryptographically-secure random data, and
|
||||
after each use is advanced by setting $`R_{i+1} = H(R_i)`$, where $`H`$ is
|
||||
a hash function.
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
R_{i,0} &=
|
||||
\begin{cases}
|
||||
H_0\left(R_{2^{24}(n-1),0}\right) &\text{if }\exists n | i = 2^{24}n\\
|
||||
R_{i-1,0} &\text{otherwise}
|
||||
\end{cases}\\
|
||||
R_{i,1} &=
|
||||
\begin{cases}
|
||||
H_1\left(R_{2^{24}(n-1),0}\right) &\text{if }\exists n | i = 2^{24}n\\
|
||||
H_1\left(R_{2^{16}(m-1),1}\right) &\text{if }\exists m | i = 2^{16}m\\
|
||||
R_{i-1,1} &\text{otherwise}
|
||||
\end{cases}\\
|
||||
R_{i,2} &=
|
||||
\begin{cases}
|
||||
H_2\left(R_{2^{24}(n-1),0}\right) &\text{if }\exists n | i = 2^{24}n\\
|
||||
H_2\left(R_{2^{16}(m-1),1}\right) &\text{if }\exists m | i = 2^{16}m\\
|
||||
H_2\left(R_{2^8(p-1),2}\right) &\text{if }\exists p | i = 2^8p\\
|
||||
R_{i-1,2} &\text{otherwise}
|
||||
\end{cases}\\
|
||||
R_{i,3} &=
|
||||
\begin{cases}
|
||||
H_3\left(R_{2^{24}(n-1),0}\right) &\text{if }\exists n | i = 2^{24}n\\
|
||||
H_3\left(R_{2^{16}(m-1),1}\right) &\text{if }\exists m | i = 2^{16}m\\
|
||||
H_3\left(R_{2^8(p-1),2}\right) &\text{if }\exists p | i = 2^8p\\
|
||||
H_3\left(R_{i-1,3}\right) &\text{otherwise}
|
||||
\end{cases}
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
where $`H_0`$, $`H_1`$, $`H_2`$, and $`H_3`$ are different hash
|
||||
functions. In summary: every $`2^8`$ iterations, $`R_{i,3}`$ is
|
||||
reseeded from $`R_{i,2}`$. Every $`2^{16}`$ iterations, $`R_{i,2}`$
|
||||
and $`R_{i,3}`$ are reseeded from $`R_{i,1}`$. Every $`2^{24}`$
|
||||
iterations, $`R_{i,1}`$, $`R_{i,2}`$ and $`R_{i,3}`$ are reseeded
|
||||
from $`R_{i,0}`$.
|
||||
|
||||
The complete ratchet value, $`R_{i}`$, is hashed to generate the keys used
|
||||
to encrypt each message. This scheme allows the ratchet to be advanced an
|
||||
arbitrary amount forwards while needing at most 1020 hash computations. A
|
||||
client can decrypt chat history onwards from the earliest value of the ratchet
|
||||
The ratchet value, $`R_{i}`$, is hashed to generate the keys used
|
||||
to encrypt each message. This scheme allows a client
|
||||
to decrypt chat history onwards from the earliest value of the ratchet
|
||||
it is aware of, but cannot decrypt history from before that point without
|
||||
reversing the hash function.
|
||||
|
||||
|
@ -85,7 +47,6 @@ This allows a participant to share its ability to decrypt chat history with
|
|||
another from a point in the conversation onwards by giving a copy of the
|
||||
ratchet at that point in the conversation.
|
||||
|
||||
|
||||
## The Megolm protocol
|
||||
|
||||
### Session setup
|
||||
|
@ -95,8 +56,7 @@ session consists of three parts:
|
|||
|
||||
* a 32 bit counter, $`i`$.
|
||||
* an [Ed25519][] keypair, $`K`$.
|
||||
* a ratchet, $`R_i`$, which consists of four 256-bit values,
|
||||
$`R_{i,j}`$ for $`j \in {0,1,2,3}`$.
|
||||
* a ratchet, $`R_i`$, consisting of a single 256-bit value.
|
||||
|
||||
The counter $`i`$ is initialised to $`0`$. A new Ed25519 keypair is
|
||||
generated for $`K`$. The ratchet is simply initialised with 1024 bits of
|
||||
|
@ -157,18 +117,16 @@ received the session data.
|
|||
### Advancing the ratchet
|
||||
|
||||
After each message is encrypted, the ratchet is advanced. This is done as
|
||||
described in [The Megolm ratchet algorithm](#the-megolm-ratchet-algorithm), using the following definitions:
|
||||
described in [The Megolm V2 ratchet algorithm](#the-megolm-v2-ratchet-algorithm),
|
||||
using the following definition for $`H`$:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
H_0(A) &\equiv \operatorname{HMAC}(A,\text{``\char`\\x00"}) \\
|
||||
H_1(A) &\equiv \operatorname{HMAC}(A,\text{``\char`\\x01"}) \\
|
||||
H_2(A) &\equiv \operatorname{HMAC}(A,\text{``\char`\\x02"}) \\
|
||||
H_3(A) &\equiv \operatorname{HMAC}(A,\text{``\char`\\x03"}) \\
|
||||
H(A) &\equiv \operatorname{HMAC}(A,\text{``\char`\\x00"}) \\
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
where $`\operatorname{HMAC}(A, T)`$ is the HMAC-SHA-256 of ``T``, using ``A`` as the
|
||||
where $`\operatorname{HMAC}(A, T)`$ is the HMAC-SHA-256 of $`T`$, using $`A`$ as the
|
||||
key.
|
||||
|
||||
For outbound sessions, the updated ratchet and counter are stored in the
|
||||
|
@ -191,16 +149,16 @@ session.
|
|||
The session sharing format is as follows:
|
||||
|
||||
```
|
||||
+---+----+--------+--------+--------+--------+------+-----------+
|
||||
| V | i | R(i,0) | R(i,1) | R(i,2) | R(i,3) | Kpub | Signature |
|
||||
+---+----+--------+--------+--------+--------+------+-----------+
|
||||
0 1 5 37 69 101 133 165 229 bytes
|
||||
+---+----+------+------+-----------+
|
||||
| V | i | R(i) | Kpub | Signature |
|
||||
+---+----+------+------+-----------+
|
||||
0 1 5 37 69 133 bytes
|
||||
```
|
||||
|
||||
The version byte, ``V``, is ``"\x02"``.
|
||||
The version byte, ``V``, is ``"\x04"``.
|
||||
|
||||
This is followed by the ratchet index, $`i`$, which is encoded as a
|
||||
big-endian 32-bit integer; the ratchet values $`R_{i,j}`$; and the public
|
||||
big-endian 32-bit integer; the ratchet value $`R_{i}`$; and the public
|
||||
part of the Ed25519 keypair $`K`$.
|
||||
|
||||
The data is then signed using the Ed25519 keypair, and the 64-byte signature is
|
||||
|
@ -221,16 +179,16 @@ format](#session-sharing-format) except for dropping the signature.
|
|||
The Megolm session export format is thus as follows:
|
||||
|
||||
```
|
||||
+---+----+--------+--------+--------+--------+------+
|
||||
| V | i | R(i,0) | R(i,1) | R(i,2) | R(i,3) | Kpub |
|
||||
+---+----+--------+--------+--------+--------+------+
|
||||
0 1 5 37 69 101 133 165 bytes
|
||||
+---+----+------+------+
|
||||
| V | i | R(i) | Kpub |
|
||||
+---+----+------+------+
|
||||
0 1 5 37 69 bytes
|
||||
```
|
||||
|
||||
The version byte, ``V``, is ``"\x01"``.
|
||||
The version byte, ``V``, is ``"\x03"``.
|
||||
|
||||
This is followed by the ratchet index, $`i`$, which is encoded as a
|
||||
big-endian 32-bit integer; the ratchet values $`R_{i,j}`$; and the public
|
||||
big-endian 32-bit integer; the ratchet value $`R_{i}`$; and the public
|
||||
part of the Ed25519 keypair $`K`$.
|
||||
|
||||
### Message format
|
||||
|
|
142
flake.nix
142
flake.nix
|
@ -11,30 +11,126 @@
|
|||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, npmlock2nix }:
|
||||
let
|
||||
localOverlay = import ./nix/overlay.nix;
|
||||
pkgsForSystem = system: import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
(final: prev: {
|
||||
npmlock2nix = final.callPackage npmlock2nix {};
|
||||
node_modules = final.npmlock2nix.node_modules { src = ./javascript; };
|
||||
})
|
||||
localOverlay
|
||||
];
|
||||
};
|
||||
in (
|
||||
(
|
||||
# some systems cause issues, e.g. i686-linux is unsupported by gradle,
|
||||
# which causes "nix flake check" to fail. Investigate more later, but for
|
||||
# now, we will just allow x86_64-linux
|
||||
flake-utils.lib.eachSystem [ "x86_64-linux" "x86_64-darwin" "aarch64-darwin" ] (system: rec {
|
||||
legacyPackages = pkgsForSystem system;
|
||||
checks = {
|
||||
inherit (legacyPackages) olm-gcc-cmake olm-clang-cmake olm-gcc-make;
|
||||
};
|
||||
packages = {
|
||||
javascript = legacyPackages.olm-javascript;
|
||||
};
|
||||
}
|
||||
));
|
||||
flake-utils.lib.eachSystem [ "x86_64-linux" ] (system:
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
overlays = [
|
||||
(final: prev: {
|
||||
npmlock2nix = final.callPackage npmlock2nix {};
|
||||
})
|
||||
];
|
||||
};
|
||||
node_modules = pkgs.npmlock2nix.node_modules { src = ./javascript; };
|
||||
in
|
||||
rec {
|
||||
checks.gcc-cmake = pkgs.gccStdenv.mkDerivation {
|
||||
name = "olm";
|
||||
|
||||
buildInputs = [ pkgs.cmake ];
|
||||
|
||||
src = ./.;
|
||||
|
||||
buildPhase = ''
|
||||
cmake . -Bbuild
|
||||
cmake --build build
|
||||
'';
|
||||
|
||||
doCheck = true;
|
||||
checkPhase = ''
|
||||
cd build/tests
|
||||
ctest .
|
||||
cd ../..
|
||||
'';
|
||||
};
|
||||
|
||||
checks.clang-cmake = pkgs.clangStdenv.mkDerivation {
|
||||
name = "olm";
|
||||
|
||||
buildInputs = [ pkgs.cmake ];
|
||||
|
||||
src = ./.;
|
||||
|
||||
buildPhase = ''
|
||||
cmake . -Bbuild
|
||||
cmake --build build
|
||||
'';
|
||||
|
||||
doCheck = true;
|
||||
checkPhase = ''
|
||||
cd build/tests
|
||||
ctest .
|
||||
cd ../..
|
||||
'';
|
||||
};
|
||||
|
||||
checks.gcc-make = pkgs.gccStdenv.mkDerivation {
|
||||
name = "olm";
|
||||
|
||||
src = ./.;
|
||||
|
||||
buildPhase = ''
|
||||
make
|
||||
'';
|
||||
|
||||
doCheck = true;
|
||||
checkPhase = ''
|
||||
make test
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
make install PREFIX=$out
|
||||
'';
|
||||
};
|
||||
|
||||
packages.javascript = pkgs.buildEmscriptenPackage {
|
||||
pname = "olm";
|
||||
inherit (builtins.fromJSON (builtins.readFile ./javascript/package.json)) version;
|
||||
|
||||
buildInputs = with pkgs; [ gnumake python3 nodejs ];
|
||||
|
||||
src = ./.;
|
||||
|
||||
postPatch = ''
|
||||
patchShebangs .
|
||||
'';
|
||||
|
||||
configurePhase = "";
|
||||
|
||||
buildPhase = ''
|
||||
export EM_CACHE=$TMPDIR
|
||||
make javascript/exported_functions.json
|
||||
make js
|
||||
'';
|
||||
|
||||
output = [ "out" ];
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/javascript
|
||||
cd javascript
|
||||
echo sha256: > checksums.txt
|
||||
sha256sum olm.js olm_legacy.js olm.wasm >> checksums.txt
|
||||
echo sha512: >> checksums.txt
|
||||
sha512sum olm.js olm_legacy.js olm.wasm >> checksums.txt
|
||||
cp package.json olm.js olm.wasm olm_legacy.js index.d.ts README.md checksums.txt $out/javascript
|
||||
cd ..
|
||||
'';
|
||||
|
||||
checkPhase = ''
|
||||
cd javascript
|
||||
export HOME=$TMPDIR
|
||||
ln -s ${node_modules}/node_modules ./node_modules
|
||||
npm test
|
||||
cd ..
|
||||
'';
|
||||
};
|
||||
|
||||
packages.default = packages.javascript;
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -99,9 +99,9 @@ public:
|
|||
return *this;
|
||||
}
|
||||
T * this_pos = _data;
|
||||
const T * other_pos = other._data;
|
||||
T * const other_pos = other._data;
|
||||
while (other_pos != other._end) {
|
||||
*this_pos = *other_pos;
|
||||
*this_pos = *other;
|
||||
++this_pos;
|
||||
++other_pos;
|
||||
}
|
||||
|
|
|
@ -9,15 +9,15 @@
|
|||
# ifndef OLM_EXPORT
|
||||
# ifdef olm_EXPORTS
|
||||
/* We are building this library */
|
||||
# define OLM_EXPORT
|
||||
# define OLM_EXPORT __attribute__((visibility("default")))
|
||||
# else
|
||||
/* We are using this library */
|
||||
# define OLM_EXPORT
|
||||
# define OLM_EXPORT __attribute__((visibility("default")))
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef OLM_NO_EXPORT
|
||||
# define OLM_NO_EXPORT
|
||||
# define OLM_NO_EXPORT __attribute__((visibility("hidden")))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
|
16
javascript/index.d.ts
vendored
16
javascript/index.d.ts
vendored
|
@ -51,10 +51,7 @@ declare class Session {
|
|||
has_received_message(): boolean;
|
||||
matches_inbound(one_time_key_message: string): boolean;
|
||||
matches_inbound_from(identity_key: string, one_time_key_message: string): boolean;
|
||||
encrypt(plaintext: string): {
|
||||
type: 0 | 1; // 0: PreKey, 1: Message
|
||||
body: string;
|
||||
};
|
||||
encrypt(plaintext: string): object;
|
||||
decrypt(message_type: number, message: string): string;
|
||||
describe(): string;
|
||||
}
|
||||
|
@ -73,10 +70,7 @@ declare class InboundGroupSession {
|
|||
unpickle(key: string | Uint8Array, pickle: string): void;
|
||||
create(session_key: string): string;
|
||||
import_session(session_key: string): string;
|
||||
decrypt(message: string): {
|
||||
message_index: number;
|
||||
plaintext: string;
|
||||
};
|
||||
decrypt(message: string): object;
|
||||
session_id(): string;
|
||||
first_known_index(): number;
|
||||
export_session(message_index: number): string;
|
||||
|
@ -98,11 +92,7 @@ declare class PkEncryption {
|
|||
constructor();
|
||||
free(): void;
|
||||
set_recipient_key(key: string): void;
|
||||
encrypt(plaintext: string): {
|
||||
ciphertext: string;
|
||||
mac: string;
|
||||
ephemeral: string;
|
||||
};
|
||||
encrypt(plaintext: string): object;
|
||||
}
|
||||
|
||||
declare class PkDecryption {
|
||||
|
|
|
@ -14,6 +14,7 @@ if (typeof(window) !== 'undefined') {
|
|||
var bytes = nodeCrypto['randomBytes'](buf.length);
|
||||
buf.set(bytes);
|
||||
};
|
||||
process = global["process"];
|
||||
} else {
|
||||
throw new Error("Cannot find global to attach library to");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@matrix-org/olm",
|
||||
"version": "3.2.16",
|
||||
"version": "3.2.13",
|
||||
"description": "An implementation of the Double Ratchet cryptographic ratchet",
|
||||
"main": "olm.js",
|
||||
"files": [
|
||||
|
@ -31,5 +31,8 @@
|
|||
"homepage": "https://gitlab.matrix.org/matrix-org/olm",
|
||||
"devDependencies": {
|
||||
"jasmine": "^3.0.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"@matrix-org:registry":"https://gitlab.matrix.org/api/v4/projects/27/packages/npm/"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,123 +1,123 @@
|
|||
/*********************************************************************
|
||||
* Filename: aes.h
|
||||
* Author: Brad Conte (brad AT bradconte.com)
|
||||
* Copyright:
|
||||
* Disclaimer: This code is presented "as is" without any guarantees.
|
||||
* Details: Defines the API for the corresponding AES implementation.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef AES_H
|
||||
#define AES_H
|
||||
|
||||
/*************************** HEADER FILES ***************************/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
/****************************** MACROS ******************************/
|
||||
#define AES_BLOCK_SIZE 16 // AES operates on 16 bytes at a time
|
||||
|
||||
/**************************** DATA TYPES ****************************/
|
||||
typedef uint8_t BYTE; // 8-bit byte
|
||||
typedef uint32_t WORD; // 32-bit word, change to "long" for 16-bit machines
|
||||
|
||||
/*********************** FUNCTION DECLARATIONS **********************/
|
||||
///////////////////
|
||||
// AES
|
||||
///////////////////
|
||||
// Key setup must be done before any AES en/de-cryption functions can be used.
|
||||
void aes_key_setup(const BYTE key[], // The key, must be 128, 192, or 256 bits
|
||||
WORD w[], // Output key schedule to be used later
|
||||
int keysize); // Bit length of the key, 128, 192, or 256
|
||||
|
||||
void aes_encrypt(const BYTE in[], // 16 bytes of plaintext
|
||||
BYTE out[], // 16 bytes of ciphertext
|
||||
const WORD key[], // From the key setup
|
||||
int keysize); // Bit length of the key, 128, 192, or 256
|
||||
|
||||
void aes_decrypt(const BYTE in[], // 16 bytes of ciphertext
|
||||
BYTE out[], // 16 bytes of plaintext
|
||||
const WORD key[], // From the key setup
|
||||
int keysize); // Bit length of the key, 128, 192, or 256
|
||||
|
||||
///////////////////
|
||||
// AES - CBC
|
||||
///////////////////
|
||||
int aes_encrypt_cbc(const BYTE in[], // Plaintext
|
||||
size_t in_len, // Must be a multiple of AES_BLOCK_SIZE
|
||||
BYTE out[], // Ciphertext, same length as plaintext
|
||||
const WORD key[], // From the key setup
|
||||
int keysize, // Bit length of the key, 128, 192, or 256
|
||||
const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long
|
||||
|
||||
// Only output the CBC-MAC of the input.
|
||||
int aes_encrypt_cbc_mac(const BYTE in[], // plaintext
|
||||
size_t in_len, // Must be a multiple of AES_BLOCK_SIZE
|
||||
BYTE out[], // Output MAC
|
||||
const WORD key[], // From the key setup
|
||||
int keysize, // Bit length of the key, 128, 192, or 256
|
||||
const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long
|
||||
|
||||
///////////////////
|
||||
// AES - CTR
|
||||
///////////////////
|
||||
void increment_iv(BYTE iv[], // Must be a multiple of AES_BLOCK_SIZE
|
||||
int counter_size); // Bytes of the IV used for counting (low end)
|
||||
|
||||
void aes_encrypt_ctr(const BYTE in[], // Plaintext
|
||||
size_t in_len, // Any byte length
|
||||
BYTE out[], // Ciphertext, same length as plaintext
|
||||
const WORD key[], // From the key setup
|
||||
int keysize, // Bit length of the key, 128, 192, or 256
|
||||
const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long
|
||||
|
||||
void aes_decrypt_ctr(const BYTE in[], // Ciphertext
|
||||
size_t in_len, // Any byte length
|
||||
BYTE out[], // Plaintext, same length as ciphertext
|
||||
const WORD key[], // From the key setup
|
||||
int keysize, // Bit length of the key, 128, 192, or 256
|
||||
const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long
|
||||
|
||||
///////////////////
|
||||
// AES - CCM
|
||||
///////////////////
|
||||
// Returns True if the input parameters do not violate any constraint.
|
||||
int aes_encrypt_ccm(const BYTE plaintext[], // IN - Plaintext.
|
||||
WORD plaintext_len, // IN - Plaintext length.
|
||||
const BYTE associated_data[], // IN - Associated Data included in authentication, but not encryption.
|
||||
unsigned short associated_data_len, // IN - Associated Data length in bytes.
|
||||
const BYTE nonce[], // IN - The Nonce to be used for encryption.
|
||||
unsigned short nonce_len, // IN - Nonce length in bytes.
|
||||
BYTE ciphertext[], // OUT - Ciphertext, a concatination of the plaintext and the MAC.
|
||||
WORD *ciphertext_len, // OUT - The length of the ciphertext, always plaintext_len + mac_len.
|
||||
WORD mac_len, // IN - The desired length of the MAC, must be 4, 6, 8, 10, 12, 14, or 16.
|
||||
const BYTE key[], // IN - The AES key for encryption.
|
||||
int keysize); // IN - The length of the key in bits. Valid values are 128, 192, 256.
|
||||
|
||||
// Returns True if the input parameters do not violate any constraint.
|
||||
// Use mac_auth to ensure decryption/validation was preformed correctly.
|
||||
// If authentication does not succeed, the plaintext is zeroed out. To overwride
|
||||
// this, call with mac_auth = NULL. The proper proceedure is to decrypt with
|
||||
// authentication enabled (mac_auth != NULL) and make a second call to that
|
||||
// ignores authentication explicitly if the first call failes.
|
||||
int aes_decrypt_ccm(const BYTE ciphertext[], // IN - Ciphertext, the concatination of encrypted plaintext and MAC.
|
||||
WORD ciphertext_len, // IN - Ciphertext length in bytes.
|
||||
const BYTE assoc[], // IN - The Associated Data, required for authentication.
|
||||
unsigned short assoc_len, // IN - Associated Data length in bytes.
|
||||
const BYTE nonce[], // IN - The Nonce to use for decryption, same one as for encryption.
|
||||
unsigned short nonce_len, // IN - Nonce length in bytes.
|
||||
BYTE plaintext[], // OUT - The plaintext that was decrypted. Will need to be large enough to hold ciphertext_len - mac_len.
|
||||
WORD *plaintext_len, // OUT - Length in bytes of the output plaintext, always ciphertext_len - mac_len .
|
||||
WORD mac_len, // IN - The length of the MAC that was calculated.
|
||||
int *mac_auth, // OUT - TRUE if authentication succeeded, FALSE if it did not. NULL pointer will ignore the authentication.
|
||||
const BYTE key[], // IN - The AES key for decryption.
|
||||
int keysize); // IN - The length of the key in BITS. Valid values are 128, 192, 256.
|
||||
|
||||
///////////////////
|
||||
// Test functions
|
||||
///////////////////
|
||||
int aes_test();
|
||||
int aes_ecb_test();
|
||||
int aes_cbc_test();
|
||||
int aes_ctr_test();
|
||||
int aes_ccm_test();
|
||||
|
||||
#endif // AES_H
|
||||
/*********************************************************************
|
||||
* Filename: aes.h
|
||||
* Author: Brad Conte (brad AT bradconte.com)
|
||||
* Copyright:
|
||||
* Disclaimer: This code is presented "as is" without any guarantees.
|
||||
* Details: Defines the API for the corresponding AES implementation.
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef AES_H
|
||||
#define AES_H
|
||||
|
||||
/*************************** HEADER FILES ***************************/
|
||||
#include <stddef.h>
|
||||
|
||||
/****************************** MACROS ******************************/
|
||||
#define AES_BLOCK_SIZE 16 // AES operates on 16 bytes at a time
|
||||
|
||||
/**************************** DATA TYPES ****************************/
|
||||
typedef unsigned char BYTE; // 8-bit byte
|
||||
typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines
|
||||
|
||||
/*********************** FUNCTION DECLARATIONS **********************/
|
||||
///////////////////
|
||||
// AES
|
||||
///////////////////
|
||||
// Key setup must be done before any AES en/de-cryption functions can be used.
|
||||
void aes_key_setup(const BYTE key[], // The key, must be 128, 192, or 256 bits
|
||||
WORD w[], // Output key schedule to be used later
|
||||
int keysize); // Bit length of the key, 128, 192, or 256
|
||||
|
||||
void aes_encrypt(const BYTE in[], // 16 bytes of plaintext
|
||||
BYTE out[], // 16 bytes of ciphertext
|
||||
const WORD key[], // From the key setup
|
||||
int keysize); // Bit length of the key, 128, 192, or 256
|
||||
|
||||
void aes_decrypt(const BYTE in[], // 16 bytes of ciphertext
|
||||
BYTE out[], // 16 bytes of plaintext
|
||||
const WORD key[], // From the key setup
|
||||
int keysize); // Bit length of the key, 128, 192, or 256
|
||||
|
||||
///////////////////
|
||||
// AES - CBC
|
||||
///////////////////
|
||||
int aes_encrypt_cbc(const BYTE in[], // Plaintext
|
||||
size_t in_len, // Must be a multiple of AES_BLOCK_SIZE
|
||||
BYTE out[], // Ciphertext, same length as plaintext
|
||||
const WORD key[], // From the key setup
|
||||
int keysize, // Bit length of the key, 128, 192, or 256
|
||||
const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long
|
||||
|
||||
// Only output the CBC-MAC of the input.
|
||||
int aes_encrypt_cbc_mac(const BYTE in[], // plaintext
|
||||
size_t in_len, // Must be a multiple of AES_BLOCK_SIZE
|
||||
BYTE out[], // Output MAC
|
||||
const WORD key[], // From the key setup
|
||||
int keysize, // Bit length of the key, 128, 192, or 256
|
||||
const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long
|
||||
|
||||
///////////////////
|
||||
// AES - CTR
|
||||
///////////////////
|
||||
void increment_iv(BYTE iv[], // Must be a multiple of AES_BLOCK_SIZE
|
||||
int counter_size); // Bytes of the IV used for counting (low end)
|
||||
|
||||
void aes_encrypt_ctr(const BYTE in[], // Plaintext
|
||||
size_t in_len, // Any byte length
|
||||
BYTE out[], // Ciphertext, same length as plaintext
|
||||
const WORD key[], // From the key setup
|
||||
int keysize, // Bit length of the key, 128, 192, or 256
|
||||
const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long
|
||||
|
||||
void aes_decrypt_ctr(const BYTE in[], // Ciphertext
|
||||
size_t in_len, // Any byte length
|
||||
BYTE out[], // Plaintext, same length as ciphertext
|
||||
const WORD key[], // From the key setup
|
||||
int keysize, // Bit length of the key, 128, 192, or 256
|
||||
const BYTE iv[]); // IV, must be AES_BLOCK_SIZE bytes long
|
||||
|
||||
///////////////////
|
||||
// AES - CCM
|
||||
///////////////////
|
||||
// Returns True if the input parameters do not violate any constraint.
|
||||
int aes_encrypt_ccm(const BYTE plaintext[], // IN - Plaintext.
|
||||
WORD plaintext_len, // IN - Plaintext length.
|
||||
const BYTE associated_data[], // IN - Associated Data included in authentication, but not encryption.
|
||||
unsigned short associated_data_len, // IN - Associated Data length in bytes.
|
||||
const BYTE nonce[], // IN - The Nonce to be used for encryption.
|
||||
unsigned short nonce_len, // IN - Nonce length in bytes.
|
||||
BYTE ciphertext[], // OUT - Ciphertext, a concatination of the plaintext and the MAC.
|
||||
WORD *ciphertext_len, // OUT - The length of the ciphertext, always plaintext_len + mac_len.
|
||||
WORD mac_len, // IN - The desired length of the MAC, must be 4, 6, 8, 10, 12, 14, or 16.
|
||||
const BYTE key[], // IN - The AES key for encryption.
|
||||
int keysize); // IN - The length of the key in bits. Valid values are 128, 192, 256.
|
||||
|
||||
// Returns True if the input parameters do not violate any constraint.
|
||||
// Use mac_auth to ensure decryption/validation was preformed correctly.
|
||||
// If authentication does not succeed, the plaintext is zeroed out. To overwride
|
||||
// this, call with mac_auth = NULL. The proper proceedure is to decrypt with
|
||||
// authentication enabled (mac_auth != NULL) and make a second call to that
|
||||
// ignores authentication explicitly if the first call failes.
|
||||
int aes_decrypt_ccm(const BYTE ciphertext[], // IN - Ciphertext, the concatination of encrypted plaintext and MAC.
|
||||
WORD ciphertext_len, // IN - Ciphertext length in bytes.
|
||||
const BYTE assoc[], // IN - The Associated Data, required for authentication.
|
||||
unsigned short assoc_len, // IN - Associated Data length in bytes.
|
||||
const BYTE nonce[], // IN - The Nonce to use for decryption, same one as for encryption.
|
||||
unsigned short nonce_len, // IN - Nonce length in bytes.
|
||||
BYTE plaintext[], // OUT - The plaintext that was decrypted. Will need to be large enough to hold ciphertext_len - mac_len.
|
||||
WORD *plaintext_len, // OUT - Length in bytes of the output plaintext, always ciphertext_len - mac_len .
|
||||
WORD mac_len, // IN - The length of the MAC that was calculated.
|
||||
int *mac_auth, // OUT - TRUE if authentication succeeded, FALSE if it did not. NULL pointer will ignore the authentication.
|
||||
const BYTE key[], // IN - The AES key for decryption.
|
||||
int keysize); // IN - The length of the key in BITS. Valid values are 128, 192, 256.
|
||||
|
||||
///////////////////
|
||||
// Test functions
|
||||
///////////////////
|
||||
int aes_test();
|
||||
int aes_ecb_test();
|
||||
int aes_cbc_test();
|
||||
int aes_ctr_test();
|
||||
int aes_ccm_test();
|
||||
|
||||
#endif // AES_H
|
||||
|
|
|
@ -11,14 +11,13 @@
|
|||
|
||||
/*************************** HEADER FILES ***************************/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************** MACROS ******************************/
|
||||
#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
|
||||
|
||||
/**************************** DATA TYPES ****************************/
|
||||
typedef uint8_t BYTE; // 8-bit byte
|
||||
typedef uint32_t WORD; // 32-bit word, change to "long" for 16-bit machines
|
||||
typedef unsigned char BYTE; // 8-bit byte
|
||||
typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines
|
||||
|
||||
typedef struct {
|
||||
BYTE data[64];
|
||||
|
|
|
@ -4498,7 +4498,7 @@ namespace {
|
|||
sigaltstack(&sigStack, &oldSigStack);
|
||||
struct sigaction sa = {};
|
||||
sa.sa_handler = handleSignal; // NOLINT
|
||||
sa.sa_flags = SS_ONSTACK;
|
||||
sa.sa_flags = SA_ONSTACK;
|
||||
for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
|
||||
sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
|
||||
}
|
||||
|
|
|
@ -1684,7 +1684,7 @@ namespace {
|
|||
sigaltstack(&sigStack, &oldSigStack);
|
||||
struct sigaction sa = {};
|
||||
sa.sa_handler = handleSignal; // NOLINT
|
||||
sa.sa_flags = SS_ONSTACK;
|
||||
sa.sa_flags = SA_ONSTACK;
|
||||
for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
|
||||
sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
|
||||
}
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
final: prev: {
|
||||
olm-gcc-cmake = prev.gccStdenv.mkDerivation {
|
||||
name = "olm_gcc_cmake";
|
||||
|
||||
src = ./..;
|
||||
|
||||
nativeBuildInputs = [ prev.cmake ];
|
||||
doCheck = true;
|
||||
checkPhase = ''
|
||||
(cd tests && ctest . -j $NIX_BUILD_CORES)
|
||||
'';
|
||||
};
|
||||
|
||||
olm-clang-cmake = prev.clangStdenv.mkDerivation {
|
||||
name = "olm_clang_cmake";
|
||||
|
||||
src = ./..;
|
||||
|
||||
nativeBuildInputs = [ prev.cmake ];
|
||||
|
||||
doCheck = true;
|
||||
checkPhase = ''
|
||||
(cd tests && ctest . -j $NIX_BUILD_CORES)
|
||||
'';
|
||||
};
|
||||
|
||||
olm-gcc-make = prev.gccStdenv.mkDerivation {
|
||||
name = "olm";
|
||||
|
||||
src = ./..;
|
||||
|
||||
doCheck = true;
|
||||
makeFlags = [ "PREFIX=$out" ];
|
||||
};
|
||||
|
||||
olm-javascript = final.buildEmscriptenPackage {
|
||||
pname = "olm_javascript";
|
||||
inherit (builtins.fromJSON (builtins.readFile ../javascript/package.json)) version;
|
||||
|
||||
src = ./..;
|
||||
|
||||
nativeBuildInputs = with prev; [ gnumake python3 nodejs ];
|
||||
|
||||
postPatch = ''
|
||||
patchShebangs .
|
||||
'';
|
||||
|
||||
configurePhase = false;
|
||||
|
||||
buildPhase = ''
|
||||
export EM_CACHE=$TMPDIR
|
||||
make javascript/exported_functions.json
|
||||
make js
|
||||
'';
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/javascript
|
||||
cd javascript
|
||||
echo sha256: > checksums.txt
|
||||
sha256sum olm.js olm_legacy.js olm.wasm >> checksums.txt
|
||||
echo sha512: >> checksums.txt
|
||||
sha512sum olm.js olm_legacy.js olm.wasm >> checksums.txt
|
||||
cp package.json olm.js olm.wasm olm_legacy.js index.d.ts README.md checksums.txt $out/javascript
|
||||
cd ..
|
||||
'';
|
||||
|
||||
checkPhase = ''
|
||||
cd javascript
|
||||
export HOME=$TMPDIR
|
||||
ln -s ${final.node_modules}/node_modules ./node_modules
|
||||
npm test
|
||||
cd ..
|
||||
'';
|
||||
};
|
||||
|
||||
}
|
|
@ -34,7 +34,7 @@ test:python:
|
|||
image: docker.io/python:$PYTHON_VERSIONS
|
||||
parallel:
|
||||
matrix:
|
||||
- PYTHON_VERSIONS: [ "3.8", "3.9", "3.10", "3.11", "3.12" ]
|
||||
- PYTHON_VERSIONS: [ "3.6", "3.7", "3.8", "3.9" ]
|
||||
script:
|
||||
- pip install tox
|
||||
- make headers
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
include include/olm/*.h
|
||||
include include/olm/olm.h
|
||||
include include/olm/pk.h
|
||||
include include/olm/sas.h
|
||||
include Makefile
|
||||
include olm_build.py
|
||||
|
|
|
@ -15,18 +15,6 @@ found [here][6].
|
|||
|
||||
The full API reference can be found [here][7].
|
||||
|
||||
# Installation instructions
|
||||
|
||||
To install from the source package, you will need:
|
||||
|
||||
- cmake (recommended) or GNU make
|
||||
- a C/C++ compiler
|
||||
|
||||
You can then run `pip install python-olm`.
|
||||
|
||||
This should work in UNIX-like environments, including macOS, and may work in
|
||||
other environments too, but is known to not work yet in Windows.
|
||||
|
||||
# Accounts
|
||||
|
||||
Accounts create and hold the central identity of the Olm protocol, they consist of a fingerprint and identity
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
DIR=$(mktemp -d)
|
||||
SRC=$(pwd)
|
||||
|
||||
echo "Making headers"
|
||||
make headers
|
||||
|
||||
cd $DIR
|
||||
|
||||
echo "Copying python module"
|
||||
cp -a $SRC/* .
|
||||
mkdir -p libolm
|
||||
echo "Cleaning sources"
|
||||
make clean > /dev/null
|
||||
cp -a $SRC/include .
|
||||
echo "Copying libolm sources"
|
||||
for src in cmake CMakeLists.txt common.mk include lib Makefile olm.pc.in src tests; do
|
||||
cp -a $SRC/../$src libolm
|
||||
done
|
||||
find libolm -name \*~ -delete
|
||||
find libolm -name \#\*\# -delete
|
||||
|
||||
echo "Building"
|
||||
patch -p1 < $SRC/packaging.diff
|
||||
python3 -m build -s
|
||||
|
||||
echo "Copying result"
|
||||
mkdir -p $SRC/dist
|
||||
cp dist/* $SRC/dist
|
||||
|
||||
echo "Cleaning up"
|
||||
cd $SRC
|
||||
rm -rf $DIR
|
9
python/olm/__version__.py
Normal file
9
python/olm/__version__.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
__title__ = "python-olm"
|
||||
__description__ = ("python CFFI bindings for the olm "
|
||||
"cryptographic ratchet library")
|
||||
__url__ = "https://github.com/poljar/python-olm"
|
||||
__version__ = "3.2.13"
|
||||
__author__ = "Damir Jelić"
|
||||
__author_email__ = "poljar@termina.org.uk"
|
||||
__license__ = "Apache 2.0"
|
||||
__copyright__ = "Copyright 2018-2019 Damir Jelić"
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
This is designed for avoiding __del__.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import traceback
|
||||
|
|
|
@ -32,6 +32,8 @@ import json
|
|||
from builtins import bytes, super
|
||||
from typing import AnyStr, Dict, Optional, Type
|
||||
|
||||
from future.utils import bytes_to_native_str
|
||||
|
||||
# pylint: disable=no-name-in-module
|
||||
from _libolm import ffi, lib # type: ignore
|
||||
|
||||
|
@ -91,7 +93,8 @@ class Account(object):
|
|||
if ret != lib.olm_error():
|
||||
return
|
||||
|
||||
last_error = ffi.string((lib.olm_account_last_error(self._account))).decode()
|
||||
last_error = bytes_to_native_str(
|
||||
ffi.string((lib.olm_account_last_error(self._account))))
|
||||
|
||||
raise OlmAccountError(last_error)
|
||||
|
||||
|
@ -206,7 +209,7 @@ class Account(object):
|
|||
for i in range(0, len(bytes_message)):
|
||||
bytes_message[i] = 0
|
||||
|
||||
return ffi.unpack(out_buffer, out_length).decode()
|
||||
return bytes_to_native_str(ffi.unpack(out_buffer, out_length))
|
||||
|
||||
@property
|
||||
def max_one_time_keys(self):
|
||||
|
|
|
@ -28,6 +28,8 @@ Examples:
|
|||
from builtins import bytes, super
|
||||
from typing import AnyStr, Optional, Tuple, Type
|
||||
|
||||
from future.utils import bytes_to_native_str
|
||||
|
||||
# pylint: disable=no-name-in-module
|
||||
from _libolm import ffi, lib # type: ignore
|
||||
|
||||
|
@ -169,9 +171,8 @@ class InboundGroupSession(object):
|
|||
if ret != lib.olm_error():
|
||||
return
|
||||
|
||||
last_error = ffi.string(
|
||||
lib.olm_inbound_group_session_last_error(self._session)
|
||||
).decode()
|
||||
last_error = bytes_to_native_str(ffi.string(
|
||||
lib.olm_inbound_group_session_last_error(self._session)))
|
||||
|
||||
raise OlmGroupSessionError(last_error)
|
||||
|
||||
|
@ -251,7 +252,7 @@ class InboundGroupSession(object):
|
|||
id_length
|
||||
)
|
||||
self._check_error(ret)
|
||||
return ffi.unpack(id_buffer, id_length).decode()
|
||||
return bytes_to_native_str(ffi.unpack(id_buffer, id_length))
|
||||
|
||||
@property
|
||||
def first_known_index(self):
|
||||
|
@ -289,7 +290,7 @@ class InboundGroupSession(object):
|
|||
message_index
|
||||
)
|
||||
self._check_error(ret)
|
||||
export_str = ffi.unpack(export_buffer, export_length).decode()
|
||||
export_str = bytes_to_native_str(ffi.unpack(export_buffer, export_length))
|
||||
|
||||
# clear out copies of the key
|
||||
lib.memset(export_buffer, 0, export_length)
|
||||
|
@ -372,9 +373,9 @@ class OutboundGroupSession(object):
|
|||
if ret != lib.olm_error():
|
||||
return
|
||||
|
||||
last_error = ffi.string(
|
||||
last_error = bytes_to_native_str(ffi.string(
|
||||
lib.olm_outbound_group_session_last_error(self._session)
|
||||
).decode()
|
||||
))
|
||||
|
||||
raise OlmGroupSessionError(last_error)
|
||||
|
||||
|
@ -482,7 +483,7 @@ class OutboundGroupSession(object):
|
|||
for i in range(0, len(byte_plaintext)):
|
||||
byte_plaintext[i] = 0
|
||||
|
||||
return ffi.unpack(message_buffer, message_length).decode()
|
||||
return bytes_to_native_str(ffi.unpack(message_buffer, message_length))
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
|
@ -498,7 +499,7 @@ class OutboundGroupSession(object):
|
|||
)
|
||||
self._check_error(ret)
|
||||
|
||||
return ffi.unpack(id_buffer, id_length).decode()
|
||||
return bytes_to_native_str(ffi.unpack(id_buffer, id_length))
|
||||
|
||||
@property
|
||||
def message_index(self):
|
||||
|
@ -528,4 +529,4 @@ class OutboundGroupSession(object):
|
|||
)
|
||||
self._check_error(ret)
|
||||
|
||||
return ffi.unpack(key_buffer, key_length).decode()
|
||||
return bytes_to_native_str(ffi.unpack(key_buffer, key_length))
|
||||
|
|
|
@ -36,6 +36,8 @@ Examples:
|
|||
from builtins import super
|
||||
from typing import AnyStr, Type
|
||||
|
||||
from future.utils import bytes_to_native_str
|
||||
|
||||
from _libolm import ffi, lib # type: ignore
|
||||
|
||||
from ._compat import URANDOM, to_bytearray, to_unicode_str
|
||||
|
@ -114,9 +116,8 @@ class PkEncryption(object):
|
|||
if ret != lib.olm_error():
|
||||
return
|
||||
|
||||
last_error = ffi.string(
|
||||
lib.olm_pk_encryption_last_error(self._pk_encryption)
|
||||
).decode()
|
||||
last_error = bytes_to_native_str(
|
||||
ffi.string(lib.olm_pk_encryption_last_error(self._pk_encryption)))
|
||||
|
||||
raise PkEncryptionError(last_error)
|
||||
|
||||
|
@ -165,9 +166,12 @@ class PkEncryption(object):
|
|||
byte_plaintext[i] = 0
|
||||
|
||||
message = PkMessage(
|
||||
ffi.unpack(ephemeral_key, ephemeral_key_size).decode(),
|
||||
ffi.unpack(mac, mac_length).decode(),
|
||||
ffi.unpack(ciphertext, ciphertext_length).decode(),
|
||||
bytes_to_native_str(
|
||||
ffi.unpack(ephemeral_key, ephemeral_key_size)),
|
||||
bytes_to_native_str(
|
||||
ffi.unpack(mac, mac_length)),
|
||||
bytes_to_native_str(
|
||||
ffi.unpack(ciphertext, ciphertext_length))
|
||||
)
|
||||
return message
|
||||
|
||||
|
@ -213,19 +217,18 @@ class PkDecryption(object):
|
|||
random_buffer, random_length
|
||||
)
|
||||
self._check_error(ret)
|
||||
self.public_key: str = ffi.unpack(
|
||||
self.public_key: str = bytes_to_native_str(ffi.unpack(
|
||||
key_buffer,
|
||||
key_length
|
||||
).decode()
|
||||
))
|
||||
|
||||
def _check_error(self, ret):
|
||||
# type: (int) -> None
|
||||
if ret != lib.olm_error():
|
||||
return
|
||||
|
||||
last_error = ffi.string(
|
||||
lib.olm_pk_decryption_last_error(self._pk_decryption)
|
||||
).decode()
|
||||
last_error = bytes_to_native_str(
|
||||
ffi.string(lib.olm_pk_decryption_last_error(self._pk_decryption)))
|
||||
|
||||
raise PkDecryptionError(last_error)
|
||||
|
||||
|
@ -303,10 +306,10 @@ class PkDecryption(object):
|
|||
for i in range(0, len(byte_key)):
|
||||
byte_key[i] = 0
|
||||
|
||||
obj.public_key = ffi.unpack(
|
||||
obj.public_key = bytes_to_native_str(ffi.unpack(
|
||||
pubkey_buffer,
|
||||
pubkey_length
|
||||
).decode()
|
||||
))
|
||||
|
||||
return obj
|
||||
|
||||
|
@ -408,14 +411,17 @@ class PkSigning(object):
|
|||
|
||||
self._check_error(ret)
|
||||
|
||||
self.public_key = ffi.unpack(pubkey_buffer, pubkey_length).decode()
|
||||
self.public_key = bytes_to_native_str(
|
||||
ffi.unpack(pubkey_buffer, pubkey_length)
|
||||
)
|
||||
|
||||
def _check_error(self, ret):
|
||||
# type: (int) -> None
|
||||
if ret != lib.olm_error():
|
||||
return
|
||||
|
||||
last_error = ffi.string(lib.olm_pk_signing_last_error(self._pk_signing)).decode()
|
||||
last_error = bytes_to_native_str(
|
||||
ffi.string(lib.olm_pk_signing_last_error(self._pk_signing)))
|
||||
|
||||
raise PkSigningError(last_error)
|
||||
|
||||
|
@ -450,4 +456,6 @@ class PkSigning(object):
|
|||
signature_buffer, signature_length)
|
||||
self._check_error(ret)
|
||||
|
||||
return ffi.unpack(signature_buffer, signature_length).decode()
|
||||
return bytes_to_native_str(
|
||||
ffi.unpack(signature_buffer, signature_length)
|
||||
)
|
||||
|
|
|
@ -34,6 +34,8 @@ from builtins import bytes
|
|||
from functools import wraps
|
||||
from typing import Optional
|
||||
|
||||
from future.utils import bytes_to_native_str
|
||||
|
||||
from _libolm import ffi, lib
|
||||
|
||||
from ._compat import URANDOM, to_bytearray, to_bytes
|
||||
|
@ -90,7 +92,8 @@ class Sas(object):
|
|||
if ret != lib.olm_error():
|
||||
return
|
||||
|
||||
last_error = ffi.string((lib.olm_sas_last_error(self._sas))).decode()
|
||||
last_error = bytes_to_native_str(
|
||||
ffi.string((lib.olm_sas_last_error(self._sas))))
|
||||
|
||||
raise OlmSasError(last_error)
|
||||
|
||||
|
@ -112,7 +115,7 @@ class Sas(object):
|
|||
lib.olm_sas_get_pubkey(self._sas, pubkey_buffer, pubkey_length)
|
||||
)
|
||||
|
||||
return ffi.unpack(pubkey_buffer, pubkey_length).decode()
|
||||
return bytes_to_native_str(ffi.unpack(pubkey_buffer, pubkey_length))
|
||||
|
||||
@property
|
||||
def other_key_set(self):
|
||||
|
@ -205,7 +208,7 @@ class Sas(object):
|
|||
mac_length
|
||||
)
|
||||
)
|
||||
return ffi.unpack(mac_buffer, mac_length).decode()
|
||||
return bytes_to_native_str(ffi.unpack(mac_buffer, mac_length))
|
||||
|
||||
def calculate_mac_fixed_base64(self, message, extra_info):
|
||||
# type: (str, str) -> str
|
||||
|
@ -239,7 +242,7 @@ class Sas(object):
|
|||
mac_length
|
||||
)
|
||||
)
|
||||
return ffi.unpack(mac_buffer, mac_length).decode()
|
||||
return bytes_to_native_str(ffi.unpack(mac_buffer, mac_length))
|
||||
|
||||
def calculate_mac_long_kdf(self, message, extra_info):
|
||||
# type: (str, str) -> str
|
||||
|
@ -273,4 +276,4 @@ class Sas(object):
|
|||
mac_length
|
||||
)
|
||||
)
|
||||
return ffi.unpack(mac_buffer, mac_length).decode()
|
||||
return bytes_to_native_str(ffi.unpack(mac_buffer, mac_length))
|
||||
|
|
|
@ -35,6 +35,8 @@ Examples:
|
|||
from builtins import bytes, super
|
||||
from typing import AnyStr, Optional, Type
|
||||
|
||||
from future.utils import bytes_to_native_str
|
||||
|
||||
# pylint: disable=no-name-in-module
|
||||
from _libolm import ffi, lib # type: ignore
|
||||
|
||||
|
@ -144,7 +146,8 @@ class Session(object):
|
|||
if ret != lib.olm_error():
|
||||
return
|
||||
|
||||
last_error = ffi.string(lib.olm_session_last_error(self._session)).decode()
|
||||
last_error = bytes_to_native_str(
|
||||
ffi.string(lib.olm_session_last_error(self._session)))
|
||||
|
||||
raise OlmSessionError(last_error)
|
||||
|
||||
|
@ -257,16 +260,16 @@ class Session(object):
|
|||
|
||||
if message_type == lib.OLM_MESSAGE_TYPE_PRE_KEY:
|
||||
return OlmPreKeyMessage(
|
||||
ffi.unpack(
|
||||
bytes_to_native_str(ffi.unpack(
|
||||
ciphertext_buffer,
|
||||
ciphertext_length
|
||||
).decode())
|
||||
)))
|
||||
elif message_type == lib.OLM_MESSAGE_TYPE_MESSAGE:
|
||||
return OlmMessage(
|
||||
ffi.unpack(
|
||||
bytes_to_native_str(ffi.unpack(
|
||||
ciphertext_buffer,
|
||||
ciphertext_length
|
||||
).decode())
|
||||
)))
|
||||
else: # pragma: no cover
|
||||
raise ValueError("Unknown message type")
|
||||
|
||||
|
@ -337,7 +340,7 @@ class Session(object):
|
|||
self._check_error(
|
||||
lib.olm_session_id(self._session, id_buffer, id_length)
|
||||
)
|
||||
return ffi.unpack(id_buffer, id_length).decode()
|
||||
return bytes_to_native_str(ffi.unpack(id_buffer, id_length))
|
||||
|
||||
def matches(self, message, identity_key=None):
|
||||
# type: (OlmPreKeyMessage, Optional[AnyStr]) -> bool
|
||||
|
@ -404,7 +407,7 @@ class Session(object):
|
|||
lib.olm_session_describe(
|
||||
self._session, describe_buffer, buffer_length
|
||||
)
|
||||
return ffi.string(describe_buffer).decode()
|
||||
return bytes_to_native_str(ffi.string(describe_buffer))
|
||||
|
||||
|
||||
class InboundSession(Session):
|
||||
|
|
|
@ -33,6 +33,8 @@ Examples:
|
|||
# pylint: disable=redefined-builtin,unused-import
|
||||
from typing import AnyStr, Type
|
||||
|
||||
from future.utils import bytes_to_native_str
|
||||
|
||||
# pylint: disable=no-name-in-module
|
||||
from _libolm import ffi, lib # type: ignore
|
||||
|
||||
|
@ -121,7 +123,7 @@ class _Utility(object):
|
|||
|
||||
cls._check_error(ret, OlmHashError)
|
||||
|
||||
return ffi.unpack(hash, hash_length).decode()
|
||||
return bytes_to_native_str(ffi.unpack(hash, hash_length))
|
||||
|
||||
|
||||
def ed25519_verify(key, message, signature):
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
@ -26,10 +28,18 @@ PATH = os.path.dirname(__file__)
|
|||
DEVELOP = os.environ.get("DEVELOP")
|
||||
|
||||
compile_args = ["-I../include"]
|
||||
link_args = ["-L../build"]
|
||||
|
||||
if DEVELOP and DEVELOP.lower() in ["yes", "true", "1"]:
|
||||
link_args.append('-Wl,-rpath=../build')
|
||||
|
||||
# If libolm is compiled statically, we may need to link to the C++ standard
|
||||
# library dynamically. This flag allows passing the required linker flag to do
|
||||
# so.
|
||||
CXX_LIB = os.environ.get("CXX_LIB")
|
||||
if CXX_LIB:
|
||||
link_args.append(CXX_LIB)
|
||||
|
||||
headers_build = subprocess.Popen("make headers", shell=True)
|
||||
headers_build.wait()
|
||||
|
||||
|
@ -43,10 +53,8 @@ ffibuilder.set_source(
|
|||
#include <olm/sas.h>
|
||||
""",
|
||||
libraries=["olm"],
|
||||
library_dirs=[os.path.join("..", "build")],
|
||||
extra_compile_args=compile_args,
|
||||
source_extension=".cpp", # we need to link the C++ standard library, so use a C++ extension
|
||||
)
|
||||
extra_link_args=link_args)
|
||||
|
||||
with open(os.path.join(PATH, "include/olm/error.h")) as f:
|
||||
ffibuilder.cdef(f.read(), override=True)
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
--- a/MANIFEST.in
|
||||
+++ b/MANIFEST.in
|
||||
@@ -1,3 +1,8 @@
|
||||
include include/olm/*.h
|
||||
-include Makefile
|
||||
include olm_build.py
|
||||
+include libolm/*
|
||||
+include libolm/cmake/*
|
||||
+include libolm/include/olm/*
|
||||
+recursive-include libolm/lib *
|
||||
+include libolm/src/*
|
||||
+recursive-include libolm/tests *
|
||||
--- a/olm_build.py
|
||||
+++ b/olm_build.py
|
||||
@@ -25,12 +25,29 @@
|
||||
|
||||
DEVELOP = os.environ.get("DEVELOP")
|
||||
|
||||
-compile_args = ["-I../include"]
|
||||
+compile_args = ["-Ilibolm/include"]
|
||||
|
||||
if DEVELOP and DEVELOP.lower() in ["yes", "true", "1"]:
|
||||
link_args.append('-Wl,-rpath=../build')
|
||||
|
||||
-headers_build = subprocess.Popen("make headers", shell=True)
|
||||
-headers_build.wait()
|
||||
+# Try to build with cmake first, fall back to GNU make
|
||||
+try:
|
||||
+ subprocess.run(
|
||||
+ ["cmake", ".", "-Bbuild", "-DBUILD_SHARED_LIBS=NO"],
|
||||
+ cwd="libolm", check=True,
|
||||
+ )
|
||||
+ subprocess.run(
|
||||
+ ["cmake", "--build", "build"],
|
||||
+ cwd="libolm", check=True,
|
||||
+ )
|
||||
+except FileNotFoundError:
|
||||
+ try:
|
||||
+ # try "gmake" first because some systems have a non-GNU make
|
||||
+ # installed as "make"
|
||||
+ subprocess.run(["gmake", "static"], cwd="libolm", check=True)
|
||||
+ except FileNotFoundError:
|
||||
+ # some systems have GNU make installed without the leading "g"
|
||||
+ # so give that a try (though this may fail if it isn't GNU make)
|
||||
+ subprocess.run(["make", "static"], cwd="libolm", check=True)
|
||||
|
||||
ffibuilder.set_source(
|
||||
@@ -43,7 +60,7 @@
|
||||
#include <olm/sas.h>
|
||||
""",
|
||||
libraries=["olm"],
|
||||
- library_dirs=[os.path.join("..", "build")],
|
||||
+ library_dirs=[os.path.join("libolm", "build")],
|
||||
extra_compile_args=compile_args,
|
||||
source_extension=".cpp", # we need to link the C++ standard library, so use a C++ extension
|
||||
)
|
|
@ -1,22 +0,0 @@
|
|||
[build-system]
|
||||
requires = ["setuptools", "cffi>=1.0.0"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "python-olm"
|
||||
version = "3.2.16"
|
||||
description = "python CFFI bindings for the olm cryptographic ratchet library"
|
||||
authors = [{name = "Damir Jelić", email = "poljar@termina.org.uk"}]
|
||||
license = {text = "Apache-2.0"}
|
||||
readme = "README.md"
|
||||
classifiers = [
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"Topic :: Communications",
|
||||
]
|
||||
dependencies = ["cffi>=1.0.0"]
|
||||
|
||||
[project.urls]
|
||||
homepage = "https://gitlab.matrix.org/matrix-org/olm/-/tree/master/python"
|
||||
|
||||
[tool.setuptools]
|
||||
packages = [ "olm" ]
|
|
@ -1,2 +1,3 @@
|
|||
future
|
||||
cffi
|
||||
typing
|
||||
|
|
|
@ -3,3 +3,6 @@ testpaths = tests
|
|||
flake8-ignore =
|
||||
olm/*.py F401
|
||||
tests/*.py W503
|
||||
|
||||
[coverage:run]
|
||||
omit=olm/__version__.py
|
||||
|
|
|
@ -1,6 +1,34 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
from codecs import open
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
about = {}
|
||||
with open(os.path.join(here, "olm", "__version__.py"), "r", "utf-8") as f:
|
||||
exec(f.read(), about)
|
||||
|
||||
setup(
|
||||
cffi_modules=["olm_build.py:ffibuilder"]
|
||||
name=about["__title__"],
|
||||
version=about["__version__"],
|
||||
description=about["__description__"],
|
||||
author=about["__author__"],
|
||||
author_email=about["__author_email__"],
|
||||
url=about["__url__"],
|
||||
license=about["__license__"],
|
||||
packages=["olm"],
|
||||
setup_requires=["cffi>=1.0.0"],
|
||||
cffi_modules=["olm_build.py:ffibuilder"],
|
||||
install_requires=[
|
||||
"cffi>=1.0.0",
|
||||
"future",
|
||||
"typing;python_version<'3.5'"
|
||||
],
|
||||
zip_safe=False,
|
||||
package_data={
|
||||
"olm": ["py.typed"]
|
||||
}
|
||||
)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import base64
|
||||
import hashlib
|
||||
|
||||
from future.utils import bytes_to_native_str
|
||||
|
||||
from olm import sha256
|
||||
from olm._compat import to_bytes
|
||||
|
||||
|
@ -17,7 +19,7 @@ class TestClass(object):
|
|||
hashlib.sha256(to_bytes(input1)).digest()
|
||||
)
|
||||
|
||||
hashlib_hash = hashlib_hash[:-1].decode()
|
||||
hashlib_hash = bytes_to_native_str(hashlib_hash[:-1])
|
||||
|
||||
assert first_hash != second_hash
|
||||
assert hashlib_hash == first_hash
|
||||
|
|
|
@ -6,7 +6,7 @@ envlist = py27,py36,pypy,{py2,py3}-cov,coverage
|
|||
deps = -rrequirements.txt
|
||||
-rtest-requirements.txt
|
||||
|
||||
passenv = TOXENV,CI,TRAVIS,TRAVIS_*
|
||||
passenv = TOXENV CI TRAVIS TRAVIS_*
|
||||
commands = pytest --benchmark-disable
|
||||
usedevelop = True
|
||||
|
||||
|
|
|
@ -437,7 +437,7 @@ void olm::Session::describe(char *describe_buffer, size_t buflen) {
|
|||
|
||||
size = snprintf(
|
||||
describe_buffer, remaining,
|
||||
"sender chain index: %lu ", ratchet.sender_chain[0].chain_key.index
|
||||
"sender chain index: %d ", ratchet.sender_chain[0].chain_key.index
|
||||
);
|
||||
CHECK_SIZE_AND_ADVANCE;
|
||||
|
||||
|
@ -447,7 +447,7 @@ void olm::Session::describe(char *describe_buffer, size_t buflen) {
|
|||
for (size_t i = 0; i < ratchet.receiver_chains.size(); ++i) {
|
||||
size = snprintf(
|
||||
describe_buffer, remaining,
|
||||
" %lu", ratchet.receiver_chains[i].chain_key.index
|
||||
" %d", ratchet.receiver_chains[i].chain_key.index
|
||||
);
|
||||
CHECK_SIZE_AND_ADVANCE;
|
||||
}
|
||||
|
@ -458,7 +458,7 @@ void olm::Session::describe(char *describe_buffer, size_t buflen) {
|
|||
for (size_t i = 0; i < ratchet.skipped_message_keys.size(); ++i) {
|
||||
size = snprintf(
|
||||
describe_buffer, remaining,
|
||||
" %lu", ratchet.skipped_message_keys[i].message_key.index
|
||||
" %d", ratchet.skipped_message_keys[i].message_key.index
|
||||
);
|
||||
CHECK_SIZE_AND_ADVANCE;
|
||||
}
|
||||
|
|
|
@ -4498,7 +4498,7 @@ namespace {
|
|||
sigaltstack(&sigStack, &oldSigStack);
|
||||
struct sigaction sa = {};
|
||||
sa.sa_handler = handleSignal; // NOLINT
|
||||
sa.sa_flags = SS_ONSTACK;
|
||||
sa.sa_flags = SA_ONSTACK;
|
||||
for(std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) {
|
||||
sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue