[Impressum]
[E-Mail]
package generated.javacard.copycardMoneySecure.copycard;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.Util;
/**
* Class for T(L)V encoding of messages and other classes
*/
public class Coding {
/**
* offset into encodeDestination for writing/reading
*/
private short encoding_length;
/**
* array used for encoding/decoding
*/
private byte[] encodeDestination;
/**
* Singleton instance
*/
private static Coding the_instance;
/**
* Singleton accessor
*
* @return Singleton instance
*/
public static Coding getInstance() {
if (the_instance == null)
the_instance = new Coding();
return the_instance;
}
/**
* return offset into encodeDestination
*
* @return value of encoding_length
*/
public short getEncodingLength() {
return encoding_length;
}
/**
* initializes encoding. This method must be called before encoding an object.
* The offset (encoding_length) is reset to 0 and encodeDestination is set to dest.
*
* @param dest The (empty) destination array for encoding
*/
private void encodeInit(byte[] dest) {
encodeDestination = dest;
encoding_length = 0;
}
/**
* initializes decoding. The offset (encoding_length) is reset to 0.
*/
private void decodeInit() {
encoding_length = 0;
}
/**
* initializes encoding and encodes an object.
*
* @param o The object to encode
* @param dest destination array for the encoding
* @return length of the encoded object
*/
public short encode(Codeable o, byte[] dest) {
encodeInit(dest);
try {
encode(o);
} catch (ArrayIndexOutOfBoundsException e) {
stop();
}
return encoding_length;
}
/**
* computes the encoding length of an object without actually encoding it.
*
* @param o The object of which the encoding length should be computed
* @return encoding length
*/
private short computeSize(Codeable o) {
encoding_length = 0;
try {
compSize(o);
return encoding_length;
} catch (Exception e) {
return -1;
}
}
private void encodeShort(short o) {
encodeDestination[encoding_length++] = Code.SHORT;
Util.setShort(encodeDestination, encoding_length, o);
encoding_length += 2;
}
private void encodeByte(byte o) {
encodeDestination[encoding_length++] = Code.BYTE;
encodeDestination[encoding_length++] = o;
}
private void encodeBoolean(boolean o) {
encodeDestination[encoding_length++] = Code.BOOLEAN;
encodeDestination[encoding_length++] = (byte) (o ? 1 : 0);
}
private void compSizeShort(short o) {
encoding_length += 3;
}
private void compSizeByte(byte o) {
encoding_length += 2;
}
private void compSizeBoolean(boolean o) {
encoding_length += 2;
}
private short decodeShort(byte[] in) {
if (in[encoding_length++] != Code.SHORT)
stop();
short res = Util.getShort(in, encoding_length);
encoding_length += 2;
return res;
}
private byte decodeByte(byte[] in) {
if (in[encoding_length++] != Code.BYTE)
stop();
byte res = in[encoding_length++];
return res;
}
private boolean decodeBoolean(byte[] in) {
if (in[encoding_length++] != Code.BOOLEAN)
stop();
boolean res = (in[encoding_length++] == 1 ? true : false);
return res;
}
private void encodeByteArray(byte[] o) {
encodeDestination[encoding_length++] = Code.BYTEARRAY;
Util.setShort(encodeDestination, encoding_length, (short) (o.length));
encoding_length += 2;
Util.arrayCopy(o, (short) 0, encodeDestination, encoding_length,
(short) o.length);
encoding_length += o.length;
}
private void compSizeByteArray(byte[] o) {
encoding_length += 3;
encoding_length += o.length;
}
private void decodeByteArrayInto(byte[] in, byte[] into) {
if (in[encoding_length++] != Code.BYTEARRAY)
stop();
short len = Util.getShort(in, encoding_length);
encoding_length += 2;
Util.arrayCopy(in, encoding_length, into, (short) 0, len);
encoding_length += len;
}
private void encode(Codeable c) {
switch (c.getCode()) {
case Code.LOAD :
encodeLoad((Load) c);
break;
case Code.REQUESTBALANCE :
encodeRequestBalance((RequestBalance) c);
break;
case Code.PAY :
encodePay((Pay) c);
break;
case Code.RESREQUESTBALANCE :
encodeResRequestBalance((ResRequestBalance) c);
break;
case Code.RESPAY :
encodeResPay((ResPay) c);
break;
case Code.RESAUTHENTICATE :
encodeResAuthenticate((ResAuthenticate) c);
break;
case Code.AUTHENTICATE :
encodeAuthenticate((Authenticate) c);
break;
case Code.HASHEDDATA :
encodeHashedData((HashedData) c);
break;
case Code.AUTHDATA :
encodeAuthData((AuthData) c);
break;
case Code.NONCE :
encodeNonce((Nonce) c);
break;
case Code.SECRET :
encodeSecret((Secret) c);
break;
// never reached
default :
stop();
break;
}
}
public Message decodeMessage(byte[] in, short offset, short expectedLength) {
encoding_length = offset;
Message m = null;
try {
switch (in[encoding_length]) {
case Code.LOAD :
m = Store.newLoad();
decodeLoadInto(in, (Load) m);
break;
case Code.REQUESTBALANCE :
m = Store.newRequestBalance();
decodeRequestBalanceInto(in, (RequestBalance) m);
break;
case Code.PAY :
m = Store.newPay();
decodePayInto(in, (Pay) m);
break;
case Code.RESREQUESTBALANCE :
m = Store.newResRequestBalance();
decodeResRequestBalanceInto(in, (ResRequestBalance) m);
break;
case Code.RESPAY :
m = Store.newResPay();
decodeResPayInto(in, (ResPay) m);
break;
case Code.RESAUTHENTICATE :
m = Store.newResAuthenticate();
decodeResAuthenticateInto(in, (ResAuthenticate) m);
break;
case Code.AUTHENTICATE :
m = Store.newAuthenticate();
decodeAuthenticateInto(in, (Authenticate) m);
break;
}
} catch (ArrayIndexOutOfBoundsException e) {
stop();
}
if (m == null || encoding_length != (short) (expectedLength + offset))
stop();
return m;
}
private void compSize(Codeable c) {
switch (c.getCode()) {
case Code.LOAD :
compSizeLoad((Load) c);
break;
case Code.REQUESTBALANCE :
compSizeRequestBalance((RequestBalance) c);
break;
case Code.PAY :
compSizePay((Pay) c);
break;
case Code.RESREQUESTBALANCE :
compSizeResRequestBalance((ResRequestBalance) c);
break;
case Code.RESPAY :
compSizeResPay((ResPay) c);
break;
case Code.RESAUTHENTICATE :
compSizeResAuthenticate((ResAuthenticate) c);
break;
case Code.AUTHENTICATE :
compSizeAuthenticate((Authenticate) c);
break;
case Code.HASHEDDATA :
compSizeHashedData((HashedData) c);
break;
case Code.AUTHDATA :
compSizeAuthData((AuthData) c);
break;
case Code.NONCE :
compSizeNonce((Nonce) c);
break;
case Code.SECRET :
compSizeSecret((Secret) c);
break;
// never reached
default :
stop();
break;
}
}
private void encodeLoad(Load c) {
encodeDestination[encoding_length++] = Code.LOAD;
encodeShort((short) c.amount);
encode(c.authterminal);
}
private void decodeLoadInto(byte[] in, Load into) {
if (in[encoding_length++] != Code.LOAD)
stop();
into.amount = decodeShort(in);
decodeHashedDataInto(in, (HashedData) (into.authterminal));
}
private void compSizeLoad(Load c) {
encoding_length++;
compSizeShort(c.amount);
compSize(c.authterminal);
}
private void encodeRequestBalance(RequestBalance c) {
encodeDestination[encoding_length++] = Code.REQUESTBALANCE;
}
private void decodeRequestBalanceInto(byte[] in, RequestBalance into) {
if (in[encoding_length++] != Code.REQUESTBALANCE)
stop();
}
private void compSizeRequestBalance(RequestBalance c) {
encoding_length++;
}
private void encodePay(Pay c) {
encodeDestination[encoding_length++] = Code.PAY;
encodeShort((short) c.amount);
encode(c.terminalchallenge);
}
private void decodePayInto(byte[] in, Pay into) {
if (in[encoding_length++] != Code.PAY)
stop();
into.amount = decodeShort(in);
decodeNonceInto(in, (Nonce) (into.terminalchallenge));
}
private void compSizePay(Pay c) {
encoding_length++;
compSizeShort(c.amount);
compSize(c.terminalchallenge);
}
private void encodeResRequestBalance(ResRequestBalance c) {
encodeDestination[encoding_length++] = Code.RESREQUESTBALANCE;
encodeShort((short) c.balance);
}
private void decodeResRequestBalanceInto(byte[] in, ResRequestBalance into) {
if (in[encoding_length++] != Code.RESREQUESTBALANCE)
stop();
into.balance = decodeShort(in);
}
private void compSizeResRequestBalance(ResRequestBalance c) {
encoding_length++;
compSizeShort(c.balance);
}
private void encodeResPay(ResPay c) {
encodeDestination[encoding_length++] = Code.RESPAY;
encode(c.authcard);
}
private void decodeResPayInto(byte[] in, ResPay into) {
if (in[encoding_length++] != Code.RESPAY)
stop();
decodeHashedDataInto(in, (HashedData) (into.authcard));
}
private void compSizeResPay(ResPay c) {
encoding_length++;
compSize(c.authcard);
}
private void encodeResAuthenticate(ResAuthenticate c) {
encodeDestination[encoding_length++] = Code.RESAUTHENTICATE;
encode(c.cardletchallenge);
}
private void decodeResAuthenticateInto(byte[] in, ResAuthenticate into) {
if (in[encoding_length++] != Code.RESAUTHENTICATE)
stop();
decodeNonceInto(in, (Nonce) (into.cardletchallenge));
}
private void compSizeResAuthenticate(ResAuthenticate c) {
encoding_length++;
compSize(c.cardletchallenge);
}
private void encodeAuthenticate(Authenticate c) {
encodeDestination[encoding_length++] = Code.AUTHENTICATE;
}
private void decodeAuthenticateInto(byte[] in, Authenticate into) {
if (in[encoding_length++] != Code.AUTHENTICATE)
stop();
}
private void compSizeAuthenticate(Authenticate c) {
encoding_length++;
}
private void encodeHashedData(HashedData c) {
encodeDestination[encoding_length++] = Code.HASHEDDATA;
encodeByteArray((byte[]) c.hashed);
}
private void decodeHashedDataInto(byte[] in, HashedData into) {
if (in[encoding_length++] != Code.HASHEDDATA)
stop();
decodeByteArrayInto(in, into.hashed);
}
private void compSizeHashedData(HashedData c) {
encoding_length++;
compSizeByteArray(c.hashed);
}
private void encodeAuthData(AuthData c) {
encodeDestination[encoding_length++] = Code.AUTHDATA;
encodeShort((short) c.instruction);
encode(c.passphrase);
encode(c.challenge);
encodeShort((short) c.amount);
}
private void decodeAuthDataInto(byte[] in, AuthData into) {
if (in[encoding_length++] != Code.AUTHDATA)
stop();
into.instruction = decodeShort(in);
decodeSecretInto(in, (Secret) (into.passphrase));
decodeNonceInto(in, (Nonce) (into.challenge));
into.amount = decodeShort(in);
}
private void compSizeAuthData(AuthData c) {
encoding_length++;
compSizeShort(c.instruction);
compSize(c.passphrase);
compSize(c.challenge);
compSizeShort(c.amount);
}
private void encodeNonce(Nonce c) {
encodeDestination[encoding_length++] = Code.NONCE;
encodeByteArray((byte[]) c.nonce);
}
private void decodeNonceInto(byte[] in, Nonce into) {
if (in[encoding_length++] != Code.NONCE)
stop();
decodeByteArrayInto(in, into.nonce);
}
private void compSizeNonce(Nonce c) {
encoding_length++;
compSizeByteArray(c.nonce);
}
private void encodeSecret(Secret c) {
encodeDestination[encoding_length++] = Code.SECRET;
encodeByteArray((byte[]) c.secret);
}
private void decodeSecretInto(byte[] in, Secret into) {
if (in[encoding_length++] != Code.SECRET)
stop();
decodeByteArrayInto(in, into.secret);
}
private void compSizeSecret(Secret c) {
encoding_length++;
compSizeByteArray(c.secret);
}
public void decodeCopycard(byte[] in, short offset, Copycard thisCopycard) {
encoding_length = offset;
if (in[encoding_length++] != Code.COPYCARD)
stop();
if (in[encoding_length] != Code.IGNORE) {
decodeSecretInto(in, thisCopycard.passphrase);
} else
encoding_length++;
if (in[encoding_length] != Code.IGNORE) {
thisCopycard.state = decodeByte(in);
} else
encoding_length++;
}
private void stop() {
ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
}
}