SecurityToken: fix T=1 TPDU chaining handling

This commit is contained in:
Nikita Mikhailov
2016-05-09 15:25:06 +06:00
parent a017b9f25a
commit 9f57a1312e
4 changed files with 16 additions and 7 deletions

View File

@@ -20,6 +20,9 @@ package org.sufficientlysecure.keychain.securitytoken.usb.tpdu;
import org.sufficientlysecure.keychain.securitytoken.usb.UsbTransportException; import org.sufficientlysecure.keychain.securitytoken.usb.UsbTransportException;
public class IBlock extends Block { public class IBlock extends Block {
public static final byte MASK_RBLOCK = (byte) 0b10000000;
public static final byte MASK_VALUE_RBLOCK = (byte) 0b00000000;
private static final byte BIT_SEQUENCE = 6; private static final byte BIT_SEQUENCE = 6;
private static final byte BIT_CHAINING = 5; private static final byte BIT_CHAINING = 5;

View File

@@ -22,7 +22,10 @@ import android.support.annotation.NonNull;
import org.sufficientlysecure.keychain.securitytoken.usb.UsbTransportException; import org.sufficientlysecure.keychain.securitytoken.usb.UsbTransportException;
public class RBlock extends Block { public class RBlock extends Block {
private static final byte BIT_SEQUENCE = 5; public static final byte MASK_RBLOCK = (byte) 0b11000000;
public static final byte MASK_VALUE_RBLOCK = (byte) 0b10000000;
private static final byte BIT_SEQUENCE = 4;
public RBlock(Block baseBlock) throws UsbTransportException { public RBlock(Block baseBlock) throws UsbTransportException {
super(baseBlock); super(baseBlock);
@@ -33,7 +36,7 @@ public class RBlock extends Block {
public RBlock(BlockChecksumType checksumType, byte nad, byte sequence) public RBlock(BlockChecksumType checksumType, byte nad, byte sequence)
throws UsbTransportException { throws UsbTransportException {
super(checksumType, nad, (byte) (0b10000000 | ((sequence & 1) << BIT_SEQUENCE)), new byte[0]); super(checksumType, nad, (byte) (MASK_VALUE_RBLOCK | ((sequence & 1) << BIT_SEQUENCE)), new byte[0]);
} }
public RError getError() throws UsbTransportException { public RError getError() throws UsbTransportException {

View File

@@ -18,6 +18,9 @@
package org.sufficientlysecure.keychain.securitytoken.usb.tpdu; package org.sufficientlysecure.keychain.securitytoken.usb.tpdu;
public class SBlock extends Block { public class SBlock extends Block {
public static final byte MASK_SBLOCK = (byte) 0b11000000;
public static final byte MASK_VALUE_SBLOCK = (byte) 0b11000000;
public SBlock(Block baseBlock) { public SBlock(Block baseBlock) {
super(baseBlock); super(baseBlock);
} }

View File

@@ -103,10 +103,10 @@ public class T1TpduProtocol implements CcidTransportProtocol {
byte[] responseApdu = responseBlock.getApdu(); byte[] responseApdu = responseBlock.getApdu();
while (((IBlock) responseBlock).getChaining()) { while (((IBlock) responseBlock).getChaining()) {
Block ackBlock = newRBlock((byte) (1 - ((IBlock) responseBlock).getSequence())); Block ackBlock = newRBlock((byte) (((IBlock) responseBlock).getSequence() + 1));
mTransceiver.sendXfrBlock(ackBlock.getRawData()); mTransceiver.sendXfrBlock(ackBlock.getRawData());
responseBlock = getBlockFromResponse(mTransceiver.receive()); responseBlock = getBlockFromResponse(mTransceiver.receiveRaw());
if (responseBlock instanceof IBlock) { if (responseBlock instanceof IBlock) {
responseApdu = Arrays.concatenate(responseApdu, responseBlock.getApdu()); responseApdu = Arrays.concatenate(responseApdu, responseBlock.getApdu());
@@ -123,11 +123,11 @@ public class T1TpduProtocol implements CcidTransportProtocol {
public Block getBlockFromResponse(byte[] data) throws UsbTransportException { public Block getBlockFromResponse(byte[] data) throws UsbTransportException {
final Block baseBlock = new Block(mChecksumType, data); final Block baseBlock = new Block(mChecksumType, data);
if ((baseBlock.getPcb() & 0b10000000) == 0b00000000) { if ((baseBlock.getPcb() & IBlock.MASK_RBLOCK) == IBlock.MASK_VALUE_RBLOCK) {
return new IBlock(baseBlock); return new IBlock(baseBlock);
} else if ((baseBlock.getPcb() & 0b11000000) == 0b11000000) { } else if ((baseBlock.getPcb() & SBlock.MASK_SBLOCK) == SBlock.MASK_VALUE_SBLOCK) {
return new SBlock(baseBlock); return new SBlock(baseBlock);
} else if ((baseBlock.getPcb() & 0b11000000) == 0b10000000) { } else if ((baseBlock.getPcb() & RBlock.MASK_RBLOCK) == RBlock.MASK_VALUE_RBLOCK) {
return new RBlock(baseBlock); return new RBlock(baseBlock);
} }