Beispiel #1
0
/*!
 * \brief Function performs data transmissions T=0.<br>
 * <br>
 * \param [in] pSmartcardExtension A pointer to the smart card extension,
		SMARTCARD_EXTENSION, of the device.
 *
 * \retval STATUS_SUCCESS the routine successfully end.
 */
static NTSTATUS transmitT0(IN PSMARTCARD_EXTENSION pSmartcardExtension)
{
	dbg_log("transmitT0 start");
	NTSTATUS status = STATUS_SUCCESS;

	status = SmartcardT0Request(pSmartcardExtension);
	if (status != STATUS_SUCCESS) {
		dbg_log("SmartcardT0Request failed! - status: 0x%08X", status);
		return status;
	}
	dbg_log("transmitT0 SEND: ");
	dbg_ba2s(
	    (char const *const)pSmartcardExtension->SmartcardRequest.Buffer,
	    pSmartcardExtension->SmartcardRequest.BufferLength
	);

	// send command to JCOP simulator.
	PREADER_EXTENSION pReaderExtension = pSmartcardExtension->ReaderExtension;

	// send "APDU" meessage.
	unsigned char mty = 0x01;	// MTY 0x01(APDU)
	unsigned char nad = 0x00;	// NAD

	status = sendMessage(
	             pReaderExtension,
	             mty,
	             nad,
	             (char *)pSmartcardExtension->SmartcardRequest.Buffer,
	             (unsigned short)pSmartcardExtension->SmartcardRequest.BufferLength,
	             (char *)pSmartcardExtension->SmartcardReply.Buffer,
	             (unsigned short)pSmartcardExtension->SmartcardReply.BufferSize,
	             (unsigned short *) & pSmartcardExtension->SmartcardReply.BufferLength,
	             NULL	// wait indefinitely
	         );
	dbg_log(
	    "pSmartcardExtension->SmartcardReply.BufferLength: %d",
	    pSmartcardExtension->SmartcardReply.BufferLength
	);
	dbg_ba2s(
	    (char *const)pSmartcardExtension->SmartcardReply.Buffer,
	    pSmartcardExtension->SmartcardReply.BufferLength
	);
	if (status != STATUS_SUCCESS) {
		dbg_log("sendApduMessage failed! - status: 0x%08X", status);
		return status;
	}

	status = SmartcardT0Reply(pSmartcardExtension);
	if (status != STATUS_SUCCESS) {
		dbg_log("SmartcardT0Reply failed! - status: 0x%08X", status);
		return status;
	}

	dbg_log("transmitT0 end - status: 0x%08X", status);
	return status;
}
Beispiel #2
0
NTSTATUS
CBT0Transmit(
            PSMARTCARD_EXTENSION SmartcardExtension
            )
/*++

CBT0Transmit:
        finishes the callback RDF_TRANSMIT for the T0 protocol

Arguments:
        SmartcardExtension      context of call

Return Value:
        STATUS_SUCCESS
        STATUS_NO_MEDIA
        STATUS_TIMEOUT
        STATUS_INVALID_DEVICE_REQUEST

--*/
{
    NTSTATUS NTStatus = STATUS_SUCCESS;
    PUCHAR pRequest,pReply;
    ULONG IOBytes, APDULength, RequestLength;
    UCHAR IOData[ MAX_T1_BLOCK_SIZE ];
    UCHAR WtxReply[16];

    SmartcardDebug(
                  DEBUG_TRACE,
                  ( "PSCR!CBT0Transmit: Enter\n" )
                  );

    SysFillMemory( SmartcardExtension->SmartcardReply.Buffer, 0xCC, MAX_T1_BLOCK_SIZE );

    pRequest        = SmartcardExtension->SmartcardRequest.Buffer;
    pReply          = SmartcardExtension->SmartcardReply.Buffer;

        //      setup the command header
    pRequest[ PSCR_NAD ] =
    ( SmartcardExtension->ReaderExtension->Device == DEVICE_ICC1 ) ?
    NAD_TO_ICC1 : NAD_TO_ICC1;

    pRequest[ PSCR_PCB ] = PCB_DEFAULT;
        //
        //      get the length of the user data packet & set the appropriate LEN
        //      information the complete user packet consists of a SCARD_IO_REQUEST
        //      structure followed by the APDU. the length of SCARD_IO_REQUEST is
        //      transferred in the member cbPciLength of the structure
        //
    APDULength = SmartcardExtension->IoRequest.RequestBufferLength;
    if ((((PSCARD_IO_REQUEST) SmartcardExtension->IoRequest.RequestBuffer)->cbPciLength) >= APDULength) {
        // Prevent integer underflow
        return (STATUS_INSUFFICIENT_RESOURCES);
    }
    APDULength -= ((PSCARD_IO_REQUEST) SmartcardExtension->
                   IoRequest.RequestBuffer)->cbPciLength;
        //
        //      a 4 byte APDU will be patched to a 5 byte TPDU by the lib; see
        //      annex of the ISO
        //
    if ( APDULength == 4 ) APDULength++;
        //
        //      if the total length of the T1 (reader) packet is larger than 0xFF
        //      the extended length notation will be used
        //
    if ( APDULength >= 0xFF ) {
        pRequest[ PSCR_LEN ]    = 0xFF;
        pRequest[ PSCR_LEN+1 ]  = HIBYTE( APDULength );
        pRequest[ PSCR_LEN+2 ]  = LOBYTE( APDULength );
        SmartcardExtension->SmartcardRequest.BufferLength =
        PSCR_EXT_PROLOGUE_LENGTH;
    } else {
        pRequest[ PSCR_LEN ] = ( UCHAR ) APDULength;
        SmartcardExtension->SmartcardRequest.BufferLength =
        PSCR_PROLOGUE_LENGTH;
    }

        //      let the lib setup the T=1 APDU & check for errors
    NTStatus = SmartcardT0Request( SmartcardExtension );
    RequestLength = SmartcardExtension->SmartcardRequest.BufferLength;

    while ( NT_SUCCESS( NTStatus )) {

        //  check to see if device is busy.
        {
            PPSCR_REGISTERS IOBase;
            UCHAR           Status;

            IOBase = SmartcardExtension->ReaderExtension->IOBase;

            Status = READ_PORT_UCHAR( &IOBase->CmdStatusReg );

            if( 0x03 == Status )
            {
                NTStatus = STATUS_DEVICE_BUSY;
                break;
            }
        }

                //      send command
        IOBytes = 0;
        NTStatus = PscrWrite(
                            SmartcardExtension->ReaderExtension,
                            pRequest,
                            RequestLength,
                            &IOBytes
                            );

                //      get response
        if ( NT_SUCCESS( NTStatus )) {
            IOBytes = 0;
            NTStatus = PscrRead(
                               SmartcardExtension->ReaderExtension,
                               IOData,
                               MAX_T1_BLOCK_SIZE,
                               &IOBytes
                               );

                        //      extract APDU from T=1 transport packet
            if ( NT_SUCCESS( NTStatus )) {

                if (IOBytes < 4) {

                    NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
                    break;

                }
                if (IOData[ PSCR_PCB ] == WTX_REQUEST) {

                    WtxReply[PSCR_NAD] = NAD_TO_PSCR;
                    WtxReply[PSCR_PCB] = WTX_REPLY;
                    WtxReply[PSCR_LEN] = 1;
                    WtxReply[PSCR_INF] = IOData[PSCR_INF];

                    RequestLength = 4;
                    pRequest = WtxReply;
                    continue;
                }

                if ( IOData[ PSCR_LEN ] == 0xFF ) {
                                        //
                                        //      extended length byte used
                                        //
                    APDULength  = IOData[ PSCR_LEN + 1 ] << 8;
                    APDULength += IOData[ PSCR_LEN + 2 ];

                    SmartcardExtension->SmartcardReply.BufferLength = APDULength ;
                    if (APDULength >= (sizeof(IOData) - (PSCR_APDU + 2))) {
                        NTStatus = STATUS_BUFFER_TOO_SMALL;
                        break;
                    }
                    SysCopyMemory( pReply, &IOData[ PSCR_APDU + 2 ], APDULength );
                } else {

                    if ((IOData[PSCR_LEN] > SmartcardExtension->SmartcardReply.BufferSize) ||
                        (IOData[PSCR_LEN] > MAX_T1_BLOCK_SIZE + PSCR_APDU)) {
                        NTStatus = STATUS_DEVICE_PROTOCOL_ERROR;
                        break;
                    }
                    SmartcardExtension->SmartcardReply.BufferLength =
                    IOData[ PSCR_LEN ];

                    SysCopyMemory(
                                 pReply,
                                 &IOData[ PSCR_APDU ],
                                 IOData[ PSCR_LEN ]
                                 );
                }

                if( SmartcardExtension->ReaderCapabilities.CurrentState <=
                    SCARD_ABSENT )
                {
                    NTStatus = STATUS_NO_MEDIA;
                }
                else
                {
                    // let the lib evaluate the result & tansfer the data
                    NTStatus = SmartcardT0Reply( SmartcardExtension );
                }
                break;
            }
        }
    }

    // start freeze routine, if an interrupt was sent, but no freeze data was read
    if( SmartcardExtension->ReaderExtension->RequestInterrupt )
        PscrFreeze( SmartcardExtension );

    SmartcardDebug(
                  DEBUG_TRACE,
                  ( "PSCR!CBT0Transmit: Exit (%lx)\n", NTStatus )
                  );

    return( NTStatus );
}