github-af / SmartPGP

SmartPGP is a JavaCard implementation of the OpenPGP card specifications
GNU General Public License v2.0
232 stars 48 forks source link

Strange(?) response when trying to read RSA public key #44

Closed v3rm0n closed 2 years ago

v3rm0n commented 2 years ago

Trying to get the key from the card, but I'm seeing something that I don't understand.

For example, first command gpg-connect-agent --hex "scd apdu 00 47 81 00 02 b8 00" /bye Gives

D[0000]  7F 49 82 01 09 81 82 01  00 B4 DD 22 74 D9 EA D7   .I........."t...
D[0010]  B2 A0 C4 6A 51 EA 27 87  DD FD DD 38 AA 97 10 37   ...jQ.'....8...7
D[0020]  98 BE 47 A0 4A AC 9F 09  2A 44 D4 4B 13 33 D3 76   ..G.J...*D.K.3.v
D[0030]  B1 E3 80 03 1D 88 9F E7  10 07 57 52 41 DA FD 05   ..........WRA...
D[0040]  E8 1D FA E6 D4 26 AA 12  22 B4 A3 E6 69 34 5C 17   .....&.."...i4\.
D[0050]  05 C6 0B 74 16 41 5A C3  3B ED 78 78 9F AE 86 4F   ...t.AZ.;.xx...O
D[0060]  EE 4E 4F 94 42 00 6E B1  1F B7 5B 72 48 2C 45 A5   .NO.B.n...[rH,E.
D[0070]  4B 2D 52 64 62 68 B0 4C  61 1D 8B 6F 3B AA 6A 17   K-Rdbh.La..o;.j.
D[0080]  90 14 D7 CC 9E 7F F0 46  44 F1 96 62 B3 8B 2B 81   .......FD..b..+.
D[0090]  07 1D D3 22 00 A0 EB 01  7B 9A F9 25 30 41 34 3D   ..."....{..%0A4=
D[00A0]  39 8D A1 40 08 B4 E6 25  32 35 B4 CC 4E 00 4F 7E   9..@...%25..N.O~
D[00B0]  99 11 0C F4 69 E1 14 25  30 41 68 DC 79 97 98 46   ....i..%0Ah.y..F
D[00C0]  FE 8A 45 78 9D 9A 27 E5  A9 A0 8A B5 2C BC 2B 46   ..Ex..'.....,.+F
D[00D0]  DE 68 72 53 A2 94 EB D2  C8 D1 09 44 72 31 13 08   .hrS.......Dr1..
D[00E0]  D4 63 85 DA 1A FA C1 D2  F2 B7 E4 2E 6C 96 E5 E1   .c..........l...
D[00F0]  57 CE 4B BE 11 8A E2 24  FD 60 74 C7 F5 28 2F 12   W.K....$.`t..(/.
D[0100]  5E 12 35 84 FC 42 61 0E                            ^.5..Ba.
OK

Since I get 0x610E I'm running: gpg-connect-agent --hex "scd apdu 00 c0 00 00" /bye

D[0000]  59 0E 6F 48 46 C7 D3 35  A9 82 03 01 00 01 90 00   Y.oHF..5........
OK

Why do I think it's strange: the length of 0x7F49 should be 265 (0x0109), but the actual response is longer (280 - 4 sw bytes - 5 header bytes = 271)

Looks like the modulus is 6 bytes too long. If I remove it then everything fits:

What am I not getting here?

af-anssi commented 2 years ago

You are right, there is something odd in the response you get from you card. It seems your public key is RSA 2048 bits (= 256 bytes = 0x100) but the modulus in the response is longer (262 bytes = 0x106); the exponent is normal (3 bytes). See below for the parsing of the response.

7F49  82 0109
  81  82 0100 (<= expected length, but actual data length is 0x106)
   [000] B4 DD 22 74 D9 EA D7 B2  A0 C4 6A 51 EA 27 87 DD
   [010] FD DD 38 AA 97 10 37 98  BE 47 A0 4A AC 9F 09 2A
   [020] 44 D4 4B 13 33 D3 76 B1  E3 80 03 1D 88 9F E7 10
   [030] 07 57 52 41 DA FD 05 E8  1D FA E6 D4 26 AA 12 22
   [040] B4 A3 E6 69 34 5C 17 05  C6 0B 74 16 41 5A C3 3B
   [050] ED 78 78 9F AE 86 4F EE  4E 4F 94 42 00 6E B1 1F
   [060] B7 5B 72 48 2C 45 A5 4B  2D 52 64 62 68 B0 4C 61
   [070] 1D 8B 6F 3B AA 6A 17 90  14 D7 CC 9E 7F F0 46 44
   [080] F1 96 62 B3 8B 2B 81 07  1D D3 22 00 A0 EB 01 7B
   [090] 9A F9 25 30 41 34 3D 39  8D A1 40 08 B4 E6 25 32
   [0A0] 35 B4 CC 4E 00 4F 7E 99  11 0C F4 69 E1 14 25 30
   [0B0] 41 68 DC 79 97 98 46 FE  8A 45 78 9D 9A 27 E5 A9
   [0C0] A0 8A B5 2C BC 2B 46 DE  68 72 53 A2 94 EB D2 C8
   [0D0] D1 09 44 72 31 13 08 D4  63 85 DA 1A FA C1 D2 F2
   [0E0] B7 E4 2E 6C 96 E5 E1 57  CE 4B BE 11 8A E2 24 FD
   [0F0] 60 74 C7 F5 28 2F 12 5E  12 35 84 FC 42 59 0E 6F
   [100] 48 46 C7 D3 35 A9
  82  03
   [000] 01 00 01 

Which version of SmartPGP are you running ? On which card have you installed it ? Could you post the output of gpg2 --card-status ?

af-anssi commented 2 years ago

This key has been generated in your card or have you imported it ?

v3rm0n commented 2 years ago

I'm running the latest javacard-3.0.1 branch on a JC30M48CR card, the key is generated on the card. gpg --card-status gives me:

Reader ...........: OMNIKEY CardMan 1021
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 : 4
KDF setting ......: off
Signature key ....: 98BC 79A3 8F40 468E 7431  E04E DEF0 4473 E7BC 7B57
      created ....: 2022-06-10 13:42:15
Encryption key....: C0BD FEA3 FD76 FA3B 7E96  D56E 2314 1F97 08F1 C9CB
      created ....: 2022-06-10 13:42:15
Authentication key: EA96 E0EC 7AC8 8B63 4406  57E0 5D72 9719 98ED 0522
      created ....: 2022-06-10 13:42:15
General key info..: pub  rsa2048/DEF04473E7BC7B57 2022-06-10 Maido
sec>  rsa2048/DEF04473E7BC7B57  created: 2022-06-10  expires: never
                                card-no: AFAF 00000000
ssb>  rsa2048/5D72971998ED0522  created: 2022-06-10  expires: never
                                card-no: AFAF 00000000
ssb>  rsa2048/23141F9708F1C9CB  created: 2022-06-10  expires: never
                                card-no: AFAF 00000000

By the way I'm seeing the same thing happening on my Yubikey with both rsa2048 and rsa4096...

af-anssi commented 2 years ago

Ok there is nothing odd in the key attributes.

The expected length of the modulus (0x100 here) is obtained from the key attributes and is used to build the tag-length attribute for the modulus (81 820100): https://github.com/ANSSI-FR/SmartPGP/blob/0ae195547852911bf208478ec99d5308e0428d02/src/fr/anssi/smartpgp/PGPKey.java#L548

Then the modulus data are written using the standard API of the JavaCard system: https://github.com/ANSSI-FR/SmartPGP/blob/0ae195547852911bf208478ec99d5308e0428d02/src/fr/anssi/smartpgp/PGPKey.java#L561

It seems this card has a strong problem either during key generation (it was asked for 2048 bits key but returned a larger one) or with the specific API above (it outputs the modulus plus "something else"...).

af-anssi commented 2 years ago

Are you able to use this key with GnuPG actually (sign+verify, encrypt+decrypt, authenticate via SSH for instance) ?

af-anssi commented 2 years ago

What about the two other keys ? Do they also have an incorrect modulus size ?

v3rm0n commented 2 years ago

Signature:

➜  SmartPGP git:(javacard-3.0.1) ✗ gpg-connect-agent --hex "scd apdu 00 47 81 00 02 b6 00" /bye
D[0000]  7F 49 82 01 09 81 82 01  00 CC 49 09 C3 BA 67 25   .I........I...g%
D[0010]  32 35 F9 16 7F FC 0E 86  10 25 30 41 BE 37 50 60   25.......%0A.7P`
D[0020]  D6 E6 C3 5B 68 02 F9 E2  88 4D 3B F2 3D E2 BF FD   ...[h....M;.=...
D[0030]  90 F8 4B F2 6D D8 C4 77  85 62 78 15 C2 F3 C8 BE   ..K.m..w.bx.....
D[0040]  27 77 7D A9 B1 45 E9 F6  9F 56 B0 7D B6 97 20 2D   'w}..E...V.}.. -
D[0050]  64 2A 17 41 31 26 73 CF  52 01 7B 98 19 64 20 ED   d*.A1&s.R.{..d .
D[0060]  EF 25 32 35 EE 0B EC D9  A2 74 F8 76 25 32 35 3A   .%25.....t.v%25:
D[0070]  5F D2 B0 96 96 F9 C3 9A  3A 8E 87 EA 57 FB 07 21   _.......:...W..!
D[0080]  BD 76 C3 EF 1C 07 81 BA  10 22 72 43 30 53 50 DB   .v......."rC0SP.
D[0090]  F6 2A 37 C3 7B 95 09 29  6D D9 63 AF E2 2F 4F EB   .*7.{..)m.c../O.
D[00A0]  FE 25 32 35 DA 01 40 D7  49 C8 0F D3 F9 8F D5 A7   .%25..@.I.......
D[00B0]  75 1B A0 DF D3 7F CA 71  78 83 28 A9 5B EC 05 A9   u......qx.(.[...
D[00C0]  C7 DA 26 D2 ED F6 73 F0  4D 75 11 71 A2 66 35 5B   ..&...s.Mu.q.f5[
D[00D0]  95 66 B0 90 CE 11 25 30  41 63 5D A1 EB 5B 93 6B   .f....%0Ac]..[.k
D[00E0]  7C 31 D7 BB 7F 0F C1 1A  C8 08 0C CF 22 86 39 01   |1..........".9.
D[00F0]  2B CD E0 63 AB B7 B1 1E  1A 5F 25 32 35 5A BE 90   +..c....._%25Z..
D[0100]  04 6E 4B 53 0C FA 95 5F  C1 13 5F D6 D1 64 61 0E   .nKS..._.._..da.
OK
➜  SmartPGP git:(javacard-3.0.1) ✗ gpg-connect-agent --hex "scd apdu 00 c0 00 00 00 00 00" /bye
D[0000]  A1 36 38 61 B0 BC DD 9A  EB 82 03 01 00 01 90 00   .68a............
OK

Authentication:

➜  SmartPGP git:(javacard-3.0.1) ✗ gpg-connect-agent --hex "scd apdu 00 47 81 00 02 a4 00" /bye
D[0000]  7F 49 82 01 09 81 82 01  00 B1 92 FF 7B DC 28 56   .I..........{.(V
D[0010]  70 D3 1A FC 5D 95 A5 50  0B B4 7D 4E 9E 68 4E 0B   p...]..P..}N.hN.
D[0020]  0F 53 89 CD 91 A2 33 C7  34 F7 B4 54 BF B1 DE 3C   .S....3.4..T...<
D[0030]  A7 1C 18 81 48 7A 3C F4  3B 80 33 62 20 0C 1D D0   ....Hz<.;.3b ...
D[0040]  99 2C 83 24 5A D8 67 7D  FD 79 3E 67 6D CE BA 92   .,.$Z.g}.y>gm...
D[0050]  E3 8F AF AD 08 C7 80 D4  17 28 B2 EF 2E A8 61 4F   .........(....aO
D[0060]  01 9F 75 26 80 45 1E CE  A2 C2 98 53 82 C6 69 C7   ..u&.E.....S..i.
D[0070]  39 34 92 69 76 A2 12 5C  90 46 12 BE 3C C5 2E 01   94.iv..\.F..<...
D[0080]  06 CE 79 7B F5 9E C4 C2  62 9E 6A 65 C2 C2 3B F9   ..y{....b.je..;.
D[0090]  65 30 99 9C 31 89 3B D2  E3 36 1D 7B 96 61 42 B3   e0..1.;..6.{.aB.
D[00A0]  FF 59 6C 4B AD 79 2D C9  4F 1A C2 31 56 BD 51 E0   .YlK.y-.O..1V.Q.
D[00B0]  C5 BC E6 55 AE 7C 15 53  30 00 45 FE 80 00 B1 E3   ...U.|.S0.E.....
D[00C0]  07 12 AD 3E CD A7 4F D5  BB A1 70 E0 06 F5 8D EF   ...>..O...p.....
D[00D0]  06 95 25 30 44 97 11 AB  FC 12 CB 9B 20 EF 43 A5   ..%0D....... .C.
D[00E0]  96 A4 25 32 35 0C 0E 76  3F 28 95 9C BC 56 DD 80   ..%25..v?(...V..
D[00F0]  36 9F EB FC FE E2 EC 68  98 C6 84 D5 2F 74 5F 15   6......h..../t_.
D[0100]  8E CD 1F 10 61 0E                                  ....a.
OK
➜  SmartPGP git:(javacard-3.0.1) ✗ gpg-connect-agent --hex "scd apdu 00 c0 00 00 00 00 00" /bye
D[0000]  28 A1 64 03 99 CD 98 EF  19 82 03 01 00 01 90 00   (.d.............
OK

I can encrypt/decrypt files using GPG with this smartcard...

A friend tried with his Yubikey and he got a similar result (incorrect modulus size), so a different smartcard, different computer, but the same platform (macOS with M1). Wondering if that has anything to do with it. Will try to see with a different platform just in case. ykman apdu -a OPENPGP -s 0047810002b800 -s 00c00000 gives a similar result for a Yubikey so not related to gpg itself I guess?

af-anssi commented 2 years ago

Could you give the output of gpg --list-keys --with-key-data XXXX where XXXX is the mail attached to you card ? I am only interested by lines starting with pkd:0:2048: which contain modulus of the corresponding keys as stored in gnupg. I would like to compare it with the modulus as returned by the card to know if/where there is special format/treatment.

v3rm0n commented 2 years ago

I've been experimenting a bit so the key has changed (but the issue hasn't) so the current state is:

➜  SmartPGP git:(javacard-3.0.1) ✗ gpg-connect-agent --hex "scd apdu 00 47 81 00 02 b8 00" /bye
D[0000]  7F 49 82 01 09 81 82 01  00 B2 11 17 07 78 C7 34   .I...........x.4
D[0010]  BD 99 CA F4 B8 3E CA 94  8F F8 4D 4F F9 B4 15 68   .....>....MO...h
D[0020]  DC 86 EC F4 37 37 9B 31  05 36 A5 B8 D8 9B 9C D5   ....77.1.6......
D[0030]  B8 CA 4A FC 0E 24 33 1F  17 2F 95 11 23 84 95 7A   ..J..$3../..#..z
D[0040]  F3 1F E2 B5 B5 CC 10 98  AF 2A DD 25 30 44 45 DE   .........*.%0DE.
D[0050]  AE A6 D1 1C D5 BD D9 AA  84 CB D6 92 98 6F 02 0E   .............o..
D[0060]  39 0E 97 94 B8 10 7B 50  81 BF 91 63 17 2D 8A FE   9.....{P...c.-..
D[0070]  D8 1A DA 67 D4 60 EF E2  58 C9 CC 73 B2 70 F4 B1   ...g.`..X..s.p..
D[0080]  5A 2D 3A C5 25 32 35 5A  82 BA 5D BF 96 B2 BD 97   Z-:.%25Z..].....
D[0090]  74 75 4E 86 9C 37 2C 4F  62 5E 75 14 95 52 E7 42   tuN..7,Ob^u..R.B
D[00A0]  EF A9 E2 1E 4A 32 DD 4E  C3 2D 43 71 0C 38 C9 E9   ....J2.N.-Cq.8..
D[00B0]  98 2B 56 2E 9A 25 30 41  41 43 F5 2E CF B9 60 2B   .+V..%0AAC....`+
D[00C0]  E3 2C B2 BC DC 98 B6 8F  FB 65 5C 59 F4 25 32 35   .,.......e\Y.%25
D[00D0]  A8 70 1D 4F CB 95 D7 CC  C3 32 97 3E 49 EA 70 18   .p.O.....2.>I.p.
D[00E0]  E4 A7 7B B0 5D 4A C9 E0  16 DA 01 81 AB 35 69 0C   ..{.]J.......5i.
D[00F0]  52 5E 72 AD BD FB D3 33  EB D9 6A 89 5F A2 8B A2   R^r....3..j._...
D[0100]  06 4E A0 6D D3 9F 5F 5F  61 0E                     .N.m..__a.
OK
➜  SmartPGP git:(javacard-3.0.1) ✗ gpg-connect-agent --hex "scd apdu 00 c0 00 00 00 00 00" /bye
D[0000]  83 AA 3C 64 C0 88 42 00  9F 82 03 01 00 01 90 00   ..<d..B.........
OK

Key data from gpg:

pkd:0:2048:B211170778C734BD99CAF4B83ECA948FF84D4FF9B41568DC86ECF437379B310536A5B8D89B9CD5B8CA4AFC0E24331F172F95112384957AF31FE2B5B5CC1098AF2ADD0D45DEAEA6D11CD5BDD9AA84CBD692986F020E390E9794B8107B5081BF9163172D8AFED81ADA67D460EFE258C9CC73B270F4B15A2D3AC5255A82BA5DBF96B2BD9774754E869C372C4F625E75149552E742EFA9E21E4A32DD4EC32D43710C38C9E9982B562E9A0A4143F52ECFB9602BE32CB2BCDC98B68FFB655C59F425A8701D4FCB95D7CCC332973E49EA7018E4A77BB05D4AC9E016DA0181AB35690C525E72ADBDFBD333EBD96A895FA28BA2064EA06DD39F5F5F83AA3C64C08842009F:
af-anssi commented 2 years ago

Thank you. For a reason I do not understand (yet), this card escapes some values (OD => 253044, 25 => 253235, ...) which is correctly understood by gnupg... And it seems that lengths are "correct"/"has expected", i.e. lengths are expressed on non-escaped data...

af-anssi commented 2 years ago

Could you try, with no scdaemon running, the following command opensc-tool -s 00:47:81:00:02:b8:00 ? Or dump the raw APDU commands and responses (pcscd -a -f -d) corresponding to the same command ? I would like to ensure where the escape is done (in the card or in scdaemon or ...).

v3rm0n commented 2 years ago
➜  gnupg git:(master) ✗ opensc-tool -s 00:47:81:00:02:b8:00
Using reader with a card: OMNIKEY CardMan 1021
Sending: 00 47 81 00 02 B8 00
Received (SW1=0x90, SW2=0x00):
7F 49 82 01 09 81 82 01 00 B2 11 17 07 78 C7 34 .I...........x.4
BD 99 CA F4 B8 3E CA 94 8F F8 4D 4F F9 B4 15 68 .....>....MO...h
DC 86 EC F4 37 37 9B 31 05 36 A5 B8 D8 9B 9C D5 ....77.1.6......
B8 CA 4A FC 0E 24 33 1F 17 2F 95 11 23 84 95 7A ..J..$3../..#..z
F3 1F E2 B5 B5 CC 10 98 AF 2A DD 0D 45 DE AE A6 .........*..E...
D1 1C D5 BD D9 AA 84 CB D6 92 98 6F 02 0E 39 0E ...........o..9.
97 94 B8 10 7B 50 81 BF 91 63 17 2D 8A FE D8 1A ....{P...c.-....
DA 67 D4 60 EF E2 58 C9 CC 73 B2 70 F4 B1 5A 2D .g.`..X..s.p..Z-
3A C5 25 5A 82 BA 5D BF 96 B2 BD 97 74 75 4E 86 :.%Z..].....tuN.
9C 37 2C 4F 62 5E 75 14 95 52 E7 42 EF A9 E2 1E .7,Ob^u..R.B....
4A 32 DD 4E C3 2D 43 71 0C 38 C9 E9 98 2B 56 2E J2.N.-Cq.8...+V.
9A 0A 41 43 F5 2E CF B9 60 2B E3 2C B2 BC DC 98 ..AC....`+.,....
B6 8F FB 65 5C 59 F4 25 A8 70 1D 4F CB 95 D7 CC ...e\Y.%.p.O....
C3 32 97 3E 49 EA 70 18 E4 A7 7B B0 5D 4A C9 E0 .2.>I.p...{.]J..
16 DA 01 81 AB 35 69 0C 52 5E 72 AD BD FB D3 33 .....5i.R^r....3
EB D9 6A 89 5F A2 8B A2 06 4E A0 6D D3 9F 5F 5F ..j._....N.m..__
af-anssi commented 2 years ago

Ok ! There is no problem here (no escaped value). So this is scdaemon or gpg-agent that escapes some values ! (That would have been very odd from the card). I cannot do anything at the applet level to solve this issue.

v3rm0n commented 2 years ago

Ah ok. Thanks for spending your time on this! I was looking for an adhoc way to read the public key from the card so I think I can just use opensc-tool instead of gpg-agent.

af-anssi commented 2 years ago

FYI if you want to continue using gpg-agent/scdaemon, the escaping is described here (see "raw data"): https://www.gnupg.org/documentation/manuals/assuan/Server-responses.html#Server-responses