Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
matrix-org
Olm
Commits
5ef6a844
Commit
5ef6a844
authored
Oct 16, 2018
by
Hubert Chathi
Browse files
overwrite buffers that may contain sensitive data
also reduce the amount of memory copying that we do
parent
357d4ff4
Changes
6
Hide whitespace changes
Inline
Side-by-side
python/Makefile
View file @
5ef6a844
...
@@ -3,6 +3,8 @@ all: olm-python2 olm-python3
...
@@ -3,6 +3,8 @@ all: olm-python2 olm-python3
include/olm/olm.h
:
../include/olm/olm.h ../include/olm/inbound_group_session.h ../include/olm/outbound_group_session.h
include/olm/olm.h
:
../include/olm/olm.h ../include/olm/inbound_group_session.h ../include/olm/outbound_group_session.h
mkdir
-p
include/olm
mkdir
-p
include/olm
$(CPP)
-I
dummy
-I
../include ../include/olm/olm.h
-o
include/olm/olm.h
$(CPP)
-I
dummy
-I
../include ../include/olm/olm.h
-o
include/olm/olm.h
# add memset to the header so that we can use it to clear buffers
echo
'void *memset(void *s, int c, size_t n);'
>>
include/olm/olm.h
olm-python2
:
include/olm/olm.h
olm-python2
:
include/olm/olm.h
DEVELOP
=
$(DEVELOP)
python2 setup.py build
DEVELOP
=
$(DEVELOP)
python2 setup.py build
...
...
python/olm/_compat.py
View file @
5ef6a844
...
@@ -26,6 +26,16 @@ except ImportError: # pragma: no cover
...
@@ -26,6 +26,16 @@ except ImportError: # pragma: no cover
URANDOM
=
urandom
# type: ignore
URANDOM
=
urandom
# type: ignore
def
to_bytearray
(
string
):
# type: (AnyStr) -> bytes
if
isinstance
(
string
,
bytes
):
return
bytearray
(
string
)
elif
isinstance
(
string
,
str
):
return
bytearray
(
string
,
"utf-8"
)
raise
TypeError
(
"Invalid type {}"
.
format
(
type
(
string
)))
def
to_bytes
(
string
):
def
to_bytes
(
string
):
# type: (AnyStr) -> bytes
# type: (AnyStr) -> bytes
if
isinstance
(
string
,
bytes
):
if
isinstance
(
string
,
bytes
):
...
...
python/olm/account.py
View file @
5ef6a844
...
@@ -37,7 +37,7 @@ from future.utils import bytes_to_native_str
...
@@ -37,7 +37,7 @@ from future.utils import bytes_to_native_str
# pylint: disable=no-name-in-module
# pylint: disable=no-name-in-module
from
_libolm
import
ffi
,
lib
# type: ignore
from
_libolm
import
ffi
,
lib
# type: ignore
from
._compat
import
URANDOM
,
to_byte
s
from
._compat
import
URANDOM
,
to_byte
array
from
._finalize
import
track_for_finalization
from
._finalize
import
track_for_finalization
# This is imported only for type checking purposes
# This is imported only for type checking purposes
...
@@ -82,12 +82,12 @@ class Account(object):
...
@@ -82,12 +82,12 @@ class Account(object):
random_length
=
lib
.
olm_create_account_random_length
(
self
.
_account
)
random_length
=
lib
.
olm_create_account_random_length
(
self
.
_account
)
random
=
URANDOM
(
random_length
)
random
=
URANDOM
(
random_length
)
random_buffer
=
ffi
.
new
(
"char[]"
,
random
)
self
.
_check_error
(
self
.
_check_error
(
lib
.
olm_create_account
(
self
.
_account
,
rand
om_buffer
,
lib
.
olm_create_account
(
self
.
_account
,
ffi
.
fr
om_buffer
(
random
)
,
random_length
))
random_length
))
def
_check_error
(
self
,
ret
):
def
_check_error
(
self
,
ret
):
# type: (int) -> None
# type: (int) -> None
if
ret
!=
lib
.
olm_error
():
if
ret
!=
lib
.
olm_error
():
...
@@ -111,15 +111,23 @@ class Account(object):
...
@@ -111,15 +111,23 @@ class Account(object):
passphrase(str, optional): The passphrase to be used to encrypt
passphrase(str, optional): The passphrase to be used to encrypt
the account.
the account.
"""
"""
byte_key
=
bytes
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
byte_key
=
bytearray
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
key_buffer
=
ffi
.
new
(
"char[]"
,
byte_key
)
pickle_length
=
lib
.
olm_pickle_account_length
(
self
.
_account
)
pickle_length
=
lib
.
olm_pickle_account_length
(
self
.
_account
)
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle_length
)
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle_length
)
self
.
_check_error
(
try
:
lib
.
olm_pickle_account
(
self
.
_account
,
key_buffer
,
len
(
byte_key
),
self
.
_check_error
(
pickle_buffer
,
pickle_length
))
lib
.
olm_pickle_account
(
self
.
_account
,
ffi
.
from_buffer
(
byte_key
),
len
(
byte_key
),
pickle_buffer
,
pickle_length
))
finally
:
# zero out copies of the passphrase
for
i
in
range
(
0
,
len
(
byte_key
)):
byte_key
[
i
]
=
0
return
ffi
.
unpack
(
pickle_buffer
,
pickle_length
)
return
ffi
.
unpack
(
pickle_buffer
,
pickle_length
)
@
classmethod
@
classmethod
...
@@ -143,15 +151,22 @@ class Account(object):
...
@@ -143,15 +151,22 @@ class Account(object):
if
not
pickle
:
if
not
pickle
:
raise
ValueError
(
"Pickle can't be empty"
)
raise
ValueError
(
"Pickle can't be empty"
)
byte_key
=
byte
s
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
byte_key
=
byte
array
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
key_buffer
=
ffi
.
new
(
"char[]"
,
byte_key
)
# copy because unpickle will destroy the buffer
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle
)
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle
)
obj
=
cls
.
__new__
(
cls
)
obj
=
cls
.
__new__
(
cls
)
ret
=
lib
.
olm_unpickle_account
(
obj
.
_account
,
key_buffer
,
len
(
byte_key
),
try
:
pickle_buffer
,
len
(
pickle
))
ret
=
lib
.
olm_unpickle_account
(
obj
.
_account
,
obj
.
_check_error
(
ret
)
ffi
.
from_buffer
(
byte_key
),
len
(
byte_key
),
pickle_buffer
,
len
(
pickle
))
obj
.
_check_error
(
ret
)
finally
:
for
i
in
range
(
0
,
len
(
byte_key
)):
byte_key
[
i
]
=
0
return
obj
return
obj
...
@@ -178,14 +193,21 @@ class Account(object):
...
@@ -178,14 +193,21 @@ class Account(object):
Args:
Args:
message(str): The message to sign.
message(str): The message to sign.
"""
"""
bytes_message
=
to_byte
s
(
message
)
bytes_message
=
to_byte
array
(
message
)
out_length
=
lib
.
olm_account_signature_length
(
self
.
_account
)
out_length
=
lib
.
olm_account_signature_length
(
self
.
_account
)
message_buffer
=
ffi
.
new
(
"char[]"
,
bytes_message
)
out_buffer
=
ffi
.
new
(
"char[]"
,
out_length
)
out_buffer
=
ffi
.
new
(
"char[]"
,
out_length
)
self
.
_check_error
(
try
:
lib
.
olm_account_sign
(
self
.
_account
,
message_buffer
,
self
.
_check_error
(
len
(
bytes_message
),
out_buffer
,
out_length
))
lib
.
olm_account_sign
(
self
.
_account
,
ffi
.
from_buffer
(
bytes_message
),
len
(
bytes_message
),
out_buffer
,
out_length
))
finally
:
# clear out copies of the message, which may be plaintext
if
bytes_message
is
not
message
:
for
i
in
range
(
0
,
len
(
bytes_message
)):
bytes_message
[
i
]
=
0
return
bytes_to_native_str
(
ffi
.
unpack
(
out_buffer
,
out_length
))
return
bytes_to_native_str
(
ffi
.
unpack
(
out_buffer
,
out_length
))
...
@@ -214,10 +236,10 @@ class Account(object):
...
@@ -214,10 +236,10 @@ class Account(object):
random_length
=
lib
.
olm_account_generate_one_time_keys_random_length
(
random_length
=
lib
.
olm_account_generate_one_time_keys_random_length
(
self
.
_account
,
count
)
self
.
_account
,
count
)
random
=
URANDOM
(
random_length
)
random
=
URANDOM
(
random_length
)
random_buffer
=
ffi
.
new
(
"char[]"
,
random
)
self
.
_check_error
(
self
.
_check_error
(
lib
.
olm_account_generate_one_time_keys
(
lib
.
olm_account_generate_one_time_keys
(
self
.
_account
,
count
,
rand
om_buffer
,
random_length
))
self
.
_account
,
count
,
ffi
.
fr
om_buffer
(
random
)
,
random_length
))
@
property
@
property
def
one_time_keys
(
self
):
def
one_time_keys
(
self
):
...
...
python/olm/group_session.py
View file @
5ef6a844
...
@@ -33,7 +33,7 @@ from future.utils import bytes_to_native_str
...
@@ -33,7 +33,7 @@ from future.utils import bytes_to_native_str
# pylint: disable=no-name-in-module
# pylint: disable=no-name-in-module
from
_libolm
import
ffi
,
lib
# type: ignore
from
_libolm
import
ffi
,
lib
# type: ignore
from
._compat
import
URANDOM
,
to_bytes
from
._compat
import
URANDOM
,
to_bytearray
,
to_bytes
from
._finalize
import
track_for_finalization
from
._finalize
import
track_for_finalization
...
@@ -78,12 +78,17 @@ class InboundGroupSession(object):
...
@@ -78,12 +78,17 @@ class InboundGroupSession(object):
if
False
:
# pragma: no cover
if
False
:
# pragma: no cover
self
.
_session
=
self
.
_session
# type: ffi.cdata
self
.
_session
=
self
.
_session
# type: ffi.cdata
byte_session_key
=
to_bytes
(
session_key
)
byte_session_key
=
to_bytearray
(
session_key
)
key_buffer
=
ffi
.
new
(
"char[]"
,
byte_session_key
)
try
:
ret
=
lib
.
olm_init_inbound_group_session
(
ret
=
lib
.
olm_init_inbound_group_session
(
self
.
_session
,
key_buffer
,
len
(
byte_session_key
)
self
.
_session
,
)
ffi
.
from_buffer
(
byte_session_key
),
len
(
byte_session_key
)
)
finally
:
if
byte_session_key
is
not
session_key
:
for
i
in
range
(
0
,
len
(
byte_session_key
)):
byte_session_key
[
i
]
=
0
self
.
_check_error
(
ret
)
self
.
_check_error
(
ret
)
def
pickle
(
self
,
passphrase
=
""
):
def
pickle
(
self
,
passphrase
=
""
):
...
@@ -98,19 +103,23 @@ class InboundGroupSession(object):
...
@@ -98,19 +103,23 @@ class InboundGroupSession(object):
passphrase(str, optional): The passphrase to be used to encrypt
passphrase(str, optional): The passphrase to be used to encrypt
the session.
the session.
"""
"""
byte_passphrase
=
byte
s
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
byte_passphrase
=
byte
array
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
passphrase_buffer
=
ffi
.
new
(
"char[]"
,
byte_passphrase
)
pickle_length
=
lib
.
olm_pickle_inbound_group_session_length
(
pickle_length
=
lib
.
olm_pickle_inbound_group_session_length
(
self
.
_session
)
self
.
_session
)
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle_length
)
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle_length
)
ret
=
lib
.
olm_pickle_inbound_group_session
(
try
:
self
.
_session
,
passphrase_buffer
,
len
(
byte_passphrase
),
ret
=
lib
.
olm_pickle_inbound_group_session
(
pickle_buffer
,
pickle_length
self
.
_session
,
)
ffi
.
from_buffer
(
byte_passphrase
),
len
(
byte_passphrase
),
pickle_buffer
,
pickle_length
self
.
_check_error
(
ret
)
)
self
.
_check_error
(
ret
)
finally
:
# clear out copies of the passphrase
for
i
in
range
(
0
,
len
(
byte_passphrase
)):
byte_passphrase
[
i
]
=
0
return
ffi
.
unpack
(
pickle_buffer
,
pickle_length
)
return
ffi
.
unpack
(
pickle_buffer
,
pickle_length
)
...
@@ -135,20 +144,25 @@ class InboundGroupSession(object):
...
@@ -135,20 +144,25 @@ class InboundGroupSession(object):
if
not
pickle
:
if
not
pickle
:
raise
ValueError
(
"Pickle can't be empty"
)
raise
ValueError
(
"Pickle can't be empty"
)
byte_passphrase
=
byte
s
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
byte_passphrase
=
byte
array
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
passphrase_buffer
=
ffi
.
new
(
"char[]"
,
byte_passphrase
)
# copy because unpickle will destroy the buffer
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle
)
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle
)
obj
=
cls
.
__new__
(
cls
)
obj
=
cls
.
__new__
(
cls
)
ret
=
lib
.
olm_unpickle_inbound_group_session
(
try
:
obj
.
_session
,
ret
=
lib
.
olm_unpickle_inbound_group_session
(
passphrase_buffer
,
obj
.
_session
,
len
(
byte_passphrase
),
ffi
.
from_buffer
(
byte_passphrase
),
pickle_buffer
,
len
(
byte_passphrase
),
len
(
pickle
)
pickle_buffer
,
)
len
(
pickle
)
obj
.
_check_error
(
ret
)
)
obj
.
_check_error
(
ret
)
finally
:
# clear out copies of the passphrase
for
i
in
range
(
0
,
len
(
byte_passphrase
)):
byte_passphrase
[
i
]
=
0
return
obj
return
obj
...
@@ -189,12 +203,15 @@ class InboundGroupSession(object):
...
@@ -189,12 +203,15 @@ class InboundGroupSession(object):
byte_ciphertext
=
to_bytes
(
ciphertext
)
byte_ciphertext
=
to_bytes
(
ciphertext
)
# copy because max_plaintext_length will destroy the buffer
ciphertext_buffer
=
ffi
.
new
(
"char[]"
,
byte_ciphertext
)
ciphertext_buffer
=
ffi
.
new
(
"char[]"
,
byte_ciphertext
)
max_plaintext_length
=
lib
.
olm_group_decrypt_max_plaintext_length
(
max_plaintext_length
=
lib
.
olm_group_decrypt_max_plaintext_length
(
self
.
_session
,
ciphertext_buffer
,
len
(
byte_ciphertext
)
self
.
_session
,
ciphertext_buffer
,
len
(
byte_ciphertext
)
)
)
self
.
_check_error
(
max_plaintext_length
)
plaintext_buffer
=
ffi
.
new
(
"char[]"
,
max_plaintext_length
)
plaintext_buffer
=
ffi
.
new
(
"char[]"
,
max_plaintext_length
)
# copy because max_plaintext_length will destroy the buffer
ciphertext_buffer
=
ffi
.
new
(
"char[]"
,
byte_ciphertext
)
ciphertext_buffer
=
ffi
.
new
(
"char[]"
,
byte_ciphertext
)
message_index
=
ffi
.
new
(
"uint32_t*"
)
message_index
=
ffi
.
new
(
"uint32_t*"
)
...
@@ -206,10 +223,15 @@ class InboundGroupSession(object):
...
@@ -206,10 +223,15 @@ class InboundGroupSession(object):
self
.
_check_error
(
plaintext_length
)
self
.
_check_error
(
plaintext_length
)
return
bytes_to_native_str
(
ffi
.
unpack
(
plaintext
=
bytes_to_native_str
(
ffi
.
unpack
(
plaintext_buffer
,
plaintext_buffer
,
plaintext_length
plaintext_length
)),
message_index
[
0
]
))
# clear out copies of the plaintext
lib
.
memset
(
plaintext_buffer
,
0
,
max_plaintext_length
)
return
plaintext
,
message_index
[
0
]
@
property
@
property
def
id
(
self
):
def
id
(
self
):
...
@@ -281,15 +303,19 @@ class InboundGroupSession(object):
...
@@ -281,15 +303,19 @@ class InboundGroupSession(object):
"""
"""
obj
=
cls
.
__new__
(
cls
)
obj
=
cls
.
__new__
(
cls
)
byte_session_key
=
to_byte
s
(
session_key
)
byte_session_key
=
to_byte
array
(
session_key
)
key_buffer
=
ffi
.
new
(
"char[]"
,
byte_session_key
)
try
:
ret
=
lib
.
olm_import_inbound_group_session
(
ret
=
lib
.
olm_import_inbound_group_session
(
obj
.
_session
,
obj
.
_session
,
key_buffer
,
ffi
.
from_buffer
(
byte_session_key
),
len
(
byte_session_key
)
len
(
byte_session_key
)
)
)
obj
.
_check_error
(
ret
)
obj
.
_check_error
(
ret
)
finally
:
if
byte_session_key
is
not
session_key
:
for
i
in
range
(
0
,
len
(
byte_session_key
)):
byte_session_key
[
i
]
=
0
return
obj
return
obj
...
@@ -323,10 +349,9 @@ class OutboundGroupSession(object):
...
@@ -323,10 +349,9 @@ class OutboundGroupSession(object):
self
.
_session
self
.
_session
)
)
random
=
URANDOM
(
random_length
)
random
=
URANDOM
(
random_length
)
random_buffer
=
ffi
.
new
(
"char[]"
,
random
)
ret
=
lib
.
olm_init_outbound_group_session
(
ret
=
lib
.
olm_init_outbound_group_session
(
self
.
_session
,
rand
om_buffer
,
random_length
self
.
_session
,
ffi
.
fr
om_buffer
(
random
)
,
random_length
)
)
self
.
_check_error
(
ret
)
self
.
_check_error
(
ret
)
...
@@ -353,17 +378,23 @@ class OutboundGroupSession(object):
...
@@ -353,17 +378,23 @@ class OutboundGroupSession(object):
passphrase(str, optional): The passphrase to be used to encrypt
passphrase(str, optional): The passphrase to be used to encrypt
the session.
the session.
"""
"""
byte_passphrase
=
bytes
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
byte_passphrase
=
bytearray
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
passphrase_buffer
=
ffi
.
new
(
"char[]"
,
byte_passphrase
)
pickle_length
=
lib
.
olm_pickle_outbound_group_session_length
(
pickle_length
=
lib
.
olm_pickle_outbound_group_session_length
(
self
.
_session
)
self
.
_session
)
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle_length
)
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle_length
)
ret
=
lib
.
olm_pickle_outbound_group_session
(
try
:
self
.
_session
,
passphrase_buffer
,
len
(
byte_passphrase
),
ret
=
lib
.
olm_pickle_outbound_group_session
(
pickle_buffer
,
pickle_length
self
.
_session
,
)
ffi
.
from_buffer
(
byte_passphrase
),
len
(
byte_passphrase
),
self
.
_check_error
(
ret
)
pickle_buffer
,
pickle_length
)
self
.
_check_error
(
ret
)
finally
:
# clear out copies of the passphrase
for
i
in
range
(
0
,
len
(
byte_passphrase
)):
byte_passphrase
[
i
]
=
0
return
ffi
.
unpack
(
pickle_buffer
,
pickle_length
)
return
ffi
.
unpack
(
pickle_buffer
,
pickle_length
)
@
classmethod
@
classmethod
...
@@ -387,20 +418,25 @@ class OutboundGroupSession(object):
...
@@ -387,20 +418,25 @@ class OutboundGroupSession(object):
if
not
pickle
:
if
not
pickle
:
raise
ValueError
(
"Pickle can't be empty"
)
raise
ValueError
(
"Pickle can't be empty"
)
byte_passphrase
=
byte
s
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
byte_passphrase
=
byte
array
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
passphrase_buffer
=
ffi
.
new
(
"char[]"
,
byte_passphrase
)
# copy because unpickle will destroy the buffer
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle
)
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle
)
obj
=
cls
.
__new__
(
cls
)
obj
=
cls
.
__new__
(
cls
)
ret
=
lib
.
olm_unpickle_outbound_group_session
(
try
:
obj
.
_session
,
ret
=
lib
.
olm_unpickle_outbound_group_session
(
passphrase_buffer
,
obj
.
_session
,
len
(
byte_passphrase
),
ffi
.
from_buffer
(
byte_passphrase
),
pickle_buffer
,
len
(
byte_passphrase
),
len
(
pickle
)
pickle_buffer
,
)
len
(
pickle
)
obj
.
_check_error
(
ret
)
)
obj
.
_check_error
(
ret
)
finally
:
# clear out copies of the passphrase
for
i
in
range
(
0
,
len
(
byte_passphrase
)):
byte_passphrase
[
i
]
=
0
return
obj
return
obj
...
@@ -414,21 +450,26 @@ class OutboundGroupSession(object):
...
@@ -414,21 +450,26 @@ class OutboundGroupSession(object):
plaintext(str): A string that will be encrypted using the group
plaintext(str): A string that will be encrypted using the group
session.
session.
"""
"""
byte_plaintext
=
to_byte
s
(
plaintext
)
byte_plaintext
=
to_byte
array
(
plaintext
)
message_length
=
lib
.
olm_group_encrypt_message_length
(
message_length
=
lib
.
olm_group_encrypt_message_length
(
self
.
_session
,
len
(
byte_plaintext
)
self
.
_session
,
len
(
byte_plaintext
)
)
)
message_buffer
=
ffi
.
new
(
"char[]"
,
message_length
)
message_buffer
=
ffi
.
new
(
"char[]"
,
message_length
)
plaintext_buffer
=
ffi
.
new
(
"char[]"
,
byte_plaintext
)
try
:
ret
=
lib
.
olm_group_encrypt
(
self
.
_session
,
ffi
.
from_buffer
(
byte_plaintext
),
len
(
byte_plaintext
),
message_buffer
,
message_length
,
)
self
.
_check_error
(
ret
)
finally
:
# clear out copies of plaintext
if
byte_plaintext
is
not
plaintext
:
for
i
in
range
(
0
,
len
(
byte_plaintext
)):
byte_plaintext
[
i
]
=
0
ret
=
lib
.
olm_group_encrypt
(
self
.
_session
,
plaintext_buffer
,
len
(
byte_plaintext
),
message_buffer
,
message_length
,
)
self
.
_check_error
(
ret
)
return
bytes_to_native_str
(
ffi
.
unpack
(
message_buffer
,
message_length
))
return
bytes_to_native_str
(
ffi
.
unpack
(
message_buffer
,
message_length
))
@
property
@
property
...
...
python/olm/session.py
View file @
5ef6a844
...
@@ -40,7 +40,7 @@ from future.utils import bytes_to_native_str
...
@@ -40,7 +40,7 @@ from future.utils import bytes_to_native_str
# pylint: disable=no-name-in-module
# pylint: disable=no-name-in-module
from
_libolm
import
ffi
,
lib
# type: ignore
from
_libolm
import
ffi
,
lib
# type: ignore
from
._compat
import
URANDOM
,
to_bytes
from
._compat
import
URANDOM
,
to_bytearray
,
to_bytes
from
._finalize
import
track_for_finalization
from
._finalize
import
track_for_finalization
# This is imported only for type checking purposes
# This is imported only for type checking purposes
...
@@ -164,15 +164,22 @@ class Session(object):
...
@@ -164,15 +164,22 @@ class Session(object):
passphrase(str, optional): The passphrase to be used to encrypt
passphrase(str, optional): The passphrase to be used to encrypt
the session.
the session.
"""
"""
byte_key
=
bytes
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
byte_key
=
bytearray
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
key_buffer
=
ffi
.
new
(
"char[]"
,
byte_key
)
pickle_length
=
lib
.
olm_pickle_session_length
(
self
.
_session
)
pickle_length
=
lib
.
olm_pickle_session_length
(
self
.
_session
)
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle_length
)
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle_length
)
self
.
_check_error
(
try
:
lib
.
olm_pickle_session
(
self
.
_session
,
key_buffer
,
len
(
byte_key
),
self
.
_check_error
(
pickle_buffer
,
pickle_length
))
lib
.
olm_pickle_session
(
self
.
_session
,
ffi
.
from_buffer
(
byte_key
),
len
(
byte_key
),
pickle_buffer
,
pickle_length
))
finally
:
# clear out copies of the passphrase
for
i
in
range
(
0
,
len
(
byte_key
)):
byte_key
[
i
]
=
0
return
ffi
.
unpack
(
pickle_buffer
,
pickle_length
)
return
ffi
.
unpack
(
pickle_buffer
,
pickle_length
)
@
classmethod
@
classmethod
...
@@ -196,16 +203,23 @@ class Session(object):
...
@@ -196,16 +203,23 @@ class Session(object):
if
not
pickle
:
if
not
pickle
:
raise
ValueError
(
"Pickle can't be empty"
)
raise
ValueError
(
"Pickle can't be empty"
)
byte_key
=
byte
s
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
byte_key
=
byte
array
(
passphrase
,
"utf-8"
)
if
passphrase
else
b
""
key_buffer
=
ffi
.
new
(
"char[]"
,
byte_key
)
# copy because unpickle will destroy the buffer
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle
)
pickle_buffer
=
ffi
.
new
(
"char[]"
,
pickle
)
session
=
cls
.
__new__
(
cls
)
session
=
cls
.
__new__
(
cls
)
ret
=
lib
.
olm_unpickle_session
(
session
.
_session
,
key_buffer
,
try
:
len
(
byte_key
),
pickle_buffer
,
ret
=
lib
.
olm_unpickle_session
(
session
.
_session
,
len
(
pickle
))
ffi
.
from_buffer
(
byte_key
),
session
.
_check_error
(
ret
)
len
(
byte_key
),
pickle_buffer
,