diff --git a/src/main/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoService.java b/src/main/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoService.java index 53af823..586683d 100644 --- a/src/main/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoService.java +++ b/src/main/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoService.java @@ -1931,7 +1931,7 @@ public class JnaPcieCryptoService implements PcieCryptoService { List userKeyRequests = requireUserKeyRequests(req.getUserKeyRequests()); try { - return sessionTemplate.withSession("SDFE_RecoverMasterKeyMaterial", (lib, deviceHandle, sessionHandle) -> { + DeviceStatusResult deviceStatus = sessionTemplate.withSession("SDFE_RecoverMasterKeyMaterial", (lib, deviceHandle, sessionHandle) -> { sessionTemplate.ensureSuccess( "SDFE_InitIdentify", lib.SDFE_InitIdentify(sessionHandle, oldPin, oldPin.length, newPin, newPin.length) @@ -1946,19 +1946,23 @@ public class JnaPcieCryptoService implements PcieCryptoService { "SDFE_RecoverIK_EX", lib.SDFE_RecoverIK_EX(sessionHandle, IK_KEY_TYPE_DEVICE, deviceIkComponent) ); - DeviceStatusResult deviceStatus = readDeviceStatus(lib, sessionHandle); + return readDeviceStatus(lib, sessionHandle); + }); + + byte[] seedMac = sessionTemplate.withSession("SDFE_RecoverUserKey", (lib, deviceHandle, sessionHandle) -> { for (RecoverUserKeyRequest userKeyRequest : userKeyRequests) { recoverUserKeyInCurrentSession(lib, sessionHandle, userKeyRequest); } sessionTemplate.ensureSuccess("SDFE_CheckLMK", lib.SDFE_CheckLMK(sessionHandle)); byte[] mac = new byte[LMK_SEED_MAC_LENGTH]; sessionTemplate.ensureSuccess("SDFE_ExportLMKSeedMAC", lib.SDFE_ExportLMKSeedMAC(sessionHandle, mac)); - - MasterKeyRecoveryResult result = new MasterKeyRecoveryResult(); - result.setDeviceStatus(deviceStatus); - result.setLmkSeedMac(Arrays.copyOf(mac, mac.length)); - return result; + return Arrays.copyOf(mac, mac.length); }); + + MasterKeyRecoveryResult result = new MasterKeyRecoveryResult(); + result.setDeviceStatus(deviceStatus); + result.setLmkSeedMac(seedMac); + return result; } finally { wipe(oldPin); wipe(newPin); diff --git a/src/test/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoServiceTest.java b/src/test/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoServiceTest.java index 2afd9f9..fe7d29c 100644 --- a/src/test/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoServiceTest.java +++ b/src/test/java/com/cisd/tms/integration/crypto/pcie/service/JnaPcieCryptoServiceTest.java @@ -11,6 +11,7 @@ import com.cisd.tms.integration.crypto.pcie.jna.SdfeDeviceStatus; import com.cisd.tms.integration.crypto.pcie.jna.SdfeIkComponent; import com.cisd.tms.integration.crypto.pcie.jna.SdfeLmkComponent; import com.cisd.tms.integration.crypto.pcie.model.BackupDataResult; +import com.cisd.tms.integration.crypto.pcie.model.DeviceStatusResult; import com.cisd.tms.integration.crypto.pcie.model.DigestRequest; import com.cisd.tms.integration.crypto.pcie.model.EccInternalDecryptRequest; import com.cisd.tms.integration.crypto.pcie.model.EccInternalEncryptRequest; @@ -141,11 +142,12 @@ class JnaPcieCryptoServiceTest { } @Test - void shouldRecoverMasterKeyMaterialWithinSingleSessionAndReturnSeedMac() { + void shouldRecoverMasterKeyMaterialWithUserKeysInSeparateSessionAndReturnSeedMac() { PcieSessionTemplate sessionTemplate = Mockito.mock(PcieSessionTemplate.class); CryptoCardProperties properties = new CryptoCardProperties(); JnaPcieCryptoService service = new JnaPcieCryptoService(sessionTemplate, properties); - Pointer session = Pointer.createConstant(2); + Pointer restoreSession = Pointer.createConstant(2); + Pointer userKeySession = Pointer.createConstant(3); byte[] seedMac = new byte[] {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18}; MasterKeyRecoveryRequest request = new MasterKeyRecoveryRequest(); @@ -164,46 +166,63 @@ class JnaPcieCryptoServiceTest { encKey.setEncryptedKey(new byte[] {0x11, 0x12, 0x13}); request.setUserKeyRequests(List.of(signKey, encKey)); - AtomicReference libRef = new AtomicReference<>(); + AtomicReference restoreLibRef = new AtomicReference<>(); + AtomicReference userKeyLibRef = new AtomicReference<>(); Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_RecoverMasterKeyMaterial"), Mockito.any())) .thenAnswer(invocation -> { @SuppressWarnings("unchecked") - PcieSessionTemplate.SessionCallback callback = - (PcieSessionTemplate.SessionCallback) invocation.getArgument(1); + PcieSessionTemplate.SessionCallback callback = + (PcieSessionTemplate.SessionCallback) invocation.getArgument(1); PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class); - libRef.set(lib); - Mockito.when(lib.SDFE_InitIdentify(Mockito.eq(session), Mockito.any(), Mockito.anyInt(), Mockito.any(), Mockito.anyInt())).thenReturn(0); - Mockito.when(lib.SDFE_RecoverLMK_EX(Mockito.eq(session), Mockito.any(SdfeLmkComponent.class))).thenReturn(0); - Mockito.when(lib.SDFE_LoadLMK(Mockito.eq(session))).thenReturn(0); - Mockito.when(lib.SDFE_RecoverIK_EX(Mockito.eq(session), Mockito.eq(2), Mockito.any(SdfeIkComponent.class))).thenReturn(0); - Mockito.when(lib.SDFE_RecoverIK_EX(Mockito.eq(session), Mockito.eq(1), Mockito.any(SdfeIkComponent.class))).thenReturn(0); - Mockito.when(lib.SDFE_DeviceStatusGet(Mockito.eq(session), Mockito.any(SdfeDeviceStatus.class))).thenReturn(0); - Mockito.when(lib.SDFE_RecoverUserKey(Mockito.eq(session), Mockito.eq(1), Mockito.anyInt(), Mockito.any(), Mockito.anyInt(), Mockito.anyByte())).thenReturn(0); - Mockito.when(lib.SDFE_CheckLMK(Mockito.eq(session))).thenReturn(0); - Mockito.when(lib.SDFE_ExportLMKSeedMAC(Mockito.eq(session), Mockito.any())).thenAnswer(exportInvocation -> { + restoreLibRef.set(lib); + Mockito.when(lib.SDFE_InitIdentify(Mockito.eq(restoreSession), Mockito.any(), Mockito.anyInt(), Mockito.any(), Mockito.anyInt())).thenReturn(0); + Mockito.when(lib.SDFE_RecoverLMK_EX(Mockito.eq(restoreSession), Mockito.any(SdfeLmkComponent.class))).thenReturn(0); + Mockito.when(lib.SDFE_LoadLMK(Mockito.eq(restoreSession))).thenReturn(0); + Mockito.when(lib.SDFE_RecoverIK_EX(Mockito.eq(restoreSession), Mockito.eq(2), Mockito.any(SdfeIkComponent.class))).thenReturn(0); + Mockito.when(lib.SDFE_RecoverIK_EX(Mockito.eq(restoreSession), Mockito.eq(1), Mockito.any(SdfeIkComponent.class))).thenReturn(0); + Mockito.when(lib.SDFE_DeviceStatusGet(Mockito.eq(restoreSession), Mockito.any(SdfeDeviceStatus.class))).thenReturn(0); + return callback.apply(lib, Pointer.createConstant(1), restoreSession); + }); + Mockito.when(sessionTemplate.withSession(Mockito.eq("SDFE_RecoverUserKey"), Mockito.any())) + .thenAnswer(invocation -> { + @SuppressWarnings("unchecked") + PcieSessionTemplate.SessionCallback callback = + (PcieSessionTemplate.SessionCallback) invocation.getArgument(1); + PcieNativeLibrary lib = Mockito.mock(PcieNativeLibrary.class); + userKeyLibRef.set(lib); + Mockito.when(lib.SDFE_RecoverUserKey(Mockito.eq(userKeySession), Mockito.eq(1), Mockito.anyInt(), Mockito.any(), Mockito.anyInt(), Mockito.anyByte())).thenReturn(0); + Mockito.when(lib.SDFE_CheckLMK(Mockito.eq(userKeySession))).thenReturn(0); + Mockito.when(lib.SDFE_ExportLMKSeedMAC(Mockito.eq(userKeySession), Mockito.any())).thenAnswer(exportInvocation -> { byte[] out = exportInvocation.getArgument(1); System.arraycopy(seedMac, 0, out, 0, seedMac.length); return 0; }); - return callback.apply(lib, Pointer.createConstant(1), session); + return callback.apply(lib, Pointer.createConstant(1), userKeySession); }); MasterKeyRecoveryResult result = service.recoverMasterKeyMaterial(request); Assertions.assertArrayEquals(seedMac, result.getLmkSeedMac()); Assertions.assertNotNull(result.getDeviceStatus()); - Mockito.verify(sessionTemplate).withSession(Mockito.eq("SDFE_RecoverMasterKeyMaterial"), Mockito.any()); - PcieNativeLibrary lib = libRef.get(); - InOrder inOrder = Mockito.inOrder(lib); - inOrder.verify(lib).SDFE_InitIdentify(Mockito.eq(session), Mockito.any(), Mockito.anyInt(), Mockito.any(), Mockito.anyInt()); - inOrder.verify(lib).SDFE_RecoverLMK_EX(Mockito.eq(session), Mockito.any(SdfeLmkComponent.class)); - inOrder.verify(lib).SDFE_LoadLMK(Mockito.eq(session)); - inOrder.verify(lib).SDFE_RecoverIK_EX(Mockito.eq(session), Mockito.eq(2), Mockito.any(SdfeIkComponent.class)); - inOrder.verify(lib).SDFE_RecoverIK_EX(Mockito.eq(session), Mockito.eq(1), Mockito.any(SdfeIkComponent.class)); - inOrder.verify(lib).SDFE_DeviceStatusGet(Mockito.eq(session), Mockito.any(SdfeDeviceStatus.class)); - inOrder.verify(lib, Mockito.times(2)).SDFE_RecoverUserKey(Mockito.eq(session), Mockito.eq(1), Mockito.anyInt(), Mockito.any(), Mockito.anyInt(), Mockito.anyByte()); - inOrder.verify(lib).SDFE_CheckLMK(Mockito.eq(session)); - inOrder.verify(lib).SDFE_ExportLMKSeedMAC(Mockito.eq(session), Mockito.any()); + InOrder sessionOrder = Mockito.inOrder(sessionTemplate); + sessionOrder.verify(sessionTemplate).withSession(Mockito.eq("SDFE_RecoverMasterKeyMaterial"), Mockito.any()); + sessionOrder.verify(sessionTemplate).withSession(Mockito.eq("SDFE_RecoverUserKey"), Mockito.any()); + + PcieNativeLibrary restoreLib = restoreLibRef.get(); + InOrder restoreOrder = Mockito.inOrder(restoreLib); + restoreOrder.verify(restoreLib).SDFE_InitIdentify(Mockito.eq(restoreSession), Mockito.any(), Mockito.anyInt(), Mockito.any(), Mockito.anyInt()); + restoreOrder.verify(restoreLib).SDFE_RecoverLMK_EX(Mockito.eq(restoreSession), Mockito.any(SdfeLmkComponent.class)); + restoreOrder.verify(restoreLib).SDFE_LoadLMK(Mockito.eq(restoreSession)); + restoreOrder.verify(restoreLib).SDFE_RecoverIK_EX(Mockito.eq(restoreSession), Mockito.eq(2), Mockito.any(SdfeIkComponent.class)); + restoreOrder.verify(restoreLib).SDFE_RecoverIK_EX(Mockito.eq(restoreSession), Mockito.eq(1), Mockito.any(SdfeIkComponent.class)); + restoreOrder.verify(restoreLib).SDFE_DeviceStatusGet(Mockito.eq(restoreSession), Mockito.any(SdfeDeviceStatus.class)); + Mockito.verify(restoreLib, Mockito.never()).SDFE_RecoverUserKey(Mockito.any(), Mockito.anyInt(), Mockito.anyInt(), Mockito.any(), Mockito.anyInt(), Mockito.anyByte()); + + PcieNativeLibrary userKeyLib = userKeyLibRef.get(); + InOrder userKeyOrder = Mockito.inOrder(userKeyLib); + userKeyOrder.verify(userKeyLib, Mockito.times(2)).SDFE_RecoverUserKey(Mockito.eq(userKeySession), Mockito.eq(1), Mockito.anyInt(), Mockito.any(), Mockito.anyInt(), Mockito.anyByte()); + userKeyOrder.verify(userKeyLib).SDFE_CheckLMK(Mockito.eq(userKeySession)); + userKeyOrder.verify(userKeyLib).SDFE_ExportLMKSeedMAC(Mockito.eq(userKeySession), Mockito.any()); } @Test