[Gnuk-users] Upgrading gnuk on a nitrokey start
NIIBE Yutaka
gniibe at fsij.org
Thu Aug 18 02:30:21 UTC 2016
On 08/16/2016 10:25 PM, Remy van Elst wrote:
> Please note that we use reGNUal in teh upgrading process. The setting
> of permission with your USB ID is requires for reGNUal too.
>
>
> Even if I do it as the root user?
If it's a simple POSIX sytem, root means full privilege, that's true.
> I didn't see a specific compile option for regnual for a different
> vidpid like in gnuk's configure script.
ReGNUal shares the configuration of Gnuk proper.
> Is there a way to see which keys are currently in there? And, is it
> possible to remove those keys if they are written? Does the
> 'gnuk_remove_keys_libusb.py' also clean up those keys?
(1) No. (2) Difficult (nobody has tried). (3) No.
For (1), it is possible to write such a tool. Nobody has tried that.
By using tool/gnuk_token.py and the method cmd_read_binary, it is
possible to write such a tool.
For (2), I think that it is possible to do so, or it is possible to
write such a tool, in theory. I'm saying because I once implement the
removal feature of upgrade RSA public key in Gnuk. Nobody has tried
that. IIUC, it is somehow likely that this sequence would work:
./tool/gnuk_put_binary_libusb.py -k 0 /dev/null
./tool/gnuk_put_binary_libusb.py -k 1 /dev/null
./tool/gnuk_put_binary_libusb.py -k 2 /dev/null
./tool/gnuk_put_binary_libusb.py -k 3 /dev/null
Please note that this is not tested at all.
'gnuk_remove_keys_libusb.py' is a tool to remove the RSA private keys
(not RSA public key for upgrade).
> When trying the upgrade with password script, this happens:
>
> $ sudo python2 ./upgrade_by_passwd.py -f -k 4 ../regnual/regnual.bin
> ../src/build/gnuk.bin
> ../regnual/regnual.bin: 4372
> ../src/build/gnuk.bin: 110592
> CRC32: 8d82b2df
>
> Device:
> Configuration: 1
> Interface: 0
> Traceback (most recent call last):
> File "./upgrade_by_passwd.py", line 130, in <module>
> main(wait_e, keyno, passwd, data_regnual, data_upgrade[4096:])
> File "./upgrade_by_passwd.py", line 48, in main
> gnuk.cmd_write_binary(1+keyno, rsa_raw_pubkey, False)
> File "/home/remy/repo/gnuk/tool/gnuk_token.py", line 288, in
> cmd_write_binary
> raise ValueError("cmd_write_binary 1", "%02x%02x" % (sw[0], sw[1]))
> ValueError: ('cmd_write_binary 1', '6581')
-k is only valid with 0 to 3.
> $ sudo python2 ./upgrade_by_passwd.py -f -k 3 ../regnual/regnual.bin
> ../src/build/gnuk.bin
> ../regnual/regnual.bin: 4372
> ../src/build/gnuk.bin: 110592
> CRC32: 8d82b2df
>
> Device:
> Configuration: 1
> Interface: 0
> Traceback (most recent call last):
> File "./upgrade_by_passwd.py", line 130, in <module>
> main(wait_e, keyno, passwd, data_regnual, data_upgrade[4096:])
> File "./upgrade_by_passwd.py", line 48, in main
> gnuk.cmd_write_binary(1+keyno, rsa_raw_pubkey, False)
> File "/home/remy/repo/gnuk/tool/gnuk_token.py", line 288, in
> cmd_write_binary
> raise ValueError("cmd_write_binary 1", "%02x%02x" % (sw[0], sw[1]))
> ValueError: ('cmd_write_binary 1', '6581')
>
> $ sudo python2 ./upgrade_by_passwd.py -f -k 2 ../regnual/regnual.bin
> ../src/build/gnuk.bin
> ../regnual/regnual.bin: 4372
> ../src/build/gnuk.bin: 110592
> CRC32: 8d82b2df
>
> Device:
> Configuration: 1
> Interface: 0
> Traceback (most recent call last):
> File "./upgrade_by_passwd.py", line 130, in <module>
> main(wait_e, keyno, passwd, data_regnual, data_upgrade[4096:])
> File "./upgrade_by_passwd.py", line 48, in main
> gnuk.cmd_write_binary(1+keyno, rsa_raw_pubkey, False)
> File "/home/remy/repo/gnuk/tool/gnuk_token.py", line 288, in
> cmd_write_binary
> raise ValueError("cmd_write_binary 1", "%02x%02x" % (sw[0], sw[1]))
> ValueError: ('cmd_write_binary 1', '6581')
>
>
> $ sudo python2 ./upgrade_by_passwd.py -f -k 1 ../regnual/regnual.bin
> ../src/build/gnuk.bin
> ../regnual/regnual.bin: 4372
> ../src/build/gnuk.bin: 110592
> CRC32: 8d82b2df
>
> Device:
> Configuration: 1
> Interface: 0
> Traceback (most recent call last):
> File "./upgrade_by_passwd.py", line 130, in <module>
> main(wait_e, keyno, passwd, data_regnual, data_upgrade[4096:])
> File "./upgrade_by_passwd.py", line 48, in main
> gnuk.cmd_write_binary(1+keyno, rsa_raw_pubkey, False)
> File "/home/remy/repo/gnuk/tool/gnuk_token.py", line 288, in
> cmd_write_binary
> raise ValueError("cmd_write_binary 1", "%02x%02x" % (sw[0], sw[1]))
> ValueError: ('cmd_write_binary 1', '6581')
I think that it's not good to proceed after a failure. Some failure is not
recoverable.
If those failures are real, there is no way to recover from here,
other than the (2) method I described above, which nobody has tried.
I don't know the reason why the invocation of upgrade_by_passwd.py
fails in that way. If it had already filled by a public key, it's
possible. If not, it's new failure mode for me.
> When I try the normal upgrade script, this is the output:
>
> $ sudo python2 ./gnuk_upgrade.py -k
> CB1522E739DD4E26F86EBC732B58AFBDA3059107 ../regnual/regnual.bin
> ../src/build/gnuk.bin
> ../regnual/regnual.bin: 4372
> ../src/build/gnuk.bin: 110592
> CRC32: 8d82b2df
No, it's not "normal upgrade script" at all. It was a tool for my
experiment, not useful after we have upgrade_by_passwd.py. It is only
useful if you successfully registered a public key to Gnuk Token, and
the private counter part is under control of gpg-agent.
> Device:
> Configuration: 1
> Interface: 0
> Traceback (most recent call last):
> File "./gnuk_upgrade.py", line 148, in <module>
> main(keyno, keygrip, data_regnual, data_upgrade[4096:])
> File "./gnuk_upgrade.py", line 95, in main
> signed = gpg_sign(keygrip, binascii.hexlify(challenge))
> File "./gnuk_upgrade.py", line 64, in gpg_sign
> pos = signed.index("D (7:sig-val(3:rsa(1:s256:") + 26
> ValueError: substring not found
I think that there are two (or more) possibilities for this failure.
It fails because the key CB1522E739DD4E26F86EBC732B58AFBDA3059107 is
not under control of gpg-agent or it fails to sign (because of sudo).
Have you asked a passphrase for the key?
Another obvious bug (which I found now) is that it only works 50%.
If the top-bit is 1, the result will be
D (7:sig-val(3:rsa(1:s257:...
So, it fails.
> If there is no way to see or wipe the current keys for firmware update
> via USB, is there another way to reset the token fully?
See (2) for the public key of firmware upgrade. Please note that I
don't know this feature is supported by Nitrokey Start's build of
Gnuk.
For resetting the token fully, we need SWD debugger.
--
More information about the gnuk-users
mailing list