/**************************************************************************** * 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; import oasis.names.tc.dss._1_0.core.schema.Result; import org.openecard.common.ECardConstants; import org.openecard.common.WSHelper; import org.openecard.common.apdu.common.CardCommandStatus; import org.openecard.common.util.ByteUtils; import org.openecard.common.util.IntegerUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author Tobias Wich <tobias.wich@ecsec.de> */ public class ExecutePACEResponse { private static final Logger logger = LoggerFactory.getLogger(ExecutePACEResponse.class); final int result; final short length; final byte[] data; public ExecutePACEResponse(byte[] response) { result = ByteUtils.toInteger(Arrays.copyOfRange(response, 0, 4), false); length = ByteUtils.toShort(Arrays.copyOfRange(response, 4, 6), false); data = Arrays.copyOfRange(response, 6, 6 + length); } public boolean isError() { return result != 0; } public int getResultCode() { return result; } public Result getResult() { switch (result) { case 0x00000000: return WSHelper.makeResultOK(); // errors in input case 0xD0000001: return WSHelper.makeResultUnknownError("Inconsistent lengths in input."); case 0xD0000002: return WSHelper.makeResultUnknownError("Unexpected data in input."); case 0xD0000003: return WSHelper.makeResultUnknownError("Unexpected combination of data in input."); // errors in protocol case 0xE0000001: return WSHelper.makeResultUnknownError("Syntax error in TLV response."); case 0xE0000002: return WSHelper.makeResultUnknownError("Unexpected or missing object in TLV response."); case 0xE0000003: return WSHelper.makeResultUnknownError("Unknown PIN-ID."); case 0xE0000006: return WSHelper.makeResultUnknownError("Wrong Authentication Token."); // Others case 0xF0100001: return WSHelper.makeResultUnknownError("Communication abort."); case 0xF0100002: return WSHelper.makeResultError(ECardConstants.Minor.IFD.NO_CARD, "No card."); case 0xF0200001: return WSHelper.makeResultError(ECardConstants.Minor.IFD.CANCELLATION_BY_USER, "Abort."); case 0xF0200002: return WSHelper.makeResultError(ECardConstants.Minor.IFD.TIMEOUT_ERROR, "Timeout."); // Response APDU of the card reports error default: { if ((result & 0xFFFC0000) == 0xF0000000) { byte[] sw = new byte[]{(byte) ((result >> 8) & 0xFF), (byte) (result & 0xFF)}; String msg = CardCommandStatus.getMessage(sw); int type = (result >> 16) & 0xFFFF; switch (type) { case 0xF000: return WSHelper.makeResultUnknownError("Select EF.CardAccess: " + msg); case 0xF001: return WSHelper.makeResultUnknownError("Read Binary EF.CardAccess: " + msg); case 0xF002: return WSHelper.makeResultUnknownError("MSE Set AT: " + msg); case 0xF003: return WSHelper.makeResultUnknownError("General Authenticat Step 1-4: " + msg); } } // unknown error String hexStringResult = ByteUtils.toHexString(IntegerUtils.toByteArray(result)); logger.warn("Unknown error in ExecutePACEResponse: {}", hexStringResult); return WSHelper.makeResultUnknownError(null); } } } public byte[] getData() { return data; } }