瀏覽代碼

Revert "Support TPDU-based CCID readers (#295)"

This reverts commit 2cf2d9490a771ef8a387ddb6709412cf5505c279.

Temporary revert due to known regressions. Will re-introduce later with
investigation.
Peter Cai 1 周之前
父節點
當前提交
6dc9cea15f

+ 0 - 61
app-common/src/main/java/im/angry/openeuicc/core/usb/UsbApduInterface.kt

@@ -21,70 +21,9 @@ class UsbApduInterface(
 
     private var channels = mutableSetOf<Int>()
 
-    // ATR parser
-    // Specs: ISO/IEC 7816-3:2006 8.2 Answer-to-Reset
-    // See also: https://en.wikipedia.org/wiki/Answer_to_reset
-    class ParsedAtr private constructor(val ts: Byte?, val t0: Byte?, val ta1: Byte?, val tb1: Byte?, val tc1: Byte?, val td1: Byte?, val ta2: Byte?, val tb2: Byte?, val tc2: Byte?, val td2: Byte?) {
-        companion object {
-            fun parse(atr: ByteArray): ParsedAtr {
-                val ts = atr[0]
-                val t0 = atr[1]
-                val tx1 = arrayOf<Byte?>(null, null, null, null)
-                val tx2 = arrayOf<Byte?>(null, null, null, null)
-                var pointer = 2
-
-                for (i in 0..3) {
-                    if (t0.toInt() and (0x10 shl i) != 0) {
-                        tx1[i] = atr[pointer]
-                        pointer++
-                    }
-                }
-
-                val td1 = tx1[3] ?: 0
-
-                for (i in 0..3) {
-                    if (td1.toInt() and (0x10 shl i) != 0) {
-                        tx2[i] = atr[pointer]
-                        pointer++
-                    }
-                }
-
-                return ParsedAtr(ts=ts, t0=t0, ta1=tx1[0], tb1=tx1[1], tc1=tx1[2], td1=tx1[3],
-                                 ta2=tx2[0], tb2=tx2[1], tc2=tx2[2], td2=tx2[3],
-                )
-            }
-        }
-    }
-
     override fun connect() {
         ccidCtx.connect()
 
-        if (ccidCtx.transceiver.isTpdu) {
-            // Send parameter selection
-            // Specs: USB-CCID 3.2.1 TPDU level of exchange
-            val parsedAtr = ParsedAtr.parse(atr!!)
-            val ta1 = parsedAtr.ta1 ?: 0x11.toByte()
-            val pts1 = ta1 // TODO: Check that reader supports baud rate proposed by the card
-            val pps = byteArrayOf(0xff.toByte(), 0x10.toByte(), pts1, 0x00.toByte())
-            Log.d(TAG, "PTS1=${pts1} PPS: ${pps.encodeHex()}")
-            ccidCtx.transceiver.sendXfrBlock(pps)
-
-            // Send Set Parameters
-            // Specs: USB-CCID 6.1.7 PC_to_RDR_SetParameters
-
-            val param = byteArrayOf(
-                pts1,
-                (if (parsedAtr.ts == 0x3F.toByte()) 0x02 else 0x00),
-                parsedAtr.tc1 ?: 0,
-                parsedAtr.tc2 ?: 0x0A,
-                0x00
-            )
-
-            Log.d(TAG, "Param: ${param.encodeHex()}")
-
-            ccidCtx.transceiver.sendParamBlock(param)
-        }
-
         // Send Terminal Capabilities
         // Specs: ETSI TS 102 221 v15.0.0 - 11.1.19 TERMINAL CAPABILITY
         val terminalCapabilities = buildCmd(

+ 1 - 3
app-common/src/main/java/im/angry/openeuicc/core/usb/UsbCcidDescription.kt

@@ -84,8 +84,6 @@ data class UsbCcidDescription(
 
     private fun hasFeature(feature: Int) = (dwFeatures and feature) != 0
 
-    val isTpdu = hasFeature(0x10000)
-
     val voltages: List<Voltage>
         get() {
             if (hasFeature(FEATURE_AUTOMATIC_VOLTAGE)) return listOf(Voltage.AUTO)
@@ -97,4 +95,4 @@ data class UsbCcidDescription(
 
     val hasT0Protocol: Boolean
         get() = (dwProtocols and MASK_T0_PROTO) != 0
-}
+}

+ 0 - 74
app-common/src/main/java/im/angry/openeuicc/core/usb/UsbCcidTransceiver.kt

@@ -143,8 +143,6 @@ class UsbCcidTransceiver(
 
     val hasAutomaticPps = usbCcidDescription.hasAutomaticPps
 
-    val isTpdu = usbCcidDescription.isTpdu
-
     private val inputBuffer = ByteArray(usbBulkIn.maxPacketSize)
 
     private var currentSequenceNumber: Byte = 0
@@ -160,46 +158,6 @@ class UsbCcidTransceiver(
         }
     }
 
-    private fun receiveParamBlock(expectedSequenceNumber: Byte): ByteArray {
-        var response: ByteArray?
-        do {
-            response = receiveParamBlockImmediate(expectedSequenceNumber)
-        } while (response!![7] == 0x80.toByte())
-        return response
-    }
-
-    private fun receiveParamBlockImmediate(expectedSequenceNumber: Byte): ByteArray {
-        /*
-         * Some USB CCID devices (notably NitroKey 3) may time-out and need a subsequent poke to
-         * carry on communications.  No particular reason why the number 3 was chosen.  If we get a
-         * zero-sized reply (or a time-out), we try again.  Clamped retries prevent an infinite loop
-         * if things really turn sour.
-         */
-        var attempts = 3
-        Log.d(TAG, "Receive data block immediate seq=$expectedSequenceNumber")
-        var readBytes: Int
-        do {
-            readBytes = usbConnection.bulkTransfer(
-                usbBulkIn, inputBuffer, inputBuffer.size, DEVICE_COMMUNICATE_TIMEOUT_MILLIS
-            )
-            if (runBlocking { verboseLoggingFlow.first() }) {
-                Log.d(TAG, "Received $readBytes bytes: ${inputBuffer.encodeHex()}")
-            }
-        } while (readBytes <= 0 && attempts-- > 0)
-        if (inputBuffer[0] != 0x82.toByte()) {
-            throw UsbTransportException(buildString {
-                append("USB-CCID error - bad CCID header")
-                append(", type ")
-                append("%d (expected %d)".format(inputBuffer[0], MESSAGE_TYPE_RDR_TO_PC_DATA_BLOCK))
-                if (expectedSequenceNumber != inputBuffer[6]) {
-                    append(", sequence number ")
-                    append("%d (expected %d)".format(inputBuffer[6], expectedSequenceNumber))
-                }
-            })
-        }
-        return inputBuffer
-    }
-
     private fun receiveDataBlock(expectedSequenceNumber: Byte): CcidDataBlock {
         var response: CcidDataBlock?
         do {
@@ -325,38 +283,6 @@ class UsbCcidTransceiver(
         return ccidDataBlock
     }
 
-    fun sendParamBlock(
-        payload: ByteArray
-    ): ByteArray {
-        val startTime = SystemClock.elapsedRealtime()
-        val l = payload.size
-        val sequenceNumber: Byte = currentSequenceNumber++
-        val headerData = byteArrayOf(
-            0x61.toByte(),
-            l.toByte(),
-            (l shr 8).toByte(),
-            (l shr 16).toByte(),
-            (l shr 24).toByte(),
-            SLOT_NUMBER.toByte(),
-            sequenceNumber,
-            0x00.toByte(),
-            0x00.toByte(),
-            0x00.toByte()
-        )
-        val data: ByteArray = headerData + payload
-        Log.d(TAG, "USB ParamBlock: ${data.encodeHex()}")
-        var sentBytes = 0
-        while (sentBytes < data.size) {
-            val bytesToSend = usbBulkOut.maxPacketSize.coerceAtMost(data.size - sentBytes)
-            sendRaw(data, sentBytes, bytesToSend)
-            sentBytes += bytesToSend
-        }
-        val ccidDataBlock = receiveParamBlock(sequenceNumber)
-        val elapsedTime = SystemClock.elapsedRealtime() - startTime
-        Log.d(TAG, "USB ParamBlock call took ${elapsedTime}ms")
-        return ccidDataBlock
-    }
-
     fun iccPowerOn(): CcidDataBlock {
         val startTime = SystemClock.elapsedRealtime()
         skipAvailableInput()