Search in sources :

Example 31 with ResponseApdu

use of es.gob.jmulticard.apdu.ResponseApdu 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 32 with ResponseApdu

use of es.gob.jmulticard.apdu.ResponseApdu 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)32 ApduConnectionException (es.gob.jmulticard.apdu.connection.ApduConnectionException)23 CommandApdu (es.gob.jmulticard.apdu.CommandApdu)20 BadPinException (es.gob.jmulticard.card.BadPinException)13 IOException (java.io.IOException)12 PinException (es.gob.jmulticard.card.PinException)10 Iso7816FourCardException (es.gob.jmulticard.card.iso7816four.Iso7816FourCardException)10 AuthenticationModeLockedException (es.gob.jmulticard.card.AuthenticationModeLockedException)7 CryptoCardException (es.gob.jmulticard.card.CryptoCardException)7 CertificateException (java.security.cert.CertificateException)7 SecureChannelException (es.gob.jmulticard.apdu.connection.cwa14890.SecureChannelException)6 StatusWord (es.gob.jmulticard.apdu.StatusWord)5 LostChannelException (es.gob.jmulticard.apdu.connection.LostChannelException)4 TlvException (es.gob.jmulticard.asn1.TlvException)4 InvalidCardException (es.gob.jmulticard.card.InvalidCardException)4 FileNotFoundException (es.gob.jmulticard.card.iso7816four.FileNotFoundException)4 CardNotPresentException (es.gob.jmulticard.apdu.connection.CardNotPresentException)3 Cwa14890Connection (es.gob.jmulticard.apdu.connection.cwa14890.Cwa14890Connection)3 PsoSignHashApduCommand (es.gob.jmulticard.apdu.iso7816eight.PsoSignHashApduCommand)3 GetResponseApduCommand (es.gob.jmulticard.apdu.iso7816four.GetResponseApduCommand)3