-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Factory-resetting a kdf-enabled card cannot restore its PINs to default values on a J3R180 card #47
Comments
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. |
Which version of the applet are you using? KDF parameters are actually reset within the applet during a factory reset: 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 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?
|
When the |
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). |
After a factory reset could you remove (after a backup if necessary) your |
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
With
The PIN codes set are correctly verified.
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 |
> I do not have such card to make some tests. Could you checkout branch `issue-47`, compile, install and test the patch [4df65b2](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 gets
… 00000000 c2 81 01 00 |....|
00000004
|
The problem does not come from the KDF DO but from the PIN objects. |
Could you confirm you properly uninstalled the applet AND the package from the card before testing the one built from branch |
> 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)]([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?`
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 Could try with last revision of branch
Could 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 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 (46da410), compile and install it and then:
- `setup-kdf` with `smartpgp-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
# Warning: no keys given, defaulting to 404142434445464748494A4B4C4D4E4F
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?
$ 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 <module>
main()
File "/home/user/git/SmartPGP/bin/smartpgp-cli", line 104, in main
VALID_COMMANDS[args.command](ctx)
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. |
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()?
|
This is really odd/strange to have to create a new OwnPIN object. This is clearly not the philosophy of JavaCard.
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 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.
|
Could you try the test mentioned above? |
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:
- 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 I have updated the branch 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 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
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` implementation
If 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 #47 .
In such case, recreating rather than updating the `OwnerPIN` objects may help. You can try to apply [this patch](https://github.com/ANSSI-FR/SmartPGP/tree/issue-47) 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 #29 (comment) , 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 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:
>
> * 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. |
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:
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:
|
Could you submit a pull request on branch |
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 error `card 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>
|
I have the same problem with this exact same card. Setting a large PIN will render the card useless until you reinstall the applet, which is a PITA. The bug seems to happen once the OwnerPIN is set to a larger value than 16. In that case, PINs smaller than or equal to 16 aren't possible anymore. As a workaround, also for an official release, what do you think about padding the PIN to 17 bytes (if it's smaller than 17 bytes). |
I have the same problem with this exact same card. Setting a large PIN will render the card useless until you reinstall the applet, which is a PITA.
The bug seems to happen once the OwnerPIN is set to a larger value than 16. In that case, PINs smaller than or equal to 16 aren't possible anymore. As a workaround, also for an official release, what do you think about padding the PIN to 17 bytes (if it's smaller than 17 bytes).
Please read the whole thread carefully. PINs longer than 16 works well on other cards, so an official release supporting longer PINs should be okay. We should consider patches to work around the problem ON THIS SPECIAL CARD.
A patch setting the PIN_MAX_SIZE to 16 ON THIS CARD is acceptable for me, for it retains the core functionality of SmartPGP on this buggy card.
|
Well it's not acceptable for me and future users will run into the same problem. Please read my answer again. I'm proposing a viable workaround to always set PINs greater than 16 bytes. Maybe what you are missing is that, that there is only a bug if you use PINs shorter than or equal to 16 bytes after you've used a longer PIN. Therefore, my workaround proposal is to always use PINs longer than 16bytes by padding shorter PINs to at least 17bytes. Then you won't trigger that bug. |
Even if the padding solution is purely internal to the applet and transparent to client applications, I would not implement such a workaround in the default release to deal with one specific card problem only. As for issue #40 I could produce a patch with a workaround (either padding, either max PIN sizes' limit) for those who really need to cope with this issue and cannot switch to another card. |
That's a shame, because what is the disadvantage of it, besides a slightly increased code size (given that the workaround will indeed work)? Isn't it about the user experience, all software is full of workarounds for real hardware (bugs). Yes it might only affect this one card or it might affect more cards. Or maybe it will affect the whole j3r family. I could write that code myself, but IMHO it should be included by default. Keep in mind, you are building something that should help users and make it easy for the users. |
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.
The text was updated successfully, but these errors were encountered: