Skip to content

Instantly share code, notes, and snippets.

@half2me
Created May 13, 2018 17:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save half2me/31bf205037b2de314e9887621945f410 to your computer and use it in GitHub Desktop.
Save half2me/31bf205037b2de314e9887621945f410 to your computer and use it in GitHub Desktop.
FidesmoCrypto
package com.fidesmo.javacard.example;
import javacard.framework.*;
import javacard.security.*;
public abstract class BaseCardlet extends Applet implements ISO7816 {
KeyPair kp;
Signature sig;
BaseCardlet(byte[] buffer, short offset, byte length) {
kp = newKey();
kp.genKeyPair();
sig = newSig();
sig.init(kp.getPrivate(), Signature.MODE_SIGN);
register();
}
protected abstract KeyPair newKey();
protected abstract Signature newSig();
protected abstract void sendPublicKey(APDU apdu, short p1);
protected abstract void signData(APDU apdu);
public void process(APDU apdu) {
if (this.selectingApplet()) {
return;
}
byte[] apduBuffer = apdu.getBuffer();
byte cla = apduBuffer[ISO7816.OFFSET_CLA];
byte ins = apduBuffer[ISO7816.OFFSET_INS];
short lc = (short) apduBuffer[ISO7816.OFFSET_LC];
short p1 = (short) apduBuffer[ISO7816.OFFSET_P1];
short p2 = (short) apduBuffer[ISO7816.OFFSET_P2];
switch (ins) {
case 0x00:
if (p1 == 0x00) {
sendPublicKeyType(apdu);
} else {
sendPublicKey(apdu, p1);
}
return;
case 0x01:
signData(apdu);
return;
default:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
private void sendPublicKeyType(APDU apdu) {
PublicKey pk = kp.getPublic();
apdu.getBuffer()[0] = pk.getType();
apdu.setOutgoingAndSend((short) 0, (short) 1);
}
}
package com.fidesmo.javacard.example;
import javacard.framework.*;
import javacard.security.KeyBuilder;
import javacard.security.KeyPair;
import javacard.security.RSAPublicKey;
import javacard.security.Signature;
public class ExampleCardlet extends BaseCardlet {
private static final short SCRATCHPAD_SIZE = 256;
private byte[] scratchpad = JCSystem.makeTransientByteArray(SCRATCHPAD_SIZE, JCSystem.CLEAR_ON_DESELECT);
public ExampleCardlet(byte[] buffer, short offset, byte length) {
super(buffer, offset, length);
}
public static void install(byte[] bArray, short bOffset, byte bLength) {
new ExampleCardlet(bArray, bOffset, bLength);
}
protected KeyPair newKey() {
return new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048);
}
protected Signature newSig() {
return Signature.getInstance(Signature.ALG_RSA_SHA_PKCS1, false);
}
protected void sendPublicKey(APDU apdu, short cmd) {
switch (cmd) {
case 0x01:
sendRSAPublicKeyExp(apdu);
return;
case 0x02:
sendRSAPublicKeyMod(apdu);
return;
default:
ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2);
}
}
private void sendRSAPublicKeyMod(APDU apdu) {
RSAPublicKey pk = (RSAPublicKey) kp.getPublic();
short len = pk.getModulus(scratchpad, (short) 0);
Util.arrayCopyNonAtomic(scratchpad, (short) 0, apdu.getBuffer(), (short) 0, len);
apdu.setOutgoingAndSend((short) 0, len);
}
private void sendRSAPublicKeyExp(APDU apdu) {
RSAPublicKey pk = (RSAPublicKey) kp.getPublic();
short len = pk.getExponent(scratchpad, (short) 0);
Util.arrayCopyNonAtomic(scratchpad, (short) 0, apdu.getBuffer(), (short) 0, len);
apdu.setOutgoingAndSend((short) 0, len);
}
protected void signData(APDU apdu) {
short len = sig.sign(apdu.getBuffer(), ISO7816.OFFSET_CDATA, apdu.getBuffer()[ISO7816.OFFSET_LC], scratchpad, (short) 0);
Util.arrayCopyNonAtomic(scratchpad, (short) 0, apdu.getBuffer(), (short) 0, len);
apdu.setOutgoingAndSend((short) 0, len);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment