Search in sources :

Example 1 with GetResponseApduCommand

use of es.gob.jmulticard.apdu.iso7816four.GetResponseApduCommand in project jmulticard by ctt-gob-es.

the class AndroidCCIDConnection method transmit.

/**
 * {@inheritDoc}
 */
@Override
public ResponseApdu transmit(final CommandApdu command) throws ApduConnectionException {
    if (!isOpen()) {
        // $NON-NLS-1$
        throw new UnavailableReaderException("No existe dispositivo USB asignado a la conexion");
    }
    try {
        if (!this.ccidReader.isCardActive()) {
            if (!this.ccidReader.isCardPresent()) {
                // No hay tarjeta en el lector
                throw new CardNotPresentException();
            }
            // Hay tarjeta, pero no esta activa
            // $NON-NLS-1$ //$NON-NLS-2$
            Log.i("es.gob.jmulticard", "La tarjeta del lector no esta activa, se reiniciara");
            this.reset();
        }
        if (DEBUG) {
            // $NON-NLS-1$ //$NON-NLS-2$
            Log.d("es.gob.jmulticard", "APDU Enviada:\n" + HexUtils.hexify(command.getBytes(), true));
        }
        final ResponseApdu response;
        try {
            response = new ResponseApdu(this.ccidReader.transmit(command.getBytes()));
            if (DEBUG) {
                // $NON-NLS-1$ //$NON-NLS-2$
                Log.d("es.gob.jmulticard", "APDU Recibida:\n" + HexUtils.hexify(response.getBytes(), true));
            }
            // Solicitamos el resultado de la operacion si es necesario
            if (response.getStatusWord().getMsb() == TAG_RESPONSE_PENDING) {
                // Si ya se ha devuelto parte de los datos, los concatenamos al resultado
                if (response.getData().length > 0) {
                    final byte[] data = response.getData();
                    final byte[] additionalData = transmit(new GetResponseApduCommand((byte) 0x00, response.getStatusWord().getLsb())).getBytes();
                    final byte[] fullResponse = new byte[data.length + additionalData.length];
                    System.arraycopy(data, 0, fullResponse, 0, data.length);
                    System.arraycopy(additionalData, 0, fullResponse, data.length, additionalData.length);
                    return new ResponseApdu(fullResponse);
                }
                return transmit(new GetResponseApduCommand((byte) 0x00, response.getStatusWord().getLsb()));
            } else // (de eso se encargara la clase de conexion con canal seguro)
            if (response.getStatusWord().getMsb() == TAG_RESPONSE_INVALID_LENGTH && command.getCla() == (byte) 0x00) {
                command.setLe(response.getStatusWord().getLsb());
                return transmit(command);
            }
            return response;
        } catch (final UsbDeviceException e) {
            // $NON-NLS-1$
            throw new ApduConnectionException("Error enviando APDU: " + e, e);
        }
    } catch (final NotAvailableUSBDeviceException e) {
        // $NON-NLS-1$
        throw new UnavailableReaderException("No se puede acceder al dispositivo USB: " + e, e);
    }
}
Also used : UnavailableReaderException(es.gob.jmulticard.apdu.connection.UnavailableReaderException) UsbDeviceException(es.inteco.labs.android.usb.device.exception.UsbDeviceException) ResponseApdu(es.gob.jmulticard.apdu.ResponseApdu) GetResponseApduCommand(es.gob.jmulticard.apdu.iso7816four.GetResponseApduCommand) CardNotPresentException(es.gob.jmulticard.apdu.connection.CardNotPresentException) ApduConnectionException(es.gob.jmulticard.apdu.connection.ApduConnectionException) NotAvailableUSBDeviceException(es.inteco.labs.android.usb.device.exception.NotAvailableUSBDeviceException)

Example 2 with GetResponseApduCommand

use of es.gob.jmulticard.apdu.iso7816four.GetResponseApduCommand in project jmulticard by ctt-gob-es.

the class SmartcardIoConnection method transmit.

/**
 * {@inheritDoc}
 */
@Override
public ResponseApdu transmit(final CommandApdu command) throws ApduConnectionException {
    if (this.canal == null) {
        throw new ApduConnectionException(// $NON-NLS-1$
        "No se puede transmitir sobre una conexion cerrada");
    }
    if (command == null) {
        throw new IllegalArgumentException(// $NON-NLS-1$
        "No se puede transmitir una APDU nula");
    }
    if (DEBUG) {
        // $NON-NLS-1$
        Logger.getLogger("es.gob.jmulticard").info(// $NON-NLS-1$
        "Enviada APDU:\n" + HexUtils.hexify(command.getBytes(), true));
    }
    try {
        byte[] sendApdu;
        if (command.getData() != null) {
            // Si la APDU es mayor que 0xFF la troceamos y la envolvemos
            if (command.getData().length > 0xFF) {
                int sentLength = 0;
                final int totalLength = command.getBytes().length;
                final int CONTENT_SIZE_ENVELOPE = 250;
                while (totalLength - sentLength > CONTENT_SIZE_ENVELOPE) {
                    final byte[] apduChunk = Arrays.copyOfRange(command.getBytes(), sentLength, sentLength + CONTENT_SIZE_ENVELOPE);
                    final CommandAPDU apdu = new CommandAPDU((byte) 0x90, (byte) 0xC2, (byte) 0x00, (byte) 0x00, apduChunk);
                    final ResponseApdu response = new ResponseApdu(this.canal.transmit(apdu).getBytes());
                    if (!response.isOk()) {
                        return response;
                    }
                    sentLength += CONTENT_SIZE_ENVELOPE;
                }
                final byte[] apduChunk = Arrays.copyOfRange(command.getBytes(), sentLength, totalLength);
                sendApdu = new CommandAPDU((byte) 0x90, (byte) 0xC2, (byte) 0x00, (byte) 0x00, apduChunk).getBytes();
            } else // Si es pequena, se envia directamente
            {
                sendApdu = command.getBytes();
            }
        } else {
            sendApdu = command.getBytes();
        }
        final ResponseApdu response = new ResponseApdu(this.canal.transmit(new CommandAPDU(sendApdu)).getBytes());
        // Solicitamos el resultado de la operacion si es necesario
        if (response.getStatusWord().getMsb() == TAG_RESPONSE_PENDING) {
            // Si ya se ha devuelto parte de los datos, los concatenamos al resultado
            if (response.getData().length > 0) {
                final byte[] data = response.getData();
                final byte[] additionalData = transmit(new GetResponseApduCommand((byte) 0x00, response.getStatusWord().getLsb())).getBytes();
                final byte[] fullResponse = new byte[data.length + additionalData.length];
                System.arraycopy(data, 0, fullResponse, 0, data.length);
                System.arraycopy(additionalData, 0, fullResponse, data.length, additionalData.length);
                return new ResponseApdu(fullResponse);
            }
            return transmit(new GetResponseApduCommand((byte) 0x00, response.getStatusWord().getLsb()));
        } else // (de eso se encargara la clase de conexion con canal seguro)
        if (response.getStatusWord().getMsb() == TAG_RESPONSE_INVALID_LENGTH && command.getCla() == (byte) 0x00) {
            command.setLe(response.getStatusWord().getLsb());
            return transmit(command);
        }
        if (DEBUG) {
            // $NON-NLS-1$
            Logger.getLogger("es.gob.jmulticard").info(// $NON-NLS-1$
            "Respuesta:\n" + HexUtils.hexify(response.getBytes(), true));
        }
        return response;
    } catch (final CardException e) {
        final Throwable t = e.getCause();
        if (t != null && SCARD_W_RESET_CARD.equals(t.getMessage())) {
            throw new LostChannelException(t.getMessage());
        }
        throw new ApduConnectionException(// $NON-NLS-1$
        "Error de comunicacion con la tarjeta tratando de transmitir la APDU " + HexUtils.hexify(command.getBytes(), true) + " al lector " + // $NON-NLS-1$
        Integer.toString(this.terminalNumber) + // $NON-NLS-1$
        " en modo EXCLUSIVE=" + Boolean.toString(this.exclusive) + " con el protocolo " + // $NON-NLS-1$
        this.protocol.toString(), // $NON-NLS-1$
        e);
    } catch (final Exception e) {
        e.printStackTrace();
        throw new ApduConnectionException(// $NON-NLS-1$
        "Error tratando de transmitir la APDU " + HexUtils.hexify(command.getBytes(), true) + " al lector " + // $NON-NLS-1$
        Integer.toString(this.terminalNumber) + // $NON-NLS-1$
        " en modo EXCLUSIVE=" + Boolean.toString(this.exclusive) + " con el protocolo " + // $NON-NLS-1$
        this.protocol.toString(), // $NON-NLS-1$
        e);
    }
}
Also used : LostChannelException(es.gob.jmulticard.apdu.connection.LostChannelException) ResponseApdu(es.gob.jmulticard.apdu.ResponseApdu) GetResponseApduCommand(es.gob.jmulticard.apdu.iso7816four.GetResponseApduCommand) CardException(javax.smartcardio.CardException) CommandAPDU(javax.smartcardio.CommandAPDU) ApduConnectionException(es.gob.jmulticard.apdu.connection.ApduConnectionException) CardNotPresentException(es.gob.jmulticard.apdu.connection.CardNotPresentException) ApduConnectionException(es.gob.jmulticard.apdu.connection.ApduConnectionException) CardException(javax.smartcardio.CardException) ApduConnectionOpenedInExclusiveModeException(es.gob.jmulticard.apdu.connection.ApduConnectionOpenedInExclusiveModeException) NoReadersFoundException(es.gob.jmulticard.apdu.connection.NoReadersFoundException) LostChannelException(es.gob.jmulticard.apdu.connection.LostChannelException)

Example 3 with GetResponseApduCommand

use of es.gob.jmulticard.apdu.iso7816four.GetResponseApduCommand in project jmulticard by ctt-gob-es.

