Code: Select all
package com.infopro.javacard.Crypto;
import javacard.framework.*;
import javacard.security.*;
import javacardx.crypto.*;
public class GenCryptoRSANoPad extends javacard.framework.Applet {
final static byte GenCryptoRSANoPad_CLA =(byte)0x88;
final byte RSAEnc = (byte) 0x32;
final byte RSADec = (byte) 0x34;
final byte PinCheck = (byte) 0xCC;
final byte CLA_F0 = (byte) 0xF0;
final byte PinTryLimit = (byte)0x0A;
final byte MaxPinSize = (byte)0x04;
final short SW_WRONG_PIN = (short) 0x6BBB;// Error returnd if PIN not correctly presented
final short VERIFY_BAD = (short) 0x6CCC; // Error returnd for MAC or Signature Verify failure
final short APDUDATA = (short) ISO7816.OFFSET_CDATA; // Define apdu buffet offset for data.
static byte[] pinString = //Note this is the PIN
{
(byte)0x12, (byte)0x34, (byte)0x56, (byte)0x78
};
/* instance variables declaration */
OwnerPIN pin;
RSAPrivateCrtKey privKey;
RSAPublicKey pubKey;
Cipher cipherRSA;
private GenCryptoRSANoPad(byte buffer[],short offset,byte length) {
pin = new OwnerPIN(PinTryLimit, MaxPinSize);// Initialise the PIN data
pin.update(pinString, (short)0, (byte)4); // Load and make the PIN active.
KeyPair kp = new KeyPair(KeyPair.ALG_RSA_CRT, (short)1024);
kp.genKeyPair();
privKey = (RSAPrivateCrtKey)kp.getPrivate();
pubKey = (RSAPublicKey)kp.getPublic();
cipherRSA = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, true);
if (buffer[offset] == 0) {
register();
}
else {
register(buffer, (short)(offset+1) ,(byte)(buffer[offset]));
}
} // end of the constructor
// Install method
public static void install(byte buffer[],short offset,byte length){
// create a GenCryptoRSANoPad applet instance
new GenCryptoRSANoPad(buffer, offset, length);
} // end of install method
public boolean select() {
pin.reset();
return true;
}// end of select method
public void process(APDU apdu) {
byte apduBuffer[] = apdu.getBuffer();
// Implement a select handler
if (selectingApplet()) {
ISOException.throwIt(ISO7816.SW_NO_ERROR);
}
if (apduBuffer[ISO7816.OFFSET_CLA] != GenCryptoRSANoPad_CLA) {
ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED);
}
byte ins = apduBuffer[ISO7816.OFFSET_INS];
switch (ins) {
case RSAEnc: RunTest8(apdu); return;
case RSADec: RunTest9(apdu); return;
case PinCheck: CheckThePin(apdu); return;
default: ISOException.throwIt (ISO7816.SW_INS_NOT_SUPPORTED);
}
} // end of process method
private void CheckThePin(APDU apdu) {
byte apduBuffer[] = apdu.getBuffer();
short byteRead = (short)(apdu.setIncomingAndReceive());
if (byteRead != 4)
ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
if (pin.check(apduBuffer, (short)APDUDATA, (byte)4) == false){
ISOException.throwIt(SW_WRONG_PIN);
}
} // end of CheckThePin method
private void RunTest8(APDU apdu) {
byte apduBuffer[] = apdu.getBuffer();
if ( ! pin.isValidated() )
ISOException.throwIt (ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
short byteRead = (short)(apdu.setIncomingAndReceive());
cipherRSA.init(privKey, Cipher.MODE_ENCRYPT);
short outbytes;
outbytes = cipherRSA.doFinal(apduBuffer,(short)APDUDATA, byteRead, apduBuffer, (short)APDUDATA);
apdu.setOutgoing();
apdu.setOutgoingLength((short)outbytes);
apdu.sendBytesLong(apduBuffer, (short)APDUDATA, (short)outbytes);
}
private void RunTest9(APDU apdu) {
byte apduBuffer[] = apdu.getBuffer();
if ( ! pin.isValidated() )
ISOException.throwIt (ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED);
short byteRead = (short)(apdu.setIncomingAndReceive());
cipherRSA.init(pubKey, Cipher.MODE_DECRYPT);
cipherRSA.doFinal(apduBuffer,(short)APDUDATA, byteRead, apduBuffer, (short)APDUDATA);
apdu.setOutgoing();
apdu.setOutgoingLength(byteRead);
apdu.sendBytesLong(apduBuffer, (short)APDUDATA, byteRead);
}
} // end of class GenCryptoRSANoPad