Support authentication with KDF Data Object.
authorNIIBE Yutaka <gniibe@fsij.org>
Mon, 2 Apr 2018 02:13:55 +0000 (11:13 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Tue, 3 Apr 2018 08:17:39 +0000 (17:17 +0900)
ChangeLog
tool/gnuk_remove_keys_libusb.py
tool/upgrade_by_passwd.py

index e5b93a8..28cffdf 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-04-02  NIIBE Yutaka  <gniibe@fsij.org>
+
+       * tool/gnuk_token.py (parse_kdf_data): New.
+       * tool/kdf_calc.py: New.
+
+       * tool/gnuk_remove_keys_libusb.py (main): Support KDF auth.
+       * tool/upgrade_by_passwd.py (main): Likewise.
+
 2018-03-30  NIIBE Yutaka  <gniibe@fsij.org>
 
        * src/openpgp-do.c (rw_kdf): Support single-salt KDF.
index d9e147b..2b7d3fc 100755 (executable)
@@ -3,7 +3,7 @@
 """
 gnuk_remove_keys_libusb.py - a tool to remove keys in Gnuk Token
 
-Copyright (C) 2012 Free Software Initiative of Japan
+Copyright (C) 2012, 2018 Free Software Initiative of Japan
 Author: NIIBE Yutaka <gniibe@fsij.org>
 
 This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -24,7 +24,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import sys, os
 
-from gnuk_token import *
+from gnuk_token import gnuk_devices, gnuk_token, parse_kdf_data
+from kdf_calc import kdf_calc
 
 # Assume only single CCID device is attached to computer and it's Gnuk Token
 
@@ -42,13 +43,28 @@ def main(passwd):
             break
         except:
             pass
+    if not gnuk:
+        raise ValueError("No ICC present")
     if gnuk.icc_get_status() == 2:
         raise ValueError("No ICC present")
     elif gnuk.icc_get_status() == 1:
         gnuk.icc_power_on()
     gnuk.cmd_select_openpgp()
-    gnuk.cmd_verify(BY_ADMIN, passwd.encode('UTF-8'))
-    gnuk.cmd_select_openpgp()
+    # Compute passwd data
+    kdf_data = gnuk.cmd_get_data(0x00, 0xf9).tostring()
+    if kdf_data == "":
+        passwd_data = passwd.encode('UTF-8')
+    else:
+        algo, subalgo, iters, salt_user, salt_reset, salt_admin, \
+            hash_user, hash_admin = parse_kdf_data(kdf_data)
+        if salt_admin:
+            salt = salt_admin
+        else:
+            salt = salt_user
+        passwd_data = kdf_calc(passwd, salt, iters)
+    # And authenticate with the passwd data
+    gnuk.cmd_verify(BY_ADMIN, passwd_data)
+    # Do remove keys and related data objects
     gnuk.cmd_put_data_remove(0x00, 0xc7) # FP_SIG
     gnuk.cmd_put_data_remove(0x00, 0xce) # KGTIME_SIG
     gnuk.cmd_put_data_key_import_remove(1)
index f76f9e2..e4dd604 100755 (executable)
@@ -4,7 +4,8 @@
 upgrade_by_passwd.py - a tool to install another firmware for Gnuk Token
                        which is just shipped from factory
 
-Copyright (C) 2012, 2013, 2015  Free Software Initiative of Japan
+Copyright (C) 2012, 2013, 2015, 2018
+              Free Software Initiative of Japan
 Author: NIIBE Yutaka <gniibe@fsij.org>
 
 This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -23,9 +24,13 @@ You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 
-from gnuk_token import *
+from gnuk_token import get_gnuk_device, gnuk_devices_by_vidpid, \
+     gnuk_token, regnual, SHA256_OID_PREFIX, crc32, parse_kdf_data
+from kdf_calc import kdf_calc
+
 import sys, binascii, time, os
 import rsa
+from struct import pack
 
 DEFAULT_PW3 = "12345678"
 BY_ADMIN = 3
@@ -45,7 +50,20 @@ def main(wait_e, keyno, passwd, data_regnual, data_upgrade):
 
     gnuk = get_gnuk_device()
     gnuk.cmd_select_openpgp()
-    gnuk.cmd_verify(BY_ADMIN, passwd.encode('UTF-8'))
+    # Compute passwd data
+    kdf_data = gnuk.cmd_get_data(0x00, 0xf9).tostring()
+    if kdf_data == "":
+        passwd_data = passwd.encode('UTF-8')
+    else:
+        algo, subalgo, iters, salt_user, salt_reset, salt_admin, \
+            hash_user, hash_admin = parse_kdf_data(kdf_data)
+        if salt_admin:
+            salt = salt_admin
+        else:
+            salt = salt_user
+        passwd_data = kdf_calc(passwd, salt, iters)
+    # And authenticate with the passwd data
+    gnuk.cmd_verify(BY_ADMIN, passwd_data)
     gnuk.cmd_write_binary(1+keyno, rsa_raw_pubkey, False)
 
     gnuk.cmd_select_openpgp()