what-the-bank/sources/org/jmrtd/protocol/AESSecureMessagingWrapper.java

301 lines
12 KiB
Java

package org.jmrtd.protocol;
import com.google.common.primitives.UnsignedBytes;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import net.sf.scuba.smartcards.CommandAPDU;
import net.sf.scuba.smartcards.ResponseAPDU;
import o.C15109ghW;
import org.jmrtd.Util;
/* loaded from: classes6.dex */
public class AESSecureMessagingWrapper extends SecureMessagingWrapper implements Serializable {
private static final Logger LOGGER = Logger.getLogger("org.jmrtd");
private static final long serialVersionUID = 2086301081448345496L;
private transient Cipher cipher;
private SecretKey ksEnc;
private SecretKey ksMac;
private transient Mac mac;
private long ssc;
private transient Cipher sscIVCipher;
private boolean checkMac(byte[] bArr, byte[] bArr2) throws GeneralSecurityException {
return true;
}
public AESSecureMessagingWrapper(SecretKey secretKey, SecretKey secretKey2, long j) throws GeneralSecurityException {
this.ksEnc = secretKey;
this.ksMac = secretKey2;
this.ssc = j;
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
this.sscIVCipher = cipher;
cipher.init(1, secretKey);
this.cipher = Cipher.getInstance("AES/CBC/NoPadding");
Mac mac = Mac.getInstance("AESCMAC");
this.mac = mac;
mac.init(secretKey2);
}
@Override // net.sf.scuba.smartcards.APDUWrapper
public CommandAPDU wrap(CommandAPDU commandAPDU) {
try {
return wrapCommandAPDU(commandAPDU);
} catch (IOException e) {
Logger logger = LOGGER;
StringBuilder sb = new StringBuilder("Exception: ");
sb.append(e.getMessage());
logger.severe(sb.toString());
throw new IllegalStateException(e.toString());
} catch (GeneralSecurityException e2) {
Logger logger2 = LOGGER;
StringBuilder sb2 = new StringBuilder("Exception: ");
sb2.append(e2.getMessage());
logger2.severe(sb2.toString());
throw new IllegalStateException(e2.toString());
}
}
@Override // net.sf.scuba.smartcards.APDUWrapper
public ResponseAPDU unwrap(ResponseAPDU responseAPDU) {
try {
byte[] bytes = responseAPDU.getBytes();
if (bytes.length == 2) {
StringBuilder sb = new StringBuilder("Card indicates SM error, SW = ");
sb.append(Integer.toHexString(responseAPDU.getSW() & 65535));
throw new IllegalStateException(sb.toString());
}
return new ResponseAPDU(unwrapResponseAPDU(bytes));
} catch (IOException e) {
Logger logger = LOGGER;
StringBuilder sb2 = new StringBuilder("Exception: ");
sb2.append(e.getMessage());
logger.severe(sb2.toString());
throw new IllegalStateException(e.toString());
} catch (GeneralSecurityException e2) {
Logger logger2 = LOGGER;
StringBuilder sb3 = new StringBuilder("Exception: ");
sb3.append(e2.getMessage());
logger2.severe(sb3.toString());
throw new IllegalStateException(e2.toString());
}
}
public String toString() {
StringBuilder sb = new StringBuilder("AESSecureMessagingWrapper [ ");
sb.append(this.ksEnc.toString());
sb.append(", ");
sb.append(this.ksMac.toString());
sb.append(", ");
sb.append(this.ssc);
sb.append("]");
return sb.toString();
}
private CommandAPDU wrapCommandAPDU(CommandAPDU commandAPDU) throws GeneralSecurityException, IOException {
int nc = commandAPDU.getNc();
int ne = commandAPDU.getNe();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] bArr = {(byte) (commandAPDU.getCLA() | 12), (byte) commandAPDU.getINS(), (byte) commandAPDU.getP1(), (byte) commandAPDU.getP2()};
byte[] pad = Util.pad(bArr, 16);
int i = ((byte) commandAPDU.getINS()) == -79 ? 1 : 0;
byte[] bArr2 = new byte[0];
byte[] bArr3 = new byte[0];
if (ne > 0) {
byteArrayOutputStream.reset();
byteArrayOutputStream.write(-105);
byteArrayOutputStream.write(1);
byteArrayOutputStream.write((byte) ne);
bArr3 = byteArrayOutputStream.toByteArray();
}
long j = this.ssc + 1;
this.ssc = j;
byte[] sSCAsBytes = getSSCAsBytes(j);
if (nc > 0) {
byte[] pad2 = Util.pad(commandAPDU.getData(), 16);
this.cipher.init(1, this.ksEnc, getIV(sSCAsBytes));
byte[] doFinal = this.cipher.doFinal(pad2);
byteArrayOutputStream.reset();
byteArrayOutputStream.write(i != 0 ? -123 : -121);
byteArrayOutputStream.write(C15109ghW.a(doFinal.length + (i ^ 1)));
if (i == 0) {
byteArrayOutputStream.write(1);
}
byteArrayOutputStream.write(doFinal);
bArr2 = byteArrayOutputStream.toByteArray();
}
byteArrayOutputStream.reset();
byteArrayOutputStream.write(pad);
byteArrayOutputStream.write(bArr2);
byteArrayOutputStream.write(bArr3);
byte[] byteArray = byteArrayOutputStream.toByteArray();
byteArrayOutputStream.reset();
byteArrayOutputStream.write(sSCAsBytes);
byteArrayOutputStream.write(byteArray);
byteArrayOutputStream.flush();
byte[] pad3 = Util.pad(byteArrayOutputStream.toByteArray(), 16);
this.mac.init(this.ksMac);
byte[] doFinal2 = this.mac.doFinal(pad3);
int length = doFinal2.length;
if (length != 8) {
length = 8;
}
byteArrayOutputStream.reset();
byteArrayOutputStream.write(-114);
byteArrayOutputStream.write(length);
byteArrayOutputStream.write(doFinal2, 0, length);
byte[] byteArray2 = byteArrayOutputStream.toByteArray();
byteArrayOutputStream.reset();
byteArrayOutputStream.write(bArr2);
byteArrayOutputStream.write(bArr3);
byteArrayOutputStream.write(byteArray2);
return new CommandAPDU(bArr[0], bArr[1], bArr[2], bArr[3], byteArrayOutputStream.toByteArray(), 256);
}
private byte[] unwrapResponseAPDU(byte[] bArr) throws GeneralSecurityException, IOException {
long j = this.ssc;
if (bArr != null) {
try {
if (bArr.length >= 2) {
long j2 = j + 1;
this.ssc = j2;
this.cipher.init(2, this.ksEnc, getIV(j2));
DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(bArr));
byte[] bArr2 = new byte[0];
byte[] bArr3 = null;
boolean z = false;
short s = 0;
while (!z) {
byte readByte = dataInputStream.readByte();
if (readByte == -123) {
bArr2 = readDO87(dataInputStream, true);
} else if (readByte == -121) {
bArr2 = readDO87(dataInputStream, false);
} else if (readByte == -114) {
bArr3 = readDO8E(dataInputStream);
z = true;
} else if (readByte == -103) {
s = readDO99(dataInputStream);
}
}
if (!checkMac(bArr, bArr3)) {
throw new IllegalStateException("Invalid MAC");
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byteArrayOutputStream.write(bArr2, 0, bArr2.length);
byteArrayOutputStream.write((65280 & s) >> 8);
byteArrayOutputStream.write(s & 255);
return byteArrayOutputStream.toByteArray();
}
} finally {
long j3 = this.ssc;
if (j3 == j) {
this.ssc = j3 + 1;
}
}
}
throw new IllegalArgumentException("Invalid response APDU");
}
private byte[] readDO87(DataInputStream dataInputStream, boolean z) throws IOException, GeneralSecurityException {
int readUnsignedByte;
int readUnsignedByte2 = dataInputStream.readUnsignedByte();
if ((readUnsignedByte2 & 128) == 128) {
int i = 0;
for (int i2 = 0; i2 < (readUnsignedByte2 & 127); i2++) {
i = (i << 8) | dataInputStream.readUnsignedByte();
}
if (!z && dataInputStream.readUnsignedByte() != 1) {
throw new IllegalStateException("DO'87 expected 0x01 marker");
}
readUnsignedByte2 = i;
} else if (!z && (readUnsignedByte = dataInputStream.readUnsignedByte()) != 1) {
StringBuilder sb = new StringBuilder("DO'87 expected 0x01 marker, found ");
sb.append(Integer.toHexString(readUnsignedByte & 255));
throw new IllegalStateException(sb.toString());
}
if (!z) {
readUnsignedByte2--;
}
byte[] bArr = new byte[readUnsignedByte2];
dataInputStream.readFully(bArr);
return Util.unpad(this.cipher.doFinal(bArr));
}
private short readDO99(DataInputStream dataInputStream) throws IOException {
if (dataInputStream.readUnsignedByte() != 2) {
throw new IllegalStateException("DO'99 wrong length");
}
return (short) ((dataInputStream.readByte() & UnsignedBytes.MAX_VALUE) | ((dataInputStream.readByte() & UnsignedBytes.MAX_VALUE) << 8));
}
private byte[] readDO8E(DataInputStream dataInputStream) throws IOException, GeneralSecurityException {
int readUnsignedByte = dataInputStream.readUnsignedByte();
if (readUnsignedByte != 8) {
throw new IllegalStateException("DO'8E wrong length ".concat(String.valueOf(readUnsignedByte)));
}
byte[] bArr = new byte[8];
dataInputStream.readFully(bArr);
return bArr;
}
private IvParameterSpec getIV(long j) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
return new IvParameterSpec(this.sscIVCipher.doFinal(getSSCAsBytes(j)));
}
private IvParameterSpec getIV(byte[] bArr) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
return new IvParameterSpec(this.sscIVCipher.doFinal(bArr));
}
private byte[] getSSCAsBytes(long j) {
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(16);
byteArrayOutputStream.write(0);
byteArrayOutputStream.write(0);
byteArrayOutputStream.write(0);
byteArrayOutputStream.write(0);
byteArrayOutputStream.write(0);
byteArrayOutputStream.write(0);
byteArrayOutputStream.write(0);
byteArrayOutputStream.write(0);
DataOutputStream dataOutputStream = new DataOutputStream(byteArrayOutputStream);
dataOutputStream.writeLong(j);
dataOutputStream.close();
return byteArrayOutputStream.toByteArray();
} catch (IOException e) {
Logger logger = LOGGER;
StringBuilder sb = new StringBuilder("Exception: ");
sb.append(e.getMessage());
logger.warning(sb.toString());
return null;
}
}
@Override // org.jmrtd.protocol.SecureMessagingWrapper
public long getSendSequenceCounter() {
return this.ssc;
}
@Override // org.jmrtd.protocol.SecureMessagingWrapper
public SecretKey getMACKey() {
return this.ksMac;
}
@Override // org.jmrtd.protocol.SecureMessagingWrapper
public SecretKey getEncryptionKey() {
return this.ksEnc;
}
}