490 lines
26 KiB
Java
490 lines
26 KiB
Java
|
package org.jmrtd.protocol;
|
||
|
|
||
|
import com.airbnb.deeplinkdispatch.UrlTreeKt;
|
||
|
import java.security.GeneralSecurityException;
|
||
|
import java.security.InvalidAlgorithmParameterException;
|
||
|
import java.security.KeyFactory;
|
||
|
import java.security.KeyPair;
|
||
|
import java.security.KeyPairGenerator;
|
||
|
import java.security.NoSuchAlgorithmException;
|
||
|
import java.security.PrivateKey;
|
||
|
import java.security.Provider;
|
||
|
import java.security.PublicKey;
|
||
|
import java.security.SecureRandom;
|
||
|
import java.security.interfaces.ECPrivateKey;
|
||
|
import java.security.interfaces.ECPublicKey;
|
||
|
import java.security.spec.AlgorithmParameterSpec;
|
||
|
import java.security.spec.ECParameterSpec;
|
||
|
import java.security.spec.ECPoint;
|
||
|
import java.security.spec.ECPublicKeySpec;
|
||
|
import java.security.spec.KeySpec;
|
||
|
import java.util.Arrays;
|
||
|
import java.util.Random;
|
||
|
import java.util.logging.Level;
|
||
|
import java.util.logging.Logger;
|
||
|
import javax.crypto.Cipher;
|
||
|
import javax.crypto.KeyAgreement;
|
||
|
import javax.crypto.Mac;
|
||
|
import javax.crypto.SecretKey;
|
||
|
import javax.crypto.spec.DHParameterSpec;
|
||
|
import javax.crypto.spec.IvParameterSpec;
|
||
|
import net.sf.scuba.smartcards.CardServiceException;
|
||
|
import net.sf.scuba.smartcards.ISOFileInfo;
|
||
|
import o.ghS;
|
||
|
import org.bouncycastle.pqc.jcajce.spec.McElieceCCA2KeyGenParameterSpec;
|
||
|
import org.jmrtd.BACKeySpec;
|
||
|
import org.jmrtd.CANKey;
|
||
|
import org.jmrtd.JMRTDSecurityProvider;
|
||
|
import org.jmrtd.PACEException;
|
||
|
import org.jmrtd.PassportService;
|
||
|
import org.jmrtd.Util;
|
||
|
import org.jmrtd.lds.PACEInfo;
|
||
|
|
||
|
/* loaded from: classes6.dex */
|
||
|
public class PACEProtocol {
|
||
|
private Random random = new SecureRandom();
|
||
|
private PassportService service;
|
||
|
private SecureMessagingWrapper wrapper;
|
||
|
private static final Logger LOGGER = Logger.getLogger("org.jmrtd");
|
||
|
private static final Provider BC_PROVIDER = JMRTDSecurityProvider.getBouncyCastleProvider();
|
||
|
private static final byte[] IV_FOR_PACE_CAM_DECRYPTION = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
|
||
|
|
||
|
private void pseudoRandomFunction(byte[] bArr, byte[] bArr2, Cipher cipher) {
|
||
|
}
|
||
|
|
||
|
public PACEProtocol(PassportService passportService, SecureMessagingWrapper secureMessagingWrapper) {
|
||
|
this.service = passportService;
|
||
|
this.wrapper = secureMessagingWrapper;
|
||
|
}
|
||
|
|
||
|
public PACEResult doPACE(KeySpec keySpec, String str, AlgorithmParameterSpec algorithmParameterSpec) throws PACEException {
|
||
|
try {
|
||
|
return doPACE(deriveStaticPACEKey(keySpec, str), str, algorithmParameterSpec);
|
||
|
} catch (GeneralSecurityException unused) {
|
||
|
throw new PACEException("PCD side error in key derivation step");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public PACEResult doPACE(SecretKey secretKey, String str, AlgorithmParameterSpec algorithmParameterSpec) throws PACEException {
|
||
|
byte[] bArr;
|
||
|
byte[] bArr2;
|
||
|
PACEInfo.MappingType mappingType = PACEInfo.toMappingType(str);
|
||
|
String keyAgreementAlgorithm = PACEInfo.toKeyAgreementAlgorithm(str);
|
||
|
String cipherAlgorithm = PACEInfo.toCipherAlgorithm(str);
|
||
|
String digestAlgorithm = PACEInfo.toDigestAlgorithm(str);
|
||
|
int keyLength = PACEInfo.toKeyLength(str);
|
||
|
Logger logger = LOGGER;
|
||
|
StringBuilder sb = new StringBuilder("DEBUG: PACE: oid = ");
|
||
|
sb.append(str);
|
||
|
sb.append(" -> mappingType = ");
|
||
|
sb.append(mappingType);
|
||
|
sb.append(", agreementAlg = ");
|
||
|
sb.append(keyAgreementAlgorithm);
|
||
|
sb.append(", cipherAlg = ");
|
||
|
sb.append(cipherAlgorithm);
|
||
|
sb.append(", digestAlg = ");
|
||
|
sb.append(digestAlgorithm);
|
||
|
sb.append(", keyLength = ");
|
||
|
sb.append(keyLength);
|
||
|
logger.info(sb.toString());
|
||
|
checkConsistency(keyAgreementAlgorithm, cipherAlgorithm, digestAlgorithm, keyLength, algorithmParameterSpec);
|
||
|
try {
|
||
|
StringBuilder sb2 = new StringBuilder();
|
||
|
sb2.append(cipherAlgorithm);
|
||
|
sb2.append("/CBC/NoPadding");
|
||
|
Cipher cipher = Cipher.getInstance(sb2.toString());
|
||
|
try {
|
||
|
this.service.sendMSESetATMutualAuth(this.wrapper, str, 1, null);
|
||
|
byte[] doPACEStep1 = doPACEStep1(secretKey, cipher);
|
||
|
AlgorithmParameterSpec doPACEStep2 = doPACEStep2(mappingType, keyAgreementAlgorithm, algorithmParameterSpec, doPACEStep1);
|
||
|
KeyPair doPACEStep3GenerateKeyPair = doPACEStep3GenerateKeyPair(keyAgreementAlgorithm, doPACEStep2);
|
||
|
PublicKey doPACEStep3ExchangePublicKeys = doPACEStep3ExchangePublicKeys(doPACEStep3GenerateKeyPair.getPublic(), doPACEStep2);
|
||
|
byte[] doPACEStep3KeyAgreement = doPACEStep3KeyAgreement(keyAgreementAlgorithm, doPACEStep3GenerateKeyPair.getPrivate(), doPACEStep3ExchangePublicKeys);
|
||
|
try {
|
||
|
SecretKey deriveKey = Util.deriveKey(doPACEStep3KeyAgreement, cipherAlgorithm, keyLength, 1);
|
||
|
SecretKey deriveKey2 = Util.deriveKey(doPACEStep3KeyAgreement, cipherAlgorithm, keyLength, 2);
|
||
|
byte[] doPACEStep4 = doPACEStep4(str, mappingType, doPACEStep3GenerateKeyPair, doPACEStep3ExchangePublicKeys, deriveKey2);
|
||
|
try {
|
||
|
if (cipherAlgorithm.startsWith("DESede")) {
|
||
|
this.wrapper = new DESedeSecureMessagingWrapper(deriveKey, deriveKey2);
|
||
|
} else if (cipherAlgorithm.startsWith("AES")) {
|
||
|
SecureMessagingWrapper secureMessagingWrapper = this.wrapper;
|
||
|
this.wrapper = new AESSecureMessagingWrapper(deriveKey, deriveKey2, secureMessagingWrapper == null ? 0L : secureMessagingWrapper.getSendSequenceCounter());
|
||
|
}
|
||
|
if (PACEInfo.MappingType.CAM.equals(mappingType)) {
|
||
|
if (doPACEStep4 == null) {
|
||
|
logger.severe("Encrypted Chip Authentication data is null");
|
||
|
}
|
||
|
try {
|
||
|
Cipher cipher2 = Cipher.getInstance("AES/CBC/NoPadding");
|
||
|
cipher2.init(2, deriveKey, new IvParameterSpec(IV_FOR_PACE_CAM_DECRYPTION));
|
||
|
bArr2 = Util.unpad(cipher2.doFinal(doPACEStep4));
|
||
|
} catch (GeneralSecurityException e) {
|
||
|
e = e;
|
||
|
bArr2 = null;
|
||
|
}
|
||
|
try {
|
||
|
logger.info("DEBUG: Including Chip Authentication data in PACE result");
|
||
|
} catch (GeneralSecurityException e2) {
|
||
|
e = e2;
|
||
|
LOGGER.log(Level.SEVERE, "Could not decrypt Chip Authentication data", (Throwable) e);
|
||
|
bArr = bArr2;
|
||
|
return new PACEResult(mappingType, keyAgreementAlgorithm, cipherAlgorithm, digestAlgorithm, keyLength, algorithmParameterSpec, doPACEStep1, doPACEStep2, doPACEStep3GenerateKeyPair, doPACEStep3ExchangePublicKeys, doPACEStep3KeyAgreement, doPACEStep4, bArr, this.wrapper);
|
||
|
}
|
||
|
bArr = bArr2;
|
||
|
} else {
|
||
|
bArr = null;
|
||
|
}
|
||
|
return new PACEResult(mappingType, keyAgreementAlgorithm, cipherAlgorithm, digestAlgorithm, keyLength, algorithmParameterSpec, doPACEStep1, doPACEStep2, doPACEStep3GenerateKeyPair, doPACEStep3ExchangePublicKeys, doPACEStep3KeyAgreement, doPACEStep4, bArr, this.wrapper);
|
||
|
} catch (GeneralSecurityException e3) {
|
||
|
Logger logger2 = LOGGER;
|
||
|
StringBuilder sb3 = new StringBuilder("Exception: ");
|
||
|
sb3.append(e3.getMessage());
|
||
|
logger2.severe(sb3.toString());
|
||
|
StringBuilder sb4 = new StringBuilder("Security exception in secure messaging establishment: ");
|
||
|
sb4.append(e3.getMessage());
|
||
|
throw new IllegalStateException(sb4.toString());
|
||
|
}
|
||
|
} catch (GeneralSecurityException e4) {
|
||
|
LOGGER.log(Level.SEVERE, "Security exception during secure messaging key derivation", (Throwable) e4);
|
||
|
StringBuilder sb5 = new StringBuilder("Security exception during secure messaging key derivation: ");
|
||
|
sb5.append(e4.getMessage());
|
||
|
throw new PACEException(sb5.toString());
|
||
|
}
|
||
|
} catch (CardServiceException e5) {
|
||
|
throw new PACEException("PICC side error in static PACE key derivation step", e5.getSW());
|
||
|
}
|
||
|
} catch (GeneralSecurityException unused) {
|
||
|
throw new PACEException("PCD side error in static cipher construction during key derivation step");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public byte[] doPACEStep1(SecretKey secretKey, Cipher cipher) throws PACEException {
|
||
|
try {
|
||
|
byte[] unwrapDO = Util.unwrapDO(Byte.MIN_VALUE, this.service.sendGeneralAuthenticate(this.wrapper, new byte[0], false));
|
||
|
cipher.init(2, secretKey, new IvParameterSpec(new byte[cipher.getBlockSize()]));
|
||
|
return cipher.doFinal(unwrapDO);
|
||
|
} catch (GeneralSecurityException e) {
|
||
|
Logger logger = LOGGER;
|
||
|
StringBuilder sb = new StringBuilder("Exception: ");
|
||
|
sb.append(e.getMessage());
|
||
|
logger.severe(sb.toString());
|
||
|
StringBuilder sb2 = new StringBuilder("PCD side exception in tranceiving nonce step: ");
|
||
|
sb2.append(e.getMessage());
|
||
|
throw new PACEException(sb2.toString());
|
||
|
} catch (CardServiceException e2) {
|
||
|
throw new PACEException("PICC side exception in tranceiving nonce step", e2.getSW());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* JADX INFO: Access modifiers changed from: package-private */
|
||
|
/* renamed from: org.jmrtd.protocol.PACEProtocol$1, reason: invalid class name */
|
||
|
/* loaded from: classes6.dex */
|
||
|
public static /* synthetic */ class AnonymousClass1 {
|
||
|
static final int[] $SwitchMap$org$jmrtd$lds$PACEInfo$MappingType;
|
||
|
|
||
|
static {
|
||
|
int[] iArr = new int[PACEInfo.MappingType.values().length];
|
||
|
$SwitchMap$org$jmrtd$lds$PACEInfo$MappingType = iArr;
|
||
|
try {
|
||
|
iArr[PACEInfo.MappingType.CAM.ordinal()] = 1;
|
||
|
} catch (NoSuchFieldError unused) {
|
||
|
}
|
||
|
try {
|
||
|
$SwitchMap$org$jmrtd$lds$PACEInfo$MappingType[PACEInfo.MappingType.GM.ordinal()] = 2;
|
||
|
} catch (NoSuchFieldError unused2) {
|
||
|
}
|
||
|
try {
|
||
|
$SwitchMap$org$jmrtd$lds$PACEInfo$MappingType[PACEInfo.MappingType.IM.ordinal()] = 3;
|
||
|
} catch (NoSuchFieldError unused3) {
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public AlgorithmParameterSpec doPACEStep2(PACEInfo.MappingType mappingType, String str, AlgorithmParameterSpec algorithmParameterSpec, byte[] bArr) throws PACEException {
|
||
|
int i = AnonymousClass1.$SwitchMap$org$jmrtd$lds$PACEInfo$MappingType[mappingType.ordinal()];
|
||
|
if (i == 1 || i == 2) {
|
||
|
return doPACEStep2GM(str, algorithmParameterSpec, bArr);
|
||
|
}
|
||
|
if (i == 3) {
|
||
|
return doPACEStep2IM(str, algorithmParameterSpec, bArr);
|
||
|
}
|
||
|
throw new PACEException("Unsupported mapping type ".concat(String.valueOf(mappingType)));
|
||
|
}
|
||
|
|
||
|
public AlgorithmParameterSpec doPACEStep2GM(String str, AlgorithmParameterSpec algorithmParameterSpec, byte[] bArr) throws PACEException {
|
||
|
MyECDHKeyAgreement myECDHKeyAgreement;
|
||
|
try {
|
||
|
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(str, BC_PROVIDER);
|
||
|
keyPairGenerator.initialize(algorithmParameterSpec);
|
||
|
KeyPair generateKeyPair = keyPairGenerator.generateKeyPair();
|
||
|
PublicKey publicKey = generateKeyPair.getPublic();
|
||
|
PrivateKey privateKey = generateKeyPair.getPrivate();
|
||
|
KeyAgreement keyAgreement = KeyAgreement.getInstance(str);
|
||
|
keyAgreement.init(privateKey);
|
||
|
if ("ECDH".equals(str)) {
|
||
|
myECDHKeyAgreement = new MyECDHKeyAgreement(this);
|
||
|
myECDHKeyAgreement.init((ECPrivateKey) privateKey);
|
||
|
} else {
|
||
|
myECDHKeyAgreement = null;
|
||
|
}
|
||
|
PublicKey decodePublicKeyFromSmartCard = Util.decodePublicKeyFromSmartCard(Util.unwrapDO((byte) -126, this.service.sendGeneralAuthenticate(this.wrapper, Util.wrapDO(ISOFileInfo.DATA_BYTES2, Util.encodePublicKeyForSmartCard(publicKey)), false)), algorithmParameterSpec);
|
||
|
keyAgreement.doPhase(decodePublicKeyFromSmartCard, true);
|
||
|
byte[] generateSecret = keyAgreement.generateSecret();
|
||
|
Logger logger = LOGGER;
|
||
|
StringBuilder sb = new StringBuilder("DEBUG: mappingSharedSecretBytes = ");
|
||
|
sb.append(ghS.c(generateSecret));
|
||
|
logger.info(sb.toString());
|
||
|
if ("ECDH".equals(str) && myECDHKeyAgreement != null) {
|
||
|
ECPoint doPhase = myECDHKeyAgreement.doPhase((ECPublicKey) decodePublicKeyFromSmartCard);
|
||
|
logger.info("DEBUG: calling mapNonceGMWithECDH directly");
|
||
|
StringBuilder sb2 = new StringBuilder("DEBUG: Affine X = ");
|
||
|
sb2.append(doPhase.getAffineX());
|
||
|
logger.info(sb2.toString());
|
||
|
StringBuilder sb3 = new StringBuilder("DEBUG: Affine Y = ");
|
||
|
sb3.append(doPhase.getAffineY());
|
||
|
logger.info(sb3.toString());
|
||
|
return Util.mapNonceGMWithECDH(Util.os2i(bArr), doPhase, (ECParameterSpec) algorithmParameterSpec);
|
||
|
}
|
||
|
if ("DH".equals(str)) {
|
||
|
return Util.mapNonceGMWithDH(Util.os2i(bArr), Util.os2i(generateSecret), (DHParameterSpec) algorithmParameterSpec);
|
||
|
}
|
||
|
StringBuilder sb4 = new StringBuilder("Unsupported parameters for mapping nonce, expected ECParameterSpec or DHParameterSpec, found ");
|
||
|
sb4.append(algorithmParameterSpec.getClass().getCanonicalName());
|
||
|
throw new IllegalArgumentException(sb4.toString());
|
||
|
} catch (GeneralSecurityException e) {
|
||
|
StringBuilder sb5 = new StringBuilder("PCD side error in mapping nonce step: ");
|
||
|
sb5.append(e.getMessage());
|
||
|
throw new PACEException(sb5.toString());
|
||
|
} catch (CardServiceException e2) {
|
||
|
throw new PACEException("PICC side exception in mapping nonce step", e2.getSW());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public AlgorithmParameterSpec doPACEStep2IM(String str, AlgorithmParameterSpec algorithmParameterSpec, byte[] bArr) throws PACEException {
|
||
|
try {
|
||
|
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(str, BC_PROVIDER);
|
||
|
keyPairGenerator.initialize(algorithmParameterSpec);
|
||
|
KeyPair generateKeyPair = keyPairGenerator.generateKeyPair();
|
||
|
generateKeyPair.getPublic();
|
||
|
KeyAgreement.getInstance(str).init(generateKeyPair.getPrivate());
|
||
|
byte[] bArr2 = new byte[bArr.length];
|
||
|
this.random.nextBytes(bArr2);
|
||
|
pseudoRandomFunction(bArr, bArr2, null);
|
||
|
throw new PACEException("Integrated Mapping not yet implemented");
|
||
|
} catch (GeneralSecurityException e) {
|
||
|
StringBuilder sb = new StringBuilder("PCD side error in mapping nonce step: ");
|
||
|
sb.append(e.getMessage());
|
||
|
throw new PACEException(sb.toString());
|
||
|
} catch (CardServiceException e2) {
|
||
|
throw new PACEException("PICC side exception in mapping nonce step", e2.getSW());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public KeyPair doPACEStep3GenerateKeyPair(String str, AlgorithmParameterSpec algorithmParameterSpec) throws PACEException {
|
||
|
try {
|
||
|
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(str, BC_PROVIDER);
|
||
|
keyPairGenerator.initialize(algorithmParameterSpec);
|
||
|
return keyPairGenerator.generateKeyPair();
|
||
|
} catch (GeneralSecurityException unused) {
|
||
|
throw new PACEException("PCD side error during generation of PCD key pair");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public PublicKey doPACEStep3ExchangePublicKeys(PublicKey publicKey, AlgorithmParameterSpec algorithmParameterSpec) throws PACEException {
|
||
|
try {
|
||
|
PublicKey decodePublicKeyFromSmartCard = Util.decodePublicKeyFromSmartCard(Util.unwrapDO((byte) -124, this.service.sendGeneralAuthenticate(this.wrapper, Util.wrapDO(ISOFileInfo.FILE_IDENTIFIER, Util.encodePublicKeyForSmartCard(publicKey)), false)), algorithmParameterSpec);
|
||
|
if (publicKey.equals(decodePublicKeyFromSmartCard)) {
|
||
|
throw new PACEException("PCD's public key and PICC's public key are the same in key agreement step!");
|
||
|
}
|
||
|
return decodePublicKeyFromSmartCard;
|
||
|
} catch (IllegalStateException e) {
|
||
|
StringBuilder sb = new StringBuilder("PCD side exception in key agreement step: ");
|
||
|
sb.append(e.getMessage());
|
||
|
throw new PACEException(sb.toString());
|
||
|
} catch (GeneralSecurityException e2) {
|
||
|
StringBuilder sb2 = new StringBuilder("PCD side exception in key agreement step: ");
|
||
|
sb2.append(e2.getMessage());
|
||
|
throw new PACEException(sb2.toString());
|
||
|
} catch (CardServiceException e3) {
|
||
|
throw new PACEException("PICC side exception in key agreement step", e3.getSW());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public byte[] doPACEStep3KeyAgreement(String str, PrivateKey privateKey, PublicKey publicKey) throws PACEException {
|
||
|
try {
|
||
|
KeyAgreement keyAgreement = KeyAgreement.getInstance(str, BC_PROVIDER);
|
||
|
keyAgreement.init(privateKey);
|
||
|
keyAgreement.doPhase(updateParameterSpec(publicKey, privateKey), true);
|
||
|
return keyAgreement.generateSecret();
|
||
|
} catch (GeneralSecurityException e) {
|
||
|
LOGGER.log(Level.SEVERE, "PCD side error during key agreement", (Throwable) e);
|
||
|
throw new PACEException("PCD side error during key agreement");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public byte[] doPACEStep4(String str, PACEInfo.MappingType mappingType, KeyPair keyPair, PublicKey publicKey, SecretKey secretKey) throws PACEException {
|
||
|
try {
|
||
|
byte[] wrapDO = Util.wrapDO(ISOFileInfo.PROP_INFO, generateAuthenticationToken(str, secretKey, publicKey));
|
||
|
if (!Arrays.equals(generateAuthenticationToken(str, secretKey, keyPair.getPublic()), Util.unwrapDO((byte) -122, this.service.sendGeneralAuthenticate(this.wrapper, wrapDO, true)))) {
|
||
|
throw new GeneralSecurityException("PICC authentication token mismatch");
|
||
|
}
|
||
|
if (mappingType == PACEInfo.MappingType.CAM) {
|
||
|
return Util.unwrapDO(ISOFileInfo.LCS_BYTE, wrapDO);
|
||
|
}
|
||
|
return null;
|
||
|
} catch (GeneralSecurityException e) {
|
||
|
StringBuilder sb = new StringBuilder("PCD side exception in authentication token generation step: ");
|
||
|
sb.append(e.getMessage());
|
||
|
throw new PACEException(sb.toString());
|
||
|
} catch (CardServiceException e2) {
|
||
|
throw new PACEException("PICC side exception in authentication token generation step", e2.getSW());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static SecretKey deriveStaticPACEKey(KeySpec keySpec, String str) throws GeneralSecurityException {
|
||
|
return Util.deriveKey(computeKeySeedForPACE(keySpec), PACEInfo.toCipherAlgorithm(str), PACEInfo.toKeyLength(str), 3);
|
||
|
}
|
||
|
|
||
|
public static byte[] computeKeySeedForPACE(KeySpec keySpec) throws GeneralSecurityException {
|
||
|
if (keySpec instanceof BACKeySpec) {
|
||
|
BACKeySpec bACKeySpec = (BACKeySpec) keySpec;
|
||
|
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 computeKeySeedForPACE(fixDocumentNumber(documentNumber), dateOfBirth, dateOfExpiry);
|
||
|
}
|
||
|
if (keySpec instanceof CANKey) {
|
||
|
return computeKeySeedForPACE(((CANKey) keySpec).getCardAccessNumber());
|
||
|
}
|
||
|
throw new IllegalArgumentException("Unsupported key spec, was expecting BAC or CAN key specification");
|
||
|
}
|
||
|
|
||
|
public static PublicKey updateParameterSpec(PublicKey publicKey, PrivateKey privateKey) throws GeneralSecurityException {
|
||
|
if (!(publicKey instanceof ECPublicKey) || !(privateKey instanceof ECPrivateKey)) {
|
||
|
throw new NoSuchAlgorithmException("Unsupported key type");
|
||
|
}
|
||
|
return KeyFactory.getInstance("EC").generatePublic(new ECPublicKeySpec(((ECPublicKey) publicKey).getW(), ((ECPrivateKey) privateKey).getParams()));
|
||
|
}
|
||
|
|
||
|
private static byte[] computeKeySeedForPACE(String str, String str2, String str3) throws GeneralSecurityException {
|
||
|
return Util.computeKeySeed(str, str2, str3, McElieceCCA2KeyGenParameterSpec.SHA1, false);
|
||
|
}
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
public static byte[] computeKeySeedForPACE(String str) throws GeneralSecurityException {
|
||
|
return Util.computeKeySeed(str, McElieceCCA2KeyGenParameterSpec.SHA1, false);
|
||
|
}
|
||
|
|
||
|
public static byte[] generateAuthenticationToken(String str, SecretKey secretKey, PublicKey publicKey) throws GeneralSecurityException {
|
||
|
Mac mac = Mac.getInstance(inferMacAlgorithmFromCipherAlgorithm(PACEInfo.toCipherAlgorithm(str)), BC_PROVIDER);
|
||
|
byte[] encodePublicKeyDataObject = Util.encodePublicKeyDataObject(str, publicKey);
|
||
|
mac.init(secretKey);
|
||
|
byte[] bArr = new byte[8];
|
||
|
System.arraycopy(mac.doFinal(encodePublicKeyDataObject), 0, bArr, 0, 8);
|
||
|
return bArr;
|
||
|
}
|
||
|
|
||
|
private void checkConsistency(String str, String str2, String str3, int i, AlgorithmParameterSpec algorithmParameterSpec) {
|
||
|
if (str == null) {
|
||
|
throw new IllegalArgumentException("Unknown agreement algorithm");
|
||
|
}
|
||
|
if (!"ECDH".equalsIgnoreCase(str) && !"DH".equalsIgnoreCase(str)) {
|
||
|
StringBuilder sb = new StringBuilder("Unsupported agreement algorithm, expected ECDH or DH, found \"");
|
||
|
sb.append(str);
|
||
|
sb.append("\"");
|
||
|
throw new IllegalArgumentException(sb.toString());
|
||
|
}
|
||
|
if (str2 == null) {
|
||
|
throw new IllegalArgumentException("Unknown cipher algorithm");
|
||
|
}
|
||
|
if (!"DESede".equalsIgnoreCase(str2) && !"AES".equalsIgnoreCase(str2)) {
|
||
|
StringBuilder sb2 = new StringBuilder("Unsupported cipher algorithm, expected DESede or AES, found \"");
|
||
|
sb2.append(str2);
|
||
|
sb2.append("\"");
|
||
|
throw new IllegalArgumentException(sb2.toString());
|
||
|
}
|
||
|
if (!McElieceCCA2KeyGenParameterSpec.SHA1.equalsIgnoreCase(str3) && !"SHA1".equalsIgnoreCase(str3) && !McElieceCCA2KeyGenParameterSpec.SHA256.equalsIgnoreCase(str3) && !"SHA256".equalsIgnoreCase(str3)) {
|
||
|
StringBuilder sb3 = new StringBuilder("Unsupported cipher algorithm, expected DESede or AES, found \"");
|
||
|
sb3.append(str3);
|
||
|
sb3.append("\"");
|
||
|
throw new IllegalArgumentException(sb3.toString());
|
||
|
}
|
||
|
if (i != 128 && i != 192 && i != 256) {
|
||
|
throw new IllegalArgumentException("Unsupported key length, expected 128, 192, or 256, found ".concat(String.valueOf(i)));
|
||
|
}
|
||
|
if ("ECDH".equalsIgnoreCase(str) && !(algorithmParameterSpec instanceof ECParameterSpec)) {
|
||
|
StringBuilder sb4 = new StringBuilder("Expected ECParameterSpec for agreement algorithm \"");
|
||
|
sb4.append(str);
|
||
|
sb4.append("\", found ");
|
||
|
sb4.append(algorithmParameterSpec.getClass().getCanonicalName());
|
||
|
throw new IllegalArgumentException(sb4.toString());
|
||
|
}
|
||
|
if (!"DH".equalsIgnoreCase(str) || (algorithmParameterSpec instanceof DHParameterSpec)) {
|
||
|
return;
|
||
|
}
|
||
|
StringBuilder sb5 = new StringBuilder("Expected DHParameterSpec for agreement algorithm \"");
|
||
|
sb5.append(str);
|
||
|
sb5.append("\", found ");
|
||
|
sb5.append(algorithmParameterSpec.getClass().getCanonicalName());
|
||
|
throw new IllegalArgumentException(sb5.toString());
|
||
|
}
|
||
|
|
||
|
private static String inferMacAlgorithmFromCipherAlgorithm(String str) throws InvalidAlgorithmParameterException {
|
||
|
if (str == null) {
|
||
|
throw new IllegalArgumentException("Cannot infer MAC algorithm from cipher algorithm null");
|
||
|
}
|
||
|
if (str.startsWith("DESede")) {
|
||
|
return "ISO9797Alg3Mac";
|
||
|
}
|
||
|
if (str.startsWith("AES")) {
|
||
|
return "AESCMAC";
|
||
|
}
|
||
|
StringBuilder sb = new StringBuilder("Cannot infer MAC algorithm from cipher algorithm \"");
|
||
|
sb.append(str);
|
||
|
sb.append("\"");
|
||
|
throw new InvalidAlgorithmParameterException(sb.toString());
|
||
|
}
|
||
|
|
||
|
/* loaded from: classes6.dex */
|
||
|
public class MyECDHKeyAgreement {
|
||
|
private ECPrivateKey privateKey;
|
||
|
final PACEProtocol this$0;
|
||
|
|
||
|
public MyECDHKeyAgreement(PACEProtocol pACEProtocol) {
|
||
|
this.this$0 = pACEProtocol;
|
||
|
}
|
||
|
|
||
|
public ECPoint doPhase(ECPublicKey eCPublicKey) {
|
||
|
org.bouncycastle.math.ec.ECPoint normalize = Util.toBouncyECPublicKeyParameters(eCPublicKey).getQ().multiply(Util.toBouncyECPrivateKeyParameters(this.privateKey).getD()).normalize();
|
||
|
if (normalize.isInfinity()) {
|
||
|
throw new IllegalStateException("Infinity");
|
||
|
}
|
||
|
return Util.fromBouncyCastleECPoint(normalize);
|
||
|
}
|
||
|
|
||
|
public void init(ECPrivateKey eCPrivateKey) {
|
||
|
this.privateKey = eCPrivateKey;
|
||
|
}
|
||
|
}
|
||
|
}
|