From ad9a901e1b17681cc57bcf85e133e1770c3e6c6c Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Tue, 25 Dec 2012 14:47:08 +0900 Subject: [PATCH] upgrade_by_passwd.py --- ChangeLog | 10 ++- NEWS | 2 +- tool/rsa.py | 70 +++++++++++++++++++ tool/rsa_example.key | 4 ++ .../upgrade_by_passwd.py | 12 ++-- 5 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 tool/rsa.py create mode 100644 tool/rsa_example.key rename test/factory_upgrade.py => tool/upgrade_by_passwd.py (91%) diff --git a/ChangeLog b/ChangeLog index 5050e14..2dc97b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ -2012-12-19 Niibe Yutaka +2012-12-25 Niibe Yutaka - * test/factory_upgrade.py: New. + * tool/rsa.py: New. + + * tool/rsa_example.key: New. Example RSA key information. + + * tool/upgrade_by_passwd.py: New. + +2012-12-19 Niibe Yutaka * src/Makefile.in (USE_OPT): -O3 and -Os (was: -O2). diff --git a/NEWS b/NEWS index da6293b..94dddc2 100644 --- a/NEWS +++ b/NEWS @@ -8,7 +8,7 @@ Gnuk NEWS - User visible changes Since the USB ID Repository suggests not including vendor name in product string, we changed the product string. -** New tool (experimental): test/factory_upgrade.py +** New tool (experimental): test/upgrade_by_passwd.py This is the tool to install new firmware to Gnuk Token, provided that it's just shipped from factory (and nothing changed). It authenticate as admin by factory setting, register a public key diff --git a/tool/rsa.py b/tool/rsa.py new file mode 100644 index 0000000..00371f9 --- /dev/null +++ b/tool/rsa.py @@ -0,0 +1,70 @@ +from binascii import hexlify, unhexlify +import string +from os import urandom + +def read_key_from_file(file): + f = open(file) + n_str = f.readline()[:-1] + e_str = f.readline()[:-1] + p_str = f.readline()[:-1] + q_str = f.readline()[:-1] + f.close() + e = int(e_str, 16) + p = int(p_str, 16) + q = int(q_str, 16) + n = int(n_str, 16) + if n != p * q: + raise ValueError("wrong key", p, q, n) + return (unhexlify(n_str), unhexlify(e_str), unhexlify(p_str), unhexlify(q_str), e, p, q, n) + +# egcd and modinv are from wikibooks +# https://en.wikibooks.org/wiki/Algorithm_Implementation/Mathematics/Extended_Euclidean_algorithm + +def egcd(a, b): + if a == 0: + return (b, 0, 1) + else: + g, y, x = egcd(b % a, a) + return (g, x - (b // a) * y, y) + +def modinv(a, m): + g, x, y = egcd(a, m) + if g != 1: + raise Exception('modular inverse does not exist') + else: + return x % m + +def pkcs1_pad_for_sign(digestinfo): + byte_repr = '\x00' + '\x01' + string.ljust('', 256 - 19 - 32 - 3, '\xff') \ + + '\x00' + digestinfo + return int(hexlify(byte_repr), 16) + +def compute_signature(key, digestinfo): + e = key[4] + p = key[5] + q = key[6] + n = key[7] + p1 = p - 1 + q1 = q - 1 + h = p1 * q1 + d = modinv(e, h) + dp = d % p1 + dq = d % q1 + qp = modinv(q, p) + + input = pkcs1_pad_for_sign(digestinfo) + t1 = pow(input, dp, p) + t2 = pow(input, dq, q) + t = ((t1 - t2) * qp) % p + sig = t2 + t * q + return sig + +def integer_to_bytes_256(i): + s = hex(i)[2:] + s = s.rstrip('L') + if len(s) & 1: + s = '0' + s + return string.rjust(unhexlify(s), 256, '\x00') + +def get_raw_pubkey(key): + return key[0] diff --git a/tool/rsa_example.key b/tool/rsa_example.key new file mode 100644 index 0000000..cdf2d5e --- /dev/null +++ b/tool/rsa_example.key @@ -0,0 +1,4 @@ +9cf7192b51a574d1ad3ccb08ba09b87f228573893eee355529ff243e90fd4b86f79a82097cc7922c0485bed1616b1656a9b0b19ef78ea8ec34c384019adc5d5bf4db2d2a0a2d9cf14277bdcb7056f48b81214e3f7f7742231e29673966f9b1106862112cc798dba8d4a138bb5abfc6d4c12d53a5d39b2f783da916da20852ee139bbafda61d429caf2a4f30847ce7e7ae32ab4061e27dd9e4d00d60910249db8d8559dd85f7ca59659ef400c8f6318700f4e97f0c6f4165de80641490433c88da8682befe68eb311f54af2b07d97ac74edb5399cf054764211694fbb8d1d333f3269f235abe025067f811ff83a2224826219b309ea3e6c968f42b3e52f245dc9 +010001 +b5ab7b159220b18e363258f61ebde08bae83d6ce2dbfe4adc143628c527887acde9de09bf9b49f438019004d71855f30c2d69b6c29bb9882ab641b3387409fe9199464a7faa4b5230c56d9e17cd9ed074bc00180ebed62bae3af28e6ff2ac2654ad968834c5d5c88f8d9d3cc5e167b10453b049d4e454a5761fb0ac717185907 +dd2fffa9814296156a6926cd17b65564187e424dcadce9b032246ad7e46448bb0f9e0ff3c64f987424b1a40bc694e2e9ac4fb1930d163582d7acf20653a1c44b97846c1c5fd8a7b19bb225fb39c30e25410483deaf8c2538d222b748c4d8103b11cec04f666a5c0dbcbf5d5f625f158f65746c3fafe6418145f7cffa5fadeeaf diff --git a/test/factory_upgrade.py b/tool/upgrade_by_passwd.py similarity index 91% rename from test/factory_upgrade.py rename to tool/upgrade_by_passwd.py index 2234a92..92c9e8d 100755 --- a/test/factory_upgrade.py +++ b/tool/upgrade_by_passwd.py @@ -1,8 +1,8 @@ #! /usr/bin/python """ -factory_upgrade.py - a tool to install another firmware for Gnuk Token - which is just shipped from factory +upgrade_by_passwd.py - a tool to install another firmware for Gnuk Token + which is just shipped from factory Copyright (C) 2012 Free Software Initiative of Japan Author: NIIBE Yutaka @@ -25,6 +25,7 @@ along with this program. If not, see . from gnuk_token import * import sys, binascii, time, os +import rsa DEFAULT_PW3 = "12345678" BY_ADMIN = 3 @@ -39,7 +40,8 @@ def main(passwd, data_regnual, data_upgrade): print "CRC32: %04x\n" % crc32code data_regnual += pack(' 1 and sys.argv[1] == '-p': from getpass import getpass