javacard-openpgpcard
javacard-openpgpcard copied to clipboard
PIN issues
Hello.
I have trouble with changing card info through --card-edit
command.
It looks like default PINs (user and admin) not accepted.
I tried to change user PIN or change user name.
Details: Javacard: ACOSJ 40K Dual GPG: gpg (GnuPG) 2.2.3 libgcrypt 1.8.1
This is outputs I received:
passwd
command
gpg/card> passwd
gpg: DBG: chan_4 -> LEARN --sendinfo
gpg: DBG: chan_4 <- S SIG-COUNTER 0
gpg: DBG: chan_4 <- S CHV-STATUS +0+127+127+127+2+3+2
gpg: DBG: chan_4 <- S DISP-SEX 9
gpg: DBG: chan_4 <- S EXTCAP gc=1+ki=1+fc=1+pd=0+mcl3=255+aac=0+sm=2+si=0+dec=0+bt=0
gpg: DBG: chan_4 <- S APPTYPE OPENPGP
gpg: DBG: chan_4 <- S SERIALNO D2760001240102000000000000010000
gpg: DBG: chan_4 <- S READER ACS ACR 38U-CCID 00 00
gpg: DBG: chan_4 <- OK
gpg: DBG: chan_4 -> SCD GETATTR KEY-ATTR
gpg: DBG: chan_4 <- S KEY-ATTR 1 1 rsa2048 17 3
gpg: DBG: chan_4 <- S KEY-ATTR 2 1 rsa2048 17 3
gpg: DBG: chan_4 <- S KEY-ATTR 3 1 rsa2048 17 3
gpg: DBG: chan_4 <- OK
gpg: OpenPGP card no. D2760001240102000000000000010000 detected
1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit
Your selection? 1 gpg: DBG: chan_4 -> SCD PASSWD 1 gpg: DBG: chan_4 <- INQUIRE PINENTRY_LAUNCHED 25966 gtk2 1.0.0 ? ? ? gpg: DBG: chan_4 -> END gpg: DBG: chan_4 <- INQUIRE PINENTRY_LAUNCHED 26932 gtk2 1.0.0 ? ? ? gpg: DBG: chan_4 -> END gpg: DBG: chan_4 <- INQUIRE PINENTRY_LAUNCHED 28020 gtk2 1.0.0 ? ? ? gpg: DBG: chan_4 -> END gpg: DBG: chan_4 <- ERR 100663427 Conditions of use not satisfied <SCD> Error changing the PIN: Conditions of use not satisfied
1 - change PIN 2 - unblock PIN 3 - change Admin PIN 4 - set the Reset Code Q - quit
verify
command
gpg/card> verify
gpg: DBG: chan_4 -> SCD CHECKPIN D2760001240102000000000000010000
gpg: DBG: chan_4 <- INQUIRE PINENTRY_LAUNCHED 12301 gtk2 1.0.0 ? ? ?
gpg: DBG: chan_4 -> END
gpg: DBG: chan_4 <- ERR 100663404 Card error <SCD>
name
command
gpg/card> name
Cardholder's surname: [surname]
Cardholder's given name: [name]
gpg: DBG: chan_4 -> SCD SETATTR DISP-NAME Kalinin<<Dmitry
gpg: DBG: chan_4 <- INQUIRE PINENTRY_LAUNCHED 23107 gtk2 1.0.0 ? ? ?
gpg: DBG: chan_4 -> END
gpg: DBG: chan_4 <- ERR 100663404 Card error <SCD>
gpg: error setting Name: Card error
Which applet version is being installed?
With GnuPG version 2.2.3 and the latest version of the applet this seems to work for me. Is the new PIN you're trying to set at least 6 characters for user PIN and 8 for admin PIN? Could you also post the output of pcscd when run with pcscd -f -a
?
Hello.
I have tried today to test a little bit your code.
I found out that another OpenPGP implementation FluffyKaon/OpenPGP-Card
works on my card so I tried to compare these 2 versions and check.
For me it was just a "change code and try" practice since I'm a C# web dev so not very known with Java :-(.
So I tried to modify verify() function according to how it is done in FluffyKaon/OpenPGP-Card
version but still getting PIN.check() result as false. It looks like something not correct with buffer where data is passed by.
I marked changed parts so maybe it will give a hint how to test this properly.
So I will try that pcscd -f -a command tomorrow.
private void verify(APDU apdu, byte mode) {
byte temp_buffer[] = apdu.getBuffer(); << NEW
short length = (short) (temp_buffer[ISO7816.OFFSET_LC] & 0x00FF); << NEW
if (mode == (byte) 0x81 || mode == (byte) 0x82) {
// Check length of input
if (in_received < PW1_MIN_LENGTH ||
in_received > PW1_MAX_LENGTH)
{
//ISOException.throwIt(SW_WRONG_LENGTH);
}
boolean result = pw1.check(temp_buffer, ISO7816.OFFSET_CDATA, (byte) length); << NEW
if (!result) << HACK: result is false but we return SUCCESS
{
if (mode == (byte) 0x81)
{
pw1_modes[PW1_MODE_NO81] = true;
}
else
{
pw1_modes[PW1_MODE_NO82] = true;
}
return;
}
// Check given PW1 and set requested mode if verified succesfully
if (result/*pw1.check(buffer, _0, (byte) in_received)*/) {
if (mode == (byte) 0x81)
pw1_modes[PW1_MODE_NO81] = true;
else
pw1_modes[PW1_MODE_NO82] = true;
} else {
ISOException
.throwIt((short) (0x63C0 | pw1.getTriesRemaining()));
}
} else if (mode == (byte) 0x83) {
// Check length of input
if (in_received < PW3_MIN_LENGTH || in_received > PW3_MAX_LENGTH)
ISOException.throwIt(SW_WRONG_LENGTH);
// Check PW3
if (!pw3.check(buffer, _0, (byte) in_received)) {
ISOException
.throwIt((short) (0x63C0 | pw3.getTriesRemaining()));
}
} else {
ISOException.throwIt(SW_INCORRECT_P1P2);
}
}
I committed some changes to the PIN functionality in the openpgpcard3.3 branch. Could you check whether your problem still occurs with the latest code from that branch?
Hello. I have tried to build branch openpgpcard3.3 with JC Kit 3.0.3 but unfortunately got the same error when tried to execute verify command
gpg/card> verify
gpg: DBG: chan_4 -> SCD CHECKPIN D2760001240102000000000000010000
gpg: DBG: chan_4 <- INQUIRE PINENTRY_LAUNCHED 20110 gtk2 1.0.0 ? ? ?
gpg: DBG: chan_4 -> END
gpg: DBG: chan_4 <- ERR 100663404 Card error <SCD>
Also I have tried to run that pcscd when trying verify command and here is the log. Hope this will be helpful
20507383 APDU: 00 A4 00 0C 02 3F 00
00031150 SW: 6A 86
00000095 APDU: 00 A4 04 00 06 D2 76 00 01 24 01
00040377 SW: 90 00
00000089 APDU: 00 CA 00 4F 00
00091894 SW: 6C 10
00000163 APDU: 00 CA 00 4F 10
00032739 SW: D2 76 00 01 24 01 02 00 00 00 00 00 00 01 00 00 90 00
00000155 APDU: 00 CA 5F 52 00
00091388 SW: 6C 0F
00000149 APDU: 00 CA 5F 52 0F
00031583 SW: 00 73 00 00 80 00 00 00 00 00 00 00 00 00 00 90 00
00000186 APDU: 00 CA 00 C4 00
00092190 SW: 6C 07
00000143 APDU: 00 CA 00 C4 07
00021996 SW: 00 7F 7F 7F 02 03 03 90 00
00000265 APDU: 00 CA 00 6E 00
00097277 SW: 6C E0
00000152 APDU: 00 CA 00 6E E0
00285219 SW: 6E 81 DD 4F 10 D2 76 00 01 24 01 02 00 00 00 00 00 00 01 00 00 5F 52 0F 00 73 00 00 80 00 00 00 00 00 00 00 00 00 00 73 00 C0 0A F2 00 00 FF 00 FF 00 FF 00 FF C1 06 01 08 00 00 11 03 C2 06 01 08 00 00 11 03 C3 06 01 08 00 00 11 03 C4 07 00 7F 7F 7F 02 03 03 C5 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C6 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 0C 00 00 00 00 00 00 00 00 00 00 00 00 90 00
00000168 APDU: 00 CA 7F 74 00
00091293 SW: 6A 83
00000167 APDU: 00 CA 00 5E 00
00085262 SW: 90 00
00000095 APDU: 00 CA 00 6E 00
00097095 SW: 6C E0
00000072 APDU: 00 CA 00 6E E0
00285169 SW: 6E 81 DD 4F 10 D2 76 00 01 24 01 02 00 00 00 00 00 00 01 00 00 5F 52 0F 00 73 00 00 80 00 00 00 00 00 00 00 00 00 00 73 00 C0 0A F2 00 00 FF 00 FF 00 FF 00 FF C1 06 01 08 00 00 11 03 C2 06 01 08 00 00 11 03 C3 06 01 08 00 00 11 03 C4 07 00 7F 7F 7F 02 03 03 C5 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C6 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 0C 00 00 00 00 00 00 00 00 00 00 00 00 90 00
00000134 APDU: 00 CA 00 6E 00
00097139 SW: 6C E0
00000113 APDU: 00 CA 00 6E E0
00285083 SW: 6E 81 DD 4F 10 D2 76 00 01 24 01 02 00 00 00 00 00 00 01 00 00 5F 52 0F 00 73 00 00 80 00 00 00 00 00 00 00 00 00 00 73 00 C0 0A F2 00 00 FF 00 FF 00 FF 00 FF C1 06 01 08 00 00 11 03 C2 06 01 08 00 00 11 03 C3 06 01 08 00 00 11 03 C4 07 00 7F 7F 7F 02 03 03 C5 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C6 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 0C 00 00 00 00 00 00 00 00 00 00 00 00 90 00
00000087 APDU: 00 CA 00 6E 00
00097204 SW: 6C E0
00000164 APDU: 00 CA 00 6E E0
00285076 SW: 6E 81 DD 4F 10 D2 76 00 01 24 01 02 00 00 00 00 00 00 01 00 00 5F 52 0F 00 73 00 00 80 00 00 00 00 00 00 00 00 00 00 73 00 C0 0A F2 00 00 FF 00 FF 00 FF 00 FF C1 06 01 08 00 00 11 03 C2 06 01 08 00 00 11 03 C3 06 01 08 00 00 11 03 C4 07 00 7F 7F 7F 02 03 03 C5 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C6 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 0C 00 00 00 00 00 00 00 00 00 00 00 00 90 00
00000368 APDU: 00 CA 00 65 00
00091946 SW: 6C 0B
00000148 APDU: 00 CA 00 65 0B
00026626 SW: 65 09 5B 00 5F 2D 00 5F 35 01 39 90 00
00000276 APDU: 00 CA 5F 50 00
00085240 SW: 90 00
00000094 APDU: 00 CA 00 6E 00
00097168 SW: 6C E0
00000152 APDU: 00 CA 00 6E E0
00285271 SW: 6E 81 DD 4F 10 D2 76 00 01 24 01 02 00 00 00 00 00 00 01 00 00 5F 52 0F 00 73 00 00 80 00 00 00 00 00 00 00 00 00 00 73 00 C0 0A F2 00 00 FF 00 FF 00 FF 00 FF C1 06 01 08 00 00 11 03 C2 06 01 08 00 00 11 03 C3 06 01 08 00 00 11 03 C4 07 00 7F 7F 7F 02 03 03 C5 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C6 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 0C 00 00 00 00 00 00 00 00 00 00 00 00 90 00
00000212 APDU: 00 CA 00 C4 00
00092044 SW: 6C 07
00000078 APDU: 00 CA 00 C4 07
00021726 SW: 00 7F 7F 7F 02 03 03 90 00
00000112 APDU: 00 CA 00 7A 00
00091565 SW: 6C 07
00000190 APDU: 00 CA 00 7A 07
00021909 SW: 7A 05 93 03 00 00 00 90 00
00000193 APDU: 00 47 81 00 02 B6 00
00093574 SW: 6F 00
00000094 APDU: 00 47 81 00 02 B8 00
00098378 SW: 6F 00
00000143 APDU: 00 47 81 00 02 A4 00
00098547 SW: 6F 00
39123167 APDU: 00 CA 00 C4 00
00096956 SW: 6C 07
00000128 APDU: 00 CA 00 C4 07
00021794 SW: 00 7F 7F 7F 02 03 03 90 00
00000173 APDU: 00 CA 00 7A 00
00091515 SW: 6C 07
00000148 APDU: 00 CA 00 7A 07
00021830 SW: 7A 05 93 03 00 00 00 90 00
12957088 APDU: 00 CA 00 C4 00
00091938 SW: 6C 07
00000052 APDU: 00 CA 00 C4 07
00021772 SW: 00 7F 7F 7F 02 03 03 90 00
14938558 APDU: 00 20 00 82 06 31 32 33 34 35 36
00103638 SW: 63 C1
00000642 APDU: 00 CA 00 6E 00
00102155 SW: 6C E0
00000158 APDU: 00 CA 00 6E E0
00285243 SW: 6E 81 DD 4F 10 D2 76 00 01 24 01 02 00 00 00 00 00 00 01 00 00 5F 52 0F 00 73 00 00 80 00 00 00 00 00 00 00 00 00 00 73 00 C0 0A F2 00 00 FF 00 FF 00 FF 00 FF C1 06 01 08 00 00 11 03 C2 06 01 08 00 00 11 03 C3 06 01 08 00 00 11 03 C4 07 00 7F 7F 7F 01 03 03 C5 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C6 3C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 CD 0C 00 00 00 00 00 00 00 00 00 00 00 00 90 00
00000116 APDU: 00 CA 00 C4 00
00092098 SW: 6C 07
00000169 APDU: 00 CA 00 C4 07
00021779 SW: 00 7F 7F 7F 01 03 03 90 00
00000115 APDU: 00 CA 00 7A 00
00091429 SW: 6C 07
00000100 APDU: 00 CA 00 7A 07
00021747 SW: 7A 05 93 03 00 00 00 90 00
I can indeed see that the PIN is not verified, even though the correct default PIN is provided. It does suggest you tried to verify the PIN once before this log as well. There is also something weird going on when trying to retrieve the key (the status word 6f00 is returned which indicates some internal problem). Maybe this is something specific to the card that you're using, but that's hard for me to check as I only have an NXP JCOP card to test with. You didn't experience any problems with the code from FluffyKaon/OpenPGP-Card
?
Does running ant test
show any errors?
Hello. I have some news.
The code below works for verify() function.
I marked changed places so you can see.
The function apdu.setIncomingAndReceive()
looks like does some magic. Without it still buffer either not have data or has something not suitable for PIN verification.
So I think wherever input data is used that function apdu.setIncomingAndReceive()
should be called.
One more thing to have in mind. It most probably that I have a card (ACOSJ) that supports just T0 protocol (not T1), even if on the website of the producer it is stated that it supports both. So maybe this also makes some difference since I also have troubles with IsoApplet (PKI) and developer says that it has never been tested for T0 protocol.
private void verify(APDU apdu, byte mode) {
byte[] temp_buffer = apdu.getBuffer(); << NEW
byte lc = temp_buffer[ISO7816.OFFSET_LC]; << NEW
short numOfBytesRead = apdu.setIncomingAndReceive(); << NEW
if (mode == (byte) 0x81 || mode == (byte) 0x82) {
// Check length of input
if (in_received < PW1_MIN_LENGTH || in_received > PW1_MAX_LENGTH)
ISOException.throwIt(SW_WRONG_LENGTH);
// Check given PW1 and set requested mode if verified succesfully
if (pw1.check(temp_buffer, (short)ISO7816.OFFSET_CDATA, lc)) { << CHANGED
if (mode == (byte) 0x81)
pw1_modes[PW1_MODE_NO81] = true;
else
pw1_modes[PW1_MODE_NO82] = true;
} else {
ISOException
.throwIt((short) (0x63C0 | pw1.getTriesRemaining()));
}
} else if (mode == (byte) 0x83) {
// Check length of input
if (in_received < PW3_MIN_LENGTH || in_received > PW3_MAX_LENGTH)
ISOException.throwIt(SW_WRONG_LENGTH);
// Check PW3
if (!pw3.check(buffer, _0, (byte) in_received)) {
ISOException
.throwIt((short) (0x63C0 | pw3.getTriesRemaining()));
}
} else {
ISOException.throwIt(SW_INCORRECT_P1P2);
}
}
The result of verify function
gpg/card> verify
gpg: DBG: chan_4 -> SCD CHECKPIN D2760001240102000000000000010000
gpg: DBG: chan_4 <- INQUIRE PINENTRY_LAUNCHED 16928 gtk2 1.0.0 ? ? ?
gpg: DBG: chan_4 -> END
gpg: DBG: chan_4 <- OK
03337234 APDU: 00 20 00 82 06 31 32 33 34 35 36
00120625 SW: 90 00
Hope this all helps :-)
From my limited experience I know that cards can have pre-personalized
(aka unfused
) state. By using TK
(transport key) in combination with vendor-specific commands card's ATR and transmission protocol can be changed (once before fusing).
This is at least true for NXP JCOP cards.
AHA. So you mean it could be possible to like activate T1 protocol? Do you have maybe some command examples or links to resources how to do it? I have also downloaded some docs from producers website so I will try to find something similar in them.
I can find info only for JCOP (NXP cards). https://re-ws.pl/tag/jcop/
After fuse command changes can't be undone, card enters OP_READY state and applets can be loaded.
Thanks for the update. I have an ACOSJ on the way, so I can also try to replicate your problems. In the mean time I created a new branch to try to fix your issue. Could you try to see if the problem still occurs with the latest code in the PINissues
branch?