Merge pull request #2298 from open-keychain/expected-le

token: send expected result size as Le
This commit is contained in:
Vincent Breitmoser
2018-03-24 15:00:49 +01:00
committed by GitHub
4 changed files with 19 additions and 9 deletions

View File

@@ -135,8 +135,9 @@ public class OpenPgpCommandApduFactory {
} }
@NonNull @NonNull
public CommandApdu createDecipherCommand(byte[] data) { public CommandApdu createDecipherCommand(byte[] data, int expectedLength) {
return CommandApdu.create(CLA, INS_PERFORM_SECURITY_OPERATION, P1_PSO_DECIPHER, P2_PSO_DECIPHER, data); return CommandApdu.create(CLA, INS_PERFORM_SECURITY_OPERATION, P1_PSO_DECIPHER, P2_PSO_DECIPHER, data,
expectedLength);
} }
@NonNull @NonNull
@@ -220,14 +221,18 @@ public class OpenPgpCommandApduFactory {
int offset = 0; int offset = 0;
byte[] data = apdu.getData(); byte[] data = apdu.getData();
int ne = Math.min(apdu.getNe(), MAX_APDU_NE);
while (offset < data.length) { while (offset < data.length) {
int curLen = Math.min(MAX_APDU_NC, data.length - offset); int curLen = Math.min(MAX_APDU_NC, data.length - offset);
boolean last = offset + curLen >= data.length; boolean last = offset + curLen >= data.length;
int cla = apdu.getCLA() + (last ? 0 : MASK_CLA_CHAINING); int cla = apdu.getCLA() + (last ? 0 : MASK_CLA_CHAINING);
CommandApdu cmd = CommandApdu cmd;
CommandApdu.create(cla, apdu.getINS(), apdu.getP1(), apdu.getP2(), data, offset, curLen, ne); if (last) {
int ne = Math.min(apdu.getNe(), MAX_APDU_NE);
cmd = CommandApdu.create(cla, apdu.getINS(), apdu.getP1(), apdu.getP2(), data, offset, curLen, ne);
} else {
cmd = CommandApdu.create(cla, apdu.getINS(), apdu.getP1(), apdu.getP2(), data, offset, curLen);
}
result.add(cmd); result.add(cmd);
offset += curLen; offset += curLen;

View File

@@ -85,9 +85,10 @@ public class PsoDecryptTokenOp {
} }
private byte[] decryptSessionKeyRsa(byte[] encryptedSessionKeyMpi) throws IOException { private byte[] decryptSessionKeyRsa(byte[] encryptedSessionKeyMpi) throws IOException {
int mpiLength = getMpiLength(encryptedSessionKeyMpi);
byte[] psoDecipherPayload = getRsaOperationPayload(encryptedSessionKeyMpi); byte[] psoDecipherPayload = getRsaOperationPayload(encryptedSessionKeyMpi);
CommandApdu command = connection.getCommandFactory().createDecipherCommand(psoDecipherPayload); CommandApdu command = connection.getCommandFactory().createDecipherCommand(psoDecipherPayload, mpiLength);
ResponseApdu response = connection.communicate(command); ResponseApdu response = connection.communicate(command);
if (!response.isSuccess()) { if (!response.isSuccess()) {
@@ -139,7 +140,8 @@ public class PsoDecryptTokenOp {
} }
psoDecipherPayload = Arrays.concatenate(Hex.decode("A6"), dataLen, psoDecipherPayload); psoDecipherPayload = Arrays.concatenate(Hex.decode("A6"), dataLen, psoDecipherPayload);
CommandApdu command = connection.getCommandFactory().createDecipherCommand(psoDecipherPayload); CommandApdu command = connection.getCommandFactory().createDecipherCommand(
psoDecipherPayload, encryptedPoint.length);
ResponseApdu response = connection.communicate(command); ResponseApdu response = connection.communicate(command);
if (!response.isSuccess()) { if (!response.isSuccess()) {

View File

@@ -85,7 +85,7 @@ public class SecurityTokenConnectionCompatTest {
PsoDecryptTokenOp psoDecryptTokenOp = PsoDecryptTokenOp.create(mock(SecurityTokenConnection.class)); PsoDecryptTokenOp psoDecryptTokenOp = PsoDecryptTokenOp.create(mock(SecurityTokenConnection.class));
byte[] psoDecipherPayload = psoDecryptTokenOp.getRsaOperationPayload(encryptedSessionKey); byte[] psoDecipherPayload = psoDecryptTokenOp.getRsaOperationPayload(encryptedSessionKey);
CommandApdu command = openPgpCommandApduFactory.createDecipherCommand(psoDecipherPayload); CommandApdu command = openPgpCommandApduFactory.createDecipherCommand(psoDecipherPayload, encryptedSessionKey.length);
List<CommandApdu> chainedApdus = openPgpCommandApduFactory.createChainedApdus(command); List<CommandApdu> chainedApdus = openPgpCommandApduFactory.createChainedApdus(command);
List<String> apduData = new ArrayList<>(); List<String> apduData = new ArrayList<>();

View File

@@ -32,6 +32,7 @@ import org.sufficientlysecure.keychain.securitytoken.operations.PsoDecryptTokenO
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -45,6 +46,8 @@ public class PsoDecryptTokenOpTest {
"fb9d8cbcb34f28d0b968b6e09eda0e1d3ab6b251eb09f9fb9d9abfeaf9010001733b9015e9e4b6c9df61bbc76041f439d1" + "fb9d8cbcb34f28d0b968b6e09eda0e1d3ab6b251eb09f9fb9d9abfeaf9010001733b9015e9e4b6c9df61bbc76041f439d1" +
"273e41f5d0e8414a2b8d6d4c7e86f30b94cfba308b38de53d694a8ca15382301ace806c8237641b03525b3e3e8cbb017e2" + "273e41f5d0e8414a2b8d6d4c7e86f30b94cfba308b38de53d694a8ca15382301ace806c8237641b03525b3e3e8cbb017e2" +
"51265229bcbb0da5d5aeb4eafbad9779"); "51265229bcbb0da5d5aeb4eafbad9779");
private static final int RSA_ENC_MODULUS = 256;
private SecurityTokenConnection securityTokenConnection; private SecurityTokenConnection securityTokenConnection;
private OpenPgpCommandApduFactory commandFactory; private OpenPgpCommandApduFactory commandFactory;
private PsoDecryptTokenOp useCase; private PsoDecryptTokenOp useCase;
@@ -75,7 +78,7 @@ public class PsoDecryptTokenOpTest {
ResponseApdu dummyResponseApdu = ResponseApdu.fromBytes(Hex.decode("010203049000")); ResponseApdu dummyResponseApdu = ResponseApdu.fromBytes(Hex.decode("010203049000"));
when(commandFactory.createDecipherCommand(any(byte[].class))).thenReturn(dummyCommandApdu); when(commandFactory.createDecipherCommand(any(byte[].class), eq(RSA_ENC_MODULUS))).thenReturn(dummyCommandApdu);
when(securityTokenConnection.communicate(dummyCommandApdu)).thenReturn(dummyResponseApdu); when(securityTokenConnection.communicate(dummyCommandApdu)).thenReturn(dummyResponseApdu);
byte[] response = useCase.verifyAndDecryptSessionKey(RSA_ENC_SESSIONKEY_MPI, null); byte[] response = useCase.verifyAndDecryptSessionKey(RSA_ENC_SESSIONKEY_MPI, null);