46 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/test/java/co/coinfinity/infineonandroidapp/ethereum/utils/TransactionSigner.java: -------------------------------------------------------------------------------- 1 | package co.coinfinity.infineonandroidapp.ethereum.utils; 2 | 3 | import co.coinfinity.infineonandroidapp.utils.ByteWriter; 4 | import org.spongycastle.asn1.x9.X9ECParameters; 5 | import org.spongycastle.crypto.digests.SHA256Digest; 6 | import org.spongycastle.crypto.ec.CustomNamedCurves; 7 | import org.spongycastle.crypto.params.ECDomainParameters; 8 | import org.spongycastle.crypto.params.ECPrivateKeyParameters; 9 | import org.spongycastle.crypto.signers.ECDSASigner; 10 | import org.spongycastle.crypto.signers.HMacDSAKCalculator; 11 | import org.web3j.crypto.Credentials; 12 | import org.web3j.crypto.ECDSASignature; 13 | import org.web3j.utils.Convert; 14 | import org.web3j.utils.Numeric; 15 | 16 | import java.math.BigInteger; 17 | 18 | public class TransactionSigner { 19 | 20 | static final BigInteger GAS_PRICE = Convert.toWei("50", Convert.Unit.GWEI).toBigInteger(); 21 | static final BigInteger GAS_LIMIT = new BigInteger("600000"); 22 | private static final X9ECParameters CURVE_PARAMS = CustomNamedCurves.getByName("secp256k1"); 23 | public static final ECDomainParameters CURVE = new ECDomainParameters( 24 | CURVE_PARAMS.getCurve(), CURVE_PARAMS.getG(), CURVE_PARAMS.getN(), CURVE_PARAMS.getH()); 25 | //put in the private key (64 chars long) which you can export via MetaMask 26 | static Credentials credentials = Credentials.create("000000000000000000000000000000000000000000"); 27 | 28 | public static byte[] signTransaction(byte[] data) { 29 | ECDSASigner signer = new ECDSASigner(new HMacDSAKCalculator(new SHA256Digest())); 30 | 31 | ECPrivateKeyParameters privKey = new ECPrivateKeyParameters(TransactionSigner.credentials.getEcKeyPair().getPrivateKey(), CURVE); 32 | signer.init(true, privKey); 33 | BigInteger[] components = signer.generateSignature(data); 34 | 35 | ECDSASignature sig = new ECDSASignature(components[0], components[1]).toCanonicalised(); 36 | 37 | byte[] r = Numeric.toBytesPadded(sig.r, 32); 38 | byte[] s = Numeric.toBytesPadded(sig.s, 32); 39 | 40 | // Write DER encoding of signature 41 | ByteWriter writer = new ByteWriter(1024); 42 | // Write tag 43 | writer.put((byte) 0x30); 44 | // Write total length 45 | 46 | int totalLength = 2 + r.length + 2 + s.length; 47 | if (totalLength > 127) { 48 | // We assume that the total length never goes beyond a 1-byte 49 | // representation 50 | throw new RuntimeException("Unsupported signature length: " + totalLength); 51 | } 52 | writer.put((byte) (totalLength & 0xFF)); 53 | // Write type 54 | writer.put((byte) 0x02); 55 | // We assume that the length never goes beyond a 1-byte representation 56 | writer.put((byte) (r.length & 0xFF)); 57 | // Write bytes 58 | writer.putBytes(r); 59 | // Write type 60 | writer.put((byte) 0x02); 61 | // We assume that the length never goes beyond a 1-byte representation 62 | writer.put((byte) (s.length & 0xFF)); 63 | // Write bytes 64 | writer.putBytes(s); 65 | 66 | return writer.toBytes(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/src/test/java/co/coinfinity/infineonandroidapp/infineon/exceptions/ExceptionHandlerTest.java: -------------------------------------------------------------------------------- 1 | package co.coinfinity.infineonandroidapp.infineon.exceptions; 2 | 3 | import co.coinfinity.infineonandroidapp.infineon.apdu.*; 4 | import org.junit.Test; 5 | 6 | public class ExceptionHandlerTest { 7 | 8 | @Test(expected = GenerateKeypairException.class) 9 | public void testGenerateKeyPairError() throws NfcCardException { 10 | GenerateKeyPairApdu apdu = new GenerateKeyPairApdu(0); 11 | ExceptionHandler.handleErrorCodes(apdu, 0x6A84); 12 | } 13 | 14 | @Test(expected = GetKeyInfoException.class) 15 | public void testGetKeyInfoError() throws NfcCardException { 16 | GetKeyInfoApdu apdu = new GetKeyInfoApdu(0); 17 | ExceptionHandler.handleErrorCodes(apdu, 0x6A88); 18 | } 19 | 20 | @Test(expected = GenerateSignatureException.class) 21 | public void testGenerateSignatureError() throws NfcCardException { 22 | GenerateSignatureApdu apdu = new GenerateSignatureApdu(0, new byte[]{}); 23 | ExceptionHandler.handleErrorCodes(apdu, 0x6985); 24 | } 25 | 26 | @Test(expected = GenerateKeyFromSeedException.class) 27 | public void testGenerateKeyFromSeedError() throws NfcCardException { 28 | GenerateKeyFromSeedApdu apdu = new GenerateKeyFromSeedApdu(new byte[]{}); 29 | ExceptionHandler.handleErrorCodes(apdu, 0x6985); 30 | } 31 | 32 | @Test(expected = SetPinException.class) 33 | public void testSetPinError() throws NfcCardException { 34 | SetPinApdu apdu = new SetPinApdu(new byte[]{}); 35 | ExceptionHandler.handleErrorCodes(apdu, 0x6700); 36 | } 37 | 38 | @Test(expected = ChangePinException.class) 39 | public void testChangePinError() throws NfcCardException { 40 | ChangePinApdu apdu = new ChangePinApdu(new byte[]{}, new byte[]{}); 41 | ExceptionHandler.handleErrorCodes(apdu, 0x6983); 42 | } 43 | 44 | @Test(expected = VerifyPinException.class) 45 | public void testVerifyPinError() throws NfcCardException { 46 | VerifyPinApdu apdu = new VerifyPinApdu(new byte[]{}); 47 | ExceptionHandler.handleErrorCodes(apdu, 0x6983); 48 | } 49 | 50 | @Test(expected = UnlockPinException.class) 51 | public void testUnlockPinError() throws NfcCardException { 52 | UnlockPinApdu apdu = new UnlockPinApdu(new byte[]{}); 53 | ExceptionHandler.handleErrorCodes(apdu, 0x6983); 54 | } 55 | 56 | @Test(expected = SelectApplicationException.class) 57 | public void testSelectApplicationError() throws NfcCardException { 58 | SelectApplicationApdu apdu = new SelectApplicationApdu(new byte[]{}); 59 | ExceptionHandler.handleErrorCodes(apdu, 0x6A82); 60 | } 61 | 62 | @Test(expected = NfcCardException.class) 63 | public void testNfcCardError() throws NfcCardException { 64 | SelectApplicationApdu apdu = new SelectApplicationApdu(new byte[]{}); 65 | ExceptionHandler.handleErrorCodes(apdu, 0x6700); 66 | } 67 | 68 | @Test(expected = NfcCardException.class) 69 | public void testNfcCardErrorWithSW2Info() throws NfcCardException { 70 | SelectApplicationApdu apdu = new SelectApplicationApdu(new byte[]{}); 71 | ExceptionHandler.handleErrorCodes(apdu, 0x6401); 72 | } 73 | } -------------------------------------------------------------------------------- /app/src/main/java/co/coinfinity/infineonandroidapp/adapter/UnitSpinnerAdapter.java: -------------------------------------------------------------------------------- 1 | package co.coinfinity.infineonandroidapp.adapter; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.widget.AdapterView; 6 | import android.widget.ArrayAdapter; 7 | import android.widget.Spinner; 8 | import org.web3j.utils.Convert; 9 | 10 | import java.math.BigDecimal; 11 | 12 | /** 13 | * Adapter class used to calculate gas price depending on selected Ethereum unit. 14 | */ 15 | public class UnitSpinnerAdapter implements AdapterView.OnItemSelectedListener { 16 | 17 | private static final String[] units = {"wei", "kwei", "mwei", "gwei", "szabo", "finney", "ether", "kether", "mether", "gether"}; 18 | private BigDecimal multiplier = new BigDecimal("1"); 19 | 20 | /** 21 | * Needs to be called at the beginning to add this adapter to the spinner. 22 | * 23 | * @param context 24 | * @param spinner 25 | */ 26 | public void addSpinnerAdapter(Context context, Spinner spinner) { 27 | ArrayAdapter