parent
3a7221d71b
commit
70d5cb3e2b
6 changed files with 48 additions and 20 deletions
2
app
2
app
|
@ -1 +1 @@
|
||||||
Subproject commit c85581b98f5d5a06257473c3c86d56d6197e3d43
|
Subproject commit 9080913811b1916774b8eea010bb3ce46ea6f586
|
|
@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
|
||||||
|
|
||||||
# (list) Application requirements
|
# (list) Application requirements
|
||||||
# comma seperated e.g. requirements = sqlite3,kivy
|
# comma seperated e.g. requirements = sqlite3,kivy
|
||||||
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro==1.4.0, pyjnius, certifi==2018.11.29, appdirs==1.4.3, docopt==0.6.2, base58==1.0.0, colorama==0.3.7, ecdsa==0.13, jsonschema==2.6.0, pbkdf2==1.3, pyyaml, protobuf==3.6.1, keyring==10.4.0, defusedxml, git+https://github.com/lbryio/aioupnp.git@ab7ef0048bbce6404e463d20e8a15046ea6941f0#egg=aioupnp, asn1crypto, mock, netifaces, cryptography, aiohttp==3.5.4, multidict==4.5.2, yarl==1.3.0, chardet==3.0.4, async_timeout==3.0.1, coincurve, msgpack==0.6.1, six, attrs==18.2.0, pylru, hachoir, "git+https://github.com/lbryio/lbry-sdk@v0.42.1#egg=lbry&subdirectory=lbry", "git+https://github.com/lbryio/lbry-sdk@v0.42.1#egg=torba&subdirectory=torba"
|
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro==1.4.0, pyjnius, certifi==2018.11.29, appdirs==1.4.3, docopt==0.6.2, base58==1.0.0, colorama==0.3.7, ecdsa==0.13, jsonschema==2.6.0, pbkdf2==1.3, pyyaml, protobuf==3.6.1, keyring==10.4.0, defusedxml, git+https://github.com/lbryio/aioupnp.git@ab7ef0048bbce6404e463d20e8a15046ea6941f0#egg=aioupnp, asn1crypto, mock, netifaces, cryptography, aiohttp==3.5.4, multidict==4.5.2, yarl==1.3.0, chardet==3.0.4, async_timeout==3.0.1, coincurve, msgpack==0.6.1, six, attrs==18.2.0, pylru, hachoir, "git+https://github.com/lbryio/lbry-sdk@v0.43.1#egg=lbry&subdirectory=lbry", "git+https://github.com/lbryio/lbry-sdk@v0.43.1#egg=torba&subdirectory=torba"
|
||||||
|
|
||||||
# (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
|
||||||
|
|
|
@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
|
||||||
|
|
||||||
# (list) Application requirements
|
# (list) Application requirements
|
||||||
# comma seperated e.g. requirements = sqlite3,kivy
|
# comma seperated e.g. requirements = sqlite3,kivy
|
||||||
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro==1.4.0, pyjnius, certifi==2018.11.29, appdirs==1.4.3, docopt==0.6.2, base58==1.0.0, colorama==0.3.7, ecdsa==0.13, jsonschema==2.6.0, pbkdf2==1.3, pyyaml, protobuf==3.6.1, keyring==10.4.0, defusedxml, git+https://github.com/lbryio/aioupnp.git@ab7ef0048bbce6404e463d20e8a15046ea6941f0#egg=aioupnp, asn1crypto, mock, netifaces, cryptography, aiohttp==3.5.4, multidict==4.5.2, yarl==1.3.0, chardet==3.0.4, async_timeout==3.0.1, coincurve, msgpack==0.6.1, six, attrs==18.2.0, pylru, hachoir, "git+https://github.com/lbryio/lbry-sdk@v0.42.1#egg=lbry&subdirectory=lbry", "git+https://github.com/lbryio/lbry-sdk@v0.42.1#egg=torba&subdirectory=torba"
|
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro==1.4.0, pyjnius, certifi==2018.11.29, appdirs==1.4.3, docopt==0.6.2, base58==1.0.0, colorama==0.3.7, ecdsa==0.13, jsonschema==2.6.0, pbkdf2==1.3, pyyaml, protobuf==3.6.1, keyring==10.4.0, defusedxml, git+https://github.com/lbryio/aioupnp.git@ab7ef0048bbce6404e463d20e8a15046ea6941f0#egg=aioupnp, asn1crypto, mock, netifaces, cryptography, aiohttp==3.5.4, multidict==4.5.2, yarl==1.3.0, chardet==3.0.4, async_timeout==3.0.1, coincurve, msgpack==0.6.1, six, attrs==18.2.0, pylru, hachoir, "git+https://github.com/lbryio/lbry-sdk@v0.43.1#egg=lbry&subdirectory=lbry", "git+https://github.com/lbryio/lbry-sdk@v0.43.1#egg=torba&subdirectory=torba"
|
||||||
|
|
||||||
# (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
|
||||||
|
|
|
@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
|
||||||
|
|
||||||
# (list) Application requirements
|
# (list) Application requirements
|
||||||
# comma seperated e.g. requirements = sqlite3,kivy
|
# comma seperated e.g. requirements = sqlite3,kivy
|
||||||
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro==1.4.0, pyjnius, certifi==2018.11.29, appdirs==1.4.3, docopt==0.6.2, base58==1.0.0, colorama==0.3.7, ecdsa==0.13, jsonschema==2.6.0, pbkdf2==1.3, pyyaml, protobuf==3.6.1, keyring==10.4.0, defusedxml, git+https://github.com/lbryio/aioupnp.git@ab7ef0048bbce6404e463d20e8a15046ea6941f0#egg=aioupnp, asn1crypto, mock, netifaces, cryptography, aiohttp==3.5.4, multidict==4.5.2, yarl==1.3.0, chardet==3.0.4, async_timeout==3.0.1, coincurve, msgpack==0.6.1, six, attrs==18.2.0, pylru, hachoir, "git+https://github.com/lbryio/lbry-sdk@v0.42.1#egg=lbry&subdirectory=lbry", "git+https://github.com/lbryio/lbry-sdk@v0.42.1#egg=torba&subdirectory=torba"
|
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro==1.4.0, pyjnius, certifi==2018.11.29, appdirs==1.4.3, docopt==0.6.2, base58==1.0.0, colorama==0.3.7, ecdsa==0.13, jsonschema==2.6.0, pbkdf2==1.3, pyyaml, protobuf==3.6.1, keyring==10.4.0, defusedxml, git+https://github.com/lbryio/aioupnp.git@ab7ef0048bbce6404e463d20e8a15046ea6941f0#egg=aioupnp, asn1crypto, mock, netifaces, cryptography, aiohttp==3.5.4, multidict==4.5.2, yarl==1.3.0, chardet==3.0.4, async_timeout==3.0.1, coincurve, msgpack==0.6.1, six, attrs==18.2.0, pylru, hachoir, "git+https://github.com/lbryio/lbry-sdk@v0.43.1#egg=lbry&subdirectory=lbry", "git+https://github.com/lbryio/lbry-sdk@v0.43.1#egg=torba&subdirectory=torba"
|
||||||
|
|
||||||
# (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
|
||||||
|
|
|
@ -272,4 +272,4 @@ warn_on_root = 1
|
||||||
# Then, invoke the command line with the "demo" profile:
|
# Then, invoke the command line with the "demo" profile:
|
||||||
#
|
#
|
||||||
#buildozer --profile demo android debug
|
#buildozer --profile demo android debug
|
||||||
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro==1.4.0, pyjnius, certifi==2018.11.29, appdirs==1.4.3, docopt==0.6.2, base58==1.0.0, colorama==0.3.7, ecdsa==0.13, jsonschema==2.6.0, pbkdf2==1.3, pyyaml, protobuf==3.6.1, keyring==10.4.0, defusedxml, git+https://github.com/lbryio/aioupnp.git@ab7ef0048bbce6404e463d20e8a15046ea6941f0#egg=aioupnp, asn1crypto, mock, netifaces, cryptography, aiohttp==3.5.4, multidict==4.5.2, yarl==1.3.0, chardet==3.0.4, async_timeout==3.0.1, coincurve, msgpack==0.6.1, six, attrs==18.2.0, pylru, hachoir, "git+https://github.com/lbryio/lbry-sdk@v0.42.1#egg=lbry&subdirectory=lbry", "git+https://github.com/lbryio/lbry-sdk@v0.42.1#egg=torba&subdirectory=torba"
|
requirements = python3crystax, openssl, sqlite3, hostpython3crystax, android, distro==1.4.0, pyjnius, certifi==2018.11.29, appdirs==1.4.3, docopt==0.6.2, base58==1.0.0, colorama==0.3.7, ecdsa==0.13, jsonschema==2.6.0, pbkdf2==1.3, pyyaml, protobuf==3.6.1, keyring==10.4.0, defusedxml, git+https://github.com/lbryio/aioupnp.git@ab7ef0048bbce6404e463d20e8a15046ea6941f0#egg=aioupnp, asn1crypto, mock, netifaces, cryptography, aiohttp==3.5.4, multidict==4.5.2, yarl==1.3.0, chardet==3.0.4, async_timeout==3.0.1, coincurve, msgpack==0.6.1, six, attrs==18.2.0, pylru, hachoir, "git+https://github.com/lbryio/lbry-sdk@v0.43.1#egg=lbry&subdirectory=lbry", "git+https://github.com/lbryio/lbry-sdk@v0.43.1#egg=torba&subdirectory=torba"
|
|
@ -2,6 +2,7 @@ package io.lbry.browser;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Build;
|
||||||
import android.security.KeyPairGeneratorSpec;
|
import android.security.KeyPairGeneratorSpec;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -25,6 +26,8 @@ import java.security.Key;
|
||||||
import java.security.KeyPairGenerator;
|
import java.security.KeyPairGenerator;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.NoSuchProviderException;
|
import java.security.NoSuchProviderException;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
@ -40,7 +43,7 @@ import org.json.JSONObject;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
|
|
||||||
public final class Utils {
|
public final class Utils {
|
||||||
|
|
||||||
private static final String TAG = Utils.class.getName();
|
private static final String TAG = Utils.class.getName();
|
||||||
|
|
||||||
private static final String AES_MODE = "AES/ECB/PKCS7Padding";
|
private static final String AES_MODE = "AES/ECB/PKCS7Padding";
|
||||||
|
@ -56,9 +59,9 @@ public final class Utils {
|
||||||
private static final String SP_ENCRYPTION_KEY = "key";
|
private static final String SP_ENCRYPTION_KEY = "key";
|
||||||
|
|
||||||
private static final String SP_API_SECRET_KEY = "api_secret";
|
private static final String SP_API_SECRET_KEY = "api_secret";
|
||||||
|
|
||||||
public static final String SDK_URL = "http://127.0.0.1:5279";
|
public static final String SDK_URL = "http://127.0.0.1:5279";
|
||||||
|
|
||||||
public static String getAndroidRelease() {
|
public static String getAndroidRelease() {
|
||||||
return android.os.Build.VERSION.RELEASE;
|
return android.os.Build.VERSION.RELEASE;
|
||||||
}
|
}
|
||||||
|
@ -153,6 +156,7 @@ public final class Utils {
|
||||||
try {
|
try {
|
||||||
SharedPreferences pref = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
|
SharedPreferences pref = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
|
||||||
String encryptedValue = pref.getString(key, null);
|
String encryptedValue = pref.getString(key, null);
|
||||||
|
|
||||||
if (encryptedValue == null || encryptedValue.trim().length() == 0) {
|
if (encryptedValue == null || encryptedValue.trim().length() == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -255,11 +259,11 @@ public final class Utils {
|
||||||
|
|
||||||
return ks;
|
return ks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String performRequest(String url) throws ConnectException {
|
public static String performRequest(String url) throws ConnectException {
|
||||||
return performRequest(url, "GET", null);
|
return performRequest(url, "GET", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String performRequest(String requestUrl, String requestMethod, String json) throws ConnectException {
|
public static String performRequest(String requestUrl, String requestMethod, String json) throws ConnectException {
|
||||||
BufferedReader reader = null;
|
BufferedReader reader = null;
|
||||||
DataOutputStream dos = null;
|
DataOutputStream dos = null;
|
||||||
|
@ -275,14 +279,14 @@ public final class Utils {
|
||||||
conn.setDoOutput(true);
|
conn.setDoOutput(true);
|
||||||
conn.setRequestProperty("Content-type", "application/json");
|
conn.setRequestProperty("Content-type", "application/json");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json != null) {
|
if (json != null) {
|
||||||
dos = new DataOutputStream(conn.getOutputStream());
|
dos = new DataOutputStream(conn.getOutputStream());
|
||||||
dos.writeBytes(json);
|
dos.writeBytes(json);
|
||||||
dos.flush();
|
dos.flush();
|
||||||
dos.close();
|
dos.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn.getResponseCode() == 200) {
|
if (conn.getResponseCode() == 200) {
|
||||||
reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
|
reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
@ -325,7 +329,7 @@ public final class Utils {
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String sdkCall(String method) throws ConnectException {
|
public static String sdkCall(String method) throws ConnectException {
|
||||||
return sdkCall(method, null);
|
return sdkCall(method, null);
|
||||||
}
|
}
|
||||||
|
@ -341,7 +345,7 @@ public final class Utils {
|
||||||
}
|
}
|
||||||
request.put("params", requestParams);
|
request.put("params", requestParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
return performRequest(SDK_URL, "POST", request.toString());
|
return performRequest(SDK_URL, "POST", request.toString());
|
||||||
} catch (ConnectException ex) {
|
} catch (ConnectException ex) {
|
||||||
// sdk not started yet. rethrow
|
// sdk not started yet. rethrow
|
||||||
|
@ -356,11 +360,24 @@ public final class Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] rsaEncrypt(byte[] secret, KeyStore keyStore) throws Exception {
|
private static byte[] rsaEncrypt(byte[] secret, KeyStore keyStore) throws Exception {
|
||||||
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(KEY_ALIAS, null);
|
PrivateKey privateKey = null;
|
||||||
|
PublicKey publicKey = null;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
|
privateKey = (PrivateKey) keyStore.getKey(KEY_ALIAS, null);
|
||||||
|
publicKey = keyStore.getCertificate(KEY_ALIAS).getPublicKey();
|
||||||
|
} else {
|
||||||
|
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(KEY_ALIAS, null);
|
||||||
|
privateKey = privateKeyEntry.getPrivateKey();
|
||||||
|
publicKey = privateKeyEntry.getCertificate().getPublicKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (publicKey == null) {
|
||||||
|
throw new Exception("Could not obtain public key for encryption.");
|
||||||
|
}
|
||||||
|
|
||||||
// Encrypt the text
|
// Encrypt the text
|
||||||
Cipher inputCipher = Cipher.getInstance(RSA_MODE);
|
Cipher inputCipher = Cipher.getInstance(RSA_MODE);
|
||||||
inputCipher.init(Cipher.ENCRYPT_MODE, privateKeyEntry.getCertificate().getPublicKey());
|
inputCipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||||
|
|
||||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||||
CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, inputCipher);
|
CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, inputCipher);
|
||||||
|
@ -371,9 +388,20 @@ public final class Utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] rsaDecrypt(byte[] encrypted, KeyStore keyStore) throws Exception {
|
private static byte[] rsaDecrypt(byte[] encrypted, KeyStore keyStore) throws Exception {
|
||||||
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(KEY_ALIAS, null);
|
PrivateKey privateKey = null;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
|
privateKey = (PrivateKey) keyStore.getKey(KEY_ALIAS, null);
|
||||||
|
} else {
|
||||||
|
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(KEY_ALIAS, null);
|
||||||
|
privateKey = privateKeyEntry.getPrivateKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (privateKey == null) {
|
||||||
|
throw new Exception("Could not obtain private key for decryption");
|
||||||
|
}
|
||||||
|
|
||||||
Cipher output = Cipher.getInstance(RSA_MODE);
|
Cipher output = Cipher.getInstance(RSA_MODE);
|
||||||
output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());
|
output.init(Cipher.DECRYPT_MODE, privateKey);
|
||||||
CipherInputStream cipherInputStream = new CipherInputStream(new ByteArrayInputStream(encrypted), output);
|
CipherInputStream cipherInputStream = new CipherInputStream(new ByteArrayInputStream(encrypted), output);
|
||||||
ArrayList<Byte> values = new ArrayList<Byte>();
|
ArrayList<Byte> values = new ArrayList<Byte>();
|
||||||
int nextByte;
|
int nextByte;
|
||||||
|
@ -412,14 +440,14 @@ public final class Utils {
|
||||||
}
|
}
|
||||||
return new SecretKeySpec(rsaDecrypt(Base64.decode(base64Key, Base64.DEFAULT), keyStore), "AES");
|
return new SecretKeySpec(rsaDecrypt(Base64.decode(base64Key, Base64.DEFAULT), keyStore), "AES");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String capitalizeAndStrip(String text) {
|
public static String capitalizeAndStrip(String text) {
|
||||||
String[] parts = text.split(" ");
|
String[] parts = text.split(" ");
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < parts.length; i++) {
|
for (int i = 0; i < parts.length; i++) {
|
||||||
sb.append(parts[i].substring(0, 1).toUpperCase()).append(parts[i].substring(1));
|
sb.append(parts[i].substring(0, 1).toUpperCase()).append(parts[i].substring(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue