Search in sources :

Example 11 with CardResponseAPDU

use of org.openecard.common.apdu.common.CardResponseAPDU in project open-ecard by ecsec.

the class CardUtils method readFile.

/**
 * Selects and reads a file.
 *
 * @param dispatcher Dispatcher
 * @param slotHandle Slot handle
 * @param fileID File ID
 * @return File content
 * @throws APDUException
 */
@Deprecated
public static byte[] readFile(Dispatcher dispatcher, byte[] slotHandle, byte[] fileID) throws APDUException {
    CardResponseAPDU selectResponse = selectFileWithOptions(dispatcher, slotHandle, fileID, null, FCP_RESPONSE_DATA);
    FCP fcp = null;
    try {
        fcp = new FCP(selectResponse.getData());
    } catch (TLVException e) {
        LOG.warn("Couldn't get File Control Parameters from Select response.", e);
    }
    return readFile(fcp, dispatcher, slotHandle);
}
Also used : FCP(org.openecard.common.tlv.iso7816.FCP) CardResponseAPDU(org.openecard.common.apdu.common.CardResponseAPDU) TLVException(org.openecard.common.tlv.TLVException)

Example 12 with CardResponseAPDU

use of org.openecard.common.apdu.common.CardResponseAPDU in project open-ecard by ecsec.

the class CardUtils method selectFileWithOptions.

/**
 * Select a file with different options.
 *
 * @param dispatcher The Dispatcher for dispatching of the card commands.
 * @param slotHandle The SlotHandle which identifies the card terminal.
 * @param fileIdOrPath File identifier or path to the file to select.
 * @param responses List of byte arrays with the trailers which should not thrown as errors.
 * @param resultType Int value which indicates whether the select should be performed with a request of the FCP, FCI,
 * FMD or without any data. There are four public variables available in this class to use.
 * @return A CardResponseAPDU object with the requested response data.
 * @throws APDUException Thrown if the selection of a file failed.
 */
public static CardResponseAPDU selectFileWithOptions(Dispatcher dispatcher, byte[] slotHandle, byte[] fileIdOrPath, List<byte[]> responses, int resultType) throws APDUException {
    Select selectFile;
    CardResponseAPDU result = null;
    // respect the possibility that fileID could be a path
    int i = 0;
    while (i < fileIdOrPath.length) {
        if (fileIdOrPath[i] == (byte) 0x3F && fileIdOrPath[i + 1] == (byte) 0x00 && i == 0 && i + 1 == 1) {
            selectFile = new MasterFile();
            i = i + 2;
        } else if (i == fileIdOrPath.length - 2) {
            selectFile = new Select.ChildFile(new byte[] { fileIdOrPath[i], fileIdOrPath[i + 1] });
            switch(resultType) {
                case 0:
                    // do nothing except of break 0x0C is the initialization value of P2
                    break;
                case 1:
                    selectFile.setFCP();
                    break;
                case 2:
                    selectFile.setFCI();
                    break;
                case 3:
                    selectFile.setFMD();
                    break;
                default:
                    throw new APDUException("There is no value assoziated with the returnType value " + resultType);
            }
            i = i + 2;
        } else {
            selectFile = new Select.ChildDirectory(new byte[] { fileIdOrPath[i], fileIdOrPath[i + 1] });
            i = i + 2;
        }
        if (responses == null) {
            // not all cards, e.g. Estonian id card, support P1 = 00 and DataFile filled with MF Fid so work around this
            if (i == 2 && fileIdOrPath[0] == (byte) 0x3F && fileIdOrPath[1] == (byte) 0x00) {
                responses = new ArrayList<>();
                responses.add(new byte[] { (byte) 0x90, (byte) 0x00 });
                responses.add(new byte[] { (byte) 0x67, (byte) 0x00 });
                responses.add(new byte[] { (byte) 0x6A, (byte) 0x86 });
            }
            result = selectFile.transmit(dispatcher, slotHandle, responses);
            if (!Arrays.equals(result.getTrailer(), new byte[] { (byte) 0x90, (byte) 0x00 }) && i == 2 && fileIdOrPath[0] == (byte) 0x3F && fileIdOrPath[1] == (byte) 0x00) {
                selectFile = new Select((byte) 0x00, (byte) 0x0c);
                result = selectFile.transmit(dispatcher, slotHandle, responses);
                // so lets try selection by path
                if (!Arrays.equals(result.getTrailer(), new byte[] { (byte) 0x90, (byte) 0x00 }) && fileIdOrPath.length > 2) {
                    selectFile = new Select.AbsolutePath(fileIdOrPath);
                    result = selectFile.transmit(dispatcher, slotHandle);
                    if (Arrays.equals(result.getTrailer(), TrailerConstants.Success.OK())) {
                        return result;
                    }
                }
            }
        } else {
            result = selectFile.transmit(dispatcher, slotHandle, responses);
        }
    }
    return result;
}
Also used : APDUException(org.openecard.common.apdu.exception.APDUException) Select(org.openecard.common.apdu.Select) CardResponseAPDU(org.openecard.common.apdu.common.CardResponseAPDU) MasterFile(org.openecard.common.apdu.Select.MasterFile)

Example 13 with CardResponseAPDU

use of org.openecard.common.apdu.common.CardResponseAPDU in project open-ecard by ecsec.

the class CardUtils method writeFile.

public static void writeFile(Dispatcher dispatcher, byte[] slotHandle, byte[] fileID, byte[] data) throws APDUException {
    CardResponseAPDU selectResponse = selectFile(dispatcher, slotHandle, fileID);
    FCP fcp = null;
    try {
        fcp = new FCP(selectResponse.getData());
    } catch (TLVException e) {
        LOG.warn("Couldn't get File Control Parameters from Select response.", e);
    }
    writeFile(fcp, dispatcher, slotHandle, data);
}
Also used : FCP(org.openecard.common.tlv.iso7816.FCP) CardResponseAPDU(org.openecard.common.apdu.common.CardResponseAPDU) TLVException(org.openecard.common.tlv.TLVException)

Example 14 with CardResponseAPDU

use of org.openecard.common.apdu.common.CardResponseAPDU in project open-ecard by ecsec.

the class SignStep method performSignature.

/**
 * This method performs the signature creation according to BSI TR-03112 part 7.
 *
 * @param cryptoMarker The {@link CryptoMarkerType} containing the SignatureCreationInfo for creating the signature.
 * @param keyReference A byte array containing the reference of the key to use.
 * @param algorithmIdentifier A byte array containing the identifier of the signing algorithm.
 * @param message The message to sign.
 * @param slotHandle The slotHandle identifying the card.
 * @param hashRef The variable contains the reference for the hash algorithm which have to be used.
 * @param hashInfo A HashGenerationInfo object which indicates how the hash computation is to perform.
 * @return A {@link SignResponse} object containing the signature of the <b>message</b>.
 * @throws TLVException Thrown if the TLV creation for the key identifier or algorithm identifier failed.
 * @throws IncorrectParameterException Thrown if the SignatureGenerationInfo does not contain PSO_CDS or INT_AUTH
 * after an MSE_KEY command.
 * @throws APDUException Thrown if one of the command to create the signature failed.
 * @throws org.openecard.common.WSHelper.WSException Thrown if the checkResults method of WSHelper failed.
 */
private SignResponse performSignature(CryptoMarkerType cryptoMarker, byte[] keyReference, byte[] algorithmIdentifier, byte[] message, byte[] slotHandle, byte[] hashRef, HashGenerationInfoType hashInfo) throws TLVException, IncorrectParameterException, APDUException, WSHelper.WSException {
    SignResponse response = WSHelper.makeResponse(SignResponse.class, WSHelper.makeResultOK());
    TLV tagAlgorithmIdentifier = new TLV();
    tagAlgorithmIdentifier.setTagNumWithClass(CARD_ALG_REF);
    tagAlgorithmIdentifier.setValue(algorithmIdentifier);
    TLV tagKeyReference = new TLV();
    tagKeyReference.setTagNumWithClass(KEY_REFERENCE_PRIVATE_KEY);
    tagKeyReference.setValue(keyReference);
    CardCommandAPDU cmdAPDU = null;
    CardResponseAPDU responseAPDU = null;
    String[] signatureGenerationInfo = cryptoMarker.getSignatureGenerationInfo();
    for (String command : signatureGenerationInfo) {
        HashSet<String> signGenInfo = new HashSet<>(java.util.Arrays.asList(signatureGenerationInfo));
        if (command.equals("MSE_KEY")) {
            byte[] mseData = tagKeyReference.toBER();
            if (signGenInfo.contains("PSO_CDS")) {
                cmdAPDU = new ManageSecurityEnvironment(SET_COMPUTATION, ManageSecurityEnvironment.DST, mseData);
            } else if (signGenInfo.contains("INT_AUTH") && !signGenInfo.contains("PSO_CDS")) {
                cmdAPDU = new ManageSecurityEnvironment(SET_COMPUTATION, ManageSecurityEnvironment.AT, mseData);
            } else {
                String msg = "The command 'MSE_KEY' followed by 'INT_AUTH' and 'PSO_CDS' is currently not supported.";
                LOG.error(msg);
                throw new IncorrectParameterException(msg);
            }
        } else if (command.equals("PSO_CDS")) {
            cmdAPDU = new PSOComputeDigitalSignature(message, BLOCKSIZE);
        } else if (command.equals("INT_AUTH")) {
            cmdAPDU = new InternalAuthenticate(message, BLOCKSIZE);
        } else if (command.equals("MSE_RESTORE")) {
            cmdAPDU = new ManageSecurityEnvironment.Restore(ManageSecurityEnvironment.DST);
        } else if (command.equals("MSE_HASH")) {
            cmdAPDU = new ManageSecurityEnvironment.Set(SET_COMPUTATION, ManageSecurityEnvironment.HT);
            TLV mseDataTLV = new TLV();
            mseDataTLV.setTagNumWithClass((byte) 0x80);
            mseDataTLV.setValue(hashRef);
            cmdAPDU.setData(mseDataTLV.toBER());
        } else if (command.equals("PSO_HASH")) {
            if (hashInfo == HashGenerationInfoType.LAST_ROUND_ON_CARD || hashInfo == HashGenerationInfoType.NOT_ON_CARD) {
                cmdAPDU = new PSOHash(PSOHash.P2_SET_HASH_OR_PART, message);
            } else {
                cmdAPDU = new PSOHash(PSOHash.P2_HASH_MESSAGE, message);
            }
        } else if (command.equals("MSE_DS")) {
            byte[] mseData = tagAlgorithmIdentifier.toBER();
            cmdAPDU = new ManageSecurityEnvironment(SET_COMPUTATION, ManageSecurityEnvironment.DST, mseData);
        } else if (command.equals("MSE_KEY_DS")) {
            byte[] mseData = ByteUtils.concatenate(tagKeyReference.toBER(), tagAlgorithmIdentifier.toBER());
            cmdAPDU = new ManageSecurityEnvironment(SET_COMPUTATION, ManageSecurityEnvironment.DST, mseData);
        } else if (command.equals("MSE_INT_AUTH")) {
            byte[] mseData = tagKeyReference.toBER();
            cmdAPDU = new ManageSecurityEnvironment(SET_COMPUTATION, ManageSecurityEnvironment.AT, mseData);
        } else if (command.equals("MSE_KEY_INT_AUTH")) {
            byte[] mseData = ByteUtils.concatenate(tagKeyReference.toBER(), tagAlgorithmIdentifier.toBER());
            cmdAPDU = new ManageSecurityEnvironment(SET_COMPUTATION, ManageSecurityEnvironment.AT, mseData);
        } else {
            String msg = "The signature generation command '" + command + "' is unknown.";
            throw new IncorrectParameterException(msg);
        }
        responseAPDU = cmdAPDU.transmit(dispatcher, slotHandle, Collections.<byte[]>emptyList());
    }
    byte[] signedMessage = responseAPDU.getData();
    // check if further response data is available
    while (responseAPDU.getTrailer()[0] == (byte) 0x61) {
        GetResponse getResponseData = new GetResponse();
        responseAPDU = getResponseData.transmit(dispatcher, slotHandle, Collections.<byte[]>emptyList());
        signedMessage = Arrays.concatenate(signedMessage, responseAPDU.getData());
    }
    if (!Arrays.areEqual(responseAPDU.getTrailer(), new byte[] { (byte) 0x90, (byte) 0x00 })) {
        String minor = SALErrorUtils.getMinor(responseAPDU.getTrailer());
        response.setResult(WSHelper.makeResultError(minor, responseAPDU.getStatusMessage()));
        return response;
    }
    response.setSignature(signedMessage);
    return response;
}
Also used : CardCommandAPDU(org.openecard.common.apdu.common.CardCommandAPDU) PSOHash(org.openecard.sal.protocol.genericcryptography.apdu.PSOHash) GetResponse(org.openecard.common.apdu.GetResponse) PSOComputeDigitalSignature(org.openecard.sal.protocol.genericcryptography.apdu.PSOComputeDigitalSignature) SignResponse(iso.std.iso_iec._24727.tech.schema.SignResponse) IncorrectParameterException(org.openecard.common.sal.exception.IncorrectParameterException) InternalAuthenticate(org.openecard.common.apdu.InternalAuthenticate) CardResponseAPDU(org.openecard.common.apdu.common.CardResponseAPDU) ManageSecurityEnvironment(org.openecard.common.apdu.ManageSecurityEnvironment) TLV(org.openecard.common.tlv.TLV) HashSet(java.util.HashSet)

Example 15 with CardResponseAPDU

use of org.openecard.common.apdu.common.CardResponseAPDU in project open-ecard by ecsec.

the class SignStep method performLegacySignature.

/**
 * The method performs the SignatureCreation if no standard commands are possible.
 * This method creates a signature with APDUs which are not covered by the methods defined in TR-03112 part 7.
 *
 * @param cryptoMarker A {@link CryptoMarkerType} object containing the information about the creation of a signature
 *   in a legacy way.
 * @param slotHandle A slotHandle identifying the current card.
 * @param templateCTX A Map containing the context data for the evaluation of the template variables. This object
 *   contains per default the message to sign and the {@link TLVFunction}.
 * @return A {@link SignResponse} object containing the signature of the <b>message</b>.
 * @throws APDUTemplateException Thrown if the evaluation of the {@link CardCommandTemplate} failed.
 * @throws APDUException Thrown if one of the commands to execute failed.
 * @throws WSHelper.WSException Thrown if the checkResult method of WSHelper failed.
 */
private SignResponse performLegacySignature(CryptoMarkerType cryptoMarker, ConnectionHandleType connectionHandle, BaseTemplateContext templateCTX) throws APDUTemplateException, APDUException, WSHelper.WSException {
    SignResponse response = WSHelper.makeResponse(SignResponse.class, WSHelper.makeResultOK());
    List<Object> legacyCommands = cryptoMarker.getLegacySignatureGenerationInfo();
    CardCommandAPDU cmdAPDU;
    CardResponseAPDU responseAPDU = null;
    byte[] slotHandle = connectionHandle.getSlotHandle();
    byte[] signedMessage;
    for (Object next : legacyCommands) {
        if (next instanceof CardCallTemplateType) {
            CardCallTemplateType cctt = (CardCallTemplateType) next;
            CardCommandTemplate template = new CardCommandTemplate(cctt);
            cmdAPDU = template.evaluate(templateCTX);
            responseAPDU = cmdAPDU.transmit(dispatcher, slotHandle, Collections.<byte[]>emptyList());
        } else if (next instanceof APICommand) {
            sendAPICommand(connectionHandle, (APICommand) next);
        }
    }
    signedMessage = responseAPDU.getData();
    // check if further response data is available
    while (responseAPDU.getTrailer()[0] == (byte) 0x61) {
        CardCommandAPDU getResponseData = new CardCommandAPDU((byte) 0x00, (byte) 0xC0, (byte) 0x00, (byte) 0x00, responseAPDU.getTrailer()[1]);
        responseAPDU = getResponseData.transmit(dispatcher, slotHandle, Collections.<byte[]>emptyList());
        signedMessage = Arrays.concatenate(signedMessage, responseAPDU.getData());
    }
    if (!Arrays.areEqual(responseAPDU.getTrailer(), new byte[] { (byte) 0x90, (byte) 0x00 })) {
        String minor = SALErrorUtils.getMinor(responseAPDU.getTrailer());
        response.setResult(WSHelper.makeResultError(minor, responseAPDU.getStatusMessage()));
        return response;
    }
    // fix output format
    String outForm = cryptoMarker.getLegacyOutputFormat();
    if (outForm != null) {
        switch(outForm) {
            case "rawRS":
                signedMessage = encodeRawRS(signedMessage);
                break;
            default:
                LOG.warn("Unsupport outputFormat={} specified in LegacySignatureGenerationInfo.", outForm);
        }
    }
    response.setSignature(signedMessage);
    return response;
}
Also used : CardCommandAPDU(org.openecard.common.apdu.common.CardCommandAPDU) CardCallTemplateType(iso.std.iso_iec._24727.tech.schema.CardCallTemplateType) SignResponse(iso.std.iso_iec._24727.tech.schema.SignResponse) CardResponseAPDU(org.openecard.common.apdu.common.CardResponseAPDU) CardCommandTemplate(org.openecard.common.apdu.common.CardCommandTemplate) APICommand(iso.std.iso_iec._24727.tech.schema.LegacySignatureGenerationType.APICommand)

Aggregations

CardResponseAPDU (org.openecard.common.apdu.common.CardResponseAPDU)24 CardCommandAPDU (org.openecard.common.apdu.common.CardCommandAPDU)9 ConnectionHandleType (iso.std.iso_iec._24727.tech.schema.ConnectionHandleType)7 CardStateEntry (org.openecard.common.sal.state.CardStateEntry)7 ECardException (org.openecard.common.ECardException)6 APDUException (org.openecard.common.apdu.exception.APDUException)6 Select (org.openecard.common.apdu.Select)5 TLVException (org.openecard.common.tlv.TLVException)4 FCP (org.openecard.common.tlv.iso7816.FCP)4 InputAPDUInfoType (iso.std.iso_iec._24727.tech.schema.InputAPDUInfoType)3 Transmit (iso.std.iso_iec._24727.tech.schema.Transmit)3 TransmitResponse (iso.std.iso_iec._24727.tech.schema.TransmitResponse)3 BigInteger (java.math.BigInteger)3 ArrayList (java.util.ArrayList)3 CardApplicationPathType (iso.std.iso_iec._24727.tech.schema.CardApplicationPathType)2 CardApplicationSelect (iso.std.iso_iec._24727.tech.schema.CardApplicationSelect)2 DIDAuthenticateResponse (iso.std.iso_iec._24727.tech.schema.DIDAuthenticateResponse)2 DIDStructureType (iso.std.iso_iec._24727.tech.schema.DIDStructureType)2 DataSetInfoType (iso.std.iso_iec._24727.tech.schema.DataSetInfoType)2 DataSetSelect (iso.std.iso_iec._24727.tech.schema.DataSetSelect)2