New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provisioning card without secure channel #68
Comments
Hi @mistial-dev, yes this is correct there is no way to avoid SCP at all in this case for a few reasons:
Philosophically speaking, we don't encourage the 9B key at all since it provides no encryption or integrity for the subsequent management commands. It is retained for backwards-compatibility, but as you have seen it really only helps you post-issuance. I ran into the same issue with testing as you have. It is unfortunate that jCardSim doesn't support it but hey they have to make money somehow in a pretty niche market so I can't totally blame them :) Our unit testing was all inside an old commercial tool and I tried a few different approaches, but ultimately the testing framework became Zephyr Scale (on JIRA) to define the tests generically and then export them to NXP JCShell scripts. This gave us SCP support ability to easily use the P71D600 simulator (which helps with FIPS testing). It's a good tool, but I'm not happy that it is proprietary and requires an NXP NDA and a few hoops to get! The Zephyr Scale aspect gives the option to de-couple from this when a good solution is found/developed and one day we will, but for now it's a pragmatic option for testing. |
Looking at the use of GPSystem in this applet (GPSystem.getSecureChannel(), resetSecurity(), getSecurityLevel(), unwrap(), processSecurity()) then "mocking" this as a java code for jcardsim is max half day of effort. Don't know about CVM but probably the same. |
It's true, but only if we had a Java implementation of SCP to base it off :) For the accreditation process we are locked into the current JCShell path but if we had this available for JCardSim it would be a logical next step for the generic tests (Which are most of them) |
I put around that much time into trying to get mocking working before asking about alternate ways. I’m not an expert Java developer, and the techniques I use in dot net don’t really translate well. jCardSim seems to want a class, and mocking synthesizes a new class. I got as far as extracting the instantiated class from the jCardSim runtime, to use with the mocking framework, but then had no way to feed it back into jCardSim. My plan was to just make a fake security domain that would pass through APDUs untouched. That way I could keep my Gpshell scripts otherwise unmodified. |
ChatGPT proved surprisingly helpful. @org.junit.jupiter.api.Test
void testConfiguration() {
try (MockedStatic<GPSystem> mocked = Mockito.mockStatic(GPSystem.class)) {
SecureChannel mockedSecureChannel = Mockito.mock(SecureChannel.class);
// Mock getSecurityLevel() to return a value that indicates that the card is authenticated, has decryption, and has MAC
Mockito.when(mockedSecureChannel.getSecurityLevel()).thenReturn((byte) (SecureChannel.AUTHENTICATED | SecureChannel.C_DECRYPTION | SecureChannel.C_MAC));
// Mock getSecureChannel() to return the mocked SecureChannel
mocked.when(GPSystem::getSecureChannel).thenReturn(mockedSecureChannel);
// Mock `short processSecurity(APDU apdu)` to return 0 bytes of data.
Mockito.when(mockedSecureChannel.processSecurity(Mockito.any())).thenReturn((short)0);
// Mock `short unwrap(byte[] data, short offset, short length)` to return the length (from the third argument)
Mockito.when(mockedSecureChannel.unwrap(Mockito.any(byte[].class), Mockito.anyShort(), Mockito.anyShort())).thenAnswer(invocation -> invocation.getArgument(2));
// Check for a success response
byte[] dataBytes = simulator.selectAppletWithResult(OF201_AID);
// The last two bytes of the response should be 0x9000. Verify that.
assertArrayEquals(new byte[]{(byte) 0x90, (byte) 0x00}, new byte[]{dataBytes[dataBytes.length - 2], dataBytes[dataBytes.length - 1]});
// Define the configuration command in hex
String configurationCommand = "E4 DB 3F 00 5D 68 5B A0 24 80 01 FF 81 01 00 82 01 00 83 01 00 84 01 06 85 01 08 86 01 06 87 01 " +
"05 88 01 00 89 01 04 8A 01 00 8B 01 00 A1 12 80 01 FF 81 01 00 82 01 08 83 01 06 84 01 05 85 01 " +
"00 A2 03 80 01 00 A3 03 80 01 00 A4 15 80 01 00 81 01 00 82 01 00 83 01 00 84 01 FF 85 01 00 86 " +
"01 00";
// Execute the configuration command and get the response
CommandAPDU configurationCommandAPDU = new CommandAPDU(hexStringToByteArray(configurationCommand));
ResponseAPDU configurationResponseAPDU = simulator.transmitCommand(configurationCommandAPDU);
// Verify that the response is 0x9000
assertArrayEquals(new byte[]{(byte) 0x90, (byte) 0x00}, configurationResponseAPDU.getBytes());
}
} |
I'm working on some unit testing for use with OpenFIPS201, and am using jCardSim. The open source version does not support Global Platform or Secure Channel.
Looking through the code, I can see that administrative keys can be used for card administration, but I do not see a way to create an administrator key without using a secure channel.
Does the administrative user have to be defined in secure channel before it can be used for other operations?
The text was updated successfully, but these errors were encountered: