Skip to content

Commit

Permalink
update BC version, use internal crypto lib instead of BC on EC
Browse files Browse the repository at this point in the history
  • Loading branch information
pccr10001 committed Mar 1, 2024
1 parent a0ec90a commit e813c33
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 43 deletions.
7 changes: 3 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ android {
applicationId "li.power.app.wearos.teslanak"
minSdkVersion 24
targetSdkVersion 30
versionCode 10
versionName "1.3.1"
versionCode 14
versionName "1.3.5"

}

Expand All @@ -31,8 +31,7 @@ android {
dependencies {
implementation 'com.google.android.material:material:1.11.0'
implementation 'androidx.wear:wear:1.1.0'
implementation "org.bouncycastle:bcprov-jdk15on:1.68"
// https://mvnrepository.com/artifact/commons-codec/commons-codec
implementation "org.bouncycastle:bcprov-jdk18on:1.77"
implementation group: 'commons-codec', name: 'commons-codec', version: '1.15'
implementation "androidx.core:core-splashscreen:1.0.1"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,8 @@
import android.content.SharedPreferences;
import android.nfc.cardemulation.HostApduService;
import android.os.Bundle;
import android.util.Log;
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 @@ -23,7 +14,9 @@
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.spec.InvalidKeySpecException;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.*;

/*
*
Expand Down Expand Up @@ -54,7 +47,6 @@ 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 @@ -104,32 +96,47 @@ private byte[] processGetCardInfo() {
return new byte[]{0x00, 0x01, (byte) 0x90, 0x00};
}

public static PrivateKey loadPrivateKey(byte[] data) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException {
ECParameterSpec params = ECNamedCurveTable.getParameterSpec(CURVE);
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);
ECPrivateKeySpec prvkey = new ECPrivateKeySpec(new BigInteger(data), params);
KeyFactory kf = KeyFactory.getInstance("EC", "BC");
KeyFactory kf = KeyFactory.getInstance("EC");
return kf.generatePrivate(prvkey);
}

public static PublicKey loadPublicKey(byte[] data) throws Exception {
ECParameterSpec params = ECNamedCurveTable.getParameterSpec(CURVE);
ECPublicKeySpec pubKey = new ECPublicKeySpec(
params.getCurve().decodePoint(data), params);
KeyFactory kf = KeyFactory.getInstance("EC", "BC");
return kf.generatePublic(pubKey);

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);
}

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

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

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

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

org.bouncycastle.jce.spec.ECPublicKeySpec pubSpec = new
org.bouncycastle.jce.spec.ECPublicKeySpec(Q, ecSpec);
return (ECPublicKey) keyFactory.generatePublic(pubSpec);
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));
}

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

byte[] resp = new byte[67];
System.arraycopy(pubKey.getQ().getEncoded(false), 0, resp, 0, 65);
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;
resp[65] = (byte) 0x90;
resp[66] = 0x00;

Expand Down Expand Up @@ -175,7 +187,7 @@ private byte[] processAuthenticate(byte[] buffer) {


private byte[] doECDH(PrivateKey privKey, byte[] pubKey) throws Exception {
KeyAgreement ka = KeyAgreement.getInstance("ECDH", "BC");
KeyAgreement ka = KeyAgreement.getInstance("ECDH");
ka.init(privKey);
ka.doPhase(loadPublicKey(pubKey), true);
return ka.generateSecret();
Expand Down Expand Up @@ -213,17 +225,6 @@ 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 e813c33

Please sign in to comment.