the class AndroidNfcConnection method transmit.

@Override
public ResponseApdu transmit(final CommandApdu command) throws ApduConnectionException {
    if (this.mIsoDep == null) {
        throw new ApduConnectionException(// $NON-NLS-1$
        "No se puede transmitir sobre una conexion NFC cerrada");
    }
    if (command == null) {
        throw new IllegalArgumentException(// $NON-NLS-1$
        "No se puede transmitir una APDU nula");
    }
    if (!this.mIsoDep.isConnected()) {
        try {
            this.mIsoDep.connect();
        } catch (final IOException e) {
            throw new ApduConnectionException(// $NON-NLS-1$
            "Se ha producido un problema al intentar establecer la conexion por NFC: " + e, // $NON-NLS-1$
            e);
        }
    }
    final byte[] commandBytes;
    if (command instanceof VerifyApduCommand) {
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        final byte[] bcomm = command.getBytes();
        final byte[] bdata = command.getData();
        baos.write(bcomm, 0, bcomm.length - 2);
        try {
            baos.write(new byte[] { (byte) bdata.length });
            baos.write(bdata);
        } catch (final IOException e) {
            throw new ApduConnectionException(// $NON-NLS-1$
            "Error preparando la APDU para su envio", e);
        }
        commandBytes = baos.toByteArray();
    } else {
        commandBytes = command.getBytes();
    }
    // Liberamos la conexion para transmitir
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
        NFCWatchdogRefresher.stopHoldingConnection();
    }
    final byte[] bResp;
    try {
        bResp = this.mIsoDep.transceive(commandBytes);
    } catch (final IOException e) {
        // Evitamos que salga el PIN en la traza de excepcion
        throw new ApduConnectionException(// $NON-NLS-1$
        "Error tratando de transmitir la APDU" + (// $NON-NLS-1$
        (command instanceof VerifyApduCommand) ? // $NON-NLS-1$
        " de verificacion de PIN" : (" " + HexUtils.hexify(command.getBytes(), true))) + // $NON-NLS-1$
        " via NFC", e);
    } finally {
        // Retenemos la conexion hasta nuestro siguiente envio
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
            NFCWatchdogRefresher.holdConnection(this.mIsoDep);
        }
    }
    if (bResp.length < 2) {
        throw new ApduConnectionException(// $NON-NLS-1$
        "No se ha recibido respuesta al envio del comando");
    }
    final ResponseApdu response = new ResponseApdu(bResp);
    if (response.getStatusWord().getMsb() == 97) {
        if (response.getData().length > 0) {
            final byte[] data = response.getData();
            final byte[] additionalData = this.transmit(new GetResponseApduCommand((byte) 0, response.getStatusWord().getLsb())).getBytes();
            final byte[] fullResponse = new byte[data.length + additionalData.length];
            System.arraycopy(data, 0, fullResponse, 0, data.length);
            System.arraycopy(additionalData, 0, fullResponse, data.length, additionalData.length);
            return new ResponseApdu(fullResponse);
        }
        return this.transmit(new GetResponseApduCommand((byte) 0, response.getStatusWord().getLsb()));
    }
    if (response.getStatusWord().getMsb() == 108 && command.getCla() == 0) {
        command.setLe(response.getStatusWord().getLsb());
        return this.transmit(command);
    }
    return response;
}
Also used : ResponseApdu(es.gob.jmulticard.apdu.ResponseApdu) GetResponseApduCommand(es.gob.jmulticard.apdu.iso7816four.GetResponseApduCommand) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ApduConnectionException(es.gob.jmulticard.apdu.connection.ApduConnectionException) VerifyApduCommand(es.gob.jmulticard.apdu.dnie.VerifyApduCommand)

Aggregations

ResponseApdu (es.gob.jmulticard.apdu.ResponseApdu)3 ApduConnectionException (es.gob.jmulticard.apdu.connection.ApduConnectionException)3 GetResponseApduCommand (es.gob.jmulticard.apdu.iso7816four.GetResponseApduCommand)3 CardNotPresentException (es.gob.jmulticard.apdu.connection.CardNotPresentException)2 ApduConnectionOpenedInExclusiveModeException (es.gob.jmulticard.apdu.connection.ApduConnectionOpenedInExclusiveModeException)1 LostChannelException (es.gob.jmulticard.apdu.connection.LostChannelException)1 NoReadersFoundException (es.gob.jmulticard.apdu.connection.NoReadersFoundException)1 UnavailableReaderException (es.gob.jmulticard.apdu.connection.UnavailableReaderException)1 VerifyApduCommand (es.gob.jmulticard.apdu.dnie.VerifyApduCommand)1 NotAvailableUSBDeviceException (es.inteco.labs.android.usb.device.exception.NotAvailableUSBDeviceException)1 UsbDeviceException (es.inteco.labs.android.usb.device.exception.UsbDeviceException)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 IOException (java.io.IOException)1 CardException (javax.smartcardio.CardException)1 CommandAPDU (javax.smartcardio.CommandAPDU)1