SecurityToken: fix T=1 TPDU chaining handling
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user