Wallet encryption (#14)
* enabled wallet encryption with custom keyring backend * updated with lbry and lbryum master refs for wallet encryption
This commit is contained in:
parent
55f2aba998
commit
968c5d1f8e
6 changed files with 89 additions and 14 deletions
|
@ -36,7 +36,7 @@ version = 0.1
|
||||||
|
|
||||||
# (list) Application requirements
|
# (list) Application requirements
|
||||||
# comma seperated e.g. requirements = sqlite3,kivy
|
# comma seperated e.g. requirements = sqlite3,kivy
|
||||||
requirements = openssl, sqlite3, hostpython2, pycrypto==2.6.1, android, pyjnius, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pycrypto==2.6.1, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, txrequests==0.9.5, seccure==0.3.1.3, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, git+https://github.com/lbryio/lbryschema.git@v0.0.12rc1#egg=lbryschema, git+https://github.com/lbryio/lbryum.git@v3.1.9rc2#egg=lbryum, git+https://github.com/lbryio/lbry.git#egg=lbrynet, asn1crypto, cryptography==2.0.3, funcsigs, mock, pbr, unqlite
|
requirements = openssl, sqlite3, hostpython2, android, pyjnius, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pycrypto==2.6.1, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, txrequests==0.9.5, seccure==0.3.1.3, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, git+https://github.com/lbryio/lbryschema.git@v0.0.15rc2#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git#egg=lbrynet, asn1crypto, cryptography==2.0.3, funcsigs, mock, pbr, unqlite
|
||||||
|
|
||||||
# (str) Custom source folders for requirements
|
# (str) Custom source folders for requirements
|
||||||
# Sets custom source for any requirements with recipes
|
# Sets custom source for any requirements with recipes
|
||||||
|
@ -104,10 +104,10 @@ android.ndk = 13b
|
||||||
#android.private_storage = True
|
#android.private_storage = True
|
||||||
|
|
||||||
# (str) Android NDK directory (if empty, it will be automatically downloaded.)
|
# (str) Android NDK directory (if empty, it will be automatically downloaded.)
|
||||||
android.ndk_path = ~/Dev/SDKs/android-ndk-r13b
|
#android.ndk_path = ~/Dev/SDKs/android-ndk-r13b
|
||||||
|
|
||||||
# (str) Android SDK directory (if empty, it will be automatically downloaded.)
|
# (str) Android SDK directory (if empty, it will be automatically downloaded.)
|
||||||
android.sdk_path = ~/Dev/SDKs/android
|
#android.sdk_path = ~/Dev/SDKs/android
|
||||||
|
|
||||||
# (str) ANT directory (if empty, it will be automatically downloaded.)
|
# (str) ANT directory (if empty, it will be automatically downloaded.)
|
||||||
#android.ant_path =
|
#android.ant_path =
|
||||||
|
@ -191,10 +191,10 @@ android.arch = armeabi-v7a
|
||||||
#
|
#
|
||||||
|
|
||||||
# (str) python-for-android git clone directory (if empty, it will be automatically cloned from github)
|
# (str) python-for-android git clone directory (if empty, it will be automatically cloned from github)
|
||||||
p4a.source_dir = ~/Dev/Python/lbry-android/p4a
|
p4a.source_dir = ./p4a
|
||||||
|
|
||||||
# (str) The directory in which python-for-android should look for your own build recipes (if any)
|
# (str) The directory in which python-for-android should look for your own build recipes (if any)
|
||||||
p4a.local_recipes = ~/Dev/Python/lbry-android/recipes
|
p4a.local_recipes = ./recipes
|
||||||
|
|
||||||
# (str) Filename to the hook for p4a
|
# (str) Filename to the hook for p4a
|
||||||
#p4a.hook =
|
#p4a.hook =
|
||||||
|
|
|
@ -36,7 +36,7 @@ version = 0.1
|
||||||
|
|
||||||
# (list) Application requirements
|
# (list) Application requirements
|
||||||
# comma seperated e.g. requirements = sqlite3,kivy
|
# comma seperated e.g. requirements = sqlite3,kivy
|
||||||
requirements = openssl, sqlite3, hostpython2, pycrypto==2.6.1, android, pyjnius, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pycrypto==2.6.1, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, txrequests==0.9.5, seccure==0.3.1.3, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, git+https://github.com/lbryio/lbryschema.git@v0.0.12rc1#egg=lbryschema, git+https://github.com/lbryio/lbryum.git@v3.1.9rc2#egg=lbryum, git+https://github.com/lbryio/lbry.git#egg=lbrynet, asn1crypto, cryptography==2.0.3, funcsigs, mock, pbr, unqlite
|
requirements = openssl, sqlite3, hostpython2, android, pyjnius, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pycrypto==2.6.1, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, txrequests==0.9.5, seccure==0.3.1.3, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, git+https://github.com/lbryio/lbryschema.git@v0.0.15rc2#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git#egg=lbrynet, asn1crypto, cryptography==2.0.3, funcsigs, mock, pbr, unqlite
|
||||||
|
|
||||||
# (str) Custom source folders for requirements
|
# (str) Custom source folders for requirements
|
||||||
# Sets custom source for any requirements with recipes
|
# Sets custom source for any requirements with recipes
|
||||||
|
|
|
@ -17,7 +17,7 @@ class PyCryptoRecipe(CompiledComponentsPythonRecipe):
|
||||||
site_packages_name = 'Crypto'
|
site_packages_name = 'Crypto'
|
||||||
call_hostpython_via_targetpython = False
|
call_hostpython_via_targetpython = False
|
||||||
|
|
||||||
patches = ['add_length.patch']
|
patches = ['add_length.patch', 'fix-fastmath-include-dirs.patch']
|
||||||
|
|
||||||
def get_recipe_env(self, arch=None):
|
def get_recipe_env(self, arch=None):
|
||||||
env = super(PyCryptoRecipe, self).get_recipe_env(arch)
|
env = super(PyCryptoRecipe, self).get_recipe_env(arch)
|
||||||
|
@ -40,8 +40,9 @@ class PyCryptoRecipe(CompiledComponentsPythonRecipe):
|
||||||
self.ctx.get_libs_dir(arch.arch) +
|
self.ctx.get_libs_dir(arch.arch) +
|
||||||
'-L{}'.format(self.ctx.libs_dir)) + ' -L{}'.format(
|
'-L{}'.format(self.ctx.libs_dir)) + ' -L{}'.format(
|
||||||
openssl_build_dir)
|
openssl_build_dir)
|
||||||
#env['EXTRA_CFLAGS'] = '--host linux-armv'
|
env['EXTRA_CFLAGS'] = '--host linux-armv'
|
||||||
env['ac_cv_func_malloc_0_nonnull'] = 'yes'
|
env['ac_cv_func_malloc_0_nonnull'] = 'yes'
|
||||||
|
|
||||||
return env
|
return env
|
||||||
|
|
||||||
def build_compiled_components(self, arch):
|
def build_compiled_components(self, arch):
|
||||||
|
@ -50,7 +51,7 @@ class PyCryptoRecipe(CompiledComponentsPythonRecipe):
|
||||||
env = self.get_recipe_env(arch)
|
env = self.get_recipe_env(arch)
|
||||||
with current_directory(self.get_build_dir(arch.arch)):
|
with current_directory(self.get_build_dir(arch.arch)):
|
||||||
configure = sh.Command('./configure')
|
configure = sh.Command('./configure')
|
||||||
shprint(configure, '--host=arm-linux',
|
shprint(configure, '--host=arm-eabi',
|
||||||
'--prefix={}'.format(self.ctx.get_python_install_dir()),
|
'--prefix={}'.format(self.ctx.get_python_install_dir()),
|
||||||
'--enable-shared', _env=env)
|
'--enable-shared', _env=env)
|
||||||
super(PyCryptoRecipe, self).build_compiled_components(arch)
|
super(PyCryptoRecipe, self).build_compiled_components(arch)
|
||||||
|
|
11
recipes/pycrypto/fix-fastmath-include-dirs.patch
Normal file
11
recipes/pycrypto/fix-fastmath-include-dirs.patch
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
--- a/setup.py 2013-10-14 22:38:10.000000000 +0100
|
||||||
|
+++ b/setup.py 2017-12-20 16:05:16.726389781 +0100
|
||||||
|
@@ -370,7 +370,7 @@
|
||||||
|
'ext_modules': plat_ext + [
|
||||||
|
# _fastmath (uses GNU mp library)
|
||||||
|
Extension("Crypto.PublicKey._fastmath",
|
||||||
|
- include_dirs=['src/','/usr/include/'],
|
||||||
|
+ include_dirs=['src/'],
|
||||||
|
libraries=['gmp'],
|
||||||
|
sources=["src/_fastmath.c"]),
|
||||||
|
|
|
@ -121,7 +121,50 @@ public final class Utils {
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void setPassword(String serviceName, String username, String password, Context context, KeyStore keyStore) {
|
||||||
|
try {
|
||||||
|
String encryptedUsername = String.format("u_%s_%s", serviceName, encrypt(username.getBytes(), context, keyStore));
|
||||||
|
String encryptedPassword = encrypt(password.getBytes(), context, keyStore);
|
||||||
|
SharedPreferences pref = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = pref.edit();
|
||||||
|
editor.putString(encryptedUsername, encryptedPassword);
|
||||||
|
editor.commit();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.e(TAG, "lbrynetservice - Could not set a password", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getPassword(String serviceName, String username, Context context, KeyStore keyStore) {
|
||||||
|
try {
|
||||||
|
String encryptedUsername = String.format("u_%s_%s", serviceName, encrypt(username.getBytes(), context, keyStore));
|
||||||
|
SharedPreferences pref = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
|
||||||
|
String encryptedPassword = pref.getString(encryptedUsername, null);
|
||||||
|
if (encryptedPassword == null || encryptedPassword.trim().length() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] decoded = Base64.decode(encryptedPassword, Base64.DEFAULT);
|
||||||
|
return new String(decrypt(decoded, context, keyStore), Charset.forName("UTF8"));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.e(TAG, "lbrynetservice - could not decrypt password for user", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void deletePassword(String serviceName, String username, Context context, KeyStore keyStore) {
|
||||||
|
try {
|
||||||
|
String encryptedUsername = String.format("u_%s_%s", serviceName, encrypt(username.getBytes(), context, keyStore));
|
||||||
|
SharedPreferences pref = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = pref.edit();
|
||||||
|
editor.remove(encryptedUsername);
|
||||||
|
editor.commit();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.e(TAG, "lbrynetservice - Could not delete a password", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static String encrypt(byte[] input, Context context, KeyStore keyStore) throws Exception {
|
public static String encrypt(byte[] input, Context context, KeyStore keyStore) throws Exception {
|
||||||
Cipher c = Cipher.getInstance(AES_MODE, "BC");
|
Cipher c = Cipher.getInstance(AES_MODE, "BC");
|
||||||
c.init(Cipher.ENCRYPT_MODE, getSecretKey(context, keyStore));
|
c.init(Cipher.ENCRYPT_MODE, getSecretKey(context, keyStore));
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import keyring.backend
|
||||||
import platform
|
import platform
|
||||||
import ssl
|
import ssl
|
||||||
|
|
||||||
|
@ -35,12 +36,12 @@ def save_api_keys(keys, path):
|
||||||
if key_name in keys:
|
if key_name in keys:
|
||||||
secret = keys[key_name].secret
|
secret = keys[key_name].secret
|
||||||
# TODO: For testing. Normally, this should not be displayed.
|
# TODO: For testing. Normally, this should not be displayed.
|
||||||
log.info('Saving API Secret: %s', secret);
|
log.info('Saving API Secret: %s', secret)
|
||||||
context = service.getApplicationContext();
|
context = service.getApplicationContext()
|
||||||
lbrynet_utils.saveApiSecret(secret, context, ks)
|
lbrynet_utils.saveApiSecret(secret, context, ks)
|
||||||
|
|
||||||
def initialize_api_key_file(key_path):
|
def initialize_api_key_file(key_path):
|
||||||
context = service.getApplicationContext();
|
context = service.getApplicationContext()
|
||||||
secret = lbrynet_utils.loadApiSecret(context, ks)
|
secret = lbrynet_utils.loadApiSecret(context, ks)
|
||||||
if secret is None:
|
if secret is None:
|
||||||
keys = {}
|
keys = {}
|
||||||
|
@ -53,6 +54,25 @@ lbrynet.daemon.auth.util.load_api_keys = load_api_keys
|
||||||
lbrynet.daemon.auth.util.save_api_keys = save_api_keys
|
lbrynet.daemon.auth.util.save_api_keys = save_api_keys
|
||||||
lbrynet.daemon.auth.util.initialize_api_key_file = initialize_api_key_file
|
lbrynet.daemon.auth.util.initialize_api_key_file = initialize_api_key_file
|
||||||
|
|
||||||
|
# Keyring backend
|
||||||
|
class LbryAndroidKeyring(keyring.backend.KeyringBackend):
|
||||||
|
priority = 1
|
||||||
|
|
||||||
|
def set_password(self, servicename, username, password):
|
||||||
|
context = service.getApplicationContext()
|
||||||
|
lbrynet_utils.setPassword(servicename, username, password, context, ks)
|
||||||
|
|
||||||
|
def get_password(self, servicename, username):
|
||||||
|
context = service.getApplicationContext()
|
||||||
|
return lbrynet_utils.getPassword(servicename, username, context, ks)
|
||||||
|
|
||||||
|
def delete_password(self, servicename, username):
|
||||||
|
context = service.getApplicationContext()
|
||||||
|
lbrynet_utils.deletePassword(servicename, username, context, ks)
|
||||||
|
|
||||||
|
# set the keyring backend
|
||||||
|
keyring.set_keyring(LbryAndroidKeyring())
|
||||||
|
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
from lbrynet.core import log_support
|
from lbrynet.core import log_support
|
||||||
from twisted.internet import defer, reactor
|
from twisted.internet import defer, reactor
|
||||||
|
@ -109,7 +129,7 @@ def start():
|
||||||
|
|
||||||
if test_internet_connection():
|
if test_internet_connection():
|
||||||
analytics_manager = analytics.Manager.new_instance()
|
analytics_manager = analytics.Manager.new_instance()
|
||||||
start_server_and_listen(True, analytics_manager)
|
start_server_and_listen(False, analytics_manager)
|
||||||
reactor.run()
|
reactor.run()
|
||||||
else:
|
else:
|
||||||
log.info("Not connected to internet, unable to start")
|
log.info("Not connected to internet, unable to start")
|
||||||
|
|
Loading…
Reference in a new issue