root/pykcs11/trunk/samples/dumpit.py

Revision 195, 9.5 kB (checked in by lrousseau, 2 months ago)

make pep8 happy

  • Property svn:executable set to *
Line 
1 #!/usr/bin/env python
2
3 #   Copyright (C) 2006-2008 Ludovic Rousseau (ludovic.rousseau@free.fr)
4 #
5 # This file is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18
19 import PyKCS11
20 import getopt
21 import sys
22 import platform
23
24 # from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/142812
25 # Title: Hex dumper
26 # Submitter: Sebastien Keim (other recipes)
27 # Last Updated: 2002/08/05
28 # Version no: 1.0
29
30
31 def hexx(intval):
32     x = hex(intval)[2:]
33     if (x[-1:].upper() == 'L'):
34         x = x[:-1]
35     if len(x) % 2 != 0:
36         return "0%s" % x
37     return x
38
39
40 def dump(src, length=8):
41     FILTER = ''.join([(len(repr(chr(x))) == 3) and chr(x) or '.' for x in range(256)])
42     N = 0
43     result = ''
44     while src:
45         s, src = src[:length], src[length:]
46         hexa = ' '.join(["%02X" % ord(x) for x in s])
47         s = s.translate(FILTER)
48         result += "%04X   %-*s   %s\n" % (N, length * 3, hexa, s)
49         N += length
50     return result
51
52
53 def usage():
54     print "Usage:", sys.argv[0],
55     print "[-p pin][--pin=pin]",
56     print "[-c lib][--lib=lib]",
57     print "[-S][--sign]",
58     print "[-d][--decrypt]",
59     print "[-h][--help]",
60
61 try:
62     opts, args = getopt.getopt(sys.argv[1:], "p:c:Sd:h", ["pin=", "lib=", "sign", "decrypt", "help"])
63 except getopt.GetoptError:
64     # print help information and exit:
65     usage()
66     sys.exit(2)
67
68 pin_available = False
69 decrypt = sign = False
70 lib = None
71 for o, a in opts:
72     if o in ("-h", "--help"):
73         usage()
74         sys.exit()
75     elif o in ("-p", "--pin"):
76         pin = a
77         pin_available = True
78     elif o in ("-c", "--lib"):
79         lib = a
80         print "using PKCS11 lib:", lib
81     elif o in ("-S", "--sign"):
82         sign = True
83     elif o in ("-d", "--decrypt"):
84         decrypt = True
85
86 red = blue = magenta = normal = ""
87 if sys.stdout.isatty() and platform.system().lower() != 'windows':
88     red = "\x1b[01;31m"
89     blue = "\x1b[34m"
90     magenta = "\x1b[35m"
91     normal = "\x1b[0m"
92
93 format_long = magenta + "  %s:" + blue + " %s (%s)" + normal
94 format_binary = magenta + "  %s:" + blue + " %d bytes" + normal
95 format_normal = magenta + "  %s:" + blue + " %s" + normal
96
97 pkcs11 = PyKCS11.PyKCS11Lib()
98 pkcs11.load(lib)
99 info = pkcs11.getInfo()
100 print "Library manufacturerID: " + info.manufacturerID
101
102 slots = pkcs11.getSlotList()
103 print "Available Slots:", len(slots)
104
105 for s in slots:
106     try:
107         i = pkcs11.getSlotInfo(s)
108         print "Slot no:", s
109         print format_normal % ("slotDescription", i.slotDescription.strip())
110         print format_normal % ("manufacturerID", i.manufacturerID.strip())
111
112         t = pkcs11.getTokenInfo(s)
113         print "TokenInfo"
114         print format_normal % ("label", t.label.strip())
115         print format_normal % ("manufacturerID", t.manufacturerID.strip())
116         print format_normal % ("model", t.model.strip())
117
118         session = pkcs11.openSession(s)
119         print "Opened session 0x%08X" % session.session.value()
120         if pin_available:
121             try:
122                 session.login(pin=pin)
123             except:
124                 print "login failed, exception:", str(sys.exc_info()[1])
125
126         objects = session.findObjects()
127         print
128         print "Found %d objects: %s" % (len(objects), map(lambda x: "0x%08X" % x.value(), objects))
129
130         all_attributes = PyKCS11.CKA.keys()
131         # remove the CKR_ATTRIBUTE_SENSITIVE attributes since we can't get
132         # their values and will get an exception instead
133         all_attributes.remove(PyKCS11.CKA_PRIVATE_EXPONENT)
134         all_attributes.remove(PyKCS11.CKA_PRIME_1)
135         all_attributes.remove(PyKCS11.CKA_PRIME_2)
136         all_attributes.remove(PyKCS11.CKA_EXPONENT_1)
137         all_attributes.remove(PyKCS11.CKA_EXPONENT_2)
138         all_attributes.remove(PyKCS11.CKA_COEFFICIENT)
139         # only use the integer values and not the strings like 'CKM_RSA_PKCS'
140         all_attributes = [e for e in all_attributes if isinstance(e, int)]
141
142         for o in objects:
143             print
144             print (red + "==================== Object: 0x%08X ====================" + normal) % o.value()
145             attributes = session.getAttributeValue(o, all_attributes)
146             attrDict = dict(zip(all_attributes, attributes))
147             if attrDict[PyKCS11.CKA_CLASS] == PyKCS11.CKO_PRIVATE_KEY \
148                and attrDict[PyKCS11.CKA_KEY_TYPE] == PyKCS11.CKK_RSA:
149                 m = attrDict[PyKCS11.CKA_MODULUS]
150                 e = attrDict[PyKCS11.CKA_PUBLIC_EXPONENT]
151                 if m and e:
152                     mx = eval('0x%s' % ''.join(chr(c) for c in m).encode('hex'))
153                     ex = eval('0x%s' % ''.join(chr(c) for c in e).encode('hex'))
154                 if sign:
155                     try:
156                         toSign = "12345678901234567890"  # 20 bytes, SHA1 digest
157                         print "* Signing with object 0x%08X following data: %s" % (o.value(), toSign)
158                         signature = session.sign(o, toSign)
159                         s = ''.join(chr(c) for c in signature).encode('hex')
160                         sx = eval('0x%s' % s)
161                         print "Signature:"
162                         print dump(''.join(map(chr, signature)), 16)
163                         if m and e:
164                             print "Verifying using following public key:"
165                             print "Modulus:"
166                             print dump(''.join(map(chr, m)), 16)
167                             print "Exponent:"
168                             print dump(''.join(map(chr, e)), 16)
169                             decrypted = pow(sx, ex, mx)  # RSA
170                             print "Decrypted:"
171                             d = hexx(decrypted).decode('hex')
172                             print dump(d, 16)
173                             if toSign == d[-20:]:
174                                 print "*** signature VERIFIED!\n"
175                             else:
176                                 print "*** signature NOT VERIFIED; decrypted value:"
177                                 print hex(decrypted), "\n"
178                         else:
179                             print "Unable to verify signature: MODULUS/PUBLIC_EXP not found"
180                     except:
181                         print "Sign failed, exception:", str(sys.exc_info()[1])
182                 if decrypt:
183                     if m and e:
184                         try:
185                             toEncrypt = "12345678901234567890"
186                             # note: PKCS1 BT2 padding should be random data,
187                             # but this is just a test and we use 0xFF...
188                             padded = "\x00\x02%s\x00%s" % ("\xFF" * (128 - (len(toEncrypt)) - 3), toEncrypt)
189                             print "* Decrypting with 0x%08X following data: %s" % (o.value(), toEncrypt)
190                             print "padded:\n", dump(padded, 16)
191                             encrypted = pow(eval('0x%sL' % padded.encode('hex')), ex, mx)  # RSA
192                             encrypted1 = hexx(encrypted).decode('hex')
193                             print "encrypted:\n", dump(encrypted1, 16)
194                             decrypted = session.decrypt(o, encrypted1)
195                             decrypted1 = ''.join(chr(i) for i in decrypted)
196                             print "decrypted:\n", dump(decrypted1, 16)
197                             if decrypted1 == toEncrypt:
198                                 print "decryption SUCCESSFULL!\n"
199                             else:
200                                 print "decryption FAILED!\n"
201                         except:
202                             print "Decrypt failed, exception:", str(sys.exc_info()[1])
203                     else:
204                         print "ERROR: Private key don't have MODULUS/PUBLIC_EXP"
205
206             print "Dumping attributes:"
207             for q, a in zip(all_attributes, attributes):
208                 if a == None:
209                     # undefined (CKR_ATTRIBUTE_TYPE_INVALID) attribute
210                     continue
211                 if q == PyKCS11.CKA_CLASS:
212                     print format_long % (PyKCS11.CKA[q], PyKCS11.CKO[a], a)
213                 elif q == PyKCS11.CKA_CERTIFICATE_TYPE:
214                     print format_long % (PyKCS11.CKA[q], PyKCS11.CKC[a], a)
215                 elif q == PyKCS11.CKA_KEY_TYPE:
216                     print format_long % (PyKCS11.CKA[q], PyKCS11.CKK[a], a)
217                 elif session.isBin(q):
218                     print format_binary % (PyKCS11.CKA[q], len(a))
219                     if a:
220                         print dump(''.join(map(chr, a)), 16),
221                 elif q == PyKCS11.CKA_SERIAL_NUMBER:
222                     print format_binary % (PyKCS11.CKA[q], len(a))
223                     if a:
224                         print dump(a, 16),
225                 else:
226                     print format_normal % (PyKCS11.CKA[q], a)
227         print
228
229         if pin_available:
230             try:
231                 session.logout()
232             except:
233                 print "logout failed, exception:", str(sys.exc_info()[1])
234
235         session.closeSession()
236
237     except PyKCS11.PyKCS11Error, e:
238         print "Error:", e
Note: See TracBrowser for help on using the browser.
(C) 2006 bit4id srl, for informations please contact info@bit4id.com
visitors since August 21, 2006