105 lines
4.7 KiB
Java
105 lines
4.7 KiB
Java
|
package org.jmrtd.protocol;
|
||
|
|
||
|
import com.airbnb.deeplinkdispatch.UrlTreeKt;
|
||
|
import com.google.common.primitives.UnsignedBytes;
|
||
|
import java.security.GeneralSecurityException;
|
||
|
import java.security.SecureRandom;
|
||
|
import java.util.Random;
|
||
|
import java.util.logging.Level;
|
||
|
import java.util.logging.Logger;
|
||
|
import javax.crypto.SecretKey;
|
||
|
import net.sf.scuba.smartcards.CardServiceException;
|
||
|
import org.bouncycastle.pqc.jcajce.spec.McElieceCCA2KeyGenParameterSpec;
|
||
|
import org.jmrtd.BACKeySpec;
|
||
|
import org.jmrtd.PassportService;
|
||
|
import org.jmrtd.Util;
|
||
|
|
||
|
/* loaded from: classes6.dex */
|
||
|
public class BACProtocol {
|
||
|
private static final Logger LOGGER = Logger.getLogger("org.jmrtd");
|
||
|
private Random random = new SecureRandom();
|
||
|
private PassportService service;
|
||
|
|
||
|
public BACProtocol(PassportService passportService) {
|
||
|
this.service = passportService;
|
||
|
}
|
||
|
|
||
|
public BACResult doBAC(BACKeySpec bACKeySpec) throws CardServiceException {
|
||
|
try {
|
||
|
byte[] computeKeySeedForBAC = computeKeySeedForBAC(bACKeySpec);
|
||
|
return new BACResult(bACKeySpec, doBACStep(Util.deriveKey(computeKeySeedForBAC, 1), Util.deriveKey(computeKeySeedForBAC, 2)));
|
||
|
} catch (GeneralSecurityException e) {
|
||
|
LOGGER.log(Level.WARNING, "Error during BAC", (Throwable) e);
|
||
|
throw new CardServiceException(e.toString());
|
||
|
} catch (CardServiceException e2) {
|
||
|
LOGGER.log(Level.WARNING, "BAC failed", (Throwable) e2);
|
||
|
throw e2;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public BACResult doBAC(SecretKey secretKey, SecretKey secretKey2) throws CardServiceException, GeneralSecurityException {
|
||
|
return new BACResult(doBACStep(secretKey, secretKey2));
|
||
|
}
|
||
|
|
||
|
private SecureMessagingWrapper doBACStep(SecretKey secretKey, SecretKey secretKey2) throws CardServiceException, GeneralSecurityException {
|
||
|
byte[] sendGetChallenge = this.service.sendGetChallenge();
|
||
|
byte[] bArr = new byte[8];
|
||
|
this.random.nextBytes(bArr);
|
||
|
byte[] bArr2 = new byte[16];
|
||
|
this.random.nextBytes(bArr2);
|
||
|
byte[] sendMutualAuth = this.service.sendMutualAuth(bArr, sendGetChallenge, bArr2, secretKey, secretKey2);
|
||
|
byte[] bArr3 = new byte[16];
|
||
|
System.arraycopy(sendMutualAuth, 16, bArr3, 0, 16);
|
||
|
byte[] bArr4 = new byte[16];
|
||
|
for (int i = 0; i < 16; i++) {
|
||
|
bArr4[i] = (byte) ((bArr2[i] & UnsignedBytes.MAX_VALUE) ^ (bArr3[i] & UnsignedBytes.MAX_VALUE));
|
||
|
}
|
||
|
return new DESedeSecureMessagingWrapper(Util.deriveKey(bArr4, 1), Util.deriveKey(bArr4, 2), computeSendSequenceCounter(sendGetChallenge, bArr));
|
||
|
}
|
||
|
|
||
|
public static byte[] computeKeySeedForBAC(BACKeySpec bACKeySpec) throws GeneralSecurityException {
|
||
|
String documentNumber = bACKeySpec.getDocumentNumber();
|
||
|
String dateOfBirth = bACKeySpec.getDateOfBirth();
|
||
|
String dateOfExpiry = bACKeySpec.getDateOfExpiry();
|
||
|
if (dateOfBirth == null || dateOfBirth.length() != 6) {
|
||
|
throw new IllegalArgumentException("Wrong date format used for date of birth. Expected yyMMdd, found ".concat(String.valueOf(dateOfBirth)));
|
||
|
}
|
||
|
if (dateOfExpiry == null || dateOfExpiry.length() != 6) {
|
||
|
throw new IllegalArgumentException("Wrong date format used for date of expiry. Expected yyMMdd, found ".concat(String.valueOf(dateOfExpiry)));
|
||
|
}
|
||
|
if (documentNumber == null) {
|
||
|
throw new IllegalArgumentException("Wrong document number. Found ".concat(String.valueOf(documentNumber)));
|
||
|
}
|
||
|
return computeKeySeedForBAC(fixDocumentNumber(documentNumber), dateOfBirth, dateOfExpiry);
|
||
|
}
|
||
|
|
||
|
public static long computeSendSequenceCounter(byte[] bArr, byte[] bArr2) {
|
||
|
if (bArr == null || bArr.length != 8 || bArr2 == null || bArr2.length != 8) {
|
||
|
throw new IllegalStateException("Wrong length input");
|
||
|
}
|
||
|
long j = 0;
|
||
|
for (int i = 4; i < 8; i++) {
|
||
|
j = (j << 8) + (bArr[i] & UnsignedBytes.MAX_VALUE);
|
||
|
}
|
||
|
for (int i2 = 4; i2 < 8; i2++) {
|
||
|
j = (j << 8) + (bArr2[i2] & UnsignedBytes.MAX_VALUE);
|
||
|
}
|
||
|
return j;
|
||
|
}
|
||
|
|
||
|
private static byte[] computeKeySeedForBAC(String str, String str2, String str3) throws GeneralSecurityException {
|
||
|
return Util.computeKeySeed(str, str2, str3, McElieceCCA2KeyGenParameterSpec.SHA1, true);
|
||
|
}
|
||
|
|
||
|
private static String fixDocumentNumber(String str) {
|
||
|
String replace = str.replace(UrlTreeKt.configurablePathSegmentPrefixChar, ' ').trim().replace(' ', UrlTreeKt.configurablePathSegmentPrefixChar);
|
||
|
while (replace.length() < 9) {
|
||
|
StringBuilder sb = new StringBuilder();
|
||
|
sb.append(replace);
|
||
|
sb.append(UrlTreeKt.configurablePathSegmentPrefix);
|
||
|
replace = sb.toString();
|
||
|
}
|
||
|
return replace;
|
||
|
}
|
||
|
}
|