use of org.openecard.common.apdu.GeneralAuthenticate in project open-ecard by ecsec.
the class PACEImplementation method generalAuthenticateMutualAuthentication.
/**
* Step 5: Mutual authentication
*/
private void generalAuthenticateMutualAuthentication() throws Exception {
// Calculate shared key k
byte[] k = cryptoSuite.generateSharedSecret(keyPCD.getEncodedPrivateKey(), keyPICC.getEncodedPublicKey());
// Derive key MAC
keyMAC = kdf.deriveMAC(k);
// Derive key ENC
keyENC = kdf.deriveENC(k);
// Calculate token T_PCD
AuthenticationToken tokenPCD = new AuthenticationToken(psip.getPACEInfo());
tokenPCD.generateToken(keyMAC, keyPICC.getEncodedPublicKey());
CardCommandAPDU gaMutualAuth = new GeneralAuthenticate((byte) 0x85, tokenPCD.toByteArray());
// Calculate token T_PICC
AuthenticationToken tokenPICC = new AuthenticationToken(psip.getPACEInfo());
tokenPICC.generateToken(keyMAC, keyPCD.getEncodedPublicKey());
try {
response = gaMutualAuth.transmit(dispatcher, slotHandle);
if (tokenPICC.verifyToken(response.getData(), specifiedCHAT)) {
currentCAR = tokenPICC.getCurrentCAR();
previousCAR = tokenPICC.getPreviousCAR();
} else {
throw new GeneralSecurityException("Cannot verify authentication token.");
}
} catch (APDUException e) {
if (e.getResponseAPDU() == null) {
if (e.getCause() instanceof Exception) {
throw (Exception) e.getCause();
} else {
throw new ProtocolException(ECardConstants.Minor.IFD.UNKNOWN_ERROR, e.getMessage());
}
}
LOG.error(e.getMessage(), e);
int sw = e.getResponseAPDU().getSW();
if ((sw & (short) 0xFFF0) == (short) 0x63C0) {
retryCounter = (byte) (sw & (short) 0x000F);
if (retryCounter == (byte) 0x00) {
// The password is blocked.
LOG.warn("The password is blocked. The password MUST be unblocked.");
throw new ProtocolException(ECardConstants.Minor.IFD.PASSWORD_BLOCKED, "The password is blocked. The password MUST be unblocked.");
} else if (retryCounter == (byte) 0x01) {
// The password is suspended.
LOG.warn("The password is suspended. The password MUST be resumed.");
throw new ProtocolException(ECardConstants.Minor.IFD.PASSWORD_SUSPENDED, "The password is suspended. The password MUST be resumed.");
} else if (retryCounter == (byte) 0x02) {
// The password is wrong.
LOG.warn("The password is wrong.");
throw new ProtocolException(ECardConstants.Minor.IFD.PASSWORD_ERROR, "The password is wrong.");
}
} else {
throw new ProtocolException(ECardConstants.Minor.IFD.AUTHENTICATION_FAILED, "Authentication failed.");
}
} catch (Exception e) {
LOG.error(e.getMessage(), e);
throw new ProtocolException(ECardConstants.Minor.IFD.UNKNOWN_ERROR, e.getMessage());
}
}
use of org.openecard.common.apdu.GeneralAuthenticate in project open-ecard by ecsec.
the class ChipAuthentication method generalAuthenticate.
/**
* Performs a General Authenticate.
* Sends an General Authenticate APDU. (Protocol step 2)
* See BSI-TR-03110, version 2.10, part 3, B.11.2.
*
* @param key Ephemeral Public Key
* @return Response APDU
* @throws ProtocolException
*/
public byte[] generalAuthenticate(byte[] key) throws ProtocolException {
try {
if (key[0] != (byte) 0x04) {
key = ByteUtils.concatenate((byte) 0x04, key);
}
CardCommandAPDU generalAuthenticate = new GeneralAuthenticate((byte) 0x80, key);
CardResponseAPDU response = generalAuthenticate.transmit(dispatcher, slotHandle);
return response.getData();
} catch (APDUException e) {
throw new ProtocolException(e.getResult());
}
}
use of org.openecard.common.apdu.GeneralAuthenticate in project open-ecard by ecsec.
the class PACEImplementation method generalAuthenticateMapNonce.
/**
* Step 3: Mapping nonce
*/
private void generalAuthenticateMapNonce() throws Exception {
byte[] pkMapPCD = null;
PACEMapping mapping = cryptoSuite.getMapping();
if (mapping instanceof PACEGenericMapping) {
PACEGenericMapping gm = (PACEGenericMapping) mapping;
pkMapPCD = gm.getMappingKey().getEncodedPublicKey();
} else if (mapping instanceof PACEIntegratedMapping) {
throw new UnsupportedOperationException("Not implemented yet.");
}
CardCommandAPDU gaMapNonce = new GeneralAuthenticate((byte) 0x81, pkMapPCD);
gaMapNonce.setChaining();
try {
response = gaMapNonce.transmit(dispatcher, slotHandle);
} catch (APDUException e) {
LOG.error(e.getMessage(), e);
throw new ProtocolException(e.getResult());
}
if (mapping instanceof PACEGenericMapping) {
PACEGenericMapping gm = (PACEGenericMapping) mapping;
PACEKey keyMapPICC = new PACEKey(domainParameter);
keyMapPICC.decodePublicKey(response.getData());
byte[] pkMapPICC = keyMapPICC.getEncodedPublicKey();
if (ByteUtils.compare(pkMapPICC, pkMapPCD)) {
throw new GeneralSecurityException("PACE security violation: equal keys");
}
domainParameter = gm.map(pkMapPICC, s);
} else if (mapping instanceof PACEIntegratedMapping) {
throw new UnsupportedOperationException("Not implemented yet.");
}
// Continue with Step 4
generalAuthenticateKeyAgreement();
}
use of org.openecard.common.apdu.GeneralAuthenticate in project open-ecard by ecsec.
the class PACEImplementation method generalAuthenticateEncryptedNonce.
/**
* Step 2: Encrypted nonce
*/
private void generalAuthenticateEncryptedNonce() throws Exception {
CardCommandAPDU gaEncryptedNonce = new GeneralAuthenticate();
gaEncryptedNonce.setChaining();
// Derive key PI
byte[] keyPI = kdf.derivePI(password);
try {
response = gaEncryptedNonce.transmit(dispatcher, slotHandle);
s = cryptoSuite.decryptNonce(keyPI, response.getData());
// Continue with Step 3
generalAuthenticateMapNonce();
} catch (APDUException e) {
LOG.error(e.getMessage(), e);
throw new ProtocolException(e.getResult());
} catch (GeneralSecurityException e) {
LOG.error(e.getMessage(), e);
throw new ProtocolException(e.getMessage());
}
}
use of org.openecard.common.apdu.GeneralAuthenticate in project open-ecard by ecsec.
the class PACEImplementation method generalAuthenticateKeyAgreement.
/**
* Step 4: Key agreement
*
* @param mapPK_PICC
*/
private void generalAuthenticateKeyAgreement() throws Exception {
keyPCD = new PACEKey(domainParameter);
keyPCD.generateKeyPair();
byte[] keyPKPCD = keyPCD.getEncodedPublicKey();
CardCommandAPDU gaKeyAgreement = new GeneralAuthenticate((byte) 0x83, keyPKPCD);
gaKeyAgreement.setChaining();
try {
response = gaKeyAgreement.transmit(dispatcher, slotHandle);
keyPICC = new PACEKey(domainParameter);
byte[] keyPKPICC = keyPICC.decodePublicKey(response.getData());
if (!ByteUtils.compare(keyPKPCD, keyPKPICC)) {
// Continue with Step 5
generalAuthenticateMutualAuthentication();
} else {
throw new GeneralSecurityException("PACE security violation: equal keys");
}
} catch (APDUException e) {
LOG.error(e.getMessage(), e);
throw new ProtocolException(e.getResult());
} catch (GeneralSecurityException e) {
LOG.error(e.getMessage(), e);
throw new ProtocolException(e.getMessage());
}
}
Aggregations