Skip to content

Commit

Permalink
back to use BC, disable minify and proguard to make BC can be found i…
Browse files Browse the repository at this point in the history
…n release.
  • Loading branch information
pccr10001 committed Mar 2, 2024
1 parent e813c33 commit efe6d19
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 45 deletions.
8 changes: 4 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ android {
applicationId "li.power.app.wearos.teslanak"
minSdkVersion 24
targetSdkVersion 30
versionCode 14
versionName "1.3.5"
versionCode 15
versionName "1.3.6"

}

buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
minifyEnabled false
// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
buildFeatures {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,17 @@
import android.content.SharedPreferences;
import android.nfc.cardemulation.HostApduService;
import android.os.Bundle;

import android.widget.Toast;

import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.interfaces.ECPrivateKey;
import org.bouncycastle.jce.interfaces.ECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;

import javax.crypto.*;
Expand All @@ -14,9 +23,7 @@
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.*;
import java.security.spec.InvalidKeySpecException;

/*
*
Expand Down Expand Up @@ -47,6 +54,7 @@ public class TeslaNAKService extends HostApduService {

@Override
public void onCreate() {
setupBouncyCastle();
sharedPreferences = getSharedPreferences(KEY_ALIAS, MODE_PRIVATE);
try {
keyStore = KeyStore.getInstance(KEYSTORE_PROVIDER);
Expand Down Expand Up @@ -96,47 +104,32 @@ private byte[] processGetCardInfo() {
return new byte[]{0x00, 0x01, (byte) 0x90, 0x00};
}

public static PrivateKey loadPrivateKey(byte[] data) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidParameterSpecException {
AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC");
parameters.init(new ECGenParameterSpec("secp256r1"));
ECParameterSpec params = parameters.getParameterSpec(ECParameterSpec.class);
public static PrivateKey loadPrivateKey(byte[] data) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException {
ECParameterSpec params = ECNamedCurveTable.getParameterSpec(CURVE);
ECPrivateKeySpec prvkey = new ECPrivateKeySpec(new BigInteger(data), params);
KeyFactory kf = KeyFactory.getInstance("EC");
KeyFactory kf = KeyFactory.getInstance("EC", "BC");
return kf.generatePrivate(prvkey);
}

public static PublicKey loadPublicKey(byte[] data) throws Exception {

AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC");
parameters.init(new ECGenParameterSpec("secp256r1"));
ECParameterSpec params = parameters.getParameterSpec(ECParameterSpec.class);
ECPublicKeySpec pubSpec = new ECPublicKeySpec(getPointFromEncoded(data), params);
KeyFactory kf = KeyFactory.getInstance("EC");
return (ECPublicKey) kf.generatePublic(pubSpec);
ECParameterSpec params = ECNamedCurveTable.getParameterSpec(CURVE);
ECPublicKeySpec pubKey = new ECPublicKeySpec(
params.getCurve().decodePoint(data), params);
KeyFactory kf = KeyFactory.getInstance("EC", "BC");
return kf.generatePublic(pubKey);
}

private ECPublicKey getPublicKeyFromPrivate(ECPrivateKey privateKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance("EC");

AlgorithmParameters parameters = AlgorithmParameters.getInstance("EC");
parameters.init(new ECGenParameterSpec("secp256r1"));
ECParameterSpec params = parameters.getParameterSpec(ECParameterSpec.class);
KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");

BigInteger d = privateKey.getD();
org.bouncycastle.jce.spec.ECParameterSpec ecSpec =
ECNamedCurveTable.getParameterSpec("secp256r1");
org.bouncycastle.math.ec.ECPoint q = ecSpec.getG().multiply(privateKey.getS());
ECPublicKeySpec spec = new ECPublicKeySpec(getPointFromEncoded(q.getEncoded(false)), params);
privateKey.getParameters();
ECPoint Q = privateKey.getParameters().getG().multiply(d);

return (ECPublicKey) keyFactory.generatePublic(spec);
}

private static ECPoint getPointFromEncoded(byte[] encoded){
byte[] rawX = new byte[32];
byte[] rawY = new byte[32];
System.arraycopy(encoded,1,rawX, 0,32);
System.arraycopy(encoded,33,rawY, 0,32);

return new ECPoint(new BigInteger(1,rawX), new BigInteger(1,rawY));
org.bouncycastle.jce.spec.ECPublicKeySpec pubSpec = new
org.bouncycastle.jce.spec.ECPublicKeySpec(Q, ecSpec);
return (ECPublicKey) keyFactory.generatePublic(pubSpec);
}

private byte[] processGetPublicKey() {
Expand All @@ -146,12 +139,7 @@ private byte[] processGetPublicKey() {
ECPublicKey pubKey = getPublicKeyFromPrivate(privKey);

byte[] resp = new byte[67];
byte[] x = pubKey.getW().getAffineX().toByteArray();
byte[] y = pubKey.getW().getAffineY().toByteArray();

System.arraycopy(x, 0, resp, 1, 32);
System.arraycopy(y, 0, resp, 33, 32);
resp[0] = 0x04;
System.arraycopy(pubKey.getQ().getEncoded(false), 0, resp, 0, 65);
resp[65] = (byte) 0x90;
resp[66] = 0x00;

Expand All @@ -171,7 +159,10 @@ private byte[] processAuthenticate(byte[] buffer) {
byte[] pubKey = new byte[65];
System.arraycopy(buffer, 0, pubKey, 0, 65);
byte[] challenge = new byte[16];
System.arraycopy(buffer, 65, challenge, 0, 16);
byte[] salt = new byte[4];
random.nextBytes(salt);
System.arraycopy(salt, 0, challenge, 0, 4);
System.arraycopy(buffer, 69, challenge, 4, 12);
try {
ECPrivateKey privKey = (ECPrivateKey) loadPrivateKey(decryptRSA(Hex.decode(sharedPreferences.getString(KEY_ALIAS, ""))));
byte[] resp = new byte[18];
Expand All @@ -187,7 +178,7 @@ private byte[] processAuthenticate(byte[] buffer) {


private byte[] doECDH(PrivateKey privKey, byte[] pubKey) throws Exception {
KeyAgreement ka = KeyAgreement.getInstance("ECDH");
KeyAgreement ka = KeyAgreement.getInstance("ECDH", "BC");
ka.init(privKey);
ka.doPhase(loadPublicKey(pubKey), true);
return ka.generateSecret();
Expand Down Expand Up @@ -225,6 +216,17 @@ private byte[] decryptRSA(byte[] ciphertext) throws UnrecoverableKeyException, K
return cipher.doFinal(ciphertext);
}

private void setupBouncyCastle() {
final Provider provider = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);
if (provider == null) {
return;
}
if (provider.getClass().equals(BouncyCastleProvider.class)) {
return;
}
Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
Security.insertProviderAt(new BouncyCastleProvider(), 1);
}

@Override
public void onDeactivated(int reason) {
Expand Down

0 comments on commit efe6d19

Please sign in to comment.