rename to keycard (#11)
* rename to keycard * clean imports * update to latest SDK * use unified SDK
This commit is contained in:
parent
85177fe5d3
commit
98caa6106e
|
@ -22,9 +22,7 @@ dependencies {
|
|||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'com.android.support:appcompat-v7:27.1.1'
|
||||
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
|
||||
implementation 'com.madgag.spongycastle:core:1.58.0.0'
|
||||
implementation 'com.madgag.spongycastle:prov:1.58.0.0'
|
||||
implementation 'com.github.status-im:hardwallet-lite-android:c749e5a'
|
||||
implementation 'com.github.status-im.status-keycard-java:android:2.0rc1'
|
||||
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getTargetContext();
|
||||
|
||||
assertEquals("im.status.applet_installer_test.appletinstaller", appContext.getPackageName());
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="im.status.applet_installer_test.appletinstaller">
|
||||
package="im.status.keycard.installer">
|
||||
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
<uses-feature android:name="android.hardware.nfc.hce"
|
||||
|
@ -13,7 +13,7 @@
|
|||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".MainActivity">
|
||||
<activity android:name="im.status.keycard.installer.MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
|
|
Binary file not shown.
|
@ -1,30 +0,0 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
|
||||
|
||||
public class HexUtils {
|
||||
public static byte[] hexStringToByteArray(String s) {
|
||||
int len = s.length();
|
||||
byte[] data = new byte[len/2];
|
||||
|
||||
for(int i = 0; i < len; i+=2){
|
||||
data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16));
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
final protected static char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
||||
|
||||
public static String byteArrayToHexString(byte[] bytes) {
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
int v;
|
||||
|
||||
for(int j=0; j < bytes.length; j++) {
|
||||
v = bytes[j] & 0xFF;
|
||||
hexChars[j * 2] = hexArray[v>>>4];
|
||||
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
||||
}
|
||||
|
||||
return new String(hexChars);
|
||||
}
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
import im.status.hardwallet_lite_android.globalplatform.Load;
|
||||
import im.status.hardwallet_lite_android.io.APDUException;
|
||||
import im.status.hardwallet_lite_android.io.APDUResponse;
|
||||
import im.status.hardwallet_lite_android.io.CardChannel;
|
||||
import im.status.hardwallet_lite_android.globalplatform.ApplicationID;
|
||||
import im.status.hardwallet_lite_android.globalplatform.GlobalPlatformCommandSet;
|
||||
import im.status.hardwallet_lite_android.wallet.WalletAppletCommandSet;
|
||||
|
||||
public class Installer {
|
||||
private CardChannel plainChannel;
|
||||
private AssetManager assets;
|
||||
private String capPath;
|
||||
|
||||
static final byte[] PACKAGE_AID = HexUtils.hexStringToByteArray("53746174757357616C6C6574");
|
||||
static final byte[] WALLET_AID = HexUtils.hexStringToByteArray("53746174757357616C6C6574417070");
|
||||
static final byte[] NDEF_APPLET_AID = HexUtils.hexStringToByteArray("53746174757357616C6C65744E4643");
|
||||
static final byte[] NDEF_INSTANCE_AID = HexUtils.hexStringToByteArray("D2760000850101");
|
||||
|
||||
private GlobalPlatformCommandSet cmdSet;
|
||||
|
||||
private boolean testSecrets;
|
||||
|
||||
public Installer(CardChannel channel, AssetManager assets, String capPath, boolean testSecrets) {
|
||||
this.plainChannel = channel;
|
||||
this.assets = assets;
|
||||
this.capPath = capPath;
|
||||
this.testSecrets = testSecrets;
|
||||
}
|
||||
|
||||
public void start() throws IOException, APDUException, NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
Logger.i("installation started...");
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
Logger.i("auto select sdaid...");
|
||||
cmdSet = new GlobalPlatformCommandSet(this.plainChannel);
|
||||
ApplicationID sdaid = new ApplicationID(cmdSet.select().checkOK().getData());
|
||||
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte hostChallenge[] = new byte[8];
|
||||
random.nextBytes(hostChallenge);
|
||||
Logger.i("initialize update...");
|
||||
cmdSet.initializeUpdate(hostChallenge).checkOK();
|
||||
|
||||
Logger.i("external authenticate...");
|
||||
cmdSet.externalAuthenticate(hostChallenge).checkOK();
|
||||
|
||||
|
||||
Logger.i("delete NDEF instance AID...");
|
||||
cmdSet.delete(NDEF_INSTANCE_AID).checkSW(APDUResponse.SW_OK, APDUResponse.SW_REFERENCED_DATA_NOT_FOUND);
|
||||
|
||||
Logger.i("delete wallet AID...");
|
||||
cmdSet.delete(WALLET_AID).checkSW(APDUResponse.SW_OK, APDUResponse.SW_REFERENCED_DATA_NOT_FOUND);
|
||||
|
||||
Logger.i("delete package AID...");
|
||||
cmdSet.delete(PACKAGE_AID).checkSW(APDUResponse.SW_OK, APDUResponse.SW_REFERENCED_DATA_NOT_FOUND);
|
||||
|
||||
Logger.i("install for load...");
|
||||
cmdSet.installForLoad(PACKAGE_AID, sdaid.getAID()).checkSW(APDUResponse.SW_OK, APDUResponse.SW_REFERENCED_DATA_NOT_FOUND);
|
||||
|
||||
InputStream in = this.assets.open(this.capPath);
|
||||
Load load = new Load(in);
|
||||
|
||||
byte[] block;
|
||||
int steps = load.blocksCount();
|
||||
while((block = load.nextDataBlock()) != null) {
|
||||
int count = load.getCount() - 1;
|
||||
Logger.i(String.format("load %d/%d...", count + 1, steps));
|
||||
cmdSet.load(block, count, load.hasMore()).checkOK();
|
||||
}
|
||||
|
||||
Logger.i("install for install ndef...");
|
||||
byte[] params = HexUtils.hexStringToByteArray("0024d40f12616e64726f69642e636f6d3a706b67696d2e7374617475732e657468657265756d");
|
||||
cmdSet.installForInstall(PACKAGE_AID, NDEF_APPLET_AID, NDEF_INSTANCE_AID, params).checkOK();
|
||||
|
||||
Logger.i("install for install wallet...");
|
||||
cmdSet.installForInstall(PACKAGE_AID, WALLET_AID, WALLET_AID, new byte[0]).checkOK();
|
||||
|
||||
this.personalizeApplet();
|
||||
|
||||
long duration = System.currentTimeMillis() - startTime;
|
||||
Logger.i(String.format("\n\ninstallation completed in %d seconds", duration / 1000));
|
||||
}
|
||||
|
||||
private void personalizeApplet() throws NoSuchAlgorithmException, InvalidKeySpecException, APDUException, IOException {
|
||||
Secrets secrets = testSecrets ? Secrets.testSecrets() : Secrets.generate();
|
||||
|
||||
WalletAppletCommandSet cmdSet = new WalletAppletCommandSet(this.plainChannel);
|
||||
cmdSet.select().checkOK();
|
||||
cmdSet.init(secrets.getPin(), secrets.getPuk(), secrets.getPairingToken()).checkOK();
|
||||
|
||||
Logger.i(String.format("PIN: %s\nPUK: %s\nPairing password: %s\nPairing token: %s", secrets.getPin(), secrets.getPuk(), secrets.getPairingPassword(), HexUtils.byteArrayToHexString(secrets.getPairingToken())));
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Base64;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import static android.util.Base64.NO_PADDING;
|
||||
|
||||
public class Secrets {
|
||||
private String pin;
|
||||
private String puk;
|
||||
private String pairingPassword;
|
||||
private byte[] pairingToken;
|
||||
|
||||
private static long PIN_BOUND = 999999L;
|
||||
private static long PUK_BOUND = 999999999999L;
|
||||
|
||||
public Secrets(String pin, String puk, String pairingPassword, byte[] pairingToken) {
|
||||
this.pin = pin;
|
||||
this.puk = puk;
|
||||
this.pairingPassword = pairingPassword;
|
||||
this.pairingToken = pairingToken;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static Secrets generate() throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
String pairingPassword = randomToken(12);
|
||||
byte[] pairingToken = generatePairingKey(pairingPassword.toCharArray());
|
||||
long pinNumber = randomLong(PIN_BOUND);
|
||||
long pukNumber = randomLong(PUK_BOUND);
|
||||
String pin = String.format("%06d", pinNumber);
|
||||
String puk = String.format("%012d", pukNumber);
|
||||
|
||||
return new Secrets(pin, puk, pairingPassword, pairingToken);
|
||||
}
|
||||
|
||||
public static Secrets testSecrets() throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
String pairingPassword = "WalletAppletTest";
|
||||
byte[] pairingToken = generatePairingKey(pairingPassword.toCharArray());
|
||||
return new Secrets("000000", "123456789012", pairingPassword, pairingToken);
|
||||
}
|
||||
|
||||
public String getPin() {
|
||||
return pin;
|
||||
}
|
||||
|
||||
public String getPuk() {
|
||||
return puk;
|
||||
}
|
||||
|
||||
public String getPairingPassword() {
|
||||
return pairingPassword;
|
||||
}
|
||||
|
||||
public byte[] getPairingToken() {
|
||||
return pairingToken;
|
||||
}
|
||||
|
||||
public static byte[] randomBytes(int length) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte data[] = new byte[length];
|
||||
random.nextBytes(data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public static String randomToken(int length) {
|
||||
return Base64.encodeToString(randomBytes(length), NO_PADDING);
|
||||
}
|
||||
|
||||
public static long randomLong(long bound) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
return Math.abs(random.nextLong()) % bound;
|
||||
}
|
||||
|
||||
public static byte[] generatePairingKey(char[] pairing) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
|
||||
String salt = "Status Hardware Wallet Lite";
|
||||
PBEKeySpec spec = new PBEKeySpec(pairing, salt.getBytes(), 50000, 32*8);
|
||||
SecretKey key = skf.generateSecret(spec);
|
||||
|
||||
return key.getEncoded();
|
||||
}
|
||||
}
|
|
@ -1,12 +1,9 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
package im.status.keycard.installer;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.nfc.tech.IsoDep;
|
||||
import im.status.hardwallet_lite_android.io.APDUException;
|
||||
import im.status.hardwallet_lite_android.io.CardChannel;
|
||||
import im.status.hardwallet_lite_android.io.CardListener;
|
||||
import im.status.keycard.io.APDUException;
|
||||
import im.status.keycard.io.CardChannel;
|
||||
import im.status.keycard.io.CardListener;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Timer;
|
|
@ -0,0 +1,73 @@
|
|||
package im.status.keycard.installer;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import im.status.keycard.applet.KeycardCommandSet;
|
||||
import im.status.keycard.globalplatform.GlobalPlatformCommandSet;
|
||||
import im.status.keycard.globalplatform.LoadCallback;
|
||||
import im.status.keycard.io.APDUException;
|
||||
import im.status.keycard.io.CardChannel;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
public class Installer {
|
||||
private CardChannel plainChannel;
|
||||
private AssetManager assets;
|
||||
private String capPath;
|
||||
|
||||
private GlobalPlatformCommandSet cmdSet;
|
||||
|
||||
private boolean testSecrets;
|
||||
|
||||
public Installer(CardChannel channel, AssetManager assets, String capPath, boolean testSecrets) {
|
||||
this.plainChannel = channel;
|
||||
this.assets = assets;
|
||||
this.capPath = capPath;
|
||||
this.testSecrets = testSecrets;
|
||||
}
|
||||
|
||||
public void start() throws IOException, APDUException, NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
Logger.i("installation started...");
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
Logger.i("select ISD...");
|
||||
cmdSet = new GlobalPlatformCommandSet(this.plainChannel);
|
||||
cmdSet.select().checkOK();
|
||||
|
||||
Logger.i("opening secure channel...");
|
||||
cmdSet.openSecureChannel();
|
||||
|
||||
Logger.i("deleting old version (if present)...");
|
||||
cmdSet.deleteKeycardInstancesAndPackage();
|
||||
|
||||
Logger.i("loading package...");
|
||||
cmdSet.loadKeycardPackage(this.assets.open(this.capPath), new LoadCallback() {
|
||||
public void blockLoaded(int loadedBlock, int blockCount) {
|
||||
Logger.i(String.format("load %d/%d...", loadedBlock, blockCount));
|
||||
}
|
||||
});
|
||||
|
||||
Logger.i("installing NDEF applet...");
|
||||
cmdSet.installNDEFApplet(Hex.decode("0024d40f12616e64726f69642e636f6d3a706b67696d2e7374617475732e657468657265756d")).checkOK();
|
||||
|
||||
Logger.i("installing Keycard applet...");
|
||||
cmdSet.installKeycardApplet().checkOK();
|
||||
|
||||
this.personalizeApplet();
|
||||
|
||||
long duration = System.currentTimeMillis() - startTime;
|
||||
Logger.i(String.format("\n\ninstallation completed in %d seconds", duration / 1000));
|
||||
}
|
||||
|
||||
private void personalizeApplet() throws NoSuchAlgorithmException, InvalidKeySpecException, APDUException, IOException {
|
||||
Secrets secrets = testSecrets ? Secrets.testSecrets() : Secrets.generate();
|
||||
|
||||
KeycardCommandSet cmdSet = new KeycardCommandSet(this.plainChannel);
|
||||
cmdSet.select().checkOK();
|
||||
cmdSet.init(secrets.getPin(), secrets.getPuk(), secrets.getPairingPassword()).checkOK();
|
||||
|
||||
Logger.i(String.format("PIN: %s\nPUK: %s\nPairing password: %s", secrets.getPin(), secrets.getPuk(), secrets.getPairingPassword()));
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
package im.status.keycard.installer;
|
||||
|
||||
import android.util.Log;
|
||||
|
|
@ -1,24 +1,17 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
package im.status.keycard.installer;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.text.method.ScrollingMovementMethod;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import im.status.hardwallet_lite_android.io.CardManager;
|
||||
|
||||
import java.security.Security;
|
||||
import im.status.keycard.android.NFCCardManager;
|
||||
|
||||
public class MainActivity extends AppCompatActivity implements UILogger {
|
||||
static {
|
||||
Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1);
|
||||
}
|
||||
|
||||
private NfcAdapter nfcAdapter;
|
||||
private TextView textView;
|
||||
private ScrollView textViewScroll;
|
||||
|
@ -27,7 +20,7 @@ public class MainActivity extends AppCompatActivity implements UILogger {
|
|||
private Button buttonInstallTest;
|
||||
private Button buttonPerfTest;
|
||||
private ActionRunner actionRunner;
|
||||
private CardManager cardManager;
|
||||
private NFCCardManager cardManager;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -37,8 +30,8 @@ public class MainActivity extends AppCompatActivity implements UILogger {
|
|||
Logger.setUILogger(this);
|
||||
|
||||
AssetManager assets = this.getAssets();
|
||||
this.actionRunner = new ActionRunner(assets, "wallet.cap");
|
||||
this.cardManager = new CardManager();
|
||||
this.actionRunner = new ActionRunner(assets, "keycard.cap");
|
||||
this.cardManager = new NFCCardManager();
|
||||
this.cardManager.setCardListener(this.actionRunner);
|
||||
cardManager.start();
|
||||
|
|
@ -1,19 +1,15 @@
|
|||
package im.status.applet_installer_test.appletinstaller;
|
||||
package im.status.keycard.installer;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import im.status.hardwallet_lite_android.io.CardChannel;
|
||||
import im.status.hardwallet_lite_android.wallet.WalletAppletCommandSet;
|
||||
import org.spongycastle.jce.ECNamedCurveTable;
|
||||
import org.spongycastle.jce.spec.ECParameterSpec;
|
||||
import im.status.keycard.io.CardChannel;
|
||||
import im.status.keycard.applet.KeycardCommandSet;
|
||||
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.util.Random;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
public class PerfTest {
|
||||
private CardChannel cardChannel;
|
||||
private WalletAppletCommandSet cmdSet;
|
||||
private KeycardCommandSet cmdSet;
|
||||
|
||||
private long openSecureChannelTime = 0;
|
||||
private long loadKeysTime = 0;
|
||||
|
@ -28,11 +24,10 @@ public class PerfTest {
|
|||
}
|
||||
|
||||
public void test() throws Exception {
|
||||
cmdSet = new WalletAppletCommandSet(cardChannel);
|
||||
cmdSet = new KeycardCommandSet(cardChannel);
|
||||
cmdSet.select().checkOK();
|
||||
|
||||
String pairingPassword = "WalletAppletTest";
|
||||
cmdSet.autoPair(cmdSet.pairingPasswordToSecret(pairingPassword));
|
||||
cmdSet.autoPair(cmdSet.pairingPasswordToSecret(Secrets.testSecrets().getPairingPassword()));
|
||||
openSecureChannelTime = System.currentTimeMillis();
|
||||
cmdSet.autoOpenSecureChannel();
|
||||
openSecureChannelTime = System.currentTimeMillis() - openSecureChannelTime;
|
||||
|
@ -69,7 +64,7 @@ public class PerfTest {
|
|||
long time = System.currentTimeMillis();
|
||||
cmdSet.select().checkOK();
|
||||
cmdSet.autoOpenSecureChannel();
|
||||
cmdSet.getStatus(WalletAppletCommandSet.GET_STATUS_P1_APPLICATION).checkOK();
|
||||
cmdSet.getStatus(KeycardCommandSet.GET_STATUS_P1_APPLICATION).checkOK();
|
||||
getStatusTime = System.currentTimeMillis() - time;
|
||||
}
|
||||
|
||||
|
@ -84,12 +79,10 @@ public class PerfTest {
|
|||
}
|
||||
|
||||
private void loadKeys() throws Exception {
|
||||
KeyPairGenerator g = keypairGenerator();
|
||||
KeyPair keyPair = g.generateKeyPair();
|
||||
byte[] chainCode = new byte[32];
|
||||
new Random().nextBytes(chainCode);
|
||||
byte[] seed = new byte[64];
|
||||
new SecureRandom().nextBytes(seed);
|
||||
|
||||
cmdSet.loadKey(keyPair, false, chainCode).checkOK();
|
||||
cmdSet.loadKey(seed).checkOK();
|
||||
|
||||
long time = System.currentTimeMillis();
|
||||
cmdSet.deriveKey(BIP44_WALLET_PATH).checkOK();
|
||||
|
@ -104,12 +97,4 @@ public class PerfTest {
|
|||
cmdSet.sign("any32bytescanbeahashyouknowthat!".getBytes()).checkOK();
|
||||
signTime = System.currentTimeMillis() - time;
|
||||
}
|
||||
|
||||
private KeyPairGenerator keypairGenerator() throws Exception {
|
||||
ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("secp256k1");
|
||||
KeyPairGenerator g = KeyPairGenerator.getInstance("ECDH");
|
||||
g.initialize(ecSpec);
|
||||
|
||||
return g;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package im.status.keycard.installer;
|
||||
|
||||
import android.util.Base64;
|
||||
import im.status.keycard.globalplatform.Crypto;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import static android.util.Base64.NO_PADDING;
|
||||
import static im.status.keycard.globalplatform.Crypto.randomLong;
|
||||
|
||||
public class Secrets {
|
||||
private String pin;
|
||||
private String puk;
|
||||
private String pairingPassword;
|
||||
|
||||
public Secrets(String pin, String puk, String pairingPassword) {
|
||||
this.pin = pin;
|
||||
this.puk = puk;
|
||||
this.pairingPassword = pairingPassword;
|
||||
}
|
||||
|
||||
public static Secrets generate() {
|
||||
String pairingPassword = randomToken(12);
|
||||
long pinNumber = randomLong(Crypto.PIN_BOUND);
|
||||
long pukNumber = randomLong(Crypto.PUK_BOUND);
|
||||
String pin = String.format("%06d", pinNumber);
|
||||
String puk = String.format("%012d", pukNumber);
|
||||
|
||||
return new Secrets(pin, puk, pairingPassword);
|
||||
}
|
||||
|
||||
public static Secrets testSecrets() {
|
||||
String pairingPassword = "KeycardTest";
|
||||
return new Secrets("000000", "123456789012", pairingPassword);
|
||||
}
|
||||
|
||||
public String getPin() {
|
||||
return pin;
|
||||
}
|
||||
|
||||
public String getPuk() {
|
||||
return puk;
|
||||
}
|
||||
|
||||
public String getPairingPassword() {
|
||||
return pairingPassword;
|
||||
}
|
||||
|
||||
public static byte[] randomBytes(int length) {
|
||||
SecureRandom random = new SecureRandom();
|
||||
byte data[] = new byte[length];
|
||||
random.nextBytes(data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public static String randomToken(int length) {
|
||||
return Base64.encodeToString(randomBytes(length), NO_PADDING);
|
||||
}
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
<resources>
|
||||
<string name="app_name">AppletInstaller</string>
|
||||
<string name="app_name">KeycardInstaller</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue