token: send expected result size as Le
This is a different take on 1c8cc99c68,
sending the expected result size. It's not what the spec says, but it's
what GnuPG does, so it should achieve good compatibility.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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()) {
|
||||||
|
|||||||
@@ -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<>();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user