makinako / openfips201 Goto Github PK
View Code? Open in Web Editor NEWAn open source reference card application for NIST FIPS 201-2 / NIST SP800-73-4, targeting Javacard 3.0.4+
License: Other
An open source reference card application for NIST FIPS 201-2 / NIST SP800-73-4, targeting Javacard 3.0.4+
License: Other
Signing data with an RSA key on the latest OpenFIPS201 applet causes the card to stall out, with the command eventually failing. Signing data with an ECC key works fine. This was tested on a JCOP 3 P60 CS with 144KB EEPROM.
This is what we're getting back from the card from the signing command:
A>> T=1 (4+0255) 1087079A FF 7C8201068200818201000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003031300D060960864801650304020105000420450BFD34051D6CC04A80B36F3497C7849DD9A1F11A
A<< (0000+2) (49ms) 9000
A>> T=1 (4+0011) 0087079A 0B B83CCB10DBECBC03548729 00
<< SCardTransmit got response 0x45d (null: null)
Failed to communicate with card in apdu4j.LoggingCardTerminal@244038d0: SCardTransmit got response 0x45d (null: null)
After some investigation, we've been able to get signing working again by not removing the public key from the card after keygen, though we're unable to determine exactly why this would affect later signing operations with the private key.
--- a/src/com/makina/security/OpenFIPS201/PIVKeyObjectPKI.java
+++ b/src/com/makina/security/OpenFIPS201/PIVKeyObjectPKI.java
@@ -100,8 +100,6 @@ public abstract class PIVKeyObjectPKI extends PIVKeyObject {
// We effectively new'd these objects so we will make sure the memory
// is freed up.
keyPair = null;
- // Any existing public key is now invalid
- clearPublic();
runGc();
}
return length;
Build and install the latest OpenFIPS201 applet onto a card. Run the example pre-personalisation script, and add an ECC P-256 and ECC P-384 key object for the 9A, 9C, 9D, and 9E keys. Then run the following commands with GlobalPlatformPro (or equivalent):
// Inject a test PIN
java -jar gp.jar -dv --reader "<reader>" --mode enc --sdaid A000000308000010000100 --secure-apdu 0424FF80083132333435363738
// Generate an RSA-2048 key in the 9A slot
java -jar gp.jar -dv --reader "<reader>" --mode enc --sdaid A000000308000010000100 --secure-apdu 0447009A05AC03800107
// Sign a padded hash using the 9A key, authenticating with the test PIN
java -jar gp.jar -dv --reader "<reader>" --applet A000000308000010000100 --apdu 00200080083132333435363738 --apdu 1087079AFF7C8201068200818201000001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003031300D060960864801650304020105000420450BFD34051D6CC04A80B36F3497C7849DD9A1F11A --apdu 0087079A0BB83CCB10DBECBC0354872900
The signing command will return the output from the log above.
Hello, I'm trying to use OpenFIPS201 applet with jcardsim.
First, build the CAP file with ant
as
JC_HOME=$PWD/OpenFIPS201/tools/sdk/jc310 ant -v all -f build/build.xml
then create jcardsim configuration file
com.licel.jcardsim.card.applet.0.AID=A00000030800001000
com.licel.jcardsim.card.applet.0.Class=com.makina.security.openfips201.OpenFIPS201
com.licel.jcardsim.card.ATR=3B80800101
com.licel.jcardsim.vsmartcard.host=localhost
com.licel.jcardsim.vsmartcard.port=35963
but starting the applet with command (assuming that jcardsim JAR is ok)
java -noverify -cp OpenFIPS201/build/bin:jcardsim/target/jcardsim-3.0.5-SNAPSHOT.jar com.licel.jcardsim.remote.VSmartCard jcardsim.cfg
ends with exception
Exception in thread "main" javacard.framework.SystemException
at javacard.framework.SystemException.throwIt(Unknown Source)
at com.licel.jcardsim.base.Simulator.loadApplet(Simulator.java:146)
at com.licel.jcardsim.base.Simulator.<init>(Simulator.java:114)
at com.licel.jcardsim.base.Simulator.<init>(Simulator.java:65)
at com.licel.jcardsim.remote.VSmartCard.startThread(VSmartCard.java:87)
at com.licel.jcardsim.remote.VSmartCard.<init>(VSmartCard.java:43)
at com.licel.jcardsim.remote.VSmartCard.main(VSmartCard.java:83)
I'm not sure, whether this problem is related to building the CAP file or rather jcardsim - do you have any experience using OpenFIPS201 with jcardsim, or maybe any idea what might be wrong? Here is the whole used script, some insight would be very helpful.
Looking at things from a CMS standpoint, attestation certificates in some form or another help provide assurance that keys were generated on-module. As an example of such a process from the windows server documentation:
Every TPM ships with a unique asymmetric key, called the Endorsement Key (EK), burned by the manufacturer. > We refer to the public portion of this key as EKPub and the associated private key as EKPriv.
Some TPM chips also have an EK certificate that is issued by the manufacturer for the EKPub. We refer to this cert as EKCert.
A CA establishes trust in the TPM either via EKPub or EKCert.
A user proves to the CA that the RSA key for which the certificate is being requested is cryptographically related to the EKPub and that the user owns the EKpriv.
The CA issues a certificate with a special issuance policy OID to denote that the key is now attested to be protected by a TPM.
YubiKey PIV support does something similar by burning in a key and certificate that is used to essentially issue X509 certs for public keys on the YubiKey, with metadata about the slot (PIN and Touch policy) present. This allows card management software to identify the serial number of the token, verify that it was generated within the cryptographic boundary, ensure the appropriate PIN policy is set, and that it is in the appropriate DO (which matters in terms of Windows assumptions with the built-in PIV driver).
There are three specific use cases in which attestation is extremely useful for card issuers.
The first is for organizations that wish to buy or make a batch of cards. These cards would be initialized with an attestation key (exactly like YubiKeys are now), and could be provided to users later for remote personalization. This can greatly aid in legal non-repudiation, as the keys are generated and the certificate issued only after the user has taken physical possession of the card and set the PIN.
The second use is for easy re-keying. Given the industry trends towards shorter certificate and key lifetimes (something the CA/Browser forum enforces for web browsers), users will need to re-key and re-issue certificates more often. Doing so without attestation, however, increases the chance of a user providing a CSR for keys not protected within a hardware cryptographic boundary.
The third use is to assist with compliance requirements. For example, Adobe Trust List (PDF signing) requires:
All end-entity key pairs must:
(a) be generated:
- either by using a trustworthy system, taking all reasonable precautions to prevent any
loss, disclosure, or unauthorized use of the private key, and then securely transferred
in a secure cryptographic hardware device conform to (c) below, or,- directly generated by and stored in such a secure cryptographic hardware device
SSL.com uses YubiKey attestation to allow them to meet these requirements on user-possessed tokens, keyed and re-keyed in the field.
Would some sort of attestation mechanism make sense for OpenFIPS201?
There is currently no way limit what can be done with a given key. For example: Keys 9A, 9C and 9E can be used to perform ECDH as well as ECDSA. This is why the PIV specs talk about ECDSA only for keys 9A, 9C and 9E whereas ECDH is only talked about for keys 04 and 9D. See Table 7-1 of NIST SP 800-78-4.
In general one should use a key for exactly one thing (e.g. key agreement but not signing or vice versa). There is also an attack there using carefully crafted points during an ECDH can compromise a card based private key. Disallowing these attacks on keys where ECDH is not intended improves the security of the keys. Note: Checking for these points is covered in issue #28
I propose that during the creation of the key objects that there be a bit mask that specifies exactly what can be done with a key. Not specifying the mask would allow the key to be used for anything so as to not break any current functionality. Mask elements might include:
private static final short USAGE_SIGN = (short)0b00000001;
private static final short USAGE_VERIFY = (short)0b00000010;
private static final short USAGE_ENCRYPT = (short)0b00000100;
private static final short USAGE_DECRYPT = (short)0b00001000;
private static final short USAGE_KEY_AGREEMENT = (short)0b00010000;
private static final short USAGE_ALL = (short)0b11111111;
When reading the CHUID, it's often not necessary to grab the entire data structure if pre-enrollment has occurred.
SP 800-73-4 Appendix A states "For each container, compliant cards shall return all TLV elements of the container in the order listed in this appendix."
Looking at the Cardholder Unique Identifier, there is one optional element before the FASC-N (2 bytes), a 25-byte FASC-N, 4 bytes of Organizational Identifier, 9 bytes of DUNS, and 16 bytes of GUID at the beginning of the element. Thus, for a compliant card you can get the first 0x38 bytes of the CHUID and have both the FASC-N and GUID. With a pre-enrolled card, and signature verification at enrollment, this is fine. I successfully do this with other cards without issue.
When I attempt to do this with OpenFIPS201 cards, the following operation results in a "Conditions of use not satisfied."
This appears to be a result of ChainBuffer class.
OpenFIPS201/src/com/makina/security/openfips201/ChainBuffer.java
Lines 218 to 224 in 25cb2e6
This does not seem to be correct behaviour as far as I can tell. Is this how the applet is intended to behave?
[=] Session log /Users/mistial/.proxmark3/logs/log_20230328.txt
[+] loaded from JSON file /Users/mistial/.proxmark3/preferences.json
[=] Using UART port /dev/tty.usbmodem101
[=] Communicating with PM3 over USB-CDC
[+] executing commands from file: ec_sign.cmd
[usb|script] pm3 --> hf 14a apdu -stk 00A4040009A0000003080000100000
[+] ( select, keep, TLV )
[+] >>> 00A4040009A0000003080000100000
[+] <<< 61818F4F0BA00000030800001000010079074F05A000000308500B4F70656E464950533230315F5049687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466AC1E80010080010380010880010A80010C8001068001078001118001140601009000 | a..O............y.O......P.OpenFIPS201_PIhttp://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73-4.pdf..................................
[+] <<< status: 90 00 - Command successfully executed (OK).
[=] -------------------- TLV decoded --------------------
[=] --61[8f] 'Application Template':
[=] --4f[0b] 'Application Dedicated File (ADF) Name':
[=] 00: A0 00 00 03 08 00 00 10 00 01 00 | ...........
[=] --79[07] 'Unknown ???':
[=] --4f[05] 'Application Dedicated File (ADF) Name':
[=] 00: A0 00 00 03 08 | .....
[=] --50[0b] 'Application Label': String value '4F70656E46495053323031'
[=] 00: 4F 70 65 6E 46 49 50 53 32 30 31 | OpenFIPS201
[=] --5f50[49] 'Issuer URL': String value '687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466'
[=] 00: 68 74 74 70 3A 2F 2F 6E 76 6C 70 75 62 73 2E 6E | http://nvlpubs.n
[=] 10: 69 73 74 2E 67 6F 76 2F 6E 69 73 74 70 75 62 73 | ist.gov/nistpubs
[=] 20: 2F 53 70 65 63 69 61 6C 50 75 62 6C 69 63 61 74 | /SpecialPublicat
[=] 30: 69 6F 6E 73 2F 4E 49 53 54 2E 53 50 2E 38 30 30 | ions/NIST.SP.800
[=] 40: 2D 37 33 2D 34 2E 70 64 66 | -73-4.pdf
[=] --ac[1e] 'Unknown ???':
[=] --80[01] 'Response Message Template Format 1':
[=] 00: 00 | .
[=] --80[01] 'Response Message Template Format 1':
[=] 00: 03 | .
[=] --80[01] 'Response Message Template Format 1':
[=] 00: 08 | .
[=] --80[01] 'Response Message Template Format 1':
[=] 00: 0A | .
[=] --80[01] 'Response Message Template Format 1':
[=] 00: 0C | .
[=] --80[01] 'Response Message Template Format 1':
[=] 00: 06 | .
[=] --80[01] 'Response Message Template Format 1':
[=] 00: 07 | .
[=] --80[01] 'Response Message Template Format 1':
[=] 00: 11 | .
[=] --80[01] 'Response Message Template Format 1':
[=] 00: 14 | .
[=] -- 6[01] 'Object Identifier (OID)':
[=] 00: 00 | .
[usb|script] pm3 --> hf 14a apdu -k 00CB3FFF055C035FC10238
[+] ( , keep )
[+] >>> 00CB3FFF055C035FC10238
[+] <<< 533B3019D4E739DA739CED39CE739D8360D82108421A9333CCE739A3E13410399990000000105483934F504E5048593508323033373132336105 | S;0...9.s..9.s..`.!.B..3..9..4.9......T..OPNPHY5.2037123a.
[+] <<< status: 61 05 - Command successfully executed; 'XX' bytes of data are available and can be requested using GET RESPONSE.
[usb|script] pm3 --> hf 14a apdu 0087119E267C2482008120000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
[+] ( )
[+] >>> 0087119E267C2482008120000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
[+] <<< 6985 | i.
[+] <<< status: 69 85 - Conditions of use not satisfied.
[usb|script] pm3 --> hf 14a list -u
[=] downloading tracelog data from device
[+] Recorded activity (trace len = 550 bytes)
[=] start = start of start frame end = end of frame. src = source of transfer
[=] ISO14443A - all times are in microseconds
Start | End | Src | Data (! denotes parity error) | CRC | Annotation
------------+------------+-----+-------------------------------------------------------------------------+-----+--------------------
0.0 | 73.2 | Rdr |52(7) | | WUPA
156.0 | 330.7 | Tag |48 00 | |
519.2 | 700.9 | Rdr |93 20 | | ANTICOLL
779.1 | 1213.3 | Tag |88 04 6c 47 a7 | |
1406.5 | 2182.9 | Rdr |93 70 88 04 6c 47 a7 30 01 | ok | SELECT_UID
2261.1 | 2520.6 | Tag |24 d8 36 | |
2624.2 | 2805.9 | Rdr |95 20 | | ANTICOLL-2
2884.1 | 3318.3 | Tag |b2 97 14 90 a1 | |
3511.5 | 4287.9 | Rdr |95 70 b2 97 14 90 a1 99 3b | ok | SELECT_UID-2
4366.1 | 4630.4 | Tag |20 fc 70 | |
4757.5 | 5109.1 | Rdr |e0 80 31 73 | ok | RATS
5206.2 | 6230.4 | Tag |0a 78 77 91 02 80 73 c8 21 10 56 4d | ok |
28903.8 | 30444.8 | Rdr |02 00 a4 04 00 09 a0 00 00 03 08 00 00 10 00 00 b1 70 | ok |
45248.7 | 45248.7 | Tag |02 61 81 8f 4f 0b a0 00 00 03 08 00 00 10 00 01 00 79 | |
| | |07 4f 05 a0 00 00 03 08 50 0b 4f 70 65 6e 46 49 50 53 | |
| | |32 30 31 5f 50 49 68 74 74 70 3a 2f 2f 6e 76 6c 70 75 | |
| | |62 73 2e 6e 69 73 74 2e 67 6f 76 2f 6e 69 73 74 70 75 | |
| | |62 73 2f 53 70 65 63 69 61 6c 50 75 62 6c 69 63 61 74 | |
| | |69 6f 6e 73 2f 4e 49 53 54 2e 53 50 2e 38 30 30 2d 37 | |
| | |33 2d 34 2e 70 64 66 ac 1e 80 01 00 80 01 03 80 01 08 | |
| | |80 01 0a 80 01 0c 80 01 06 80 01 07 80 01 11 80 01 14 | |
| | |06 01 00 90 00 2b c1 | ok |
81642.5 | 82838.9 | Rdr |03 00 cb 3f ff 05 5c 03 5f c1 02 38 a5 0a | ok |
90416.8 | 90416.8 | Tag |03 53 3b 30 19 d4 e7 39 da 73 9c ed 39 ce 73 9d 83 60 | |
| | |d8 21 08 42 1a 93 33 cc e7 39 a3 e1 34 10 39 99 90 00 | |
| | |00 00 10 54 83 93 4f 50 4e 50 48 59 35 08 32 30 33 37 | |
| | |31 32 33 61 05 5c ff | ok |
123638.9 | 127558.7 | Rdr |02 00 87 11 9e 26 7c 24 82 00 81 20 00 01 02 03 04 05 | |
| | |06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 | |
| | |18 19 1a 1b 1c 1d 1e 1f d8 70 | ok |
132205.6 | 132635.1 | Tag |02 69 85 44 71 | |
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?
I am trying to set a virtual card using jcardsim and the OpenFips applet will not load. It appears that jcardsim needs OpenFips.java
to have the public
access modifier.
There should be a mechanism which allows for the use of transactions when performing multi step operations which result in changes to the data managed by the applet.
An example where this may be useful would be when credentials are renewed. The card would generate a new keypair and the service side would form and sign a certificate and write it to the card. This may be done in a not strictly controlled environment (e.g. at a reception desk when issuing a visitor badge) and there may be cases where it fails for any number of reasons (e.g. an issue with a cloud based CA, etc).
gpshell (and others) attempt to read parameters before setting up a secure channel by sending the following APDU
APDU: 80 CA 00 66 00
SW: 66 [... 76 bytes ...] 02 90 00
this works fine with the SecurityDomain Applet, but when the OPENFips201 applet is selected, gpshell gets
APDU: 80 CA 00 66 00
SW: 6E 00
I worked around this by having gpshell cache those data and selecting the SecurityDomain first. What is the expected what to set up the SCP without these data.
I'm also slightly confused about the security properties of the secure channel. With most RSA applets, knowing the key for the security domain only grants the ability to add and remove applets, but in OpenFIPS201, it would appear that the security domain key can be used to reset the admin key, the PIN and the PUK. Is that a deliberate design decision, as it makes loading other applets administered by other parties exceedingly complicated as the ISD key can't be shared.
Public keys are never used by the card application in PIV so there's no need to keep them. They are stored in the corresponding X.509 certificate in any case.
This means:
At present, pre-personalisation can occur post-issuance. In some scenarios it is desirable to lock this down so that the applet filesystem is defined once and then locked:
Suggestion:
Assume we put data to an object of some length La
We then overwrite the object with data of length Lb where Lb < La
A get on the object will return a total of La bytes, the first Lb being those written in the second write the remaining being zeros
There is an attack where using a carefully crafted public key not on the curve can compromise a private key during ECDH. It is unclear if the ECDH implementation in the JCRE does this check or if it is done in all implementations.
I'm recently working on a project that requires attestation of generated keypair public key. Would like to know what is the reason not having R-MAC/ENC supported. Though I do see in documentation said it's not enforced, I wonder if this is simply reusing existing GP libraries. Which would be something looking like:
// STEP 1 - Generate the key pair
PIVKeyObjectPKI keyPair = (PIVKeyObjectPKI) key;
short length = keyPair.generate(scratch, ZERO);
// Added wrapping
SecureChannel sc = GPSystem.getSecureChannel();
byte mask = SecureChannel.AUTHENTICATED | SecureChannel.R_ENCRYPTION | SecureChannel.R_MAC;
if ((sc.getSecurityLevel() & mask) == mask) {
length = sc.wrap(scratch, ZERO, length);
}
I tried this customizing code snippet but the R-MAC value is not correct when receiving the response from the applet. Any suggestion making this work? I can help sending out MRs to get this supported.
Also though PIV spec doesn't specify the authenticity of the key generated, is there a recommended security scheme that how we can generate an signature from the applet as an option when generating keypair? Thanks
SM/VCI/Pairing Code is the next feature to be added and there are a couple of remaining implementation details that I could use some feedback on.
The first point is that the SM CVC is not a Data Object and is used during the General Auth command. This suggests that the CVC is a 'key element' that needs to be injected before the SM key is active. So the key preparation steps I'm implementing are:
There is one issue with this, which is that in SP 800-73-4 4.1.5 it states:
Before signing the CVC the signer shall ....[other stuff] .... and shall verify that the PIV Card is in possession of the corresponding private key.
This suggests that signing functionality is required for this key also. The problem here is that to perform a signing operation you must call GENERAL AUTHENTICATE, passing a CHALLENGE tag with the data to sign and an empty CHALLENGE RESPONSE tag, which is exactly the same structure you would send for SM Key Establishment.
So if the key reference and request structure are identical, how do we tell the difference? The only way I can see to do it is to use the following logic:
@dengert / @dmercer-google any thoughts?
The TLV parser will read nested TLVs beyond the length of their parent container. Consider the nested TLV below:
010108 020100 0303000000
this parses correctly.
Now consider the erroneous TLV below:
010106 020100 0303000000
This also parses with no error despite the length of the top level container being set, erroneously, to 6 vs 8.
We encountered this while reviewing our pre-personalization of the CHUID container. In our case we had changed from 1 byte to 3 byte container IDs but we had neglected to add 2 to the overall container length. Despite the error, pre-provisioning worked fine when it should have failed.
JC 3.0.5 introduced Cipher.OneShot
operations.
Our experience with OneShot
signatures indicates a significant performance boost (40ms+ ???, I don't remember the exact number) when using ECDSA P-256 on one of the chips we target. While 40ms may not seem like much, it does make a difference when using CAK Auth to open doors. We have found that the 40ms reduction in time to open the door has changes the door UX from being a noticeable lag to it being unnoticeable. I guess that that is some human perception threshold thing?
In addition, OneShot
operations may improve memory utilization because of the way state is maintained. We have no data on this but logic would suggest that this is the case.
This will require compiling different source depending on support for OneShot
operations on the card and a build that supports pulling different source depending on various factors (e.g. JC version, chip being targeted, etc.). We have decided that the added build complexity is worth the performance gain.
To make things a bit more complex: I could be wrong but I seem to remember reading that full support for OneShot
ciphers may be optional in JC 3.0.5. That would mean that the build would not only have to take into account the JC version being built but also the particular chip being targeted. One of the chips we target is JC 3.0.5 and compilation with OneShot
works just fine. However, trying to execute operations on said throw because the chip manufacturer has not implemented OneShot
ciphers.
In PIVSecurityProvider.java, lines 307-314 of checkAccessModeAdmin():
//
// ACCESS CONDITION 3 - User Administration Privilege
//
if ((mode != PIVObject.ACCESS_MODE_ALWAYS)
&& ((mode & PIVObject.ACCESS_MODE_USER_ADMIN) == PIVObject.ACCESS_MODE_USER_ADMIN)
&& checkAccessModeObject(object)) {
result = true;
}
This checks that ACCESS_MODE_USER_ADMIN is set when ACCESS_MODE_ALWAYS is not specified. There is no clause that results TRUE when ACCESS_MODE_ALWAYS is set. This means that an object with ACCESS_MODE_ALWAYS will not pass the security check in this method.
Should there be another if() clause for this? e.g.
if(mode == PIVObject.ACCESS_MODE_ALWAYS) {
result = true;
}
Or is this specifically not allowed for the checkAccessModeAdmin() function? I see that it is handled as I would expect in the checkAccessModeObject() method.
The code path that led me to this is from PIV.putData(). I expect that I can call putData() on a PIV object with ACCESS_MODE_ALWAYS and be able to mutate it, but the code is preventing that. Is this a bug or WAI?
The 9C (Digital Signature) key is intended to always be generated on-card for privacy and repudiation purposes. Currently this must be enforced by the card/application management system but it would give higher assurance if this could be enforced by the applet.
Suggestion:
Add a flag to the pre-personalisation file-system flags (KeyRole) to indicate whether a key cannot be injected. If the flag is set, then key injection commands will fail for that key record.
When using the 'Change Reference Data Admin' command to set key part values, it checks if the 'SEQUENCE' element (0x30) is present but then doesn't check that the length of the sequence corresponds to the remaining length of the apdu.
At present, the card must support all cryptographic primitives or the applet will not install.
Instead, it should:
I'm attempting to provision the GSA ICAM golden PIV card to OpenFIPS201. I can successfully enroll to the PIVClass Workstation software (which is generally fairly picky), but the PIVClass reader/PAM is rejecting the use of my imported contactless card authentication (9e) key.
Sniffing the transaction, I get the following:
[usb] pm3 --> hf 14a list
[=] downloading tracelog data from device
[+] Recorded activity (trace len = 1139 bytes)
[=] start = start of start frame end = end of frame. src = source of transfer
[=] ISO14443A - all times are in carrier periods (1/13.56MHz)
Start | End | Src | Data (! denotes parity error) | CRC | Annotation
------------+------------+-----+-------------------------------------------------------------------------+-----+--------------------
0 | 576 | Tag |0f(3) | |
120092 | 121084 | Rdr |52(7) | | WUPA
125520 | 126608 | Tag |fc! | |
159776 | 160480 | Tag |1f(4) | |
28600044 | 28601036 | Rdr |52(7) | | WUPA
28602288 | 28604656 | Tag |48 00 | |
28611372 | 28613836 | Rdr |93 20 | | ANTICOLL
28615024 | 28620912 | Tag |88 04 6f 22 c1 | |
28628716 | 28639180 | Rdr |93 70 88 04 6f 22 c1 89 f3 | ok | SELECT_UID
28640432 | 28643952 | Tag |24 d8 36 | |
28651148 | 28653612 | Rdr |95 20 | | ANTICOLL-2
28654816 | 28660704 | Tag |b2 97 14 90 a1 | |
28668524 | 28679052 | Rdr |95 70 b2 97 14 90 a1 99 3b | ok | SELECT_UID-2
28680256 | 28683840 | Tag |20 fc 70 | |
28691260 | 28696028 | Rdr |e0 80 31 73 | ok | RATS
28697472 | 28711360 | Tag |0a 78 77 91 02 80 73 c8 21 10 56 4d | ok |
28727804 | 28733660 | Rdr |d0 11 00 52 a6 | ok | PPS
28735552 | 28739072 | Tag |d0 73 87 | |
30053228 | 30075276 | Rdr |0a 00 00 a4 04 00 09 a0 00 00 03 08 00 00 10 00 00 a4 | |
| | |c8 | ok |
31136336 | 31136336 | Tag |0a 00 61 81 8f 4f 0b a0 00 00 03 08 00 00 10 00 01 00 | |
| | |79 07 4f 05 a0 00 00 03 08 50 0b 4f 70 65 6e 46 49 50 | |
| | |53 32 30 31 5f 50 49 68 74 74 70 3a 2f 2f 6e 76 6c 70 | |
| | |75 62 73 2e 6e 69 73 74 2e 67 6f 76 2f 6e 69 73 74 70 | |
| | |75 62 73 2f 53 70 65 63 69 61 6c 50 75 62 6c 69 63 61 | |
| | |74 69 6f 6e 73 2f 4e 49 53 54 2e 53 50 2e 38 30 30 2d | |
| | |37 33 2d 34 2e 70 64 66 ac 1e 80 01 00 80 01 03 80 01 | |
| | |08 80 01 0a 80 01 0c 80 01 06 80 01 07 80 01 11 80 01 | |
| | |14 06 01 00 90 00 d2 72 | ok |
32720348 | 32737788 | Rdr |0b 00 00 cb 3f ff 05 5c 03 5f c1 02 00 25 1a | ok |
33125040 | 33125232 | Tag |01(0) | |
33141232 | 33141232 | Tag |1b 00 53 82 08 63 30 19 d1 38 10 d8 28 ab 6c 10 c3 39 | |
| | |e5 a1 68 5a 08 c9 2a de 0a 61 84 e7 39 c3 e7 32 04 31 | |
| | |32 33 34 34 10 7b 13 d0 e6 1f 6e 47 8e a0 aa be 0f 9a | |
| | |d6 4a 6c 35 08 32 30 33 32 31 32 30 32 36 10 db 17 53 | |
| | |91 47 49 4a 32 97 7d 7a 38 43 77 5e 8a 3e 82 08 0e 30 | |
| | |82 08 0a 06 09 2a 86 48 86 f7 0d 01 07 02 a0 82 07 fb | |
| | |30 82 07 f7 02 01 03 31 0f 30 0d 06 09 60 86 48 01 65 | |
| | |03 04 02 01 05 00 30 0a 06 08 60 86 48 01 65 03 06 01 | |
| | |a0 82 05 55 30 82 05 51 30 82 03 b9 a0 03 02 01 02 02 | |
| | |0a 58 53 cc e2 52 18 01 41 20 10 30 0d 06 09 2a 86 48 | |
| | |86 f7 0d 01 01 0b 05 00 30 65 31 0b 30 09 06 03 55 04 | |
| | |06 13 02 55 53 31 00 | !! |
33468908 | 33473676 | Rdr |aa 00 2f 4c | ok |
33569696 | 33581344 | Tag |0a 00 73 31 22 30 61 ff 7e 26 | ok |
39627196 | 39627196 | Rdr |0b 00 10 87 07 9e f0 7c 82 01 06 82 00 81 82 01 00 00 | |
| | |7a 0e 53 fe 2b 04 c3 df 43 72 2d 8c 27 e1 71 53 e4 8f | |
| | |a8 a8 ba 2c ce ee b7 8a 2c e7 fb e4 ab 02 86 9f 71 98 | |
| | |db c4 bd 08 a2 1f 7e db 29 bc 4b e1 fe a7 e7 de 17 67 | |
| | |ce 29 62 4f 0b 42 16 5c ba c7 fd a7 b3 17 63 7c db d3 | |
| | |ed b5 04 4a c4 ee 0d db 48 00 84 b8 d6 83 e5 3f 76 93 | |
| | |bd 0f 3f 0a 63 6e b6 61 48 69 57 3b e0 ca fa 96 65 6f | |
| | |e0 bf 9a ee 32 39 6a ff 0b 28 7a 4d d1 40 1d 92 1d ea | |
| | |be 57 37 00 e7 28 0e 9f 21 4e 6d 95 a8 15 4a 9e 41 b7 | |
| | |aa 5e 15 13 b2 dc 27 39 6b a7 a6 09 c0 e9 99 87 3a 10 | |
| | |d0 c5 c2 4e b4 9c 2b 06 97 be 4b 25 2b 9e 51 c8 f5 cd | |
| | |98 bd de 39 cb 12 dc d5 c8 3b 97 01 83 8b 9c a2 8f aa | |
| | |07 35 11 73 14 5a 74 da 23 16 7f 55 33 3b 90 81 4a 30 | |
| | |d4 01 70 d4 1c 2c 7c 65 aa 09 ed 95 26 00 eb 64 | ok |
40053888 | 40054144 | Tag |00(1) | |
40182496 | 40189536 | Tag |0b 00 69 85 fd f7 | ok |
40742652 | 40784284 | Rdr |0a 00 00 87 07 9e 1a fc 4e f4 0d 45 2e 29 0a ed e1 e4 | |
| | |33 67 4d 15 e2 4a 3e e5 63 4c 49 08 99 0c 80 00 6d d5 | ok |
41143200 | 41143392 | Tag |01(0) | |
41187472 | 41194448 | Tag |0a 00 69 84 cf fa | ok |
I am using the attached configuration script, card objects, and keys:
The objects themselves can be found here: https://github.com/GSA/gsa-icam-card-builder/tree/master/cards/ICAM_Card_Objects/01_Golden_PIV
The configuration script and card provisioning seems to succeed just fine, and some PIV software I have seems to verify. 9E should work from what I see:
print CREATE KEY - 9E - Card Authentication Key (RSA2048)
send_apdu -sc 1 -APDU 00DB3F001466128B019E8C017F8D017F8E01078F0104900110
# 00 DB 3F 00 14
# 66 12
# 8B 01 9E -- slot 9E
# 8C 01 7F -- Contact Always
# 8D 01 7F -- Contactless Always
# 8E 01 07 -- Key Mechanism (RSA-2048)
# 8F 01 04 -- Key Role = Authenticate
# 90 01 10 -- Key Attribute = importable
This should be the private key in use:
openssl pkcs12 -in "6 - ICAM_PIV_Card_Auth_SP_800-73-4.p12" -nodes -nocerts -passin pass: | openssl rsa -inform PEM -text -noout
RSA Private-Key: (2048 bit, 2 primes)
modulus:
00:c1:82:9e:4e:ae:15:56:82:2c:8e:6a:97:e3:bb:
10:25:5b:5e:f2:44:96:b4:e5:56:29:bb:42:6f:38:
10:fb:d3:25:12:73:29:90:8d:98:26:8d:7f:9b:f9:
61:81:9d:63:8a:8d:dc:9e:14:a2:35:5b:8e:85:f7:
e1:78:a7:a5:2b:3e:fb:71:24:5b:6a:35:4c:21:da:
0c:de:99:6d:a3:c9:8a:65:97:91:f3:4e:e9:1a:d2:
24:f0:b7:a7:bb:f6:f5:3b:e8:b6:09:ab:8b:dc:4f:
a0:b4:e1:42:2b:6f:a7:4d:b1:6c:e7:d5:53:cf:a2:
7f:8b:53:d4:f1:e7:8b:9e:10:13:2d:5d:2d:ae:f8:
0b:c6:4a:94:0c:4f:6b:92:cf:ec:60:94:c8:a0:bf:
61:3c:7b:57:0c:50:d7:62:2e:9d:ab:ab:1b:c5:3d:
b6:07:ba:d4:5c:b0:3b:d0:fb:85:19:ef:0d:fa:ea:
6d:80:df:88:6e:a0:78:9b:b6:49:9f:29:51:ee:ad:
63:d1:18:04:13:30:b7:85:80:37:71:ff:b3:02:b0:
a1:cc:b1:8a:71:b7:4d:08:50:a7:17:cc:32:31:08:
10:5c:2b:22:be:91:01:63:23:b2:e2:b5:a2:d3:4e:
6d:a7:12:9c:88:a9:3c:13:09:a8:93:2e:96:c5:c0:
79:87
publicExponent: 65537 (0x10001)
privateExponent:
10:74:90:0b:b6:c7:ff:bc:40:17:b8:3e:c4:51:d2:
f4:aa:49:6f:a6:9f:7e:30:86:5c:34:1d:59:21:d6:
67:e3:b3:a2:57:02:b0:d5:29:9c:15:aa:45:54:36:
93:74:13:d3:e3:6e:60:4e:f6:e0:3c:b1:e8:f8:84:
46:e3:52:ab:53:c6:c3:ff:48:7a:c6:9f:7b:bd:74:
1c:b5:c5:5a:09:38:68:9d:33:ff:11:b5:c6:df:19:
df:12:6f:04:0f:e3:18:be:18:44:c8:3e:b3:74:5e:
01:23:aa:a1:d0:f3:d4:2a:83:4d:4f:99:b9:ed:62:
95:31:82:c9:33:5c:6f:0b:5f:0a:0f:79:25:a8:27:
81:ff:74:13:87:8b:bb:41:3f:ab:d0:ce:83:cb:26:
2d:0a:c6:36:58:20:c7:ad:06:4b:b3:3a:d3:fb:33:
9b:3d:f3:55:b5:2a:49:49:db:59:e7:2d:8e:e9:c8:
d4:7b:42:e2:c1:9d:cc:53:93:80:c6:17:a2:2f:5c:
53:a0:67:49:15:75:a2:c0:30:f6:7e:06:fa:f5:02:
b3:a4:f6:aa:db:3b:27:b8:1a:ba:97:6f:7d:99:1d:
c0:79:d6:a2:ed:46:d8:9b:9f:06:15:2e:79:42:88:
9f:d9:58:d6:df:40:d0:1b:5e:1e:ac:e8:dc:f5:b8:
59
prime1:
00:e2:71:1e:23:c3:cc:99:a1:94:c5:48:26:e8:ff:
c2:66:54:fb:4c:fb:f9:01:57:bf:39:b8:91:4a:cc:
83:9d:34:0e:ea:a7:f8:4d:b5:57:45:da:6e:f1:28:
7a:2a:c6:82:44:e5:9e:49:78:30:d7:df:6f:ef:b9:
f4:a7:fd:34:60:f9:bd:e2:31:e6:4b:bc:89:e7:9c:
a2:e3:1e:2d:50:2d:e5:76:15:fd:38:87:97:ea:36:
05:27:48:f2:6e:fa:c7:a1:b8:28:2b:10:5e:1b:fc:
7a:b6:30:6e:04:6e:f8:ed:43:b2:e9:28:e2:32:1a:
92:b7:97:2b:26:85:45:45:f3
prime2:
00:da:c5:0a:d8:9f:a3:31:5d:f2:ab:4d:fb:9e:6b:
af:d1:6c:45:ba:16:b6:05:d9:c2:2a:98:dd:ad:64:
4b:c7:3e:71:20:33:45:e2:c4:25:6c:ce:c2:d4:ac:
a2:07:9b:4a:44:3b:97:94:3e:25:bd:01:d2:7a:8d:
72:72:2a:38:8a:3b:4f:36:84:78:d5:29:ec:01:18:
e0:19:44:c1:5e:3d:05:b5:66:25:ff:25:85:af:37:
05:26:a9:21:3c:1d:01:4c:e5:88:e9:38:b2:f9:b5:
bd:72:07:aa:37:9d:04:b4:b1:01:af:3a:d7:44:cc:
38:5d:cd:e4:7f:bc:fc:7f:1d
exponent1:
00:a5:71:b6:6e:b5:21:28:e2:78:bb:07:73:7e:6b:
57:92:c2:e6:75:21:e8:95:c5:91:ae:cf:9e:40:43:
5a:aa:22:1d:ff:ee:c7:a9:a7:23:e3:a2:ab:ca:41:
23:b9:5b:1e:54:ce:5b:af:1c:44:bb:84:c1:d9:2a:
49:89:ef:a3:34:73:63:fb:ff:2f:5f:08:9a:cd:81:
91:35:55:98:0f:eb:e8:aa:35:78:b4:b3:c5:17:d7:
6e:3e:7c:ba:bc:c1:37:d8:7d:9f:c3:8f:0a:e3:71:
be:0a:9d:29:d4:cd:6b:cc:96:d9:02:27:df:d4:71:
bb:de:ad:71:56:8c:aa:c7:67
exponent2:
00:b9:eb:5b:1c:5e:0e:c2:95:a4:f6:10:80:16:52:
4e:49:1c:4a:e5:ab:07:66:51:79:c1:d9:c8:0a:e3:
81:c3:02:3e:01:af:91:64:f6:6d:17:db:5f:98:7e:
5d:f5:38:f4:14:a8:d0:59:1b:b7:d6:b9:05:b7:41:
1e:52:07:af:a5:4a:62:37:62:bd:8d:ea:e2:b6:cb:
fd:27:7c:57:19:4f:a2:da:56:c5:53:e0:ff:8b:b8:
a6:98:04:84:4a:22:1c:48:cd:89:5d:2a:e2:6f:75:
14:5b:24:48:74:9a:ec:b4:e2:f9:1b:82:56:10:11:
be:95:79:b5:07:1a:05:3b:c1
coefficient:
77:e8:39:4a:0a:b8:b4:65:03:ec:ee:fa:91:05:57:
c4:eb:48:68:09:17:30:17:70:30:de:b0:39:c9:0d:
82:3e:06:8c:4b:ec:81:06:48:d7:b4:46:28:48:a1:
55:e0:c5:7c:c1:42:b3:98:e1:59:e5:13:50:1f:0b:
07:ea:6a:d8:30:5e:a3:b5:e3:16:0a:ff:7d:6b:b9:
88:1f:00:38:55:b7:05:7e:37:a3:af:d1:7b:97:a5:
85:53:00:bb:e0:93:fb:e3:ec:d5:63:b4:b0:24:02:
2b:45:a5:cb:fc:88:54:7f:f5:be:41:14:6a:b7:fb:
4b:02:95:68:9a:8f:30:66
Pairing with MacOS works, so that should mean that the 9A and 9D RSA keys are working over contact.
The NIST compliant Profile for key objects does not specify any OCC conditions. While I realize that OCC is not currently supported It would be good to address them in the provisioning scripts so that when it is people wont have to change their scripts. Also note my prior two bugs about occ
vs occAlways
and VCI
. This should be added to the profile when addressed, even though they are not yet implemented.
There is a mismatch between the ASN.1 schema provided in the documentation and the actual implementation for importing ECDSA keys:
According to the documentation, the ECC secrect key element eccS should have the tag 0x89, whilst the ECC public key element eccW should have the tag 0x88. When looking at the implementation however, the actual tags used in PIVKeyObjectECC.java are 0x87 and 0x86, corresponding to rsaPQ and rsaDQ, respectively.
Hello,
by running the commands of Appendix - NIST Compliant Profile on a clean installation, the PIN Sequence policy is firstly set to 4:
However, in the next step, the PIN is told to be set to 123456, which will fail with SW_WRONG_DATA, because the in-code variable maxAscending
is calculated to 6:
.
I know that you should respect the configuration when setting PIN, but the documentation suggests we could just run all commands one by one to comply with the NIST profile, which is now incorrect in the first two steps.
Suggested solution: raise the PIN Sequence limit to 7 in the first APDU (Configuration Steps) on the page Appendix - NIST Compliant Profile???
NIST 800-73-4 (and similar wording in older versions) "3.2.1 X.509 Certificate for Digital Signature" says:
"The PKI cryptographic function (see Table 4b) is protected with a โPIN Alwaysโ or โOCC Alwaysโ access rule. In other words, the PIN or OCC data must be submitted and verified every time immediately before a digital signature key operation."
All other PIV cards I have seen interprete "immediately before" to mean no other card commands between the "verify" and the "digital signature key operation".
Reading the the code it appears that other commands can be done between the "verify" and the "digital signature key operation". It appears it is set when the verify is done and reset when the cspPIV.checkAccessModeObject()
is called for keys and data. But this does not cover other card commands such as verify Lc=0, or SELECT AID. (And maybe others.)
Every other PIV card I have seen resets the PIV Always for any APDU to the card. I like your version, but it does not match other cards.
Hello,
under the wiki-page Security-Personalisation it says I have to inject a symmetric key with the APDU
0024039B2230208018101112131415161718191A1B1C1D1E1F2021222324252627
However, when sending that APDU, it returns:
Exception in thread "main" java.lang.IllegalArgumentException: Invalid APDU: length=33, b1=34
at apdu4j.CommandAPDU.parse(CommandAPDU.java:295)
at apdu4j.CommandAPDU.(CommandAPDU.java:85)
at pro.javacard.gp.GPTool.main(GPTool.java:222)
What can I do about that? Tested on both J2E081 and J3D081.
Thanks!
We are unable to build the PIV filesystem.
the command : java -jar gp.jar -d -v -sdaid A000000308000010000100 --mode enc -s "00 DB 3F 00 10 30 0E 8A 01 01 8B 03 5F C1 07 8C 01 7F 8D 01 00"
return 6982 error Code
We use J3H145 NXP and HID Omnikey 3121 card reader.
GlobalPlatformPro v20.01.23-0-g5ad373b
Running on Linux 4.19.0-8-amd64 amd64, Java 1.8.0_292 by AdoptOpenJDK
[] VMware Virtual USB CCID 00 00
SCardConnect("VMware Virtual USB CCID 00 00", T=) -> T=1, 3BDC18FF8191FE1FC38073C821136605036351000250
SCardBeginTransaction("VMware Virtual USB CCID 00 00")
Reader: VMware Virtual USB CCID 00 00
ATR: 3BDC18FF8191FE1FC38073C821136605036351000250
More information about your card:
http://smartcard-atr.appspot.com/parse?ATR=3BDC18FF8191FE1FC38073C821136605036351000250
[DEBUG] GPSession - (I)SD AID: A000000308000010000100
A>> T=1 (4+0011) 00A40400 0B A000000308000010000100 00
A<< (0146+2) (55ms) 61818F4F0BA00000030800001000010079074F05A000000308500B4F70656E464950533230315F5049687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466AC1E80010080010380010880010A80010C800106800107800111800114060100 9000
[TRACE] GPSession - [61]
[TRACE] GPSession - [4F] A000000308000010000100
[TRACE] GPSession - [79]
[TRACE] GPSession - [4F] A000000308
[TRACE] GPSession - [50] 4F70656E46495053323031
[TRACE] GPSession - [5F50] 687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466
[TRACE] GPSession - [AC]
[TRACE] GPSession - [80] 00
[TRACE] GPSession - [80] 03
[TRACE] GPSession - [80] 08
[TRACE] GPSession - [80] 0A
[TRACE] GPSession - [80] 0C
[TRACE] GPSession - [80] 06
[TRACE] GPSession - [80] 07
[TRACE] GPSession - [80] 11
[TRACE] GPSession - [80] 14
[TRACE] GPSession - [06] 00
[WARN] GPSession - No FCI returned to SELECT
Warning: no keys given, using default test key 404142434445464748494A4B4C4D4E4F
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[INFO] GPSession - Using card master keys: ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for null
[TRACE] GPSession - Generated host challenge: 15B6CFB236DC6BF0
A>> T=1 (4+0008) 80500000 08 15B6CFB236DC6BF0 00
A<< (0029+2) (102ms) 00008048009485073469FF030053370E331AC20A14728760D7A5A90244 9000
[DEBUG] GPSession - Host challenge: 15B6CFB236DC6BF0
[DEBUG] GPSession - Card challenge: 53370E331AC20A14
[DEBUG] GPSession - Card reports SCP03 i=00 with key version 255 (0xFF)
[INFO] GPSession - Diversified card keys: ENC=404142434445464748494A4B4C4D4E4F (KCV: 504A77) MAC=404142434445464748494A4B4C4D4E4F (KCV: 504A77) DEK=404142434445464748494A4B4C4D4E4F (KCV: 504A77) for SCP03
[INFO] GPSession - Session keys: ENC=5BCDE70553517CCB0835F8CCA7F0BAE7 MAC=5F41361D3F2FC49EF97308D4898E9D35 RMAC=B70FCCD1452094D1FBE49E07B95FF6B4, card keys=ENC=404142434445464748494A4B4C4D4E4F (KCV: 504A77) MAC=404142434445464748494A4B4C4D4E4F (KCV: 504A77) DEK=404142434445464748494A4B4C4D4E4F (KCV: 504A77) for SCP03
[DEBUG] GPSession - Verified card cryptogram: 728760D7A5A90244
[DEBUG] GPSession - Calculated host cryptogram: 0A4044378F077A50
A>> T=1 (4+0016) 84820300 10 0A4044378F077A50CB4ED26FC2CB0139
A<< (0000+2) (165ms) 9000
A>> T=1 (4+0040) 04DB3F00 28 9D4F051F355F0956B99E4858E4ED4DCE4EAE78C5393DD4F1E41E1FCB8477AB11A9BB28F5D5854CB4
A<< (0000+2) (121ms) 6982
SCardEndTransaction("VMware Virtual USB CCID 00 00")
SCardDisconnect("VMware Virtual USB CCID 00 00", true) tx:97/rx:183
The TLV reader class seems to handle multibyte TLVs correctly when seeking the length field but not when getting a tag.
static short getLength(byte[] data, short offset)
handles multibyte tags correctly when skipping over them to het the length of the TLV.
The problem is that there are only getTag
and getTagShort
methods. There should also be a getTagByteArray
which returns either the full multibyte array or only the actual value with high byte stripped and continuation bits cleared.
The getTag
and getTagShort
methods just assume that you know what you are doing and know the length of the tag and will happily truncate or read beyond the actual tag if requested. IMO, its never a good idea to assume that engineers know what they are doing.
In addition: getTag
and getTagShort
should throw if the tag is not of the appropriate type length. For example:
If the tag is 5FC107. I would expect:
getTag
to throw,getTagShort
to return 0x4107
. Note that the high continuation bit was stripped giving the raw short. Up to you if you choose to strip it or not as long as the behaviour is documented.getTagByteArray
to return new byte[] {0x41, 0x07}
. Again note that continuation but is stripped.Lastly: the various getTagShort
and getTagByteArray
methods should document whether the value returned is with or without the multibyte tag indicator byte and if the continuation bit is set ot not.
I spent a considerable amount of time to understand how the personalization of this applet works, in conjunction with the TestRunner configuration. I'm now stuck at at point, I can't see what's wrong in my setup. GeneralAuthenticate is not working, because I can't succeed to load any key (first is the RSA 9A key).
The card is fully initialized with prePerso, putData and securityPerso.
The relevant part is (sent over SCP) :
# Adding KEY 9A RSA2048
00DB3F001430128A01028B019A8C01018D01008E01078F0104
# Change REFERENCE DATA Key 9A Mechanism = 07, RSA PRIVATE EXPONENT (Part 1 of 2)
1024079AEF3082010483820100745B051384D2F77BDB0B715029E2C37805BFB7B9EFC6FA4C53C089D8D8018727E5158DB6F2B1EC06071CB8EE0F0DE9B0C149B5A655DABD91174168046A3DA70540099167544E7C5360F0EF8F72A4FE2F31E04E335325FABDB4AF19FAC263712039AE193937B164FB9E6F3398E253D98059F98E595E521424E4D1B5D5C95D2C62F04C449F24A2558658493B24A72C8B7785189995E53284A1E3E62FE01E4B80D732F1BC7BE6010FFD59FE9D9CD71CB31F4B5A50FAC3280F9D405E987572E61DDCEB28BA57F29C11EA548CF957AF1A2D74EBB795AE01DE443B5401B73A61756B102F1E0EB37A0955
# Part 2 of 2
0024079A19CAF9DF11475A12F33D839037B58C8921540979633239785801
# Change REFERENCE DATA Key 9A Mechanism = 07, RSA MODULUS (Part 1 of 2)
1024079AEF3082010481820100A0484891B95A13CB951C592B6893A2FD988E8ECBA6FBE0F01AEE356DBC8EE947650472EA9B9E88EE953724B0E13324CC460CF38F476BADC209D4008C424DA9D5F027021D376EC35B5FB76CF42C88CEBBDB684D970F12CCD648D1758730D93BCFD87952635B721977BB5AF8146FA5682730FF662A832EB81B2AF40C17EE05B69199C5F3ECC364DECB5B05B1039E8FA4E4B2E6754949432618CC702034AF411D80D478842DC9ED84BEEE658AD570E06039B2D35BBB120FA2CFB13482592A181F68A1D18C81501DDD209D2017616EA3BD8A3ED37C1CE48A5AD5E23E0A4D793D2130FB02CBE8D998EF
# Part 2 of 2
0024079A19BC25B61263D58F44FEEBC36A336F691F6EFABC488480394C59
# Change REFERENCE DATA Key 9A Mechanism = 07, RSA PUBLIC EXPONENT
0024079A0730058203010001
Here the session full log relative to the 9A key "07" loading (RSA 2048) :
CHANGE REFERENCE DATA - Key = 9A, Mechanism = 07 (RSA PRIVATE EXPONENT) (Part 1 of 2)
-> 1024079AEF3082010483820100745B051384D2F77BDB0B715029E2C37805BFB7B9EFC6FA4C53C089D8D8018727E5158DB6F2B1EC06071CB8EE0F0DE9B0C149B5A655DABD91174168046A3DA70540099167544E7C5360F0EF8F72A4FE2F31E04E335325FABDB4AF19FAC263712039AE193937B164FB9E6F3398E253D98059F98E595E521424E4D1B5D5C95D2C62F04C449F24A2558658493B24A72C8B7785189995E53284A1E3E62FE01E4B80D732F1BC7BE6010FFD59FE9D9CD71CB31F4B5A50FAC3280F9D405E987572E61DDCEB28BA57F29C11EA548CF957AF1A2D74EBB795AE01DE443B5401B73A61756B102F1E0EB37A0955
GlobalPlatformPro v20.01.23-0-g5ad373b
Running on Windows 10 10.0 amd64, Java 1.8.0_241 by Oracle Corporation
# Detected readers from JNA2PCSC
[*] Smart Card Reader
SCardConnect("Smart Card Reader", T=*) -> T=1, 3BFE6700008131FE45FF43727970746E6F7820436172644C
SCardBeginTransaction("Smart Card Reader")
[DEBUG] GPSession - (I)SD AID: A000000308000010000100
A>> T=1 (4+0011) 00A40400 0B A000000308000010000100 00
A<< (0146+2) (32ms) 61818F4F0BA00000030800001000010079074F05A000000308500B4F70656E464950533230315F5049687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466AC1E80010080010380010880010A80010C800106800107800111800114060100 9000
[TRACE] GPSession - [61]
[TRACE] GPSession - [4F] A000000308000010000100
[TRACE] GPSession - [79]
[TRACE] GPSession - [4F] A000000308
[TRACE] GPSession - [50] 4F70656E46495053323031
[TRACE] GPSession - [5F50] 687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466
[TRACE] GPSession - [AC]
[TRACE] GPSession - [80] 00
[TRACE] GPSession - [80] 03
[TRACE] GPSession - [80] 08
[TRACE] GPSession - [80] 0A
[TRACE] GPSession - [80] 0C
[TRACE] GPSession - [80] 06
[TRACE] GPSession - [80] 07
[TRACE] GPSession - [80] 11
[TRACE] GPSession - [80] 14
[TRACE] GPSession - [06] 00
[WARN] GPSession - No FCI returned to SELECT
Warning: no keys given, using default test key 404142434445464748494A4B4C4D4E4F
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[INFO] GPSession - Using card master keys: ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for null
[TRACE] GPSession - Generated host challenge: ECF3F8968684E1B3
A>> T=1 (4+0008) 80500000 08 ECF3F8968684E1B3 00
A<< (0028+2) (51ms) 000093265160639940790102057DA375B645EBD34D4DCFC8169936F0 9000
[DEBUG] GPSession - Host challenge: ECF3F8968684E1B3
[DEBUG] GPSession - Card challenge: 057DA375B645EBD3
[DEBUG] GPSession - Card reports SCP02 with key version 1 (0x01)
[INFO] GPSession - Diversified card keys: ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for SCP02
[INFO] GPSession - Session keys: ENC=3ADD7E394FB42BD29268FC3081199A27 MAC=E0039ABE2AC6EA5386CF90758F6025B4 RMAC=0C8ADE6FA99888652828B2E7A84B4E60, card keys=ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for SCP02
[DEBUG] GPSession - Verified card cryptogram: 4D4DCFC8169936F0
[DEBUG] GPSession - Calculated host cryptogram: F8F9A16146ED3414
[TRACE] SCP02Wrapper - MAC input: 8482030010F8F9A16146ED3414
A>> T=1 (4+0016) 84820300 10 F8F9A16146ED341439E6162178FB2707
A<< (0000+2) (28ms) 9000
[TRACE] SCP02Wrapper - MAC input: 1424079AF73082010483820100745B051384D2F77BDB0B715029E2C37805BFB7B9EFC6FA4C53C089D8D8018727E5158DB6F2B1EC06071CB8EE0F0DE9B0C149B5A655DABD91174168046A3DA70540099167544E7C5360F0EF8F72A4FE2F31E04E335325FABDB4AF19FAC263712039AE193937B164FB9E6F3398E253D98059F98E595E521424E4D1B5D5C95D2C62F04C449F24A2558658493B24A72C8B7785189995E53284A1E3E62FE01E4B80D732F1BC7BE6010FFD59FE9D9CD71CB31F4B5A50FAC3280F9D405E987572E61DDCEB28BA57F29C11EA548CF957AF1A2D74EBB795AE01DE443B5401B73A61756B102F1E0EB37A0955
A>> T=1 (4+0248) 1424079A F8 CD51AA108FF9321FA1C42AE23243149230B45318567217C1C11982771B09E8F7B494CAED17979CFD17412676B7936C1A1B43FB161C0C783EB8C565B5D135AD659352FA741A0EAAE65665E291366EE4FA1164213BA40F4AC5BC49CF8822C4C912C2CF42659D314244F20967052CE8ADA22CC14B10DD2E5F388B1DED3FD3FEF448B8A31FFDC7870451D0A5A9F5C6B04DC9043E0586BFF45A2A08897781D38A125E2459F556CB7BAEC483A83EB1DE08499DA096512970488F62C7F0DF83B3ED8F2B046E7B79ABEEBBD91BB0879AE838AC519DD98426C748666618B75FE56829B087E929EE93B18045B090B22BBA10E64C48F482A68E0019B1D2
A<< (0000+2) (41ms) 9000
SCardEndTransaction("Smart Card Reader")
SCardDisconnect("Smart Card Reader", true) tx:305/rx:182
CHANGE REFERENCE DATA - Key = 9A, Mechanism = 07 (RSA PRIVATE EXPONENT) (Part 2 of 2)
-> 0024079A19CAF9DF11475A12F33D839037B58C8921540979633239785801
GlobalPlatformPro v20.01.23-0-g5ad373b
Running on Windows 10 10.0 amd64, Java 1.8.0_241 by Oracle Corporation
# Detected readers from JNA2PCSC
[*] Smart Card Reader
SCardConnect("Smart Card Reader", T=*) -> T=1, 3BFE6700008131FE45FF43727970746E6F7820436172644C
SCardBeginTransaction("Smart Card Reader")
[DEBUG] GPSession - (I)SD AID: A000000308000010000100
A>> T=1 (4+0011) 00A40400 0B A000000308000010000100 00
A<< (0146+2) (32ms) 61818F4F0BA00000030800001000010079074F05A000000308500B4F70656E464950533230315F5049687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466AC1E80010080010380010880010A80010C800106800107800111800114060100 9000
[TRACE] GPSession - [61]
[TRACE] GPSession - [4F] A000000308000010000100
[TRACE] GPSession - [79]
[TRACE] GPSession - [4F] A000000308
[TRACE] GPSession - [50] 4F70656E46495053323031
[TRACE] GPSession - [5F50] 687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466
[TRACE] GPSession - [AC]
[TRACE] GPSession - [80] 00
[TRACE] GPSession - [80] 03
[TRACE] GPSession - [80] 08
[TRACE] GPSession - [80] 0A
[TRACE] GPSession - [80] 0C
[TRACE] GPSession - [80] 06
[TRACE] GPSession - [80] 07
[TRACE] GPSession - [80] 11
[TRACE] GPSession - [80] 14
[TRACE] GPSession - [06] 00
[WARN] GPSession - No FCI returned to SELECT
Warning: no keys given, using default test key 404142434445464748494A4B4C4D4E4F
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[INFO] GPSession - Using card master keys: ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for null
[TRACE] GPSession - Generated host challenge: 4F7A7111C5AEA6ED
A>> T=1 (4+0008) 80500000 08 4F7A7111C5AEA6ED 00
A<< (0028+2) (51ms) 000093265160639940790102057E5805BBBB338CDB5EC604DDBF224B 9000
[DEBUG] GPSession - Host challenge: 4F7A7111C5AEA6ED
[DEBUG] GPSession - Card challenge: 057E5805BBBB338C
[DEBUG] GPSession - Card reports SCP02 with key version 1 (0x01)
[INFO] GPSession - Diversified card keys: ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for SCP02
[INFO] GPSession - Session keys: ENC=463FD50C999A029544A4A54F3F1D7F9B MAC=778F37A6588A50DCB776EDB22B5DF8FC RMAC=10CE2113F6FFD07587104741047798CC, card keys=ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for SCP02
[DEBUG] GPSession - Verified card cryptogram: DB5EC604DDBF224B
[DEBUG] GPSession - Calculated host cryptogram: 1FAD35C73685CCBB
[TRACE] SCP02Wrapper - MAC input: 84820300101FAD35C73685CCBB
A>> T=1 (4+0016) 84820300 10 1FAD35C73685CCBB133873EE97C4653F
A<< (0000+2) (27ms) 9000
[TRACE] SCP02Wrapper - MAC input: 0424079A21CAF9DF11475A12F33D839037B58C8921540979633239785801
A>> T=1 (4+0040) 0424079A 28 3001582EDFA322864A9E24C985A4C804C825D104F53045E892A322B5CEB637E88606A3889693680C
A<< (0000+2) (21ms) 6A88
SCardEndTransaction("Smart Card Reader")
SCardDisconnect("Smart Card Reader", true) tx:97/rx:182
CHANGE REFERENCE DATA - Key = 9A, Mechanism = 07 (RSA MODULUS) (Part 1 of 2)
-> 1024079AEF3082010481820100A0484891B95A13CB951C592B6893A2FD988E8ECBA6FBE0F01AEE356DBC8EE947650472EA9B9E88EE953724B0E13324CC460CF38F476BADC209D4008C424DA9D5F027021D376EC35B5FB76CF42C88CEBBDB684D970F12CCD648D1758730D93BCFD87952635B721977BB5AF8146FA5682730FF662A832EB81B2AF40C17EE05B69199C5F3ECC364DECB5B05B1039E8FA4E4B2E6754949432618CC702034AF411D80D478842DC9ED84BEEE658AD570E06039B2D35BBB120FA2CFB13482592A181F68A1D18C81501DDD209D2017616EA3BD8A3ED37C1CE48A5AD5E23E0A4D793D2130FB02CBE8D998EF
GlobalPlatformPro v20.01.23-0-g5ad373b
Running on Windows 10 10.0 amd64, Java 1.8.0_241 by Oracle Corporation
# Detected readers from JNA2PCSC
[*] Smart Card Reader
SCardConnect("Smart Card Reader", T=*) -> T=1, 3BFE6700008131FE45FF43727970746E6F7820436172644C
SCardBeginTransaction("Smart Card Reader")
[DEBUG] GPSession - (I)SD AID: A000000308000010000100
A>> T=1 (4+0011) 00A40400 0B A000000308000010000100 00
A<< (0146+2) (32ms) 61818F4F0BA00000030800001000010079074F05A000000308500B4F70656E464950533230315F5049687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466AC1E80010080010380010880010A80010C800106800107800111800114060100 9000
[TRACE] GPSession - [61]
[TRACE] GPSession - [4F] A000000308000010000100
[TRACE] GPSession - [79]
[TRACE] GPSession - [4F] A000000308
[TRACE] GPSession - [50] 4F70656E46495053323031
[TRACE] GPSession - [5F50] 687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466
[TRACE] GPSession - [AC]
[TRACE] GPSession - [80] 00
[TRACE] GPSession - [80] 03
[TRACE] GPSession - [80] 08
[TRACE] GPSession - [80] 0A
[TRACE] GPSession - [80] 0C
[TRACE] GPSession - [80] 06
[TRACE] GPSession - [80] 07
[TRACE] GPSession - [80] 11
[TRACE] GPSession - [80] 14
[TRACE] GPSession - [06] 00
[WARN] GPSession - No FCI returned to SELECT
Warning: no keys given, using default test key 404142434445464748494A4B4C4D4E4F
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[INFO] GPSession - Using card master keys: ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for null
[TRACE] GPSession - Generated host challenge: 89B3E037EDE87816
A>> T=1 (4+0008) 80500000 08 89B3E037EDE87816 00
A<< (0028+2) (50ms) 000093265160639940790102057F443EA38261A873E84B76D2A1970B 9000
[DEBUG] GPSession - Host challenge: 89B3E037EDE87816
[DEBUG] GPSession - Card challenge: 057F443EA38261A8
[DEBUG] GPSession - Card reports SCP02 with key version 1 (0x01)
[INFO] GPSession - Diversified card keys: ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for SCP02
[INFO] GPSession - Session keys: ENC=2B76742DEAA2A5103810A045087110DC MAC=46957A34959EFCACEF660BA0104BD79A RMAC=B662B5B4EF5FA1A592F666BDC596AE66, card keys=ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for SCP02
[DEBUG] GPSession - Verified card cryptogram: 73E84B76D2A1970B
[DEBUG] GPSession - Calculated host cryptogram: 4F68FC7390859A5C
[TRACE] SCP02Wrapper - MAC input: 84820300104F68FC7390859A5C
A>> T=1 (4+0016) 84820300 10 4F68FC7390859A5C20E734CEB9105808
A<< (0000+2) (27ms) 9000
[TRACE] SCP02Wrapper - MAC input: 1424079AF73082010481820100A0484891B95A13CB951C592B6893A2FD988E8ECBA6FBE0F01AEE356DBC8EE947650472EA9B9E88EE953724B0E13324CC460CF38F476BADC209D4008C424DA9D5F027021D376EC35B5FB76CF42C88CEBBDB684D970F12CCD648D1758730D93BCFD87952635B721977BB5AF8146FA5682730FF662A832EB81B2AF40C17EE05B69199C5F3ECC364DECB5B05B1039E8FA4E4B2E6754949432618CC702034AF411D80D478842DC9ED84BEEE658AD570E06039B2D35BBB120FA2CFB13482592A181F68A1D18C81501DDD209D2017616EA3BD8A3ED37C1CE48A5AD5E23E0A4D793D2130FB02CBE8D998EF
A>> T=1 (4+0248) 1424079A F8 93BC9E7BFF48EF6B6A7FA4952A7F49E59D2BE3ACE96D3FBF6EC0B94B3E2F15B9023388ED811B2BFADEFE398D1917D589ED63955DFB5652DA147A0B4F9AC1F3C0710E6C74E4FCFC56AFD94CBD45E26ABCEBC5450DE836CC10168913C443DCCEA274DC618C50500292F7B5CF72497CC123A96E395FEB11E1D0944E5F7D3FD94DDC4B7F0824B4D2201CF678E148B044A550B458011BDCB781BD3F83C5BD92A4FBBD5D2007C4E316BA71528CCAA29CC9A188CC912343EAAAE3E289547B85A9A07F8B0123D2B15425FB8F5AC2E9D4ACA9BCCCEA2FA5996FC7F7ABB224135106A3F3A1F3BBECD5602E0FA06D778F9A927F23154EE074818E27C04D
A<< (0000+2) (41ms) 9000
SCardEndTransaction("Smart Card Reader")
SCardDisconnect("Smart Card Reader", true) tx:305/rx:182
CHANGE REFERENCE DATA - Key = 9A, Mechanism = 07 (RSA MODULUS) (Part 2 of 2)
-> 0024079A19BC25B61263D58F44FEEBC36A336F691F6EFABC488480394C59
GlobalPlatformPro v20.01.23-0-g5ad373b
Running on Windows 10 10.0 amd64, Java 1.8.0_241 by Oracle Corporation
# Detected readers from JNA2PCSC
[*] Smart Card Reader
SCardConnect("Smart Card Reader", T=*) -> T=1, 3BFE6700008131FE45FF43727970746E6F7820436172644C
SCardBeginTransaction("Smart Card Reader")
[DEBUG] GPSession - (I)SD AID: A000000308000010000100
A>> T=1 (4+0011) 00A40400 0B A000000308000010000100 00
A<< (0146+2) (32ms) 61818F4F0BA00000030800001000010079074F05A000000308500B4F70656E464950533230315F5049687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466AC1E80010080010380010880010A80010C800106800107800111800114060100 9000
[TRACE] GPSession - [61]
[TRACE] GPSession - [4F] A000000308000010000100
[TRACE] GPSession - [79]
[TRACE] GPSession - [4F] A000000308
[TRACE] GPSession - [50] 4F70656E46495053323031
[TRACE] GPSession - [5F50] 687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466
[TRACE] GPSession - [AC]
[TRACE] GPSession - [80] 00
[TRACE] GPSession - [80] 03
[TRACE] GPSession - [80] 08
[TRACE] GPSession - [80] 0A
[TRACE] GPSession - [80] 0C
[TRACE] GPSession - [80] 06
[TRACE] GPSession - [80] 07
[TRACE] GPSession - [80] 11
[TRACE] GPSession - [80] 14
[TRACE] GPSession - [06] 00
[WARN] GPSession - No FCI returned to SELECT
Warning: no keys given, using default test key 404142434445464748494A4B4C4D4E4F
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[INFO] GPSession - Using card master keys: ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for null
[TRACE] GPSession - Generated host challenge: D8C948C6A61EEA2C
A>> T=1 (4+0008) 80500000 08 D8C948C6A61EEA2C 00
A<< (0028+2) (51ms) 00009326516063994079010205807CBE9D3BF026E625F4E72602BF0B 9000
[DEBUG] GPSession - Host challenge: D8C948C6A61EEA2C
[DEBUG] GPSession - Card challenge: 05807CBE9D3BF026
[DEBUG] GPSession - Card reports SCP02 with key version 1 (0x01)
[INFO] GPSession - Diversified card keys: ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for SCP02
[INFO] GPSession - Session keys: ENC=71758AE9CE747312FC70C89DD6FA3E98 MAC=A3090CE14165EC6B026100B08D9C2C78 RMAC=0E55F723C6F2894A401EDDF9229688A5, card keys=ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for SCP02
[DEBUG] GPSession - Verified card cryptogram: E625F4E72602BF0B
[DEBUG] GPSession - Calculated host cryptogram: 1996D3230B5C2BEC
[TRACE] SCP02Wrapper - MAC input: 84820300101996D3230B5C2BEC
A>> T=1 (4+0016) 84820300 10 1996D3230B5C2BEC4A38939A6793BFE9
A<< (0000+2) (28ms) 9000
[TRACE] SCP02Wrapper - MAC input: 0424079A21BC25B61263D58F44FEEBC36A336F691F6EFABC488480394C59
A>> T=1 (4+0040) 0424079A 28 5446D24B5E6A1F9978A4144D2F419A5432F563D171401977B8F517A361065D0908335D65E5545363
A<< (0000+2) (22ms) 6A88
SCardEndTransaction("Smart Card Reader")
SCardDisconnect("Smart Card Reader", true) tx:97/rx:182
CHANGE REFERENCE DATA - Key = 9A, Mechanism = 07 (RSA PUBLIC EXPONENT)
-> 0024079A0730058203010001
GlobalPlatformPro v20.01.23-0-g5ad373b
Running on Windows 10 10.0 amd64, Java 1.8.0_241 by Oracle Corporation
# Detected readers from JNA2PCSC
[*] Smart Card Reader
SCardConnect("Smart Card Reader", T=*) -> T=1, 3BFE6700008131FE45FF43727970746E6F7820436172644C
SCardBeginTransaction("Smart Card Reader")
[DEBUG] GPSession - (I)SD AID: A000000308000010000100
A>> T=1 (4+0011) 00A40400 0B A000000308000010000100 00
A<< (0146+2) (32ms) 61818F4F0BA00000030800001000010079074F05A000000308500B4F70656E464950533230315F5049687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466AC1E80010080010380010880010A80010C800106800107800111800114060100 9000
[TRACE] GPSession - [61]
[TRACE] GPSession - [4F] A000000308000010000100
[TRACE] GPSession - [79]
[TRACE] GPSession - [4F] A000000308
[TRACE] GPSession - [50] 4F70656E46495053323031
[TRACE] GPSession - [5F50] 687474703A2F2F6E766C707562732E6E6973742E676F762F6E697374707562732F5370656369616C5075626C69636174696F6E732F4E4953542E53502E3830302D37332D342E706466
[TRACE] GPSession - [AC]
[TRACE] GPSession - [80] 00
[TRACE] GPSession - [80] 03
[TRACE] GPSession - [80] 08
[TRACE] GPSession - [80] 0A
[TRACE] GPSession - [80] 0C
[TRACE] GPSession - [80] 06
[TRACE] GPSession - [80] 07
[TRACE] GPSession - [80] 11
[TRACE] GPSession - [80] 14
[TRACE] GPSession - [06] 00
[WARN] GPSession - No FCI returned to SELECT
Warning: no keys given, using default test key 404142434445464748494A4B4C4D4E4F
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[WARN] PlaintextKeys - Don't know how to calculate KCV, defaulting to SCP02
[INFO] GPSession - Using card master keys: ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for null
[TRACE] GPSession - Generated host challenge: 1D687DA7F557E13B
A>> T=1 (4+0008) 80500000 08 1D687DA7F557E13B 00
A<< (0028+2) (51ms) 000093265160639940790102058186BDF409FE6E3692436F7821CBE0 9000
[DEBUG] GPSession - Host challenge: 1D687DA7F557E13B
[DEBUG] GPSession - Card challenge: 058186BDF409FE6E
[DEBUG] GPSession - Card reports SCP02 with key version 1 (0x01)
[INFO] GPSession - Diversified card keys: ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for SCP02
[INFO] GPSession - Session keys: ENC=1BE44E6E6CFEFD8894641F989465D09A MAC=C9254BFE68B5CFB4237A294485E9BD27 RMAC=74C88CCD1CF1F06E001CEAA3533AB292, card keys=ENC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) MAC=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) DEK=404142434445464748494A4B4C4D4E4F (KCV: 8BAF47) for SCP02
[DEBUG] GPSession - Verified card cryptogram: 3692436F7821CBE0
[DEBUG] GPSession - Calculated host cryptogram: 962EFDFBD3FBE065
[TRACE] SCP02Wrapper - MAC input: 8482030010962EFDFBD3FBE065
A>> T=1 (4+0016) 84820300 10 962EFDFBD3FBE0655BCE42408BCF2F46
A<< (0000+2) (28ms) 9000
[TRACE] SCP02Wrapper - MAC input: 0424079A0F30058203010001
A>> T=1 (4+0016) 0424079A 10 4B1D9AFCAB7872DE7F6ECC923AFC541B
A<< (0000+2) (19ms) 6A88
So when the card gets 0024 data, it replies with 0x6A88.
Any idea why the card is repling this? What's wrong?
One of the most significant requirements of FIPS 140 is that when submitting for accreditation, you must submit a specific combination of software, hardware and configuration, which becomes the accredited profile. Any change to these effectively becomes a non-accredited profile.
Currently, OpenFIPS201 has many configuration elements that are compile-time. This made sense at the time has advantages in allowing the compiler to ignore code that will never be used, but it also means even changes to things like PIN requirements require a recompile.
The aim now is to take many of the FEATURE_ and similar configuration constants that are in Config.java and convert them into parameters that can be set via administrative PUT DATA and GET DATA commands (extending the current pre-personalisation interface).
There is also an option to lock this configuration when the applet life-cycle changes to PERSONALISED (see issue #26).
Also in [OpenSC's issues as #1274] (OpenSC/OpenSC#1274)
with current OpenSC master 1d4f59ea51dd1713a3b99186498cb8fe074abc4c and current master of OpenFIPS201 580bb5cd36c41c38d38eb86c985f05dbd38be0d5 opensc is unable to read the certificates on the card
OpenSC send INS_PIV_GET_DATA to read the certificate from the card
APDU: 00 CB 3F FF 05 5C 03 5F C1 05 08
and the card responds with
SW: 53 82 02 A4 70 82 02 9B 61 FF
as card-piv.c is only probing for the length of the file at this point it doesn't want to read the whole
certificate, and as SC_APDU_FLAGS_NO_GET_RESP in apdu.flags is set, sc_transmit_apdu doesn't read the rest of the data.
the next apdu opensc sends attempts to read the certificate in full.
APDU: 00 CB 3F FF 05 5C 03 5F C1 02 08
but the card is still waiting for opensc to complete reading the previous INS_PIV_GET_DATA and so responds with
SW: 68 83 (SW_LAST_COMMAND_EXPECTED)
OpenSC then assumes the slot is empty as it failed to read the cert
with the attached patch opensc completes the first read in full
APDU: 00 CB 3F FF 05 5C 03 5F C1 05 08
SW: 53 82 02 A4 70 82 02 9B 61 FF
APDU: 00 C0 00 00 FF
SW: 30 ... 61 FF
APDU: 00 C0 00 00 FF
SW: 5B ... 61 A2
APDU: 00 C0 00 00 FF
SW: 4A ... 90 00
and the subsequent read now succeeds.
APDU: 00 CB 3F FF 05 5C 03 5F C1 05 00
SW: 53 .. 61 FF
etc.
If this is a bug in OpenSC rather than an implementation error in OpenFIPS201 then the following patch fixes it. Although the solution is not optimal, as it causes lots of data to be read twice over the
slow smartcard interface.
--- opensc-0.17.1.orig/src/libopensc/apdu.c +++ opensc-0.17.1/src/libopensc/apdu.c @@ -424,7 +424,7 @@ sc_set_le_and_transmit(struct sc_card *c static int -sc_get_response(struct sc_card *card, struct sc_apdu *apdu, size_t olen) +sc_get_response(struct sc_card *card, struct sc_apdu *apdu, size_t olen, int complete_reads) { struct sc_context *ctx = card->ctx; size_t le, minlen, buflen; @@ -497,6 +497,11 @@ sc_get_response(struct sc_card *card, st le = minlen; } while (rv != 0 && minlen != 0); + while ( complete_reads && (rv > 0)) { + unsigned char resp[256]; + size_t resp_len; + rv=card->ops->get_response(card, &resp_len, resp); + } /* we've read all data, let's return 0x9000 */ apdu->resplen = buf - apdu->resp; apdu->sw1 = 0x90; @@ -512,7 +517,7 @@ sc_get_response(struct sc_card *card, st * @return SC_SUCCESS on success and an error value otherwise */ static int -sc_transmit(sc_card_t *card, sc_apdu_t *apdu) +sc_transmit(sc_card_t *card, sc_apdu_t *apdu, int complete_reads) { struct sc_context *ctx = card->ctx; size_t olen = apdu->resplen; @@ -536,8 +541,8 @@ sc_transmit(sc_card_t *card, sc_apdu_t * * Unless the SC_APDU_FLAGS_NO_GET_RESP is set we try to read as * much data as possible using GET RESPONSE. */ - if (apdu->sw1 == 0x61 && (apdu->flags & SC_APDU_FLAGS_NO_GET_RESP) == 0) - r = sc_get_response(card, apdu, olen); + if (apdu->sw1 == 0x61 && (((apdu->flags & SC_APDU_FLAGS_NO_GET_RESP) == 0) || complete_reads)) + r = sc_get_response(card, apdu, olen, complete_reads); LOG_TEST_RET(ctx, r, "cannot get all data with 'GET RESPONSE'"); LOG_FUNC_RETURN(ctx, SC_SUCCESS); @@ -609,7 +614,7 @@ int sc_transmit_apdu(sc_card_t *card, sc break; } - r = sc_transmit(card, &tapdu); + r = sc_transmit(card, &tapdu, 1); if (r != SC_SUCCESS) break; if (last != 0) { @@ -629,7 +634,7 @@ int sc_transmit_apdu(sc_card_t *card, sc } } else /* transmit single APDU */ - r = sc_transmit(card, apdu); + r = sc_transmit(card, apdu, 0); /* all done => release lock */ if (sc_unlock(card) != SC_SUCCESS) sc_log(card->ctx, "sc_unlock failed");
Build and install OpenFIPS201 on a smartcard (I had to s/RSAPrivateKey/RSAPrivateCRTKey/g s/ALG_RSA/ALG_RSA_CRT/g to get it to work on a J3A081 ), use the example script to populate the PIV objects. Inject a Key for 9B. Then use yubico-piv-tool to populate slot 9a with a key and selfsigned certitifcate. Finally run
root@box:~# pkcs11-tool --type cert --list-objects Using slot with index 2 (0x8)
with the above patch
root@box:~# pkcs11-tool --type cert --list-objects Using slot with index 2 (0x8) Certificate Object; type = X.509 cert label: Certificate for PIV Authentication ID: 01
0x7f1a6ef58700 15:34:45.688 [opensc-pkcs11] pkcs15.c:2344:sc_pkcs15_read_file: called
0x7f1a6ef58700 15:34:45.688 [opensc-pkcs11] pkcs15.c:2345:sc_pkcs15_read_file: path=0101cece, index=0, count=-1
[...]
0x7f1a6ef58700 15:34:45.688 [opensc-pkcs11] reader-pcsc.c:284:pcsc_transmit:
Outgoing APDU (11 bytes):
00 CB 3F FF 05 5C 03 5F C1 05 08 ..?..\._...
0x7f1a6ef58700 15:34:45.688 [opensc-pkcs11] reader-pcsc.c:212:pcsc_internal_transmit: called
0x7f1a6ef58700 15:34:45.708 [opensc-pkcs11] reader-pcsc.c:293:pcsc_transmit:
Incoming APDU (10 bytes):
53 82 02 A4 70 82 02 9B 61 FF S...p...a.
0x7f1a6ef58700 15:34:45.708 [opensc-pkcs11] apdu.c:390:sc_single_transmit: returning with: 0 (Success)
[...]
0x7f1a6ef58700 15:34:45.708 [opensc-pkcs11] reader-pcsc.c:284:pcsc_transmit:
Outgoing APDU (11 bytes):
00 CB 3F FF 05 5C 03 5F C1 05 00 ..?..\._...
0x7f1a6ef58700 15:34:45.708 [opensc-pkcs11] reader-pcsc.c:212:pcsc_internal_transmit: called
0x7f1a6ef58700 15:34:45.720 [opensc-pkcs11] reader-pcsc.c:293:pcsc_transmit:
Incoming APDU (2 bytes):
68 83 h.
0x7f1a6ef58700 15:34:45.720 [opensc-pkcs11] apdu.c:390:sc_single_transmit: returning with: 0 (Success)
Since we now require 3.0.4 JCRE, it seems unlikely that we will not have support for garbage collection.
Looking at JCAlgTest, the only unsupported 3.x cards are JCardSim (though some are missing from this list).
The pro of this is that it could simplify object management code and unit testing.
The con is obviously if there are 3.x cards that don't support it so feedback is helpful if this is a known case.
If implemented, it would mean checking for this at install and failing if it isn't.
At present, in pre-perso you can define a key multiple times with different mechanisms. This is great because you may have a need to choose at perso which one you want, however there doesn't seem to be a point in allowing you to actually generate/inject multiple instances of one ID.
This is especially true of PKI keys because for each key you must have a corresponding certificate of which there can only be one data object, so having more than one mechanism instantiated is useless imho. I'm thinking of putting a restriction in that lets you pre-perso/define all the mechanisms you want to support, but only can be initialised.
The only downside I can see is with symmetric, where there doesn't need to be a corresponding certificate.
Options are:
The APDu fails when writing to the above data object, even though the object was successfully has been created during pre-personalisation.
It is probably no coincidence that this is the only data object with a 2-byte object identifer (7F61h).
The underlying cause has not yet been found.
At present, OpenFIPS201 only considers the last byte for Data Objects and has special cases for the Discovery Object and the Biometric Info Template Group (BITG). This was originally a tokenistic gesture to optimisation, but in retrospect it wasn't a good design choice for a few reasons:
I realise this would be a compatibility-breaking change, so I'm interested in feedback on whether this screws with peoples issuance scripts too much to be worth the hassle?
The General Authenticate command takes a number of BET-TLV tags/objects as arguments (Request, Response, Challenge, Witness). When multiple tags are supplied, there is no clear direction as to which order these should be in, and this is evident in various middleware implementations.
When an INTERNAL AUTHENTICATE is performed (which is used for all RSA cryptographic operations), GeneralAuthenticate expects a Challenge and Response (request) to be presented.
A bug exists in OpenFIPS201 where if the Challenge is received before the response request, part of the resulting ciphertext may be clobbered. This is because the same buffer is used for the input and output.
The PUT_DATA_ADMIN schema enumerates pin (1)
and pinAlways (2)
which makes sense. For occ you have only defined occ (4)
and have omitted occAlways
. If you look at the Security conditions for keys 9A
and 9C
in 800-73-4 Part 1 Table 4b you will see that both OCC
and OCC Always
are used.
I suggest you:
occ (4)
to occAlways (4)
occ (8)
In your access mode enumeration documentation here you have a row:
Occ | The object may be accessed only after a successful Biometric On-Card Comparison in the current session.
This is not consistent with your docs on Pin
and Pin Always
as the former is one time and the latter is good for an entire session. I suggest that upi rename Occ
to Occ Always
and add a row for Occ
which is one time like Pin
The requirement is described in SP800-73-4 Part 2 - 3.1.1 - SELECT Card Command:
If the currently selected application is the PIV Card Application when the SELECT command is given and the AID in the data field of the SELECT command is either the AID of the PIV Card Application or the right-truncated version thereof, then the PIV Card Application shall continue to be the currently selected card application and the setting of all security status indicators in the PIV Card Application shall be unchanged.
At present, there doesn't seem to be an obvious way to achieve this in v2.2.2 of the JCRE without some sort of native/proprietary extension, as an identical sequence of events is fired if an applet is reselected, or deselected then selected again. This is being reviewed but at present this requirement isn't met.
A more detailed analysis of this issue has been documented internally, but may be distributed if needed. To request this information, contact us on [email protected].
TLVWriter
doesn't offer good support for multibyte tags. It should also have a writeTag(byte[] tag)
method.
I also noticed that writeTag(short tag)
doesn't set a multibyte indicator byte nor does it set the continuation bit on the high byte.
Regarding how the multibyte indicator is added and continuation bit(s) are set or not set, this should be clearly documented in the API comments.
Regardless of your choice of supporting writeTag(byte[] tag)
you should clearly document how the various writeTag
methods work with respect to setting the multibyte indicator byte and if the user is expected to set the continuation bit.
The Access Mode Enumeration described here does not allow for a complete expression of all access modes described in 800-73-4.
You define:
AccessMode ::= ENUMERATED {
never (0),
pin (1),
pinAlways (2),
occ (4),
userAdmin (16),
always (127)
}
If you look at 800-73-4 Part 1 Table b4 you will see that there is a need to describe VCI and PIN
, VCI and OCC
, VCI and PIN Always
and VCI and OCC Always
Looking at your PutDataCreateObjectRequest and PutDataCreateKeyRequest in the PUT DATA ADMIN schema I see that you have only defined modeContact
and modeContactless
. I think that the right way to fix this is to add modeVci
to each of these and add a tag to the pre-perso APDUs to indicate conditions specific only to the VCI interface.
BTW: We will probably be implementing VCI and will push it up to you if and when it gets done. Likewise with OCC.
As an OpenSC developer, I would like add NIST 800-73-4 Secure Messaging to the OpenSC PIV driver and test it using your applet.
Can you recommend any specific cards that meet your Hardware requirements?
Are there any cards that support both Contact and Contactless?
Preferable readily available in US. Would this one work?
https://www.amazon.com/J2A080-NXP-based-EEPROM-stripe/dp/B01M2BGJ3P
But it is not obvious which cards meet the requirements. Cost is not the primary issue. I would only be buying a few cards for testing.
(I see 2 other OpenSC developers are watching this site too. Maybe they have recommendations for a java card. )
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.