root/pykcs11/trunk/samples/dumpit.py

Revision 121, 9.3 kB (checked in by lrousseau, 5 months ago)

update copyright date

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