Open wreps8Owt opened 1 year ago
Besides, smartpgp-cli seems unable to pass the PIN authentication against a kdf-enabled card.
This issue is opened when my account remained flagged, so you might not be noticed then.
Using the factory-reset command of GnuPG on a card without kdf enabled does restore its PINs to default values, but factory-resetting a kdf-enabled card cannot. It seems that all parameters return to default, but PINs (especially the admin PIN) does not work. The only way to "restore" it is to reinstall the CAP file.
Which version of the applet are you using?
KDF parameters are actually reset within the applet during a factory reset: https://github.com/ANSSI-FR/SmartPGP/blob/master/src/fr/anssi/smartpgp/Persistent.java#L226
After a factory reset did you remove the card from the reader and then reinsert it? I suspect a caching mechanism of GnuPG to not deal correctly with the reset of the KDF parameters.
Besides, smartpgp-cli seems unable to pass the PIN authentication against a kdf-enabled card.
Yes KDF-enabled PIN is not supported in smartpgp-cli.
Using the factory-reset command of GnuPG on a card without kdf enabled does restore its PINs to default values, but factory-resetting a kdf-enabled card cannot. It seems that all parameters return to default, but PINs (especially the admin PIN) does not work. The only way to "restore" it is to reinstall the CAP file. Which version of the applet are you using? The current master, built against jc304.
KDF parameters are actually reset within the applet during a factory reset: https://github.com/ANSSI-FR/SmartPGP/blob/master/src/fr/anssi/smartpgp/Persistent.java#L226
After a factory reset did you remove the card from the reader and then reinsert it? I suspect a caching mechanism of GnuPG to not deal correctly with the reset of the KDF parameters.
Yes. After a factory reset of a card with KDF enabled, reinserting, killing gpg-agent, or even restarting pcscd, cannot make default admin PIN work.
In Persistent() of Persistent.java, key_derivation_function_length
is set to 0, and (key_derivation_function_length > 0) is judged in many place , but during reset, it seems to be "reset" to Constants.KEY_DERIVATION_FUNCTION_DEFAULT.length, which may be 3. Is this okay?
Yes. After a factory reset of a card with KDF enabled, reinserting, killing gpg-agent, or even restarting pcscd, cannot make default admin PIN work. In Persistent() of Persistent.java,
key_derivation_function_length
is set to 0, and (key_derivation_function_length > 0) is judged in many place , but during reset, it seems to be "reset" to Constants.KEY_DERIVATION_FUNCTION_DEFAULT.length, which may be 3. Is this okay?
When the Peristent
instance is created the key_derivation_function_length
is set to 0 https://github.com/ANSSI-FR/SmartPGP/blob/master/src/fr/anssi/smartpgp/Persistent.java#L131, but at the end of the constructor the reset
function is called https://github.com/ANSSI-FR/SmartPGP/blob/master/src/fr/anssi/smartpgp/Persistent.java#L137 so the key_derivation_function_length
is reset at https://github.com/ANSSI-FR/SmartPGP/blob/master/src/fr/anssi/smartpgp/Persistent.java#L233 to its default value https://github.com/ANSSI-FR/SmartPGP/blob/master/src/fr/anssi/smartpgp/Constants.java#L32.
If you agree with my explanations could you close this issue?
If you agree with my explanations could you close this issue?
Why? The issue remains persist. Your explanations cannot explain the issue.
It just mean that my guess is not the reason of this issue.
SmartPGP is implemented such that its internal status after installation is strictly the same as after a factory reset with only two exceptions: the SM certificate (that you do not use) and the use (or not) of the transaction mechanism (which is not available during first installation).
The constructor of the Persistent
instance, which holds all data in flash memory (that survives card unplug/power off), ends with a call to its reset
function which is also the one called during a factory reset: https://github.com/ANSSI-FR/SmartPGP/blob/master/src/fr/anssi/smartpgp/SmartPGPApplet.java#L1492.
After a factory reset could you remove (after a backup if necessary) your .gnupg
directory in addition to kill any daemons and finally reinsert your card?
After a factory reset could you remove (or backup it if necessary) your
.gnupg
directory in addition to kill any daemons and finally reinsert your card?Sure, and the issue persists. Even smartpgp-cli cannot pass the authentication with default admin pinl, if only the card had kdf setup, and then factory reset.
How did you setup/enable KDF?
How did you setup/enable KDF?
Use smartpgp-cli .
On a blank J3H145 where I install SmartPGP-v1.22.1.
I setup KDF using ./bin/smartpgp-cli -I kdf-setup
and define some PIN codes and obtain the following output where we can see everything went well (90 00):
Select OpenPGP Applet
90 00
Get KDF-DO
90 00
Enter User PIN:
Enter PUK PIN:
Enter Admin PIN:
Verify Admin PIN
90 00
Change PW1
90 00
Change PW3
90 00
Put KDF-DO
90 00
With gpg2 --card-status
I obtain the following output where we see KDF is on:
Reader ...........: xxxx
Application ID ...: D276000124010304AFAF000000010000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: unknown
Serial number ....: 00000001
Name of cardholder: [not set]
Language prefs ...: en
Salutation .......:
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 32 32 32
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: on
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]
The PIN codes set are correctly verified.
Using gpg2 --card-edit
I do a factory reset and then verify user PIN (which is back to the default one) and obtain the following output where we can see KDF is correctly set to off and the default user PIN is verified correctly:
gpg/card> admin
Admin commands are allowed
gpg/card> factory-reset
gpg: OpenPGP card no. D276000124010304AFAF000000010000 detected
gpg: Note: This command destroys all keys stored on the card!
Continue? (y/N) y
Really do a factory reset? (enter "yes") yes
gpg/card> list
Reader ...........: xxxx
Application ID ...: D276000124010304AFAF000000010000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: unknown
Serial number ....: 00000001
Name of cardholder: [not set]
Language prefs ...: en
Salutation .......:
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]
gpg/card> verify
Reader ...........: xxxx
Application ID ...: D276000124010304AFAF000000010000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: unknown
Serial number ....: 00000001
Name of cardholder: [not set]
Language prefs ...: en
Salutation .......:
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 0 3
Signature counter : 0
KDF setting ......: off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]
At this point I am not able to reproduce your problem. Could you try the exact same steps and provide the corresponding output?
On a fresh card J3H145 on which I install SmartPGP-v1.22.1.
I setup kdf using
./bin/smartpgp-cli -I kdf-setup
and define some PIN codes and obtain the following output where we can see everything went well (90 00):Select OpenPGP Applet 90 00 Get KDF-DO 90 00 Enter User PIN: Enter PUK PIN: Enter Admin PIN: Verify Admin PIN 90 00 Change PW1 90 00 Change PW3 90 00 Put KDF-DO 90 00
With
gpg2 --card-status
I obtain the following output where we see KDF is on:Reader ...........: xxxx Application ID ...: D276000124010304AFAF000000010000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000014 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa4096 rsa4096 rsa4096 Max. PIN lengths .: 32 32 32 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: on Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
The PIN codes set are correctly verified. Using
gpg2 --card-edit
I do a factory reset and then verify user PIN (which is back to the default one) and obtain the following output where we can see KDF is correctly set to off and the default user PIN is verified correctly:gpg/card> admin Admin commands are allowed gpg/card> factory-reset gpg: OpenPGP card no. D276000124010304AFAF000000010000 detected gpg: Note: This command destroys all keys stored on the card! Continue? (y/N) y Really do a factory reset? (enter "yes") yes gpg/card> list Reader ...........: xxxx Application ID ...: D276000124010304AFAF000000010000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000014 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa4096 rsa4096 rsa4096 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none] gpg/card> verify Reader ...........: xxxx Application ID ...: D276000124010304AFAF000000010000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000014 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa4096 rsa4096 rsa4096 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
At this point I am not able to reproduce your problem. Could you try the exact same steps and provide the corresponding output?
I repeat the same step on an J3R180. When I verify the PIN after factory reset, the following output is generated:
$ gpg --edit-card
Reader ...........: Identive Identive CLOUD 4500 F Dual Interface Reader [uTrust 4700 F Contact Reader] (53201519201674) 00 00 Application ID ...: D276000124010304AFAF000000000000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000000 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
gpg/card> verify
Reader ...........: Identive Identive CLOUD 4500 F Dual Interface Reader [uTrust 4700 F Contact Reader] (53201519201674) 00 00 Application ID ...: D276000124010304AFAF000000000000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000000 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 2 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
gpg/card> Now it seems that factory reset a card with kdf enabled works well on J3H145, but not on J3R180.
On a fresh card J3H145 on which I install SmartPGP-v1.22.1.
I setup kdf using
./bin/smartpgp-cli -I kdf-setup
and define some PIN codes and obtain the following output where we can see everything went well (90 00):Select OpenPGP Applet 90 00 Get KDF-DO 90 00 Enter User PIN: Enter PUK PIN: Enter Admin PIN: Verify Admin PIN 90 00 Change PW1 90 00 Change PW3 90 00 Put KDF-DO 90 00
With
gpg2 --card-status
I obtain the following output where we see KDF is on:Reader ...........: xxxx Application ID ...: D276000124010304AFAF000000010000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000014 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa4096 rsa4096 rsa4096 Max. PIN lengths .: 32 32 32 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: on Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
The PIN codes set are correctly verified. Using
gpg2 --card-edit
I do a factory reset and then verify user PIN (which is back to the default one) and obtain the following output where we can see KDF is correctly set to off and the default user PIN is verified correctly:gpg/card> admin Admin commands are allowed gpg/card> factory-reset gpg: OpenPGP card no. D276000124010304AFAF000000010000 detected gpg: Note: This command destroys all keys stored on the card! Continue? (y/N) y Really do a factory reset? (enter "yes") yes gpg/card> list Reader ...........: xxxx Application ID ...: D276000124010304AFAF000000010000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000014 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa4096 rsa4096 rsa4096 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none] gpg/card> verify Reader ...........: xxxx Application ID ...: D276000124010304AFAF000000010000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000014 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa4096 rsa4096 rsa4096 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
At this point I am not able to reproduce your problem. Could you try the exact same steps and provide the corresponding output?
I repeat the same step on an J3R180. When I verify the PIN after factory reset, the following output is generated:
$ gpg --edit-card
Reader ...........: Identive Identive CLOUD 4500 F Dual Interface Reader [uTrust 4700 F Contact Reader] (53201519201674) 00 00 Application ID ...: D276000124010304AFAF000000000000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000000 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
gpg/card> verify
Reader ...........: Identive Identive CLOUD 4500 F Dual Interface Reader [uTrust 4700 F Contact Reader] (53201519201674) 00 00 Application ID ...: D276000124010304AFAF000000000000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000000 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 2 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
gpg/card> Now it seems that factory reset a card with kdf enabled works well on J3H145, but not on J3R180.
I use https://github.com/ANSSI-FR/SmartPGP/releases/download/v1.22.1-3.0.4-without-secure-messaging/SmartPGP-v1.22.1-jc304-without_sm-rsa_up_to_4096.cap for the above result. Building tag v1.22.1-3.0.4 against jc305u3_kit and upload to my J3R180 gets the same result.
I do not have such card to make some tests. Could you checkout branch issue-47
, compile, install and test if the patch 4df65b2 solves the problem?
I do not have such card to make some tests. Could you checkout branch
issue-47
, compile, install and test the patch 4df65b2 solves the problem?Sadly this patch does not solve the problem.
I do not have such card to make some tests. Could you checkout branch
issue-47
, compile, install and test the patch 4df65b2 solves the problem?Sadly this patch does not solve the problem.
Besides, Using
bin/smartpgp-cli get-kdf -o kdf
to read the default kdf gets00000000 c2 81 01 00 |....| 00000004
在 2023/4/12 09:28, Driner 写道:
I do not have such card to make some tests. Could you checkout branch
issue-47
, compile, install and test the patch [4df65b2](https://github.com/ANSSI-FR/SmartPGP/commit/4df65b23e6afaa730280be4704f06a2a65f59869) solves the problem? > Sadly this patch does not solve the problem. Besides, Usingbin/smartpgp-cli get-kdf -o kdf
to read the default kdf gets … 00000000 c2 81 01 00 |....| 00000004
The problem does not come from the KDF DO but from the PIN objects.
I do not have such card to make some tests. Could you checkout branch
issue-47
, compile, install and test the patch [4df65b2](https://github.com/ANSSI-FR/SmartPGP/commit/4df65b23e6afaa730280be4704f06a2a65f59869) solves the problem? Sadly this patch does not solve the problem.
Could you confirm you properly uninstalled the applet AND the package from the card before testing the one built from branch issue-47?
I do not have such card to make some tests. Could you checkout branch
issue-47
, compile, install and test the patch [4df65b2](https://github.com/ANSSI-FR/SmartPGP/commit/4df65b23e6afaa730280be4704f06a2a65f59869) solves the problem? Sadly this patch does not solve the problem. Could you confirm you properly uninstalled the applet AND the package from the card before testing the one built from branchissue-47?
Yes. Properly uninstalling the applet AND the package from the card before testing the one built from branch
issue-47
changes nothing. The issue persists.
The KDF DO is correctly reset. It seems like the call to *_pin.update
in the reset
function of the Persistent
object has no effect. I suspect the transaction mechanism.
Could try with last revision of branch issue-47
where I just committed a change to deactivate any transaction around the user and admin PIN changes (https://github.com/ANSSI-FR/SmartPGP/commit/46da4109d835314a8dddb81414adf8d2a872c23a) to:
setup-kdf
with smartpgp-cli
gpg2 --card-edit
to change the user PIN to a non-default valueCould you please provide all outputs of the above operations? Sorry for the nconvenience of making you make a lot of tests.
The KDF DO is correctly reset. It seems like the call to
*_pin.update
in thereset
function of thePersistent
object has no effect I suspect the transaction mechanism.Could try with last revision of branch
issue-47
where I just committed a change to deactivate any transaction around the user and admin PIN changes (https://github.com/ANSSI-FR/SmartPGP/commit/46da4109d835314a8dddb81414adf8d2a872c23a), compile and install it and then:
setup-kdf
withsmartpgp-cli
- use
gpg2 --card-edit
to change the user PIN to a non-default value- factory reset the card
- verify the user PIN to check it is back ti its default value (123456)
Could you please provide all outputs of the above operations? Sorry for inconvenience of making you make a lot of tests.
$ JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 JC_HOME=../oracle_javacard_sdks/jc304_kit/ ant Buildfile: /home/user/git/SmartPGP/build.xml [get] Destination already exists (skipping): /home/user/git/SmartPGP/ant-javacard.jar
convert: [cap] INFO: using JavaCard 3.0.4 SDK in /home/user/git/oracle_javacard_sdks/jc304_kit [cap] INFO: Setting package name to fr.anssi.smartpgp [cap] Building CAP with 1 applet from package fr.anssi.smartpgp (AID: D27600012401) [cap] fr.anssi.smartpgp.SmartPGPApplet D276000124010304AFAF000000000000 [compile] Compiling files from /home/user/git/SmartPGP/src [compile] Compiling 10 source files to /tmp/jccpro12635575473400202718 [convert] [ INFO: ] Converter [v3.0.4] [convert] [ INFO: ] Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. [convert] [convert] [convert] [ INFO: ] conversion completed with 0 errors and 0 warnings. [javacard] NB! Please use JavaCard SDK 3.0.5u3 or later for verifying! [verify] Verification passed [cap] CAP saved to /home/user/git/SmartPGP/SmartPGPApplet.cap
BUILD SUCCESSFUL Total time: 3 seconds $ java -jar ../GlobalPlatformPro/gp.jar --install SmartPGPApplet.cap
CAP loaded $ bin/smartpgp-cli setup-kdf Select OpenPGP Applet 90 00 Get KDF-DO 90 00 Verify Admin PIN 90 00 Change PW1 90 00 Change PW3 90 00 Put KDF-DO 90 00 $ gpg --edit-card
Reader ...........: Identive Identive CLOUD 4500 F Dual Interface Reader [uTrust 4700 F Contact Reader] (53201519201674) 00 00 Application ID ...: D276000124010304AFAF000000000000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000000 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 32 32 32 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: on Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
gpg/card> passwd gpg: OpenPGP card no. D276000124010304AFAF000000000000 detected PIN changed.
gpg/card>
Reader ...........: Identive Identive CLOUD 4500 F Dual Interface Reader [uTrust 4700 F Contact Reader] (53201519201674) 00 00 Application ID ...: D276000124010304AFAF000000000000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000000 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 32 32 32 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: on Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
gpg/card> admin Admin commands are allowed
gpg/card> factory-reset gpg: OpenPGP card no. D276000124010304AFAF000000000000 detected
gpg: Note: This command destroys all keys stored on the card!
Continue? (y/N) y Really do a factory reset? (enter "yes") yes
gpg/card>
Reader ...........: Identive Identive CLOUD 4500 F Dual Interface Reader [uTrust 4700 F Contact Reader] (53201519201674) 00 00 Application ID ...: D276000124010304AFAF000000000000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000000 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
gpg/card> q $ killall gpg-agent
(card reinserted)
$ gpg --edit-card
Reader ...........: Identive Identive CLOUD 4500 F Dual Interface Reader [uTrust 4700 F Contact Reader] (53201519201674) 00 00 Application ID ...: D276000124010304AFAF000000000000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000000 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
gpg/card> verify
Reader ...........: Identive Identive CLOUD 4500 F Dual Interface Reader [uTrust 4700 F Contact Reader] (53201519201674) 00 00 Application ID ...: D276000124010304AFAF000000000000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unknown Serial number ....: 00000000 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 127 127 127 PIN retry counter : 2 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
gpg/card>
:( I pushed another commit which replaces any existing PIN objects at reset. This is really not a good idea in general but I would like to confirm it just works. Could you please try it?
The KDF DO is correctly reset. It seems like the call to
*_pin.update
in thereset
function of thePersistent
object has no effect I suspect the transaction mechanism.Really? Why do *_pin.update() work without KDF set, but do not work with KDF set?
From the applet point of view KDF is just a bunch of bytes that can be set and retrieved by client applications to know how to derive the PIN code before it is sent to the applet for verification. The applet does not care at all about the PIN is a raw user PIN or a KDF derived one.
I suspect you have exactly the same problem without KDF activated. On a released version of SmartPGP (NOT from issue-47)
, without KDF enabled, you can try to change the PIN to a large value such as 32 digits, verify it is working, then factory reset. If the default PIN (123456) is restored and verifies correctly then I have no clue what's going one...
:( I pushed another commit which replaces any existing PIN objects at reset. This is really not a good idea in general but I would like to confirm it just works. Could you please try it?
$ LANG=en_US.UTF-8 JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 JC_HOME=../oracle_javacard_sdks/jc304_kit/ ant Buildfile: /home/user/git/SmartPGP/build.xml [get] Destination already exists (skipping): /home/user/git/SmartPGP/ant-javacard.jar
convert: [cap] INFO: using JavaCard 3.0.4 SDK in /home/user/git/oracle_javacard_sdks/jc304_kit [cap] INFO: Setting package name to fr.anssi.smartpgp [cap] Building CAP with 1 applet from package fr.anssi.smartpgp (AID: D27600012401) [cap] fr.anssi.smartpgp.SmartPGPApplet D276000124010304AFAF000000000000 [compile] Compiling files from /home/user/git/SmartPGP/src [compile] Compiling 10 source files to /tmp/jccpro10811319647470149789 [compile] /home/user/git/SmartPGP/src/fr/anssi/smartpgp/Persistent.java:237: error: cannot assign a value to final variable user_pin [compile] user_pin = new OwnerPIN(Constants.USER_PIN_RETRY_COUNT, Constants.USER_PIN_MAX_SIZE); [compile] ^ [compile] /home/user/git/SmartPGP/src/fr/anssi/smartpgp/Persistent.java:252: error: cannot assign a value to final variable admin_pin [compile] admin_pin = new OwnerPIN(Constants.ADMIN_PIN_RETRY_COUNT, Constants.ADMIN_PIN_MAX_SIZE); [compile] ^ [compile] 2 errors
BUILD FAILED /home/user/git/SmartPGP/build.xml:7: Compile failed; see the compiler error output for details.
Total time: 2 seconds
Sorry for the inconvenience, I have just fixed this.
Sorry for the inconvenience, I have just fixed this.
$ bin/smartpgp-cli setup-kdf Select OpenPGP Applet 90 00 Get KDF-DO 90 00 Verify Admin PIN 69 82 Traceback (most recent call last): File "/home/user/git/SmartPGP/bin/smartpgp-cli", line 111, in
main() File "/home/user/git/SmartPGP/bin/smartpgp-cli", line 104, in main VALID_COMMANDSargs.command File "/home/user/git/SmartPGP/bin/smartpgp/highlevel.py", line 462, in cmd_setup_kdf raise AdminPINFailed smartpgp.highlevel.AdminPINFailed
It just means you entered the incorrect current admin PIN...
It just means you entered the incorrect current admin PIN...
No. It is the first command after installing the applet, which means the default admin PIN cannot pass.
Mea culpa I forgot to set the initial/default value. It should be OK now.
Mea culpa I forward to set the initial/default value. It should be OK now.
Yes, it is okay now.
Besides, is it possible to commitTransaction() only once during Persistent.reset()?
Yes, it is okay now.
This is really odd/strange to have to create a new OwnPIN object. This is clearly not the philosophy of JavaCard.
Besides, is it possible to commitTransaction() only once during Persistent.reset()?
No, the context would be too huge for the card, and there is no chance it accepts such a large transaction at once.
As already mentioned previously: I suspect you have exactly the same problem without KDF activated. On a released version of SmartPGP (NOT a compiled version from issue-47), without KDF enabled, can you try to change the PIN to a large value such as 32 digits, verify it is working, then factory reset. If the default PIN (123456) is restored and verifies correctly then I have no clue what's going one. Otherwise there is a strong problem in the implementation of the OwnerPIN class in this platform.
As already mentioned previously: I suspect you have exactly the same problem without KDF activated. On a released version of SmartPGP (NOT a compiled version from issue-47), without KDF enabled, can you try to change the PIN to a large value such as 32 digits, verify it is working, then factory reset. If the default PIN (123456) is restored and verifies correctly then there is a strong problem in the implementation of the OwnerPIN class in this platform.
Setting a 28-byte PIN on my J3R180 running a released version of SmartPGP without KDF enabled can make the default PIN (123456) not restored nor verified after a factory reset, but it is possible to unblock it and set it to a new value via the default admin PIN.
Ok, so there is definitely a strong bug in the implementation of the update
procedure of the OwnerPIN
on the J3R180.
To confirm it, could you try, without KDF enabled and without doing a factory reset, to simply change the user PIN twice:
As already mentioned previously: I suspect you have exactly the same problem without KDF activated. On a released version of SmartPGP (NOT a compiled version from issue-47), without KDF enabled, can you try to change the PIN to a large value such as 32 digits, verify it is working, then factory reset. If the default PIN (123456) is restored and verifies correctly then there is a strong problem in the implementation of the OwnerPIN class in this platform. Setting a 28-byte PIN on my J3R180 running a released version of SmartPGP without KDF enabled can make the default PIN (123456) not restored nor verified after a factory reset, but it is possible to unblock it and set it to a new value via the default admin PIN.
However, the new value cannot be verifies correctly.
Ok, so there is definitely a strong bug in the implementation of the
update
procedure of theOwnerPIN
on the J3R180.To confirm it, could you try, without KDF enabled and without doing a factory reset, to simply change the user PIN twice:
* from the default (123456) to a large one (123456789012345678901234567890) * verify the PIN has really been changed * from the large one to a smaller one (12345678) * verify the PIN has really been changed
Could you try the test mentioned above?
Ok, so there is definitely a strong bug in the implementation of the
update
procedure of theOwnerPIN
on the J3R180.To confirm it, could you try, without KDF enabled and without doing a factory reset, to simply change the user PIN twice:
- from the default (123456) to a large one (123456789012345678901234567890)
- verify the PIN has really been changed
- from the large one to a smaller one (12345678)
- verify the PIN has really been changed
As you expect, at last the short new pin can neither be verified nor keep the last (long) value.
So it confirms the (strong) bug in the OwnerPIN.update
method on this platform.
I have updated the branch issue-47
to provide a single patch to you to have a working version: a new OwnerPIN
instance is created before each call to udpate
so everything should just work for your card. I cannot integrate such patch in the official releases of SmartPGP.
FYI @martinpaljak
So it confirms the (strong) bug in the
OwnerPIN.update
method on this platform.I have updated the branch
issue-47
to provide a single patch to you to have a working version: a newOwnerPIN
instance is created before each call toudpate
so everything should just work for your card. I cannot integrate such patch in the official releases of SmartPGP.FYI @martinpaljak
Thanks. This is okay for a patch of walk-around.
To confirm it, could you try, without KDF enabled and without doing a factory reset, to simply change the user PIN twice:
- from the default (123456) to a large one (123456789012345678901234567890)
- verify the PIN has really been changed
- from the large one to a smaller one (12345678)
- verify the PIN has really been changed
Besides, is it better to mention such test and the patch in the document? It may ease the owner of cards with a buggy
OwnerPIN
implementation to find the patch.
For example:
Installing the CAP file
...
For cards with a buggy
OwnerPIN
implementationIf you find that you cannot verify PIN right after a seemingly successful change or factory reset, your card may have a buggy
OwnerPIN
implementation, like the one mentioned in https://github.com/ANSSI-FR/SmartPGP/issues/47 .In such case, recreating rather than updating the
OwnerPIN
objects may help. You can try to apply this patch for a walk-around.
So it confirms the (strong) bug in the
OwnerPIN.update
method on this platform.This may even be another aspect related to https://github.com/ANSSI-FR/SmartPGP/issues/29#issuecomment-993684939 , as my card also belongs to the J3R series.
@bitlogik Can you test whether this issue exists in your J3R110?
Ok, so there is definitely a strong bug in the implementation of the
update
procedure of theOwnerPIN
on the J3R180.To confirm it, could you try, without KDF enabled and without doing a factory reset, to simply change the user PIN twice:
* from the default (123456) to a large one (123456789012345678901234567890) * verify the PIN has really been changed * from the large one to a smaller one (12345678) * verify the PIN has really been changed
Could you try the test mentioned above?
Further test against the new release on my J3R180 shows that a 16-byte PIN will not trigger the bug inside its
OwnerPIN
implementation, but a 17-byte PIN will, which means that 16 is the max-pin-length of my J3R180 in practice.
Is it possible to set the three *_PIN_MAX_SIZE
to 16 as a walk-around?
Unfortunately if you set the PIN_MAX_SIZE to 16 you will not be able to use KDF. KDF in OpenPGP relies on SHA256 (respectively SH512) (https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.pdf, page 19) which makes the real PIN to be stored 32 bytes (resp. 64 bytes) long :/
After I set the PIN_MAX_SIZE to 16, set a PIN longer than 16 in gpg will fail with "Error changing the PIN: Invalid value" as expected, but running bin/smartpgp-cli setup-kdf will still seemingly succeed:
$ bin/smartpgp-cli setup-kdf Select OpenPGP Applet 90 00 Get KDF-DO 90 00 Verify Admin PIN 90 00 Change PW1 67 00 Change PW3 67 00 Put KDF-DO 90 00
However, "Change PW1" and "Change PW3" are actually failed, but in highlevel.py the return value of change_reference_data_pw1() and change_reference_data_pw3() are not checked, so the smartpgp-cli does not stop, and the overall effect is only changing the kdf-do.
All possible error during setup-kdf had better be collected, like the patch below:
diff --git a/bin/smartpgp/highlevel.py b/bin/smartpgp/highlevel.py
--- a/bin/smartpgp/highlevel.py
+++ b/bin/smartpgp/highlevel.py
@@ -462,17 +462,17 @@ class CardConnectionContext:
raise AdminPINFailed
####### step 3bis
if nresetting_code != None:
- set_resetting_code(self.connection, nresetting_code)
+ (_,sw1,sw2) = set_resetting_code(self.connection, nresetting_code)
if sw1!=0x90 or sw2!=0x00:
print("set_resetting_code failed")
return
####### step 4
- change_reference_data_pw1(self.connection, ascii_encode_pin(pw1), list(npw1))
+ (sw1,sw2) = change_reference_data_pw1(self.connection, ascii_encode_pin(pw1), list(npw1))
if sw1!=0x90 or sw2!=0x00:
print("change_reference_data_pw1 failed")
return
####### step 4bis
- change_reference_data_pw3(self.connection, ascii_encode_pin(pw3), list(npw3))
+ (sw1,sw2) = change_reference_data_pw3(self.connection, ascii_encode_pin(pw3), list(npw3))
if sw1!=0x90 or sw2!=0x00:
print("change_reference_data_pw3 failed")
return
Could you submit a pull request on branch javacard-3.0.1
with this patch? So that your contribution will be tracked in the repository :)
No, thanks. I know (and hate) the game rule of github very well, but I do not want to be conspicuous, for example, to be "tracked" in the commit log of a project. That is why I posted this patch in the issue in the first place, rather than forking the whole project to submit a mere "pull request".
You are totally free to take this patch as your own contribution.
Unfortunately if you set the PIN_MAX_SIZE to 16 you will not be able to use KDF. KDF in OpenPGP relies on SHA256 (respectively SH512) (https://gnupg.org/ftp/specs/OpenPGP-smart-card-application-3.4.pdf, page 19) which make the real PIN to be stored is 32 bytes (resp. 64 bytes) long :/
Further tests show that after setting the PIN_MAX_SIZE to 16, if kdf-do is not set,
factory-reset
of gpg will fail with errorcard command TERMINATE DF failed: Bad PIN (0x6982)
, but fortunately,bin/smartpgp-cli reset
works well:$ gpg --edit-card
Reader ...........: Identive Identive CLOUD 4500 F Dual Interface Reader [uTrust 4700 F Contact Reader] (53201519201674) 00 00 Application ID ...: D276000124010304FFAF000000020000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unmanaged S/N range Serial number ....: 00000002 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 16 16 16 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: off Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
gpg/card> admin Admin commands are allowed
gpg/card> factory-reset gpg: OpenPGP card no. D276000124010304FFAF000000020000 detected
gpg: Note: This command destroys all keys stored on the card!
Continue? (y/N) y Really do a factory reset? (enter "yes") yes card command TERMINATE DF failed: Bad PIN (0x6982)
gpg/card> q $ killall gpg-agent $ bin/smartpgp-cli reset Select OpenPGP Applet 90 00 Verify Admin PIN 69 82 Verify Admin PIN 69 82 Verify Admin PIN 69 82 Terminate 90 00 Activate 90 00 but if kdf-do is set,
factory-reset
of gpg will work:$ bin/smartpgp-cli set-kdf -i kdf Select OpenPGP Applet 90 00 Verify Admin PIN 90 00 Put KDF-DO 90 00 $ gpg --edit-card
Reader ...........: Identive Identive CLOUD 4500 F Dual Interface Reader [uTrust 4700 F Contact Reader] (53201519201674) 00 00 Application ID ...: D276000124010304FFAF000000020000 Application type .: OpenPGP Version ..........: 3.4 Manufacturer .....: unmanaged S/N range Serial number ....: 00000002 Name of cardholder: [not set] Language prefs ...: en Salutation .......: URL of public key : [not set] Login data .......: [not set] Signature PIN ....: forced Key attributes ...: rsa2048 rsa2048 rsa2048 Max. PIN lengths .: 32 32 32 PIN retry counter : 3 0 3 Signature counter : 0 KDF setting ......: on Signature key ....: [none] Encryption key....: [none] Authentication key: [none] General key info..: [none]
gpg/card> admin Admin commands are allowed
gpg/card> factory-reset gpg: OpenPGP card no. D276000124010304FFAF000000020000 detected
gpg: Note: This command destroys all keys stored on the card!
Continue? (y/N) y Really do a factory reset? (enter "yes") yes
gpg/card>
Using the factory-reset command of GnuPG on a J3R180 card without kdf enabled does restore its PINs to default values, but factory-resetting a kdf-enabled card cannot. It seems that all parameters return to default, but PINs (especially the admin PIN) does not work. The only way to "restore" it is to reinstall the CAP file.