b8e0690be245414faccd9414aa7e70593ade4db4
[gnuk/gnuk.git] / tool / gnuk_remove_keys.py
1 #! /usr/bin/python
2
3 """
4 gnuk_remove_keys.py - a tool to remove keys in Gnuk Token
5
6 Copyright (C) 2012 Free Software Initiative of Japan
7 Author: NIIBE Yutaka <gniibe@fsij.org>
8
9 This file is a part of Gnuk, a GnuPG USB Token implementation.
10
11 Gnuk is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15
16 Gnuk is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
19 License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 """
24
25 import sys, os, string
26
27 # Assume only single CCID device is attached to computer and it's Gnuk Token
28
29 from smartcard.CardType import AnyCardType
30 from smartcard.CardRequest import CardRequest
31 from smartcard.util import toHexString
32
33 def s2l(s):
34     return [ ord(c) for c in s ]
35
36 class GnukToken(object):
37     def __init__(self):
38         cardtype = AnyCardType()
39         cardrequest = CardRequest(timeout=1, cardType=cardtype)
40         cardservice = cardrequest.waitforcard()
41         self.connection = cardservice.connection
42
43     def cmd_get_response(self, expected_len):
44         apdu = [0x00, 0xc0, 0x00, 0x00, expected_len]
45         response, sw1, sw2 = self.connection.transmit(apdu)
46         if not (sw1 == 0x90 and sw2 == 0x00):
47             raise ValueError, ("%02x%02x" % (sw1, sw2))
48         return response
49
50     def cmd_verify(self, who, passwd):
51         apdu = [0x00, 0x20, 0x00, 0x80+who, len(passwd)] + s2l(passwd)
52         response, sw1, sw2 = self.connection.transmit(apdu)
53         if not (sw1 == 0x90 and sw2 == 0x00):
54             raise ValueError, ("%02x%02x" % (sw1, sw2))
55
56     def cmd_select_openpgp(self):
57         apdu = [0x00, 0xa4, 0x04, 0x0c, 6, 0xd2, 0x76, 0x00, 0x01, 0x24, 0x01]
58         response, sw1, sw2 = self.connection.transmit(apdu)
59         if sw1 == 0x61:
60             response = self.cmd_get_response(sw2)
61         elif not (sw1 == 0x90 and sw2 == 0x00):
62             raise ValueError, ("%02x%02x" % (sw1, sw2))
63
64     def cmd_put_data_remove(self, tagh, tagl):
65         apdu = [0x00, 0xda, tagh, tagl, 0]
66         response, sw1, sw2 = self.connection.transmit(apdu)
67         return response
68
69     def cmd_put_data_key_import_remove(self, keyno):
70         if keyno == 1:
71             keyspec = 0xb6      # SIG
72         elif keyno == 2:
73             keyspec = 0xb8      # DEC
74         else:
75             keyspec = 0xa4      # AUT
76         apdu = [0x00, 0xdb, 0x3f, 0xff, 4, 0x4d, 0x02, keyspec, 0x00]
77         response, sw1, sw2 = self.connection.transmit(apdu)
78         return response
79
80 DEFAULT_PW3 = "12345678"
81 BY_ADMIN = 3
82
83 def main(passwd):
84     gnuk = GnukToken()
85
86     gnuk.connection.connect()
87     print "Token:", gnuk.connection.getReader()
88     print "ATR:", toHexString( gnuk.connection.getATR() )
89
90     gnuk.cmd_verify(BY_ADMIN, passwd)
91     gnuk.cmd_select_openpgp()
92     gnuk.cmd_put_data_remove(0x00, 0xc7) # FP_SIG
93     gnuk.cmd_put_data_remove(0x00, 0xce) # KGTIME_SIG
94     gnuk.cmd_put_data_key_import_remove(1)
95     gnuk.cmd_put_data_remove(0x00, 0xc8) # FP_DEC
96     gnuk.cmd_put_data_remove(0x00, 0xcf) # KGTIME_DEC
97     gnuk.cmd_put_data_key_import_remove(2)
98     gnuk.cmd_put_data_remove(0x00, 0xc9) # FP_AUT
99     gnuk.cmd_put_data_remove(0x00, 0xd0) # KGTIME_AUT
100     gnuk.cmd_put_data_key_import_remove(3)
101
102     gnuk.connection.disconnect()
103     return 0
104
105
106 if __name__ == '__main__':
107     passwd = DEFAULT_PW3
108     if len(sys.argv) > 1 and sys.argv[1] == '-p':
109         from getpass import getpass
110         passwd = getpass("Admin password: ")
111         sys.argv.pop(1)
112     main(passwd)