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;
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_CHAINING = 5;

View File

@@ -22,7 +22,10 @@ import android.support.annotation.NonNull;
import org.sufficientlysecure.keychain.securitytoken.usb.UsbTransportException;
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 {
super(baseBlock);
@@ -33,7 +36,7 @@ public class RBlock extends Block {
public RBlock(BlockChecksumType checksumType, byte nad, byte sequence)
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 {

View File

@@ -18,6 +18,9 @@
package org.sufficientlysecure.keychain.securitytoken.usb.tpdu;
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) {
super(baseBlock);
}

View File

@@ -103,10 +103,10 @@ public class T1TpduProtocol implements CcidTransportProtocol {
byte[] responseApdu = responseBlock.getApdu();
while (((IBlock) responseBlock).getChaining()) {
Block ackBlock = newRBlock((byte) (1 - ((IBlock) responseBlock).getSequence()));
Block ackBlock = newRBlock((byte) (((IBlock) responseBlock).getSequence() + 1));
mTransceiver.sendXfrBlock(ackBlock.getRawData());
responseBlock = getBlockFromResponse(mTransceiver.receive());
responseBlock = getBlockFromResponse(mTransceiver.receiveRaw());
if (responseBlock instanceof IBlock) {
responseApdu = Arrays.concatenate(responseApdu, responseBlock.getApdu());
@@ -123,11 +123,11 @@ public class T1TpduProtocol implements CcidTransportProtocol {
public Block getBlockFromResponse(byte[] data) throws UsbTransportException {
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);
} else if ((baseBlock.getPcb() & 0b11000000) == 0b11000000) {
} else if ((baseBlock.getPcb() & SBlock.MASK_SBLOCK) == SBlock.MASK_VALUE_SBLOCK) {
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);
}