Implementation of an outbound group session
This commit is contained in:
parent
68d3c7bfa9
commit
caaed796ad
11 changed files with 512 additions and 3 deletions
|
@ -34,7 +34,6 @@ enum OlmErrorCode {
|
||||||
|
|
||||||
/* remember to update the list of string constants in error.c when updating
|
/* remember to update the list of string constants in error.c when updating
|
||||||
* this list. */
|
* this list. */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** get a string representation of the given error code. */
|
/** get a string representation of the given error code. */
|
||||||
|
|
|
@ -47,6 +47,14 @@ typedef struct Megolm {
|
||||||
uint32_t counter;
|
uint32_t counter;
|
||||||
} Megolm;
|
} Megolm;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cipher used in megolm-backed conversations
|
||||||
|
*
|
||||||
|
* (AES256 + SHA256, with keys based on an HKDF with info of MEGOLM_KEYS)
|
||||||
|
*/
|
||||||
|
const struct _olm_cipher *megolm_cipher();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* initialize the megolm ratchet. random_data should be at least
|
* initialize the megolm ratchet. random_data should be at least
|
||||||
* MEGOLM_RATCHET_LENGTH bytes of randomness.
|
* MEGOLM_RATCHET_LENGTH bytes of randomness.
|
||||||
|
|
72
include/olm/message.h
Normal file
72
include/olm/message.h
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/* Copyright 2016 OpenMarket Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* functions for encoding and decoding messages in the Olm protocol.
|
||||||
|
*
|
||||||
|
* Some of these functions have only C++ bindings, and are declared in
|
||||||
|
* message.hh; in time, they should probably be converted to plain C and
|
||||||
|
* declared here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OLM_MESSAGE_H_
|
||||||
|
#define OLM_MESSAGE_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The length of the buffer needed to hold a group message.
|
||||||
|
*/
|
||||||
|
size_t _olm_encode_group_message_length(
|
||||||
|
size_t group_session_id_length,
|
||||||
|
uint32_t chain_index,
|
||||||
|
size_t ciphertext_length,
|
||||||
|
size_t mac_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the message headers into the output buffer.
|
||||||
|
*
|
||||||
|
* version: version number of the olm protocol
|
||||||
|
* session_id: group session identifier
|
||||||
|
* session_id_length: length of session_id
|
||||||
|
* chain_index: message index
|
||||||
|
* ciphertext_length: length of the ciphertext
|
||||||
|
* output: where to write the output. Should be at least
|
||||||
|
* olm_encode_group_message_length() bytes long.
|
||||||
|
* ciphertext_ptr: returns the address that the ciphertext
|
||||||
|
* should be written to, followed by the MAC.
|
||||||
|
*/
|
||||||
|
void _olm_encode_group_message(
|
||||||
|
uint8_t version,
|
||||||
|
const uint8_t *session_id,
|
||||||
|
size_t session_id_length,
|
||||||
|
uint32_t chain_index,
|
||||||
|
size_t ciphertext_length,
|
||||||
|
uint8_t *output,
|
||||||
|
uint8_t **ciphertext_ptr
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* OLM_MESSAGE_H_ */
|
|
@ -12,6 +12,18 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* functions for encoding and decoding messages in the Olm protocol.
|
||||||
|
*
|
||||||
|
* Some of these functions have plain-C bindings, and are declared in
|
||||||
|
* message.h; in time, all of the functions declared here should probably be
|
||||||
|
* converted to plain C and moved to message.h.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "olm/outbound_group_session.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
90
include/olm/outbound_group_session.h
Normal file
90
include/olm/outbound_group_session.h
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/* Copyright 2016 OpenMarket Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef OLM_OUTBOUND_GROUP_SESSION_H_
|
||||||
|
#define OLM_OUTBOUND_GROUP_SESSION_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct OlmOutboundGroupSession OlmOutboundGroupSession;
|
||||||
|
|
||||||
|
/** get the size of an outbound group session, in bytes. */
|
||||||
|
size_t olm_outbound_group_session_size();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise an outbound group session object using the supplied memory
|
||||||
|
* The supplied memory should be at least olm_outbound_group_session_size()
|
||||||
|
* bytes.
|
||||||
|
*/
|
||||||
|
OlmOutboundGroupSession * olm_outbound_group_session(
|
||||||
|
void *memory
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A null terminated string describing the most recent error to happen to a
|
||||||
|
* group session */
|
||||||
|
const char *olm_outbound_group_session_last_error(
|
||||||
|
const OlmOutboundGroupSession *session
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Clears the memory used to back this group session */
|
||||||
|
size_t olm_clear_outbound_group_session(
|
||||||
|
OlmOutboundGroupSession *session
|
||||||
|
);
|
||||||
|
|
||||||
|
/** The number of random bytes needed to create an outbound group session */
|
||||||
|
size_t olm_init_outbound_group_session_random_length(
|
||||||
|
const OlmOutboundGroupSession *session
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a new outbound group session. Returns std::size_t(-1) on failure. On
|
||||||
|
* failure last_error will be set with an error code. The last_error will be
|
||||||
|
* NOT_ENOUGH_RANDOM if the number of random bytes was too small.
|
||||||
|
*/
|
||||||
|
size_t olm_init_outbound_group_session(
|
||||||
|
OlmOutboundGroupSession *session,
|
||||||
|
uint8_t const * random, size_t random_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of bytes that will be created by encrypting a message
|
||||||
|
*/
|
||||||
|
size_t olm_group_encrypt_message_length(
|
||||||
|
OlmOutboundGroupSession *session,
|
||||||
|
size_t plaintext_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt some plain-text. Returns the length of the encrypted message or
|
||||||
|
* std::size_t(-1) on failure. On failure last_error will be set with an
|
||||||
|
* error code. The last_error will be OUTPUT_BUFFER_TOO_SMALL if the output
|
||||||
|
* buffer is too small.
|
||||||
|
*/
|
||||||
|
size_t olm_group_encrypt(
|
||||||
|
OlmOutboundGroupSession *session,
|
||||||
|
uint8_t const * plaintext, size_t plaintext_length,
|
||||||
|
uint8_t * message, size_t message_length
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* OLM_OUTBOUND_GROUP_SESSION_H_ */
|
14
src/megolm.c
14
src/megolm.c
|
@ -18,8 +18,22 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "olm/cipher.h"
|
||||||
#include "olm/crypto.h"
|
#include "olm/crypto.h"
|
||||||
|
|
||||||
|
const struct _olm_cipher *megolm_cipher() {
|
||||||
|
static const uint8_t CIPHER_KDF_INFO[] = "MEGOLM_KEYS";
|
||||||
|
static struct _olm_cipher *cipher;
|
||||||
|
static struct _olm_cipher_aes_sha_256 OLM_CIPHER;
|
||||||
|
if (!cipher) {
|
||||||
|
cipher = _olm_cipher_aes_sha_256_init(
|
||||||
|
&OLM_CIPHER,
|
||||||
|
CIPHER_KDF_INFO, sizeof(CIPHER_KDF_INFO) - 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return cipher;
|
||||||
|
}
|
||||||
|
|
||||||
/* the seeds used in the HMAC-SHA-256 functions for each part of the ratchet.
|
/* the seeds used in the HMAC-SHA-256 functions for each part of the ratchet.
|
||||||
*/
|
*/
|
||||||
#define HASH_KEY_SEED_LENGTH 1
|
#define HASH_KEY_SEED_LENGTH 1
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright 2015 OpenMarket Ltd
|
/* Copyright 2015-2016 OpenMarket Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -325,3 +325,41 @@ void olm::decode_one_time_key_message(
|
||||||
unknown = pos;
|
unknown = pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static std::uint8_t const GROUP_SESSION_ID_TAG = 052;
|
||||||
|
|
||||||
|
size_t _olm_encode_group_message_length(
|
||||||
|
size_t group_session_id_length,
|
||||||
|
uint32_t chain_index,
|
||||||
|
size_t ciphertext_length,
|
||||||
|
size_t mac_length
|
||||||
|
) {
|
||||||
|
size_t length = VERSION_LENGTH;
|
||||||
|
length += 1 + varstring_length(group_session_id_length);
|
||||||
|
length += 1 + varint_length(chain_index);
|
||||||
|
length += 1 + varstring_length(ciphertext_length);
|
||||||
|
length += mac_length;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void _olm_encode_group_message(
|
||||||
|
uint8_t version,
|
||||||
|
const uint8_t *session_id,
|
||||||
|
size_t session_id_length,
|
||||||
|
uint32_t chain_index,
|
||||||
|
size_t ciphertext_length,
|
||||||
|
uint8_t *output,
|
||||||
|
uint8_t **ciphertext_ptr
|
||||||
|
) {
|
||||||
|
std::uint8_t * pos = output;
|
||||||
|
std::uint8_t * session_id_pos;
|
||||||
|
|
||||||
|
*(pos++) = version;
|
||||||
|
pos = encode(pos, GROUP_SESSION_ID_TAG, session_id_pos, session_id_length);
|
||||||
|
std::memcpy(session_id_pos, session_id, session_id_length);
|
||||||
|
pos = encode(pos, COUNTER_TAG, chain_index);
|
||||||
|
pos = encode(pos, CIPHERTEXT_TAG, *ciphertext_ptr, ciphertext_length);
|
||||||
|
}
|
||||||
|
|
183
src/outbound_group_session.c
Normal file
183
src/outbound_group_session.c
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
/* Copyright 2016 OpenMarket Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "olm/outbound_group_session.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "olm/base64.h"
|
||||||
|
#include "olm/cipher.h"
|
||||||
|
#include "olm/error.h"
|
||||||
|
#include "olm/megolm.h"
|
||||||
|
#include "olm/message.h"
|
||||||
|
|
||||||
|
#define OLM_PROTOCOL_VERSION 3
|
||||||
|
#define SESSION_ID_RANDOM_BYTES 4
|
||||||
|
#define GROUP_SESSION_ID_LENGTH (sizeof(struct timeval) + SESSION_ID_RANDOM_BYTES)
|
||||||
|
|
||||||
|
struct OlmOutboundGroupSession {
|
||||||
|
/** the Megolm ratchet providing the encryption keys */
|
||||||
|
Megolm ratchet;
|
||||||
|
|
||||||
|
/** unique identifier for this session */
|
||||||
|
uint8_t session_id[GROUP_SESSION_ID_LENGTH];
|
||||||
|
|
||||||
|
enum OlmErrorCode last_error;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
size_t olm_outbound_group_session_size() {
|
||||||
|
return sizeof(OlmOutboundGroupSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
OlmOutboundGroupSession * olm_outbound_group_session(
|
||||||
|
void *memory
|
||||||
|
) {
|
||||||
|
OlmOutboundGroupSession *session = memory;
|
||||||
|
olm_clear_outbound_group_session(session);
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *olm_outbound_group_session_last_error(
|
||||||
|
const OlmOutboundGroupSession *session
|
||||||
|
) {
|
||||||
|
return _olm_error_to_string(session->last_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t olm_clear_outbound_group_session(
|
||||||
|
OlmOutboundGroupSession *session
|
||||||
|
) {
|
||||||
|
memset(session, 0, sizeof(OlmOutboundGroupSession));
|
||||||
|
return sizeof(OlmOutboundGroupSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t olm_init_outbound_group_session_random_length(
|
||||||
|
const OlmOutboundGroupSession *session
|
||||||
|
) {
|
||||||
|
/* we need data to initialize the megolm ratchet, plus some more for the
|
||||||
|
* session id.
|
||||||
|
*/
|
||||||
|
return MEGOLM_RATCHET_LENGTH + SESSION_ID_RANDOM_BYTES;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t olm_init_outbound_group_session(
|
||||||
|
OlmOutboundGroupSession *session,
|
||||||
|
uint8_t const * random, size_t random_length
|
||||||
|
) {
|
||||||
|
if (random_length < olm_init_outbound_group_session_random_length(session)) {
|
||||||
|
/* Insufficient random data for new session */
|
||||||
|
session->last_error = OLM_NOT_ENOUGH_RANDOM;
|
||||||
|
return (size_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
megolm_init(&(session->ratchet), random, 0);
|
||||||
|
random += MEGOLM_RATCHET_LENGTH;
|
||||||
|
|
||||||
|
/* initialise the session id. This just has to be unique. We use the
|
||||||
|
* current time plus some random data.
|
||||||
|
*/
|
||||||
|
gettimeofday((struct timeval *)(session->session_id), NULL);
|
||||||
|
memcpy((session->session_id) + sizeof(struct timeval),
|
||||||
|
random, SESSION_ID_RANDOM_BYTES);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t raw_message_length(
|
||||||
|
OlmOutboundGroupSession *session,
|
||||||
|
size_t plaintext_length)
|
||||||
|
{
|
||||||
|
size_t ciphertext_length, mac_length;
|
||||||
|
const struct _olm_cipher *cipher = megolm_cipher();
|
||||||
|
|
||||||
|
ciphertext_length = cipher->ops->encrypt_ciphertext_length(
|
||||||
|
cipher, plaintext_length
|
||||||
|
);
|
||||||
|
|
||||||
|
mac_length = cipher->ops->mac_length(cipher);
|
||||||
|
|
||||||
|
return _olm_encode_group_message_length(
|
||||||
|
GROUP_SESSION_ID_LENGTH, session->ratchet.counter,
|
||||||
|
ciphertext_length, mac_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t olm_group_encrypt_message_length(
|
||||||
|
OlmOutboundGroupSession *session,
|
||||||
|
size_t plaintext_length
|
||||||
|
) {
|
||||||
|
size_t message_length = raw_message_length(session, plaintext_length);
|
||||||
|
return _olm_encode_base64_length(message_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t olm_group_encrypt(
|
||||||
|
OlmOutboundGroupSession *session,
|
||||||
|
uint8_t const * plaintext, size_t plaintext_length,
|
||||||
|
uint8_t * message, size_t max_message_length
|
||||||
|
) {
|
||||||
|
size_t ciphertext_length;
|
||||||
|
size_t rawmsglen;
|
||||||
|
size_t result;
|
||||||
|
uint8_t *ciphertext_ptr, *message_pos;
|
||||||
|
const struct _olm_cipher *cipher = megolm_cipher();
|
||||||
|
|
||||||
|
rawmsglen = raw_message_length(session, plaintext_length);
|
||||||
|
|
||||||
|
if (max_message_length < _olm_encode_base64_length(rawmsglen)) {
|
||||||
|
session->last_error = OLM_OUTPUT_BUFFER_TOO_SMALL;
|
||||||
|
return (size_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ciphertext_length = cipher->ops->encrypt_ciphertext_length(
|
||||||
|
cipher,
|
||||||
|
plaintext_length
|
||||||
|
);
|
||||||
|
|
||||||
|
/* we construct the message at the end of the buffer, so that
|
||||||
|
* we have room to base64-encode it once we're done.
|
||||||
|
*/
|
||||||
|
message_pos = message + _olm_encode_base64_length(rawmsglen) - rawmsglen;
|
||||||
|
|
||||||
|
/* first we build the message structure, then we encrypt
|
||||||
|
* the plaintext into it.
|
||||||
|
*/
|
||||||
|
_olm_encode_group_message(
|
||||||
|
OLM_PROTOCOL_VERSION,
|
||||||
|
session->session_id, GROUP_SESSION_ID_LENGTH,
|
||||||
|
session->ratchet.counter,
|
||||||
|
ciphertext_length,
|
||||||
|
message_pos,
|
||||||
|
&ciphertext_ptr);
|
||||||
|
|
||||||
|
result = cipher->ops->encrypt(
|
||||||
|
cipher,
|
||||||
|
megolm_get_data(&(session->ratchet)), MEGOLM_RATCHET_LENGTH,
|
||||||
|
plaintext, plaintext_length,
|
||||||
|
ciphertext_ptr, ciphertext_length,
|
||||||
|
message_pos, rawmsglen
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result == (size_t)-1) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
megolm_advance(&(session->ratchet));
|
||||||
|
|
||||||
|
return _olm_encode_base64(
|
||||||
|
message_pos, rawmsglen,
|
||||||
|
message
|
||||||
|
);
|
||||||
|
}
|
56
tests/test_group_session.cpp
Normal file
56
tests/test_group_session.cpp
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
/* Copyright 2016 OpenMarket Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#include "olm/outbound_group_session.h"
|
||||||
|
#include "unittest.hh"
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
|
||||||
|
uint8_t random_bytes[] =
|
||||||
|
"0123456789ABDEF0123456789ABCDEF"
|
||||||
|
"0123456789ABDEF0123456789ABCDEF"
|
||||||
|
"0123456789ABDEF0123456789ABCDEF"
|
||||||
|
"0123456789ABDEF0123456789ABCDEF"
|
||||||
|
"0123456789ABDEF0123456789ABCDEF";
|
||||||
|
|
||||||
|
{
|
||||||
|
TestCase test_case("Group message send/receive");
|
||||||
|
|
||||||
|
size_t size = olm_outbound_group_session_size();
|
||||||
|
void *memory = alloca(size);
|
||||||
|
OlmOutboundGroupSession *session = olm_outbound_group_session(memory);
|
||||||
|
|
||||||
|
assert_equals((size_t)132,
|
||||||
|
olm_init_outbound_group_session_random_length(session));
|
||||||
|
|
||||||
|
size_t res = olm_init_outbound_group_session(
|
||||||
|
session, random_bytes, sizeof(random_bytes));
|
||||||
|
assert_equals((size_t)0, res);
|
||||||
|
|
||||||
|
uint8_t plaintext[] = "Message";
|
||||||
|
size_t plaintext_length = sizeof(plaintext) - 1;
|
||||||
|
|
||||||
|
size_t msglen = olm_group_encrypt_message_length(
|
||||||
|
session, plaintext_length);
|
||||||
|
|
||||||
|
uint8_t *msg = (uint8_t *)alloca(msglen);
|
||||||
|
res = olm_group_encrypt(session, plaintext, plaintext_length,
|
||||||
|
msg, msglen);
|
||||||
|
assert_equals(msglen, res);
|
||||||
|
|
||||||
|
// TODO: decode the message
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright 2015 OpenMarket Ltd
|
/* Copyright 2015-2016 OpenMarket Ltd
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -62,4 +62,39 @@ assert_equals(message2, output, 35);
|
||||||
|
|
||||||
} /* Message encode test */
|
} /* Message encode test */
|
||||||
|
|
||||||
|
|
||||||
|
{ /* group message encode test */
|
||||||
|
|
||||||
|
TestCase test_case("Group message encode test");
|
||||||
|
|
||||||
|
const uint8_t session_id[] = "sessionid";
|
||||||
|
size_t session_id_len = 9;
|
||||||
|
|
||||||
|
size_t length = _olm_encode_group_message_length(
|
||||||
|
session_id_len, 200, 10, 8);
|
||||||
|
size_t expected_length = 1 + (2+session_id_len) + (1+2) + (2+10) + 8;
|
||||||
|
assert_equals(expected_length, length);
|
||||||
|
|
||||||
|
uint8_t output[50];
|
||||||
|
uint8_t *ciphertext_ptr;
|
||||||
|
|
||||||
|
_olm_encode_group_message(
|
||||||
|
3,
|
||||||
|
session_id, session_id_len,
|
||||||
|
200, // counter
|
||||||
|
10, // ciphertext length
|
||||||
|
output,
|
||||||
|
&ciphertext_ptr
|
||||||
|
);
|
||||||
|
|
||||||
|
uint8_t expected[] =
|
||||||
|
"\x03"
|
||||||
|
"\x2A\x09sessionid"
|
||||||
|
"\x10\xc8\x01"
|
||||||
|
"\x22\x0a";
|
||||||
|
|
||||||
|
assert_equals(expected, output, sizeof(expected)-1);
|
||||||
|
assert_equals(output+sizeof(expected)-1, ciphertext_ptr);
|
||||||
|
} /* group message encode test */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue