move old documents to doc/note
[gnuk/gnuk.git] / doc / note / firmware-update
1 Firmware update feature
2 =======================
3
4 The firmware update feature of Gnuk is experimental.  Please be
5 careful using that.
6
7 Note that updating firmware, all data objects and keys will be
8 removed.  There is _no way_ to preserve those data.
9
10
11 Preparation
12 ===========
13
14 In addition to settings of Gnuk, I create a file
15 /etc/udev/rules.d/92-gnuk.rules::
16
17    # For updating firmware, permission settings are needed.
18    
19    SUBSYSTEMS=="usb", ATTRS{idVendor}=="234b", ATTRS{idProduct}=="0000", \
20        ENV{ID_USB_INTERFACES}=="*:ff0000:*", GROUP="pcscd"
21
22
23 While I am a member of group "pcscd" in /etc/group.
24
25 This is needed for reGNUal, the firmware update program.
26
27
28 Registering a public key for firmware update
29 ============================================
30
31 You need to register a public key to update the firmware.  It should
32 be RSA 2048-bit.
33
34 One way to extract public key data is by using "gpg-connect-agent"
35 command connecting gpg-agent.
36
37 We can examine key information of gpg-agent by "KEYINFO" command.
38 Here is my example::
39
40    $ gpg-connect-agent "KEYINFO --list" /bye
41    S KEYINFO 4970A0D537CA2EF7CE6A106E47AD89B0EFB684C8 D - - - - -
42    S KEYINFO 65F67E742101C7FE6D5B33FCEFCF4F65EAF0688C T D276000124010200F517000000010000 OPENPGP.2 - - -
43    S KEYINFO 5D6C89682D07CCFC034AF508420BF2276D8018ED T D276000124010200F517000000010000 OPENPGP.3 - - -
44    S KEYINFO 7D180C0C2A991B25204110A92F5F92A5A509845B D - - - - -
45    S KEYINFO 101DE7B639FE29F4636BDEECF442A9273AFA6565 T D276000124010200F517000000010000 OPENPGP.1 - - -
46    OK
47
48 I have two local keys (in my PC) and three keys in my token.
49
50 With the script below, I extract public key of the keygrip
51 5D6C89682D07CCFC034AF508420BF2276D8018ED into the file: 5D6C8968.bin::
52
53    $ ./get_public_key.py 5D6C89682D07CCFC034AF508420BF2276D8018ED
54
55 Here is the script, get_public_key.py::
56
57    #! /usr/bin/python
58    
59    import sys, binascii
60    from subprocess import check_output
61    
62    def get_gpg_public_key(keygrip):
63        result = check_output(["gpg-connect-agent", "READKEY %s" % keygrip, "/bye"])
64        key = ""
65        while True:
66               i = result.find('%')
67            if i < 0:
68                key += result
69                break
70            hex_str = result[i+1:i+3]
71            key += result[0:i]
72            key += chr(int(hex_str,16))
73            result = result[i+3:]
74
75        pos = key.index("D (10:public-key(3:rsa(1:n257:") + 31 # skip NUL too
76        key = key[pos:-17]           # )(1:e3:XYZ)))\nOK\n
77        if len(key) != 256:
78            raise ValueError, binascii.hexlify(key)
79        return key
80
81    if __name__ == '__main__':
82        keygrip = sys.argv[1]
83        k = get_gpg_public_key(keygrip)
84        shorthand = keygrip[0:8] + ".bin"
85        f = open(shorthand,"w")
86        f.write(k)
87        f.close()
88
89
90 Then, we can put the data of public key into token by::
91
92    $ tool/gnuk_put_binary_libusb.py -k 0 5D6C8968.bin
93
94
95 Invoking firmware update
96 ========================
97
98 We specify reGNUal binary and Gnuk binary.
99
100   $ ../tool/gnuk_upgrade.py ../regnual/regnual.bin gnuk.bin 
101
102
103 Two or more tokens
104 ==================
105
106 Currently, GnuPG doesn't support multiple devices connected to the
107 host.
108
109 In order to update the firmware of a TARGET token, we use GnuPG to
110 authenticate with public key.  It is assumed that you have another
111 AUTH token for this.  This situation is somewhat complicated.
112
113 What I do is:
114 (1) Don't run PC/SC daemon::
115
116   # /etc/init.d/pcscd stop
117
118 (2) To make sure, kill scdaemon::
119
120   $ killall -9 scdaemon
121
122 (3) Insert the AUTH token to USB, and use it::
123
124   $ gpg --card-status
125
126 (4) Insert the TARGET token to USB (after scdaemon communicates AUTH
127     token), and invoke gnuk_upgrade.py.
128     In this situation, gnuk_upgrade.py tries to connect one of tokens,
129     but a connection to the AUTH token will fail because scdaemon is
130     connecting to that device, and will be expected to connect to the
131     TARGET token succesufully, instead.
132 --