After
The setup is the same as in the previous article.
If I enter my PIN the PKCS#11 token provides a 3rd object corresponding to the private key.
Of course only part of the private key is available: the public exponent and the modulus. The private exponent (of the private key) is NOT available.
The program does not try to fetch and display sensitive attributes and so remove them from the list of attributes to fetch:
# remove the CKR_ATTRIBUTE_SENSITIVE attributes since we can't get
# their values and will get an exception instead
all_attributes.remove(PyKCS11.CKA_PRIVATE_EXPONENT)
all_attributes.remove(PyKCS11.CKA_PRIME_1)
all_attributes.remove(PyKCS11.CKA_PRIME_2)
all_attributes.remove(PyKCS11.CKA_EXPONENT_1)
all_attributes.remove(PyKCS11.CKA_EXPONENT_2)
all_attributes.remove(PyKCS11.CKA_COEFFICIENT)
The sample code also allows to sign a fixed message/pattern (a SHA1 digest) using the private key and verify the signature using the corresponding public key. Of course this is possible only if the private key is usable, so only after presenting the PIN code.
As with
If you just want to display the attribute of an object you can do that using a much simpler code. But that is for a future article.
getinfo.py
in a previous article the next sample from the PyKCS11 Python wrapper is dumpit.py
.Setup
The setup is the same as in the previous article.
Example codes provided with PyKCS11: dumpit.py
dumpit.py
is a short sample code to... dump (nearly) all the information from the token.Output
$ ./dumpit.py
Library manufacturerID: Gemalto
Available Slots: 5
Slot no: 0
slotDescription: Gemalto GemPC Twin 00 00
manufacturerID: Unknown
TokenInfo
label: .NET #AFC4963915BE14DB
manufacturerID: Gemalto
model: .NET Card
Opened session 0x00000001
Found 2 objects: [257, 514]
==================== Object: 257 ====================
Dumping attributes:
CKA_CLASS: CKO_CERTIFICATE (1)
CKA_PRIVATE: False
CKA_LABEL: eb155854-5522-60ea-16dc-016a5b43cd32
CKA_TOKEN: True
CKA_ID: 20 bytes
0000 EB 15 58 54 55 22 60 EA 16 DC 01 6A 5B 43 CD 32 ..XTU"`....j[C.2
0010 69 3D BE 1E i=..
CKA_VALUE: 1114 bytes
0000 30 82 04 56 30 82 03 BF A0 03 02 01 02 02 01 17 0..V0...........
0010 30 0D 06 09 2A 86 48 86 F7 0D 01 01 05 05 00 30 0...*.H........0
0020 7D 31 0B 30 09 06 03 55 04 06 13 02 46 52 31 13 }1.0...U....FR1.
0030 30 11 06 03 55 04 08 13 0A 53 6F 6D 65 2D 53 74 0...U....Some-St
0040 61 74 65 31 10 30 0E 06 03 55 04 07 13 07 41 75 ate1.0...U....Au
0050 62 61 67 6E 65 31 15 30 13 06 03 55 04 0A 13 0C bagne1.0...U....
0060 54 65 73 74 20 43 41 20 73 61 72 6C 31 10 30 0E Test CA sarl1.0.
0070 06 03 55 04 03 13 07 54 65 73 74 20 43 41 31 1E ..U....Test CA1.
0080 30 1C 06 09 2A 86 48 86 F7 0D 01 09 01 16 0F 72 0...*.H........r
0090 6F 6F 74 40 74 65 73 74 63 61 2E 63 6F 6D 30 1E oot@testca.com0.
00A0 17 0D 31 31 30 34 32 32 30 37 35 31 34 38 5A 17 ..110422075148Z.
00B0 0D 31 32 30 34 32 31 30 37 35 31 34 38 5A 30 7B .120421075148Z0{
00C0 31 0B 30 09 06 03 55 04 06 13 02 46 52 31 11 30 1.0...U....FR1.0
00D0 0F 06 03 55 04 07 13 08 4D 61 6E 6F 73 71 75 65 ...U....Manosque
00E0 31 15 30 13 06 03 55 04 0A 13 0C 54 65 73 74 20 1.0...U....Test
00F0 43 41 20 73 61 72 6C 31 19 30 17 06 03 55 04 03 CA sarl1.0...U..
0100 13 10 4C 75 64 6F 76 69 63 20 52 6F 75 73 73 65 ..Ludovic Rousse
0110 61 75 31 27 30 25 06 09 2A 86 48 86 F7 0D 01 09 au1'0%..*.H.....
0120 01 16 18 6C 75 64 6F 76 69 63 2E 72 6F 75 73 73 ...ludovic.rouss
0130 65 61 75 40 66 72 65 65 2E 66 72 30 82 01 22 30 eau@free.fr0.."0
0140 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05 00 03 82 ...*.H..........
0150 01 0F 00 30 82 01 0A 02 82 01 01 00 9F 9F 1E A4 ...0............
0160 4F 9B FD 76 23 D9 DD 43 46 EF DF 86 BC 80 D3 76 O..v#..CF......v
0170 30 40 22 C5 DB C6 E8 65 1F 37 7C 13 03 37 3A E2 0@"....e.7|..7:.
0180 C5 E8 5E 0B ED 51 5A 41 8F EF 2A 74 CE 10 10 2F ..^..QZA..*t.../
0190 0C 63 FE 1A 0F 25 86 20 EF 90 B8 EA 4E A6 1F 3B .c...%. ....N..;
01A0 B5 A2 76 37 B9 A4 E1 D2 0B 00 9E 6E 85 E3 AB 6B ..v7.......n...k
01B0 A1 4C 78 3C 5F B6 10 F6 0A 94 78 19 B2 B5 49 38 .Lx<_.....x...I8
01C0 FF B4 4F 69 41 90 ED 78 81 85 61 1C B6 75 70 CD ..OiA..x..a..up.
01D0 1D 16 7A 56 E7 FE C5 E8 F9 9B E9 CC F5 5E 3D BC ..zV.........^=.
01E0 10 94 FF 77 08 6D 51 2F 28 76 81 86 3C 4B 84 7D ...w.mQ/(v..<K.}
01F0 FE B3 4B FD 78 DA 8B 26 50 58 0E 80 3F 6F C0 F4 ..K.x..&PX..?o..
0200 2C 89 05 20 AF B9 1C 44 81 DA 51 5C DA BB 77 45 ,.. ...D..Q...wE
0210 85 E5 58 6C 14 A3 B6 24 D3 FB 00 A8 30 66 98 2A ..Xl...$....0f.*
0220 E2 C0 42 F6 E9 8D 3F 05 EF 77 0C 36 D1 DE D9 2F ..B...?..w.6.../
0230 EA DC 40 E9 A9 01 5B 88 E4 B3 46 4C AB CC 95 5C ..@...[...FL....
0240 AA C6 0C 3E 21 E0 42 1A 74 AD 7C D4 08 5B 07 14 ...>!.B.t.|..[..
0250 67 4F D1 A0 4C 8C 6C 41 A0 27 05 5D 02 03 01 00 gO..L.lA.'.]....
0260 01 A3 82 01 62 30 82 01 5E 30 09 06 03 55 1D 13 ....b0..^0...U..
0270 04 02 30 00 30 11 06 09 60 86 48 01 86 F8 42 01 ..0.0...`.H...B.
0280 01 04 04 03 02 04 B0 30 2B 06 09 60 86 48 01 86 .......0+..`.H..
0290 F8 42 01 0D 04 1E 16 1C 54 69 6E 79 43 41 20 47 .B......TinyCA G
02A0 65 6E 65 72 61 74 65 64 20 43 65 72 74 69 66 69 enerated Certifi
02B0 63 61 74 65 30 1D 06 03 55 1D 0E 04 16 04 14 87 cate0...U.......
02C0 7D A3 23 06 BF AE A8 D0 0C CD 6A 1F 91 DB 39 CB }.#.......j...9.
02D0 7E 95 2D 30 81 B0 06 03 55 1D 23 04 81 A8 30 81 ~.-0....U.#...0.
02E0 A5 80 14 40 3A CC 78 B2 19 6F 4B 15 2B A0 50 45 ...@:.x..oK.+.PE
02F0 83 85 B7 84 32 B8 A1 A1 81 81 A4 7F 30 7D 31 0B ....2.......0}1.
0300 30 09 06 03 55 04 06 13 02 46 52 31 13 30 11 06 0...U....FR1.0..
0310 03 55 04 08 13 0A 53 6F 6D 65 2D 53 74 61 74 65 .U....Some-State
0320 31 10 30 0E 06 03 55 04 07 13 07 41 75 62 61 67 1.0...U....Aubag
0330 6E 65 31 15 30 13 06 03 55 04 0A 13 0C 54 65 73 ne1.0...U....Tes
0340 74 20 43 41 20 73 61 72 6C 31 10 30 0E 06 03 55 t CA sarl1.0...U
0350 04 03 13 07 54 65 73 74 20 43 41 31 1E 30 1C 06 ....Test CA1.0..
0360 09 2A 86 48 86 F7 0D 01 09 01 16 0F 72 6F 6F 74 .*.H........root
0370 40 74 65 73 74 63 61 2E 63 6F 6D 82 09 00 88 E6 @testca.com.....
0380 B9 B6 6A BE 9B 09 30 1A 06 03 55 1D 12 04 13 30 ..j...0...U....0
0390 11 81 0F 72 6F 6F 74 40 74 65 73 74 63 61 2E 63 ...root@testca.c
03A0 6F 6D 30 23 06 03 55 1D 11 04 1C 30 1A 81 18 6C om0#..U....0...l
03B0 75 64 6F 76 69 63 2E 72 6F 75 73 73 65 61 75 40 udovic.rousseau@
03C0 66 72 65 65 2E 66 72 30 0D 06 09 2A 86 48 86 F7 free.fr0...*.H..
03D0 0D 01 01 05 05 00 03 81 81 00 8C 06 99 70 61 45 .............paE
03E0 7E 3E A5 7F D9 11 41 78 5C 8D C6 B5 65 28 2B 3D ~>....Ax....e(+=
03F0 03 D0 E7 B8 6E CC B4 5D C3 FE 73 27 57 0B D6 62 ....n..]..s'W..b
0400 FF 0B 8B AE 55 16 E1 42 2B E4 52 7E 3F F7 F7 DA ....U..B+.R~?...
0410 52 18 E9 60 F7 9E 03 86 84 07 3D 83 AB DC F9 85 R..`......=.....
0420 32 F5 75 54 6E 5B 9E B8 E3 30 4D 40 CA 54 25 DC 2.uTn[...0M@.T%.
0430 75 24 DB 55 E5 9E A4 70 EF D0 A6 97 03 12 22 DE u$.U...p......".
0440 64 51 6C 3B 11 4A 0C 58 E1 F8 66 E2 AB 96 09 FA dQl;.J.X..f.....
0450 81 F9 18 A4 52 7E FC 52 93 96 ....R~.R..
CKA_CERTIFICATE_TYPE: CKC_X_509 (0)
CKA_ISSUER: 127 bytes
0000 30 7D 31 0B 30 09 06 03 55 04 06 13 02 46 52 31 0}1.0...U....FR1
0010 13 30 11 06 03 55 04 08 13 0A 53 6F 6D 65 2D 53 .0...U....Some-S
0020 74 61 74 65 31 10 30 0E 06 03 55 04 07 13 07 41 tate1.0...U....A
0030 75 62 61 67 6E 65 31 15 30 13 06 03 55 04 0A 13 ubagne1.0...U...
0040 0C 54 65 73 74 20 43 41 20 73 61 72 6C 31 10 30 .Test CA sarl1.0
0050 0E 06 03 55 04 03 13 07 54 65 73 74 20 43 41 31 ...U....Test CA1
0060 1E 30 1C 06 09 2A 86 48 86 F7 0D 01 09 01 16 0F .0...*.H........
0070 72 6F 6F 74 40 74 65 73 74 63 61 2E 63 6F 6D root@testca.com
CKA_SERIAL_NUMBER: 3 bytes
0000 02 01 17 ...
CKA_TRUSTED: True
CKA_SUBJECT: 125 bytes
0000 30 7B 31 0B 30 09 06 03 55 04 06 13 02 46 52 31 0{1.0...U....FR1
0010 11 30 0F 06 03 55 04 07 13 08 4D 61 6E 6F 73 71 .0...U....Manosq
0020 75 65 31 15 30 13 06 03 55 04 0A 13 0C 54 65 73 ue1.0...U....Tes
0030 74 20 43 41 20 73 61 72 6C 31 19 30 17 06 03 55 t CA sarl1.0...U
0040 04 03 13 10 4C 75 64 6F 76 69 63 20 52 6F 75 73 ....Ludovic Rous
0050 73 65 61 75 31 27 30 25 06 09 2A 86 48 86 F7 0D seau1'0%..*.H...
0060 01 09 01 16 18 6C 75 64 6F 76 69 63 2E 72 6F 75 .....ludovic.rou
0070 73 73 65 61 75 40 66 72 65 65 2E 66 72 sseau@free.fr
CKA_START_DATE: 0 bytes
CKA_END_DATE: 0 bytes
CKA_MODIFIABLE: True
==================== Object: 514 ====================
Dumping attributes:
CKA_CLASS: CKO_PUBLIC_KEY (2)
CKA_PRIVATE: False
CKA_LABEL: eb155854-5522-60ea-16dc-016a5b43cd32
CKA_TOKEN: True
CKA_ID: 20 bytes
0000 EB 15 58 54 55 22 60 EA 16 DC 01 6A 5B 43 CD 32 ..XTU"`....j[C.2
0010 69 3D BE 1E i=..
CKA_DERIVE: 1 bytes
0000 00 .
CKA_KEY_TYPE: CKK_RSA (0)
CKA_SUBJECT: 0 bytes
CKA_ENCRYPT: True
CKA_WRAP: True
CKA_VERIFY: True
CKA_VERIFY_RECOVER: True
CKA_START_DATE: 0 bytes
CKA_END_DATE: 0 bytes
CKA_MODULUS: 256 bytes
0000 9F 9F 1E A4 4F 9B FD 76 23 D9 DD 43 46 EF DF 86 ....O..v#..CF...
0010 BC 80 D3 76 30 40 22 C5 DB C6 E8 65 1F 37 7C 13 ...v0@"....e.7|.
0020 03 37 3A E2 C5 E8 5E 0B ED 51 5A 41 8F EF 2A 74 .7:...^..QZA..*t
0030 CE 10 10 2F 0C 63 FE 1A 0F 25 86 20 EF 90 B8 EA .../.c...%. ....
0040 4E A6 1F 3B B5 A2 76 37 B9 A4 E1 D2 0B 00 9E 6E N..;..v7.......n
0050 85 E3 AB 6B A1 4C 78 3C 5F B6 10 F6 0A 94 78 19 ...k.Lx<_.....x.
0060 B2 B5 49 38 FF B4 4F 69 41 90 ED 78 81 85 61 1C ..I8..OiA..x..a.
0070 B6 75 70 CD 1D 16 7A 56 E7 FE C5 E8 F9 9B E9 CC .up...zV........
0080 F5 5E 3D BC 10 94 FF 77 08 6D 51 2F 28 76 81 86 .^=....w.mQ/(v..
0090 3C 4B 84 7D FE B3 4B FD 78 DA 8B 26 50 58 0E 80 <K.}..K.x..&PX..
00A0 3F 6F C0 F4 2C 89 05 20 AF B9 1C 44 81 DA 51 5C ?o..,.. ...D..Q.
00B0 DA BB 77 45 85 E5 58 6C 14 A3 B6 24 D3 FB 00 A8 ..wE..Xl...$....
00C0 30 66 98 2A E2 C0 42 F6 E9 8D 3F 05 EF 77 0C 36 0f.*..B...?..w.6
00D0 D1 DE D9 2F EA DC 40 E9 A9 01 5B 88 E4 B3 46 4C .../..@...[...FL
00E0 AB CC 95 5C AA C6 0C 3E 21 E0 42 1A 74 AD 7C D4 .......>!.B.t.|.
00F0 08 5B 07 14 67 4F D1 A0 4C 8C 6C 41 A0 27 05 5D .[..gO..L.lA.'.]
CKA_MODULUS_BITS: 2048
CKA_PUBLIC_EXPONENT: 3 bytes
0000 01 00 01 ...
CKA_MODIFIABLE: True
CKA_LOCAL: False
Slot no: 1
slotDescription: empty
manufacturerID: Unknown
Error: CKR_TOKEN_NOT_PRESENT (0x000000E0)
Slot no: 2
slotDescription: empty
manufacturerID: Unknown
Error: CKR_TOKEN_NOT_PRESENT (0x000000E0)
Slot no: 3
slotDescription: empty
manufacturerID: Unknown
Error: CKR_TOKEN_NOT_PRESENT (0x000000E0)
Slot no: 4
slotDescription: empty
manufacturerID: Unknown
Error: CKR_TOKEN_NOT_PRESENT (0x000000E0)
Comments
The card only contains one certificate and a pair of RSA keys. Without the PIN code only the public key is visible, the private key is hidden.Output after authentication
If I enter my PIN the PKCS#11 token provides a 3rd object corresponding to the private key.
[...]
Found 3 objects: [257, 514, 4881]
[...]
==================== Object: 4881 ====================
Dumping attributes:
CKA_CLASS: CKO_PRIVATE_KEY (3)
CKA_PRIVATE: True
CKA_LABEL: gemalto
CKA_TOKEN: True
CKA_ID: 20 bytes
0000 EB 15 58 54 55 22 60 EA 16 DC 01 6A 5B 43 CD 32 ..XTU"`....j[C.2
0010 69 3D BE 1E i=..
CKA_DERIVE: 1 bytes
0000 00 .
CKA_KEY_TYPE: CKK_RSA (0)
CKA_SUBJECT: 125 bytes
0000 30 7B 31 0B 30 09 06 03 55 04 06 13 02 46 52 31 0{1.0...U....FR1
0010 11 30 0F 06 03 55 04 07 13 08 4D 61 6E 6F 73 71 .0...U....Manosq
0020 75 65 31 15 30 13 06 03 55 04 0A 13 0C 54 65 73 ue1.0...U....Tes
0030 74 20 43 41 20 73 61 72 6C 31 19 30 17 06 03 55 t CA sarl1.0...U
0040 04 03 13 10 4C 75 64 6F 76 69 63 20 52 6F 75 73 ....Ludovic Rous
0050 73 65 61 75 31 27 30 25 06 09 2A 86 48 86 F7 0D seau1'0%..*.H...
0060 01 09 01 16 18 6C 75 64 6F 76 69 63 2E 72 6F 75 .....ludovic.rou
0070 73 73 65 61 75 40 66 72 65 65 2E 66 72 sseau@free.fr
CKA_SENSITIVE: True
CKA_DECRYPT: True
CKA_UNWRAP: True
CKA_SIGN: True
CKA_SIGN_RECOVER: True
CKA_START_DATE: 0 bytes
CKA_END_DATE: 0 bytes
CKA_MODULUS: 256 bytes
0000 9F 9F 1E A4 4F 9B FD 76 23 D9 DD 43 46 EF DF 86 ....O..v#..CF...
0010 BC 80 D3 76 30 40 22 C5 DB C6 E8 65 1F 37 7C 13 ...v0@"....e.7|.
0020 03 37 3A E2 C5 E8 5E 0B ED 51 5A 41 8F EF 2A 74 .7:...^..QZA..*t
0030 CE 10 10 2F 0C 63 FE 1A 0F 25 86 20 EF 90 B8 EA .../.c...%. ....
0040 4E A6 1F 3B B5 A2 76 37 B9 A4 E1 D2 0B 00 9E 6E N..;..v7.......n
0050 85 E3 AB 6B A1 4C 78 3C 5F B6 10 F6 0A 94 78 19 ...k.Lx<_.....x.
0060 B2 B5 49 38 FF B4 4F 69 41 90 ED 78 81 85 61 1C ..I8..OiA..x..a.
0070 B6 75 70 CD 1D 16 7A 56 E7 FE C5 E8 F9 9B E9 CC .up...zV........
0080 F5 5E 3D BC 10 94 FF 77 08 6D 51 2F 28 76 81 86 .^=....w.mQ/(v..
0090 3C 4B 84 7D FE B3 4B FD 78 DA 8B 26 50 58 0E 80 <K.}..K.x..&PX..
00A0 3F 6F C0 F4 2C 89 05 20 AF B9 1C 44 81 DA 51 5C ?o..,.. ...D..Q.
00B0 DA BB 77 45 85 E5 58 6C 14 A3 B6 24 D3 FB 00 A8 ..wE..Xl...$....
00C0 30 66 98 2A E2 C0 42 F6 E9 8D 3F 05 EF 77 0C 36 0f.*..B...?..w.6
00D0 D1 DE D9 2F EA DC 40 E9 A9 01 5B 88 E4 B3 46 4C .../..@...[...FL
00E0 AB CC 95 5C AA C6 0C 3E 21 E0 42 1A 74 AD 7C D4 .......>!.B.t.|.
00F0 08 5B 07 14 67 4F D1 A0 4C 8C 6C 41 A0 27 05 5D .[..gO..L.lA.'.]
CKA_PUBLIC_EXPONENT: 3 bytes
0000 01 00 01 ...
CKA_EXTRACTABLE: 1 bytes
0000 00 .
CKA_NEVER_EXTRACTABLE: True
CKA_ALWAYS_SENSITIVE: True
CKA_MODIFIABLE: True
CKA_LOCAL: False
Slot no: 1
slotDescription: empty
manufacturerID: Unknown
Error: CKR_TOKEN_NOT_PRESENT (0x000000E0)
Slot no: 2
slotDescription: empty
manufacturerID: Unknown
Error: CKR_TOKEN_NOT_PRESENT (0x000000E0)
Slot no: 3
slotDescription: empty
manufacturerID: Unknown
Error: CKR_TOKEN_NOT_PRESENT (0x000000E0)
Slot no: 4
slotDescription: empty
manufacturerID: Unknown
Error: CKR_TOKEN_NOT_PRESENT (0x000000E0)
Comments
Of course only part of the private key is available: the public exponent and the modulus. The private exponent (of the private key) is NOT available.
Source code
The program does not try to fetch and display sensitive attributes and so remove them from the list of attributes to fetch:
# remove the CKR_ATTRIBUTE_SENSITIVE attributes since we can't get
# their values and will get an exception instead
all_attributes.remove(PyKCS11.CKA_PRIVATE_EXPONENT)
all_attributes.remove(PyKCS11.CKA_PRIME_1)
all_attributes.remove(PyKCS11.CKA_PRIME_2)
all_attributes.remove(PyKCS11.CKA_EXPONENT_1)
all_attributes.remove(PyKCS11.CKA_EXPONENT_2)
all_attributes.remove(PyKCS11.CKA_COEFFICIENT)
#!/usr/bin/env python
# Copyright (C) 2006-2008 Ludovic Rousseau (ludovic.rousseau@free.fr)
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import PyKCS11
import getopt
import sys
import platform
# from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/142812
# Title: Hex dumper
# Submitter: Sebastien Keim (other recipes)
# Last Updated: 2002/08/05
# Version no: 1.0
def hexx(intval):
x = hex(intval)[2:]
if (x[-1:].upper() == 'L'):
x = x[:-1]
if len(x) % 2 != 0:
return "0%s" % x
return x
def dump(src, length=8):
FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.' for x in range(256)])
N = 0
result = ''
while src:
s, src = src[:length], src[length:]
hexa = ' '.join(["%02X" % ord(x) for x in s])
s = s.translate(FILTER)
result += "%04X %-*s %s\n" % (N, length * 3, hexa, s)
N += length
return result
def usage():
print "Usage:", sys.argv[0],
print "[-p pin][--pin=pin]",
print "[-c lib][--lib=lib]",
print "[-S][--sign]",
print "[-d][--decrypt]",
print "[-h][--help]",
try:
opts, args = getopt.getopt(sys.argv[1:], "p:c:Sd:h", ["pin=", "lib=", "sign", "decrypt", "help"])
except getopt.GetoptError:
# print help information and exit:
usage()
sys.exit(2)
pin_available = False
decrypt = sign = False
lib = None
for o, a in opts:
if o in ("-h", "--help"):
usage()
sys.exit()
elif o in ("-p", "--pin"):
pin = a
pin_available = True
elif o in ("-c", "--lib"):
lib = a
print "using PKCS11 lib:", lib
elif o in ("-S", "--sign"):
sign = True
elif o in ("-d", "--decrypt"):
decrypt = True
red = blue = magenta = normal = ""
if sys.stdout.isatty() and platform.system().lower() != 'windows':
red = "\x1b[01;31m"
blue = "\x1b[34m"
magenta = "\x1b[35m"
normal = "\x1b[0m"
format_long = magenta + " %s:" + blue + " %s (%s)" + normal
format_binary = magenta + " %s:" + blue + " %d bytes" + normal
format_normal = magenta + " %s:" + blue + " %s" + normal
pkcs11 = PyKCS11.PyKCS11Lib()
pkcs11.load(lib)
info = pkcs11.getInfo()
print "Library manufacturerID: " + info.manufacturerID
slots = pkcs11.getSlotList()
print "Available Slots:", len(slots)
for s in slots:
try:
i = pkcs11.getSlotInfo(s)
print "Slot no:", s
print format_normal % ("slotDescription", i.slotDescription.strip())
print format_normal % ("manufacturerID", i.manufacturerID.strip())
t = pkcs11.getTokenInfo(s)
print "TokenInfo"
print format_normal % ("label", t.label.strip())
print format_normal % ("manufacturerID", t.manufacturerID.strip())
print format_normal % ("model", t.model.strip())
session = pkcs11.openSession(s)
print "Opened session 0x%08X" % session.session.value()
if pin_available:
try:
session.login(pin=pin)
except:
print "login failed, exception:", str(sys.exc_info()[1])
objects = session.findObjects()
print "Found %d objects: %s" % (len(objects), [x.value() for x in objects])
all_attributes = PyKCS11.CKA.keys()
# remove the CKR_ATTRIBUTE_SENSITIVE attributes since we can't get
# their values and will get an exception instead
all_attributes.remove(PyKCS11.CKA_PRIVATE_EXPONENT)
all_attributes.remove(PyKCS11.CKA_PRIME_1)
all_attributes.remove(PyKCS11.CKA_PRIME_2)
all_attributes.remove(PyKCS11.CKA_EXPONENT_1)
all_attributes.remove(PyKCS11.CKA_EXPONENT_2)
all_attributes.remove(PyKCS11.CKA_COEFFICIENT)
# only use the integer values and not the strings like 'CKM_RSA_PKCS'
all_attributes = [e for e in all_attributes if isinstance(e, int)]
for o in objects:
print (red + "==================== Object: %d ====================" + normal) % o.value()
attributes = session.getAttributeValue(o, all_attributes)
attrDict = dict(zip(all_attributes, attributes))
if attrDict[PyKCS11.CKA_CLASS] == PyKCS11.CKO_PRIVATE_KEY \
and attrDict[PyKCS11.CKA_KEY_TYPE] == PyKCS11.CKK_RSA:
m = attrDict[PyKCS11.CKA_MODULUS]
e = attrDict[PyKCS11.CKA_PUBLIC_EXPONENT]
if m and e:
mx = eval('0x%s' % ''.join(chr(c) for c in m).encode('hex'))
ex = eval('0x%s' % ''.join(chr(c) for c in e).encode('hex'))
if sign:
try:
toSign = "12345678901234567890" # 20 bytes, SHA1 digest
print "* Signing with object 0x%08X following data: %s" % (o.value(), toSign)
signature = session.sign(o, toSign)
s = ''.join(chr(c) for c in signature).encode('hex')
sx = eval('0x%s' % s)
print "Signature:"
print dump(''.join(map(chr, signature)), 16)
if m and e:
print "Verifying using following public key:"
print "Modulus:"
print dump(''.join(map(chr, m)), 16)
print "Exponent:"
print dump(''.join(map(chr, e)), 16)
decrypted = pow(sx, ex, mx) # RSA
print "Decrypted:"
d = hexx(decrypted).decode('hex')
print dump(d, 16)
if toSign == d[-20:]:
print "*** signature VERIFIED!\n"
else:
print "*** signature NOT VERIFIED; decrypted value:"
print hex(decrypted), "\n"
else:
print "Unable to verify signature: MODULUS/PUBLIC_EXP not found"
except:
print "Sign failed, exception:", str(sys.exc_info()[1])
if decrypt:
if m and e:
try:
toEncrypt = "12345678901234567890"
# note: PKCS1 BT2 padding should be random data,
# but this is just a test and we use 0xFF...
padded = "\x00\x02%s\x00%s" % ("\xFF" * (128 - (len(toEncrypt)) - 3), toEncrypt)
print "* Decrypting with 0x%08X following data: %s" % (o.value(), toEncrypt)
print "padded:\n", dump(padded, 16)
encrypted = pow(eval('0x%sL' % padded.encode('hex')), ex, mx) # RSA
encrypted1 = hexx(encrypted).decode('hex')
print "encrypted:\n", dump(encrypted1, 16)
decrypted = session.decrypt(o, encrypted1)
decrypted1 = ''.join(chr(i) for i in decrypted)
print "decrypted:\n", dump(decrypted1, 16)
if decrypted1 == toEncrypt:
print "decryption SUCCESSFULL!\n"
else:
print "decryption FAILED!\n"
except:
print "Decrypt failed, exception:", str(sys.exc_info()[1])
else:
print "ERROR: Private key don't have MODULUS/PUBLIC_EXP"
print "Dumping attributes:"
for q, a in zip(all_attributes, attributes):
if a == None:
# undefined (CKR_ATTRIBUTE_TYPE_INVALID) attribute
continue
if q == PyKCS11.CKA_CLASS:
print format_long % (PyKCS11.CKA[q], PyKCS11.CKO[a], a)
elif q == PyKCS11.CKA_CERTIFICATE_TYPE:
print format_long % (PyKCS11.CKA[q], PyKCS11.CKC[a], a)
elif q == PyKCS11.CKA_KEY_TYPE:
print format_long % (PyKCS11.CKA[q], PyKCS11.CKK[a], a)
elif session.isBin(q):
print format_binary % (PyKCS11.CKA[q], len(a))
if a:
print dump(''.join(map(chr, a)), 16),
elif q == PyKCS11.CKA_SERIAL_NUMBER:
print format_binary % (PyKCS11.CKA[q], len(a))
if a:
print dump(a, 16),
else:
print format_normal % (PyKCS11.CKA[q], a)
if pin_available:
try:
session.logout()
except:
print "logout failed, exception:", str(sys.exc_info()[1])
session.closeSession()
except PyKCS11.PyKCS11Error, e:
print "Error:", e
Signing and verifying
The sample code also allows to sign a fixed message/pattern (a SHA1 digest) using the private key and verify the signature using the corresponding public key. Of course this is possible only if the private key is usable, so only after presenting the PIN code.
$ ./dumpit.py --pin=0000 --sign
[...]
==================== Object: 4881 ====================
* Signing with object 0x00001311 following data: 12345678901234567890
Signature:
0000 61 A8 4D EC A2 56 CA E8 23 03 1F 64 D9 C9 ED DD a.M..V..#..d....
0010 AA 4D DD 08 E9 21 1E 90 26 9B EB C0 29 AA 8E 3E .M...!..&...)..>
0020 AF 8D A6 70 1A 24 69 62 5A 70 F5 DD 7A 00 04 15 ...p.$ibZp..z...
0030 14 4A BC 45 24 5B 36 48 FC 2D C8 A1 81 E9 46 D3 .J.E$[6H.-....F.
0040 11 E4 C9 47 7A 63 26 67 9D 64 88 2F E1 DA 8D D7 ...Gzc&g.d./....
0050 A3 93 0E 58 7A 52 BE DC 55 09 95 88 56 8D 02 81 ...XzR..U...V...
0060 75 37 E8 A3 82 DC 91 D3 95 67 D4 26 91 6B 39 6A u7.......g.&.k9j
0070 0D B3 70 EB 99 EC 52 94 2C D1 33 14 78 B8 8F C0 ..p...R.,.3.x...
0080 B5 DA 3E 60 45 6F 11 AF 5C 56 57 85 05 45 B3 E6 ..>`Eo...VW..E..
0090 0D 05 17 8A 2A 20 D2 59 EC F9 97 60 0B E2 2C D5 ....* .Y...`..,.
00A0 62 3C D4 4B 31 5A 6A D6 B5 25 98 9A 2F 92 99 50 b<.K1Zj..%../..P
00B0 35 89 2F 13 2A C1 55 DF B9 52 BB 51 ED B7 98 90 5./.*.U..R.Q....
00C0 1C 46 F3 82 03 A5 CC 72 E9 C2 47 ED 0E A2 24 89 .F.....r..G...$.
00D0 0C 5B D0 A0 79 CF BD 5D 61 50 51 16 C9 62 6C B0 .[..y..]aPQ..bl.
00E0 4E 0D 6D 48 86 8F 94 E7 0F E8 56 50 36 18 AF E3 N.mH......VP6...
00F0 C5 73 4F B9 DD 0B 2C B0 A6 68 57 D5 A4 8A C2 5C .sO...,..hW.....
Verifying using following public key:
Modulus:
0000 9F 9F 1E A4 4F 9B FD 76 23 D9 DD 43 46 EF DF 86 ....O..v#..CF...
0010 BC 80 D3 76 30 40 22 C5 DB C6 E8 65 1F 37 7C 13 ...v0@"....e.7|.
0020 03 37 3A E2 C5 E8 5E 0B ED 51 5A 41 8F EF 2A 74 .7:...^..QZA..*t
0030 CE 10 10 2F 0C 63 FE 1A 0F 25 86 20 EF 90 B8 EA .../.c...%. ....
0040 4E A6 1F 3B B5 A2 76 37 B9 A4 E1 D2 0B 00 9E 6E N..;..v7.......n
0050 85 E3 AB 6B A1 4C 78 3C 5F B6 10 F6 0A 94 78 19 ...k.Lx<_.....x.
0060 B2 B5 49 38 FF B4 4F 69 41 90 ED 78 81 85 61 1C ..I8..OiA..x..a.
0070 B6 75 70 CD 1D 16 7A 56 E7 FE C5 E8 F9 9B E9 CC .up...zV........
0080 F5 5E 3D BC 10 94 FF 77 08 6D 51 2F 28 76 81 86 .^=....w.mQ/(v..
0090 3C 4B 84 7D FE B3 4B FD 78 DA 8B 26 50 58 0E 80 <K.}..K.x..&PX..
00A0 3F 6F C0 F4 2C 89 05 20 AF B9 1C 44 81 DA 51 5C ?o..,.. ...D..Q.
00B0 DA BB 77 45 85 E5 58 6C 14 A3 B6 24 D3 FB 00 A8 ..wE..Xl...$....
00C0 30 66 98 2A E2 C0 42 F6 E9 8D 3F 05 EF 77 0C 36 0f.*..B...?..w.6
00D0 D1 DE D9 2F EA DC 40 E9 A9 01 5B 88 E4 B3 46 4C .../..@...[...FL
00E0 AB CC 95 5C AA C6 0C 3E 21 E0 42 1A 74 AD 7C D4 .......>!.B.t.|.
00F0 08 5B 07 14 67 4F D1 A0 4C 8C 6C 41 A0 27 05 5D .[..gO..L.lA.'.]
Exponent:
0000 01 00 01 ...
Decrypted:
0000 01 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0010 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0020 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0030 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0040 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0050 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0060 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0070 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0080 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0090 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00A0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00B0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00E0 FF FF FF FF FF FF FF FF FF FF 00 31 32 33 34 35 ...........12345
00F0 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 678901234567890
*** signature VERIFIED!
Conclusion
As with
getinfo.py
the sample code dumpit.py
is more complex than needed to parse the command line arguments and pretty display the results (in color).If you just want to display the attribute of an object you can do that using a much simpler code. But that is for a future article.
ConversionConversion EmoticonEmoticon