/****************************************************************************
* Copyright (C) 2012 ecsec GmbH.
* All rights reserved.
* Contact: ecsec GmbH (info@ecsec.de)
*
* This file is part of the Open eCard App.
*
* GNU General Public License Usage
* This file may be used under the terms of the GNU General Public
* License version 3.0 as published by the Free Software Foundation
* and appearing in the file LICENSE.GPL included in the packaging of
* this file. Please review the following information to ensure the
* GNU General Public License version 3.0 requirements will be met:
* http://www.gnu.org/copyleft/gpl.html.
*
* Other Usage
* Alternatively, this file may be used in accordance with the terms
* and conditions contained in a signed written agreement between
* you and ecsec GmbH.
*
***************************************************************************/
package org.openecard.ifd.scio.reader;
import java.util.Arrays;
/**
*
* @author Tobias Wich <tobias.wich@ecsec.de>
*/
public class EstablishPACEResponse {
private byte[] statusBytes;
private short efCardAccessLength;
private byte[] efCardAccess;
// eID attributes
private byte currentCARLength;
private byte[] currentCAR;
private byte previousCARLength;
private byte[] previousCAR;
private short idiccLength;
private byte[] idicc;
public EstablishPACEResponse(byte[] response) {
int dataLen = response.length;
int idx = 4;
// read status
statusBytes = Arrays.copyOfRange(response, 0, 2);
// read card access (& 0xFF produces unsigned numbers)
efCardAccessLength = (short) ((response[2] & 0xFF) + ((response[3] & 0xFF) << 8));
if (efCardAccessLength > 0) {
efCardAccess = Arrays.copyOfRange(response, idx, idx + efCardAccessLength);
idx += efCardAccessLength;
} else {
efCardAccess = new byte[0];
}
// read car
if (dataLen > idx + 1) {
currentCARLength = (byte) (response[idx] & 0xFF);
idx++;
if (currentCARLength > 0) {
currentCAR = Arrays.copyOfRange(response, idx, idx + currentCARLength);
idx += currentCARLength;
}
}
// read car prev
if (dataLen > idx + 1) {
previousCARLength = (byte) (response[idx] & 0xFF);
idx++;
if (previousCARLength > 0) {
previousCAR = Arrays.copyOfRange(response, idx, idx + previousCARLength);
idx += previousCARLength;
}
}
// read id icc
if (dataLen > idx + 2) {
idiccLength = (short) ((response[idx] & 0xFF) + ((response[idx + 1] & 0xFF) << 8));
idx += 2;
if (idiccLength > 0) {
idicc = Arrays.copyOfRange(response, idx, idx + idiccLength);
idx += idiccLength;
}
}
}
public byte[] getStatus() {
return this.statusBytes;
}
public byte getRetryCounter() {
// TODO: verify that retry counter is extracted from 63CX statusword
if (statusBytes[0] == 0x63 && (statusBytes[1] & 0xF0) == 0xC0) {
return (byte) (statusBytes[1] & 0x0F);
} else {
// TODO: check if 3 is ok as default and if any other statuswords must be considered here
// default 3 seems to make sense
return 3;
}
}
public boolean hasEFCardAccess() {
return efCardAccessLength > 0;
}
public byte[] getEFCardAccess() {
return this.efCardAccess;
}
public boolean hasCurrentCAR() {
return currentCARLength > 0;
}
public byte[] getCurrentCAR() {
return this.currentCAR;
}
public boolean hasPreviousCAR() {
return previousCARLength > 0;
}
public byte[] getPreviousCAR() {
return previousCAR;
}
public boolean hasIDICC() {
return idiccLength > 0;
}
public byte[] getIDICC() {
return idicc;
}
}