Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
mtxclient
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Nheko Reborn
mtxclient
Commits
147836c8
Commit
147836c8
authored
6 years ago
by
Konstantinos Sideris
Browse files
Options
Downloads
Patches
Plain Diff
Refactor OlmClient to only use the C API
parent
ef67bdbc
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
src/crypto.cpp
+125
-114
125 additions, 114 deletions
src/crypto.cpp
src/crypto.hpp
+80
-70
80 additions, 70 deletions
src/crypto.hpp
tests/e2ee.cpp
+55
-33
55 additions, 33 deletions
tests/e2ee.cpp
tests/utils.cpp
+30
-57
30 additions, 57 deletions
tests/utils.cpp
with
290 additions
and
274 deletions
src/crypto.cpp
+
125
−
114
View file @
147836c8
...
...
@@ -6,163 +6,205 @@
using
json
=
nlohmann
::
json
;
using
namespace
mtx
::
client
::
crypto
;
constexpr
std
::
size_t
SIGNATURE_SIZE
=
64
;
std
::
shared_ptr
<
olm
::
Account
>
mtx
::
client
::
crypto
::
olm_new_account
()
void
OlmClient
::
create_new_account
()
{
auto
olm_account
=
std
::
make_shared
<
olm
::
Account
>
();
// The method has no effect if the account is already initialized.
if
(
account_
)
return
;
const
auto
nbytes
=
olm_account
->
new_account_random_length
();
auto
buf
=
create_buffer
(
nbytes
);
account_
=
std
::
unique_ptr
<
OlmAccount
,
OlmDeleter
>
(
olm_account
(
new
uint8_t
[
olm_account_size
()])
);
int
result
=
olm_account
->
new_account
(
buf
->
data
(),
buf
->
size
());
auto
tmp_buf
=
create_buffer
(
olm_create_account_random_length
(
account_
.
get
()));
const
int
ret
=
olm_create_account
(
account_
.
get
(),
tmp_buf
->
data
(),
tmp_buf
->
size
());
if
(
result
==
-
1
)
throw
olm_exception
(
"olm_new_account"
,
olm_account
->
last_error
);
if
(
ret
==
-
1
)
{
account_
.
reset
();
throw
olm_exception
(
"create_new_account"
,
account_
.
get
());
}
}
return
olm_account
;
void
OlmClient
::
create_new_utility
()
{
// The method has no effect if the account is already initialized.
if
(
utility_
)
return
;
utility_
=
std
::
unique_ptr
<
OlmUtility
,
OlmDeleter
>
(
olm_utility
(
new
uint8_t
[
olm_utility_size
()]));
}
IdentityKeys
mtx
::
c
lient
::
cr
ypto
::
identity_keys
(
std
::
shared_ptr
<
olm
::
Account
>
account
)
std
::
unique_ptr
<
OlmSession
,
OlmDeleter
>
OlmC
lient
::
cr
eate_new_session
(
)
{
const
auto
nbytes
=
account
->
get_identity_json_length
();
auto
buf
=
create_buffer
(
nbytes
);
return
std
::
unique_ptr
<
OlmSession
,
OlmDeleter
>
(
olm_session
(
new
uint8_t
[
olm_session_size
()]));
}
int
result
=
account
->
get_identity_json
(
buf
->
data
(),
buf
->
size
());
IdentityKeys
OlmClient
::
identity_keys
()
{
auto
tmp_buf
=
create_buffer
(
olm_account_identity_keys_length
(
account_
.
get
()));
int
result
=
olm_account_identity_keys
(
account_
.
get
(),
(
void
*
)
tmp_buf
->
data
(),
tmp_buf
->
size
());
if
(
result
==
-
1
)
throw
olm_exception
(
"identity_keys"
,
account
->
last_error
);
throw
olm_exception
(
"identity_keys"
,
account_
.
get
());
return
json
::
parse
(
std
::
string
(
tmp_buf
->
begin
(),
tmp_buf
->
end
()));
}
std
::
unique_ptr
<
BinaryBuf
>
OlmClient
::
sign_message
(
const
std
::
string
&
msg
)
{
// Message buffer
auto
buf
=
str_to_buffer
(
msg
);
std
::
string
data
(
buf
->
begin
(),
buf
->
end
());
IdentityKeys
keys
=
json
::
parse
(
data
);
// Signature buffer
auto
signature_buf
=
create_buffer
(
olm_account_signature_length
(
account_
.
get
()));
olm_account_sign
(
account_
.
get
(),
buf
->
data
(),
buf
->
size
(),
signature_buf
->
data
(),
signature_buf
->
size
());
return
keys
;
return
signature_buf
;
}
std
::
string
mtx
::
client
::
crypto
::
sign_identity_keys
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
const
IdentityKeys
&
keys
,
const
mtx
::
identifiers
::
User
&
user_id
,
const
std
::
string
&
device_id
)
OlmClient
::
sign_identity_keys
()
{
auto
keys
=
identity_keys
();
json
body
{{
"algorithms"
,
{
"m.olm.v1.curve25519-aes-sha2"
,
"m.megolm.v1.aes-sha2"
}},
{
"user_id"
,
user_id
.
to_string
()
},
{
"device_id"
,
device_id
},
{
"user_id"
,
user_id
_
},
{
"device_id"
,
device_id
_
},
{
"keys"
,
{
{
"curve25519:"
+
device_id
,
keys
.
curve25519
},
{
"ed25519:"
+
device_id
,
keys
.
ed25519
},
{
"curve25519:"
+
device_id
_
,
keys
.
curve25519
},
{
"ed25519:"
+
device_id
_
,
keys
.
ed25519
},
}}};
return
encode_base64
(
sign_message
(
account
,
body
.
dump
())
->
data
(),
SIGNATURE_SIZE
);
return
encode_base64
(
sign_message
(
body
.
dump
())
->
data
(),
olm_account_signature_length
(
account_
.
get
()));
}
std
::
size_t
mtx
::
client
::
crypto
::
generate_one_time_keys
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
std
::
size_t
number_of_keys
)
OlmClient
::
generate_one_time_keys
(
std
::
size_t
number_of_keys
)
{
const
auto
nbytes
=
account
->
generate_one_time_keys_random_length
(
number_of_keys
);
const
std
::
size_t
nbytes
=
olm_account_generate_one_time_keys_random_length
(
account_
.
get
(),
number_of_keys
);
auto
buf
=
create_buffer
(
nbytes
);
return
account
->
generate_one_time_keys
(
number_of_keys
,
buf
->
data
(),
buf
->
size
());
const
int
ret
=
olm_account_generate_one_time_keys
(
account_
.
get
(),
number_of_keys
,
buf
->
data
(),
buf
->
size
());
if
(
ret
==
-
1
)
throw
olm_exception
(
"generate_one_time_keys"
,
account_
.
get
());
return
ret
;
}
json
mtx
::
c
lient
::
crypto
::
one_time_keys
(
std
::
shared_ptr
<
olm
::
Account
>
account
)
OneTimeKeys
OlmC
lient
::
one_time_keys
()
{
const
auto
nbytes
=
account
->
get_one_time_keys_json_length
();
auto
buf
=
create_buffer
(
nbytes
);
auto
buf
=
create_buffer
(
olm_account_one_time_keys_length
(
account_
.
get
()));
int
re
sul
t
=
account
->
get
_one_time_keys
_json
(
buf
->
data
(),
buf
->
size
());
const
int
ret
=
olm_
account_one_time_keys
(
account_
.
get
(),
buf
->
data
(),
buf
->
size
());
if
(
re
sul
t
==
-
1
)
throw
olm_exception
(
"one_time_keys"
,
account
->
last_error
);
if
(
ret
==
-
1
)
throw
olm_exception
(
"one_time_keys"
,
account
_
.
get
()
);
return
json
::
parse
(
std
::
string
(
buf
->
begin
(),
buf
->
end
()));
}
std
::
string
mtx
::
client
::
crypto
::
sign_one_time_key
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
const
std
::
string
&
key
)
OlmClient
::
sign_one_time_key
(
const
std
::
string
&
key
)
{
json
j
{{
"key"
,
key
}};
auto
str_json
=
j
.
dump
();
auto
str_json
=
j
.
dump
();
auto
signature
=
sign_message
(
j
.
dump
());
auto
signature_buf
=
sign_message
(
account
,
j
.
dump
());
return
encode_base64
(
signature_buf
->
data
(),
signature_buf
->
size
());
return
encode_base64
(
signature
->
data
(),
signature
->
size
());
}
std
::
map
<
std
::
string
,
json
>
mtx
::
client
::
crypto
::
sign_one_time_keys
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
const
mtx
::
client
::
crypto
::
OneTimeKeys
&
keys
,
const
mtx
::
identifiers
::
User
&
user_id
,
const
std
::
string
&
device_id
)
OlmClient
::
sign_one_time_keys
(
const
OneTimeKeys
&
keys
)
{
// Sign & append the one time keys.
std
::
map
<
std
::
string
,
json
>
signed_one_time_keys
;
for
(
const
auto
&
elem
:
keys
.
curve25519
)
{
auto
sig
=
sign_one_time_key
(
account
,
elem
.
second
);
auto
sig
=
sign_one_time_key
(
elem
.
second
);
signed_one_time_keys
[
"signed_curve25519:"
+
elem
.
first
]
=
signed_one_time_key_json
(
user_id
,
device_id
,
elem
.
second
,
sig
);
signed_one_time_key_json
(
elem
.
second
,
sig
);
}
return
signed_one_time_keys
;
}
json
OlmClient
::
signed_one_time_key_json
(
const
std
::
string
&
key
,
const
std
::
string
&
signature
)
{
return
json
{{
"key"
,
key
},
{
"signatures"
,
{{
user_id_
,
{{
"ed25519:"
+
device_id_
,
signature
}}}}}};
}
mtx
::
requests
::
UploadKeys
OlmClient
::
create_upload_keys_request
()
{
return
create_upload_keys_request
(
one_time_keys
());
}
mtx
::
requests
::
UploadKeys
mtx
::
client
::
crypto
::
create_upload_keys_request
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
const
mtx
::
client
::
crypto
::
IdentityKeys
&
identity_keys
,
const
mtx
::
client
::
crypto
::
OneTimeKeys
&
one_time_keys
,
const
mtx
::
identifiers
::
User
&
user_id
,
const
std
::
string
&
device_id
)
OlmClient
::
create_upload_keys_request
(
const
mtx
::
client
::
crypto
::
OneTimeKeys
&
one_time_keys
)
{
mtx
::
requests
::
UploadKeys
req
;
req
.
device_keys
.
user_id
=
user_id
.
to_string
();
req
.
device_keys
.
device_id
=
device_id
;
req
.
device_keys
.
user_id
=
user_id_
;
req
.
device_keys
.
device_id
=
device_id_
;
auto
id_keys
=
identity_keys
();
req
.
device_keys
.
keys
[
"curve25519:"
+
device_id
]
=
id
entity
_keys
.
curve25519
;
req
.
device_keys
.
keys
[
"ed25519:"
+
device_id
]
=
id
entity
_keys
.
ed25519
;
req
.
device_keys
.
keys
[
"curve25519:"
+
device_id
_
]
=
id_keys
.
curve25519
;
req
.
device_keys
.
keys
[
"ed25519:"
+
device_id
_
]
=
id_keys
.
ed25519
;
// Generate and add the signature to the request.
auto
sig
=
sign_identity_keys
(
account
,
identity_keys
,
user_id
,
device_id
);
req
.
device_keys
.
signatures
[
user_id
.
to_string
()][
"ed25519:"
+
device_id
]
=
sig
;
auto
sig
=
sign_identity_keys
();
req
.
device_keys
.
signatures
[
user_id_
][
"ed25519:"
+
device_id_
]
=
sig
;
if
(
one_time_keys
.
curve25519
.
empty
())
return
req
;
// Sign & append the one time keys.
req
.
one_time_keys
=
mtx
::
client
::
crypto
::
sign_one_time_keys
(
account
,
one_time_keys
,
user_id
,
device_id
);
req
.
one_time_keys
=
sign_one_time_keys
(
one_time_keys
);
return
req
;
}
std
::
unique_ptr
<
BinaryBuf
>
mtx
::
client
::
crypto
::
sign_message
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
const
std
::
string
&
msg
)
std
::
unique_ptr
<
OlmSession
,
OlmDeleter
>
OlmClient
::
create_outbound_group_session
(
const
std
::
string
&
peer_identity_key
,
const
std
::
string
&
peer_one_time_key
)
{
// Message buffer
auto
buf
=
str_to
_buffer
(
msg
);
auto
session
=
create_new_session
();
auto
tmp_
buf
=
create
_buffer
(
olm_create_outbound_session_random_length
(
session
.
get
())
);
// Signature buffer
auto
signature_buf
=
create_buffer
(
SIGNATURE_SIZE
);
account
->
sign
(
buf
->
data
(),
buf
->
size
(),
signature_buf
->
data
(),
signature_buf
->
size
());
auto
idk_buf
=
str_to_buffer
(
peer_identity_key
);
auto
otk_buf
=
str_to_buffer
(
peer_one_time_key
);
return
signature_buf
;
}
const
int
ret
=
olm_create_outbound_session
(
session
.
get
(),
account_
.
get
(),
idk_buf
->
data
(),
idk_buf
->
size
(),
otk_buf
->
data
(),
otk_buf
->
size
(),
tmp_buf
->
data
(),
tmp_buf
->
size
());
json
mtx
::
client
::
crypto
::
signed_one_time_key_json
(
const
mtx
::
identifiers
::
User
&
user_id
,
const
std
::
string
&
device_id
,
const
std
::
string
&
key
,
const
std
::
string
&
signature
)
{
return
json
{{
"key"
,
key
},
{
"signatures"
,
{{
user_id
.
to_string
(),
{{
"ed25519:"
+
device_id
,
signature
}}}}}};
if
(
ret
==
-
1
)
throw
olm_exception
(
"init_outbound_group_session"
,
session
.
get
());
return
session
;
}
std
::
unique_ptr
<
BinaryBuf
>
...
...
@@ -213,34 +255,3 @@ mtx::client::crypto::json_to_buffer(const nlohmann::json &obj)
{
return
str_to_buffer
(
obj
.
dump
());
}
_olm_curve25519_public_key
mtx
::
client
::
crypto
::
str_to_curve25519_pk
(
const
std
::
string
&
data
)
{
auto
decoded
=
decode_base64
(
data
);
if
(
decoded
->
size
()
!=
CURVE25519_KEY_LENGTH
)
throw
olm_exception
(
"str_to_curve25519_pk: invalid input size"
);
_olm_curve25519_public_key
pk
;
std
::
copy
(
decoded
->
begin
(),
decoded
->
end
(),
pk
.
public_key
);
return
pk
;
}
olm
::
Session
mtx
::
client
::
crypto
::
init_outbound_group_session
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
const
std
::
string
&
peer_identity_key
,
const
std
::
string
&
peer_one_time_key
)
{
olm
::
Session
session
;
auto
buf
=
create_buffer
(
session
.
new_outbound_session_random_length
());
session
.
new_outbound_session
(
*
account
,
str_to_curve25519_pk
(
peer_identity_key
),
str_to_curve25519_pk
(
peer_one_time_key
),
buf
->
data
(),
buf
->
size
());
return
session
;
}
This diff is collapsed.
Click to expand it.
src/crypto.hpp
+
80
−
70
View file @
147836c8
...
...
@@ -2,6 +2,7 @@
#include
<exception>
#include
<memory>
#include
<new>
#include
<json.hpp>
#include
<sodium.h>
...
...
@@ -13,6 +14,8 @@
#include
<olm/error.h>
#include
<olm/session.hh>
#include
<olm/olm.h>
namespace
mtx
{
namespace
client
{
namespace
crypto
{
...
...
@@ -66,41 +69,28 @@ from_json(const nlohmann::json &obj, OneTimeKeys &keys)
class
olm_exception
:
public
std
::
exception
{
public:
olm_exception
(
std
::
string
msg
,
OlmErrorCode
errcode
)
:
errcode_
(
errcode
)
,
msg_
(
msg
+
": "
+
std
::
string
(
_olm_error_to_string
(
errcode
)))
olm_exception
(
std
::
string
func
,
OlmSession
*
s
)
:
msg_
(
func
+
": "
+
std
::
string
(
olm_session_last_error
(
s
)))
{}
olm_exception
(
std
::
string
func
,
OlmAccount
*
acc
)
:
msg_
(
func
+
": "
+
std
::
string
(
olm_account_last_error
(
acc
)))
{}
olm_exception
(
std
::
string
func
,
OlmUtility
*
util
)
:
msg_
(
func
+
": "
+
std
::
string
(
olm_utility_last_error
(
util
)))
{}
olm_exception
(
std
::
string
msg
)
:
msg_
(
msg
)
{}
OlmErrorCode
get_errcode
()
const
{
return
errcode_
;
}
const
char
*
get_error
()
const
{
return
_olm_error_to_string
(
errcode_
);
}
virtual
const
char
*
what
()
const
throw
()
{
return
msg_
.
c_str
();
}
private
:
OlmErrorCode
errcode_
;
std
::
string
msg_
;
};
//! Create a new olm Account.
std
::
shared_ptr
<
olm
::
Account
>
olm_new_account
();
//! Retrieve the json representation of the identity keys for the given account.
IdentityKeys
identity_keys
(
std
::
shared_ptr
<
olm
::
Account
>
user
);
//! Generate a number of one time keys.
std
::
size_t
generate_one_time_keys
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
std
::
size_t
number_of_keys
);
//! Retrieve the json representation of the one time keys for the given account.
nlohmann
::
json
one_time_keys
(
std
::
shared_ptr
<
olm
::
Account
>
user
);
//! Create a uint8_t buffer which is initialized with random bytes.
template
<
class
T
=
BinaryBuf
>
std
::
unique_ptr
<
T
>
...
...
@@ -112,42 +102,72 @@ create_buffer(std::size_t nbytes)
return
buf
;
}
//! Sign the given one time keys and encode it to base64.
std
::
string
sign_one_time_key
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
const
std
::
string
&
key
);
struct
OlmDeleter
{
void
operator
()(
OlmAccount
*
ptr
)
{
operator
delete
(
ptr
,
olm_account_size
());
}
void
operator
()(
OlmSession
*
ptr
)
{
operator
delete
(
ptr
,
olm_session_size
());
}
void
operator
()(
OlmUtility
*
ptr
)
{
operator
delete
(
ptr
,
olm_utility_size
());
}
};
//! Sign the identity keys. The result should be used as part of the /keys/upload/ request.
std
::
string
sign_identity_keys
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
const
IdentityKeys
&
keys
,
const
mtx
::
identifiers
::
User
&
user_id
,
const
std
::
string
&
device_id
);
class
OlmClient
:
public
std
::
enable_shared_from_this
<
OlmClient
>
{
public:
OlmClient
()
=
default
;
OlmClient
(
std
::
string
user_id
,
std
::
string
device_id
)
:
user_id_
(
std
::
move
(
user_id
))
,
device_id_
(
std
::
move
(
device_id
))
{}
//! Sign the given message.
std
::
unique_ptr
<
BinaryBuf
>
sign_message
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
const
std
::
string
&
msg
);
//! Generate the json structure for the signed one time key.
nlohmann
::
json
signed_one_time_key_json
(
const
mtx
::
identifiers
::
User
&
user_id
,
const
std
::
string
&
device_id
,
const
std
::
string
&
key
,
const
std
::
string
&
signature
);
//! Sign one_time_keys and generate the appropriate structure for the /keys/upload request.
std
::
map
<
std
::
string
,
nlohmann
::
json
>
sign_one_time_keys
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
const
mtx
::
client
::
crypto
::
OneTimeKeys
&
keys
,
const
mtx
::
identifiers
::
User
&
user_id
,
const
std
::
string
&
device_id
);
//! Prepare request for the /keys/upload endpoint by signing identity & one time keys.
mtx
::
requests
::
UploadKeys
create_upload_keys_request
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
const
mtx
::
client
::
crypto
::
IdentityKeys
&
identity_keys
,
const
mtx
::
client
::
crypto
::
OneTimeKeys
&
one_time_keys
,
const
mtx
::
identifiers
::
User
&
user_id
,
const
std
::
string
&
device_id
);
using
Base64String
=
std
::
string
;
using
SignedOneTimeKeys
=
std
::
map
<
std
::
string
,
json
>
;
void
set_device_id
(
std
::
string
device_id
)
{
device_id_
=
std
::
move
(
device_id
);
}
void
set_user_id
(
std
::
string
user_id
)
{
user_id_
=
std
::
move
(
user_id
);
}
//! Sign the given message.
std
::
unique_ptr
<
BinaryBuf
>
sign_message
(
const
std
::
string
&
msg
);
//! Create a new olm Account. Must be called before any other operation.
void
create_new_account
();
void
create_new_utility
();
std
::
unique_ptr
<
OlmSession
,
OlmDeleter
>
create_new_session
();
//! Retrieve the json representation of the identity keys for the given account.
IdentityKeys
identity_keys
();
//! Sign the identity keys.
//! The result should be used as part of the /keys/upload/ request.
Base64String
sign_identity_keys
();
//! Generate a number of one time keys.
std
::
size_t
generate_one_time_keys
(
std
::
size_t
nkeys
);
//! Retrieve the json representation of the one time keys for the given account.
OneTimeKeys
one_time_keys
();
//! Sign the given one time keys and encode it to base64.
Base64String
sign_one_time_key
(
const
Base64String
&
encoded_key
);
//! Sign one_time_keys and generate the appropriate structure for the /keys/upload request.
SignedOneTimeKeys
sign_one_time_keys
(
const
OneTimeKeys
&
keys
);
//! Generate the json structure for the signed one time key.
json
signed_one_time_key_json
(
const
std
::
string
&
key
,
const
std
::
string
&
signature
);
//! Prepare request for the /keys/upload endpoint by signing identity & one time keys.
mtx
::
requests
::
UploadKeys
create_upload_keys_request
(
const
OneTimeKeys
&
keys
);
mtx
::
requests
::
UploadKeys
create_upload_keys_request
();
//! Create an outbount megolm session.
std
::
unique_ptr
<
OlmSession
,
OlmDeleter
>
create_outbound_group_session
(
const
std
::
string
&
peer_identity_key
,
const
std
::
string
&
peer_one_time_key
);
OlmAccount
*
account
()
{
return
account_
.
get
();
}
OlmUtility
*
utility
()
{
return
utility_
.
get
();
}
private
:
std
::
string
user_id_
;
std
::
string
device_id_
;
std
::
unique_ptr
<
OlmAccount
,
OlmDeleter
>
account_
;
std
::
unique_ptr
<
OlmUtility
,
OlmDeleter
>
utility_
;
};
std
::
string
encode_base64
(
const
uint8_t
*
data
,
std
::
size_t
len
);
...
...
@@ -156,23 +176,13 @@ encode_base64(const uint8_t *data, std::size_t len);
std
::
unique_ptr
<
BinaryBuf
>
decode_base64
(
const
std
::
string
&
data
);
//! Convert the given string to an uint8_t buffer.
std
::
unique_ptr
<
BinaryBuf
>
str_to_buffer
(
const
std
::
string
&
data
);
//! Convert the given json struct to an uint8_t buffer.
std
::
unique_ptr
<
BinaryBuf
>
json_to_buffer
(
const
nlohmann
::
json
&
obj
);
//! Convert from base64 encoded public key.
_olm_curve25519_public_key
str_to_curve25519_pk
(
const
std
::
string
&
data
);
//! Create an outbount megolm session.
olm
::
Session
init_outbound_group_session
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
const
std
::
string
&
peer_id_key
,
const
std
::
string
&
peer_one_time_key
);
//! Convert the given string to an uint8_t buffer.
std
::
unique_ptr
<
BinaryBuf
>
str_to_buffer
(
const
std
::
string
&
data
);
}
// namespace crypto
}
// namespace client
...
...
This diff is collapsed.
Click to expand it.
tests/e2ee.cpp
+
55
−
33
View file @
147836c8
...
...
@@ -23,23 +23,20 @@ using namespace mtx::responses;
using
namespace
std
;
mtx
::
requests
::
UploadKeys
generate_keys
(
std
::
shared_ptr
<
olm
::
Account
>
account
,
const
mtx
::
identifiers
::
User
&
user_id
,
const
std
::
string
&
device_id
)
generate_keys
(
std
::
shared_ptr
<
mtx
::
client
::
crypto
::
OlmClient
>
account
)
{
auto
idks
=
mtx
::
client
::
crypto
::
identity_keys
(
account
);
auto
idks
=
account
->
identity_keys
();
account
->
generate_one_time_keys
(
1
);
auto
otks
=
account
->
one_time_keys
();
mtx
::
client
::
crypto
::
generate_one_time_keys
(
account
,
1
);
auto
otks
=
mtx
::
client
::
crypto
::
one_time_keys
(
account
);
return
mtx
::
client
::
crypto
::
create_upload_keys_request
(
account
,
idks
,
otks
,
user_id
,
device_id
);
return
account
->
create_upload_keys_request
(
otks
);
}
TEST
(
Encryption
,
UploadIdentityKeys
)
{
auto
alice
=
std
::
make_shared
<
Client
>
(
"localhost"
);
auto
olm_account
=
mtx
::
client
::
crypto
::
olm_new_account
();
auto
olm_account
=
std
::
make_shared
<
mtx
::
client
::
crypto
::
OlmClient
>
();
olm_account
->
create_new_account
();
alice
->
login
(
"alice"
,
"secret"
,
[](
const
mtx
::
responses
::
Login
&
,
RequestErr
err
)
{
check_error
(
err
);
...
...
@@ -48,14 +45,16 @@ TEST(Encryption, UploadIdentityKeys)
while
(
alice
->
access_token
().
empty
())
sleep
();
auto
identity_keys
=
mtx
::
client
::
crypto
::
identity_keys
(
olm_account
);
olm_account
->
set_user_id
(
alice
->
user_id
().
to_string
());
olm_account
->
set_device_id
(
alice
->
device_id
());
auto
id_keys
=
olm_account
->
identity_keys
();
ASSERT_TRUE
(
id
entity
_keys
.
curve25519
.
size
()
>
10
);
ASSERT_TRUE
(
id
entity
_keys
.
curve25519
.
size
()
>
10
);
ASSERT_TRUE
(
id_keys
.
curve25519
.
size
()
>
10
);
ASSERT_TRUE
(
id_keys
.
curve25519
.
size
()
>
10
);
mtx
::
client
::
crypto
::
OneTimeKeys
unused
;
auto
request
=
mtx
::
client
::
crypto
::
create_upload_keys_request
(
olm_account
,
identity_keys
,
unused
,
alice
->
user_id
(),
alice
->
device_id
());
auto
request
=
olm_account
->
create_upload_keys_request
(
unused
);
// Make the request with the signed identity keys.
alice
->
upload_keys
(
request
,
[](
const
mtx
::
responses
::
UploadKeys
&
res
,
RequestErr
err
)
{
...
...
@@ -69,7 +68,8 @@ TEST(Encryption, UploadIdentityKeys)
TEST
(
Encryption
,
UploadOneTimeKeys
)
{
auto
alice
=
std
::
make_shared
<
Client
>
(
"localhost"
);
auto
olm_account
=
mtx
::
client
::
crypto
::
olm_new_account
();
auto
olm_account
=
std
::
make_shared
<
mtx
::
client
::
crypto
::
OlmClient
>
();
olm_account
->
create_new_account
();
alice
->
login
(
"alice"
,
"secret"
,
[](
const
mtx
::
responses
::
Login
&
,
RequestErr
err
)
{
check_error
(
err
);
...
...
@@ -78,17 +78,20 @@ TEST(Encryption, UploadOneTimeKeys)
while
(
alice
->
access_token
().
empty
())
sleep
();
auto
nkeys
=
mtx
::
client
::
crypto
::
generate_one_time_keys
(
olm_account
,
5
);
olm_account
->
set_user_id
(
alice
->
user_id
().
to_string
());
olm_account
->
set_device_id
(
alice
->
device_id
());
auto
nkeys
=
olm_account
->
generate_one_time_keys
(
5
);
EXPECT_EQ
(
nkeys
,
5
);
auto
one_time_keys
=
mtx
::
client
::
crypto
::
one_time_keys
(
olm_account
);
json
otks
=
olm_account
->
one_time_keys
();
mtx
::
requests
::
UploadKeys
req
;
// Create the proper structure for uploading.
std
::
map
<
std
::
string
,
json
>
unsigned_keys
;
auto
obj
=
o
ne_time_key
s
.
at
(
"curve25519"
);
auto
obj
=
o
tk
s
.
at
(
"curve25519"
);
for
(
auto
it
=
obj
.
begin
();
it
!=
obj
.
end
();
++
it
)
unsigned_keys
[
"curve25519:"
+
it
.
key
()]
=
it
.
value
();
...
...
@@ -106,7 +109,8 @@ TEST(Encryption, UploadOneTimeKeys)
TEST
(
Encryption
,
UploadSignedOneTimeKeys
)
{
auto
alice
=
std
::
make_shared
<
Client
>
(
"localhost"
);
auto
olm_account
=
mtx
::
client
::
crypto
::
olm_new_account
();
auto
olm_account
=
std
::
make_shared
<
mtx
::
client
::
crypto
::
OlmClient
>
();
olm_account
->
create_new_account
();
alice
->
login
(
"alice"
,
"secret"
,
[](
const
mtx
::
responses
::
Login
&
,
RequestErr
err
)
{
check_error
(
err
);
...
...
@@ -115,14 +119,16 @@ TEST(Encryption, UploadSignedOneTimeKeys)
while
(
alice
->
access_token
().
empty
())
sleep
();
auto
nkeys
=
mtx
::
client
::
crypto
::
generate_one_time_keys
(
olm_account
,
5
);
olm_account
->
set_user_id
(
alice
->
user_id
().
to_string
());
olm_account
->
set_device_id
(
alice
->
device_id
());
auto
nkeys
=
olm_account
->
generate_one_time_keys
(
5
);
EXPECT_EQ
(
nkeys
,
5
);
auto
one_time_keys
=
mtx
::
client
::
crypto
::
one_time_keys
(
olm_account
);
auto
one_time_keys
=
olm_account
->
one_time_keys
();
mtx
::
requests
::
UploadKeys
req
;
req
.
one_time_keys
=
mtx
::
client
::
crypto
::
sign_one_time_keys
(
olm_account
,
one_time_keys
,
alice
->
user_id
(),
alice
->
device_id
());
req
.
one_time_keys
=
olm_account
->
sign_one_time_keys
(
one_time_keys
);
alice
->
upload_keys
(
req
,
[
nkeys
](
const
mtx
::
responses
::
UploadKeys
&
res
,
RequestErr
err
)
{
check_error
(
err
);
...
...
@@ -136,7 +142,8 @@ TEST(Encryption, UploadSignedOneTimeKeys)
TEST
(
Encryption
,
UploadKeys
)
{
auto
alice
=
std
::
make_shared
<
Client
>
(
"localhost"
);
auto
olm_account
=
mtx
::
client
::
crypto
::
olm_new_account
();
auto
olm_account
=
std
::
make_shared
<
mtx
::
client
::
crypto
::
OlmClient
>
();
olm_account
->
create_new_account
();
alice
->
login
(
"alice"
,
"secret"
,
[](
const
mtx
::
responses
::
Login
&
,
RequestErr
err
)
{
check_error
(
err
);
...
...
@@ -145,7 +152,10 @@ TEST(Encryption, UploadKeys)
while
(
alice
->
access_token
().
empty
())
sleep
();
auto
req
=
::
generate_keys
(
olm_account
,
alice
->
user_id
(),
alice
->
device_id
());
olm_account
->
set_user_id
(
alice
->
user_id
().
to_string
());
olm_account
->
set_device_id
(
alice
->
device_id
());
auto
req
=
generate_keys
(
olm_account
);
alice
->
upload_keys
(
req
,
[](
const
mtx
::
responses
::
UploadKeys
&
res
,
RequestErr
err
)
{
check_error
(
err
);
...
...
@@ -159,10 +169,13 @@ TEST(Encryption, UploadKeys)
TEST
(
Encryption
,
QueryKeys
)
{
auto
alice
=
std
::
make_shared
<
Client
>
(
"localhost"
);
auto
alice_olm
=
mtx
::
client
::
crypto
::
o
lm
_new_accou
nt
();
auto
alice_olm
=
std
::
make_shared
<
mtx
::
client
::
crypto
::
O
lm
Clie
nt
>
();
auto
bob
=
std
::
make_shared
<
Client
>
(
"localhost"
);
auto
bob_olm
=
mtx
::
client
::
crypto
::
olm_new_account
();
auto
bob_olm
=
std
::
make_shared
<
mtx
::
client
::
crypto
::
OlmClient
>
();
alice_olm
->
create_new_account
();
bob_olm
->
create_new_account
();
alice
->
login
(
"alice"
,
"secret"
,
[](
const
mtx
::
responses
::
Login
&
,
RequestErr
err
)
{
check_error
(
err
);
...
...
@@ -174,9 +187,15 @@ TEST(Encryption, QueryKeys)
while
(
alice
->
access_token
().
empty
()
||
bob
->
access_token
().
empty
())
sleep
();
alice_olm
->
set_user_id
(
alice
->
user_id
().
to_string
());
alice_olm
->
set_device_id
(
alice
->
device_id
());
bob_olm
->
set_user_id
(
bob
->
user_id
().
to_string
());
bob_olm
->
set_device_id
(
bob
->
device_id
());
// Create and upload keys for both users.
auto
alice_req
=
::
generate_keys
(
alice_olm
,
alice
->
user_id
(),
alice
->
device_id
()
);
auto
bob_req
=
::
generate_keys
(
bob_olm
,
bob
->
user_id
(),
bob
->
device_id
()
);
auto
alice_req
=
::
generate_keys
(
alice_olm
);
auto
bob_req
=
::
generate_keys
(
bob_olm
);
// Validates that both upload requests are finished.
atomic_int
uploads
(
0
);
...
...
@@ -257,7 +276,8 @@ TEST(Encryption, QueryKeys)
TEST
(
Encryption
,
KeyChanges
)
{
auto
carl
=
std
::
make_shared
<
Client
>
(
"localhost"
);
auto
carl_olm
=
mtx
::
client
::
crypto
::
olm_new_account
();
auto
carl_olm
=
std
::
make_shared
<
mtx
::
client
::
crypto
::
OlmClient
>
();
carl_olm
->
create_new_account
();
carl
->
login
(
"carl"
,
"secret"
,
[](
const
mtx
::
responses
::
Login
&
,
RequestErr
err
)
{
check_error
(
err
);
...
...
@@ -266,6 +286,9 @@ TEST(Encryption, KeyChanges)
while
(
carl
->
access_token
().
empty
())
sleep
();
carl_olm
->
set_device_id
(
carl
->
device_id
());
carl_olm
->
set_user_id
(
carl
->
user_id
().
to_string
());
mtx
::
requests
::
CreateRoom
req
;
carl
->
create_room
(
req
,
[
carl
,
carl_olm
](
const
mtx
::
responses
::
CreateRoom
&
,
RequestErr
err
)
{
...
...
@@ -281,8 +304,7 @@ TEST(Encryption, KeyChanges)
check_error
(
err
);
const
auto
next_batch_token
=
res
.
next_batch
;
auto
key_req
=
::
generate_keys
(
carl_olm
,
carl
->
user_id
(),
carl
->
device_id
());
auto
key_req
=
::
generate_keys
(
carl_olm
);
atomic_bool
keys_uploaded
(
false
);
...
...
This diff is collapsed.
Click to expand it.
tests/utils.cpp
+
30
−
57
View file @
147836c8
...
...
@@ -11,8 +11,6 @@ using json = nlohmann::json;
using
namespace
mtx
::
client
::
crypto
;
using
namespace
std
;
constexpr
int
SIGNATURE_SIZE
=
64
;
TEST
(
Utilities
,
JsonToBuffer
)
{
auto
msg
=
json
({{
"key"
,
"text"
}});
...
...
@@ -23,33 +21,39 @@ TEST(Utilities, JsonToBuffer)
TEST
(
Utilities
,
VerifySignedOneTimeKey
)
{
auto
alice
=
olm_new_account
();
auto
alice
=
make_shared
<
OlmClient
>
();
alice
->
create_new_account
();
alice
->
create_new_utility
();
generate_one_time_keys
(
alice
,
1
);
auto
keys
=
one_time_keys
(
alice
);
alice
->
identity_keys
();
a
uto
first_key
=
keys
[
"curve25519"
].
begin
()
->
get
<
std
::
string
>
(
);
auto
msg
=
json
({{
"key"
,
first_key
}}).
dump
();
a
lice
->
generate_one_time_keys
(
1
);
auto
keys
=
alice
->
one_time_keys
();
auto
sig_buf
=
sign_message
(
alice
,
msg
);
auto
first_key
=
keys
.
curve25519
.
begin
()
->
second
;
auto
msg
=
json
({{
"key"
,
first_key
}}).
dump
();
olm
::
Utility
utillity
;
auto
sig_buf
=
alice
->
sign_message
(
msg
)
;
auto
res
=
utillity
.
ed25519_verify
(
alice
->
identity_keys
.
ed25519_key
.
public_key
,
str_to_buffer
(
msg
)
->
data
(),
msg
.
size
(),
sig_buf
->
data
(),
SIGNATURE_SIZE
);
auto
res
=
olm_ed25519_verify
(
alice
->
utility
(),
str_to_buffer
(
alice
->
identity_keys
().
ed25519
)
->
data
(),
str_to_buffer
(
alice
->
identity_keys
().
ed25519
)
->
size
(),
str_to_buffer
(
msg
)
->
data
(),
str_to_buffer
(
msg
)
->
size
(),
sig_buf
->
data
(),
sig_buf
->
size
());
EXPECT_EQ
(
uti
l
lity
.
last_error
,
0
);
EXPECT_EQ
(
std
::
string
(
olm_
utility
_
last_error
(
alice
->
utility
())),
"SUCCESS"
);
EXPECT_EQ
(
res
,
0
);
}
TEST
(
Utilities
,
VerifySignedIdentityKeys
)
{
auto
alice
=
olm_new_account
();
auto
alice
=
make_shared
<
OlmClient
>
();
alice
->
create_new_account
();
alice
->
create_new_utility
();
json
keys
=
identity_keys
(
alice
);
json
keys
=
alice
->
identity_keys
();
auto
msg
=
json
({{
"algorithms"
,
{
"m.olm.v1.curve25519-aes-sha2"
,
"m.megolm.v1.aes-sha2"
}},
{
"device_id"
,
"some_device"
},
...
...
@@ -59,47 +63,16 @@ TEST(Utilities, VerifySignedIdentityKeys)
{
"ed25519:some_device"
,
keys
[
"ed25519"
]}}}})
.
dump
();
auto
sig_buf
=
sign_message
(
alice
,
msg
);
olm
::
Utility
utillity
;
auto
sig_buf
=
alice
->
sign_message
(
msg
);
auto
res
=
utillity
.
ed25519_verify
(
alice
->
identity_keys
.
ed25519_key
.
public_key
,
str_to_buffer
(
msg
)
->
data
(),
msg
.
size
(),
sig_buf
->
data
(),
SIGNATURE_SIZE
);
auto
res
=
olm_ed25519_verify
(
alice
->
utility
(),
str_to_buffer
(
alice
->
identity_keys
().
ed25519
)
->
data
(),
str_to_buffer
(
alice
->
identity_keys
().
ed25519
)
->
size
(),
str_to_buffer
(
msg
)
->
data
(),
str_to_buffer
(
msg
)
->
size
(),
sig_buf
->
data
(),
sig_buf
->
size
());
EXPECT_EQ
(
uti
l
lity
.
last_error
,
0
);
EXPECT_EQ
(
std
::
string
(
olm_
utility
_
last_error
(
alice
->
utility
())),
"SUCCESS"
);
EXPECT_EQ
(
res
,
0
);
}
TEST
(
Utilities
,
OutboundGroupSession
)
{
auto
alice
=
olm_new_account
();
auto
bob
=
olm_new_account
();
auto
carl
=
olm_new_account
();
generate_one_time_keys
(
bob
,
1
);
generate_one_time_keys
(
carl
,
1
);
OneTimeKeys
bob_otk
=
one_time_keys
(
bob
);
IdentityKeys
bob_ik
=
identity_keys
(
bob
);
OneTimeKeys
carl_otk
=
one_time_keys
(
carl
);
IdentityKeys
carl_ik
=
identity_keys
(
carl
);
auto
bob_session
=
init_outbound_group_session
(
alice
,
bob_ik
.
curve25519
,
bob_otk
.
curve25519
.
begin
()
->
second
);
auto
carl_session
=
init_outbound_group_session
(
alice
,
carl_ik
.
curve25519
,
carl_otk
.
curve25519
.
begin
()
->
second
);
auto
sid_1
=
create_buffer
(
bob_session
.
session_id_length
());
bob_session
.
session_id
(
sid_1
->
data
(),
sid_1
->
size
());
EXPECT_EQ
(
sid_1
->
size
(),
32
);
auto
sid_2
=
create_buffer
(
carl_session
.
session_id_length
());
carl_session
.
session_id
(
sid_2
->
data
(),
sid_2
->
size
());
EXPECT_EQ
(
sid_2
->
size
(),
32
);
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment