upgrade_by_passwd.py

This commit is contained in:
NIIBE Yutaka
2012-12-25 14:47:08 +09:00
parent 500b12b60d
commit ad9a901e1b
5 changed files with 89 additions and 9 deletions

View File

@@ -1,6 +1,12 @@
2012-12-19 Niibe Yutaka <gniibe@fsij.org>
2012-12-25 Niibe Yutaka <gniibe@fsij.org>
* 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 <gniibe@fsij.org>
* src/Makefile.in (USE_OPT): -O3 and -Os (was: -O2).

2
NEWS
View File

@@ -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

70
tool/rsa.py Normal file
View File

@@ -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]

4
tool/rsa_example.key Normal file
View File

@@ -0,0 +1,4 @@
9cf7192b51a574d1ad3ccb08ba09b87f228573893eee355529ff243e90fd4b86f79a82097cc7922c0485bed1616b1656a9b0b19ef78ea8ec34c384019adc5d5bf4db2d2a0a2d9cf14277bdcb7056f48b81214e3f7f7742231e29673966f9b1106862112cc798dba8d4a138bb5abfc6d4c12d53a5d39b2f783da916da20852ee139bbafda61d429caf2a4f30847ce7e7ae32ab4061e27dd9e4d00d60910249db8d8559dd85f7ca59659ef400c8f6318700f4e97f0c6f4165de80641490433c88da8682befe68eb311f54af2b07d97ac74edb5399cf054764211694fbb8d1d333f3269f235abe025067f811ff83a2224826219b309ea3e6c968f42b3e52f245dc9
010001
b5ab7b159220b18e363258f61ebde08bae83d6ce2dbfe4adc143628c527887acde9de09bf9b49f438019004d71855f30c2d69b6c29bb9882ab641b3387409fe9199464a7faa4b5230c56d9e17cd9ed074bc00180ebed62bae3af28e6ff2ac2654ad968834c5d5c88f8d9d3cc5e167b10453b049d4e454a5761fb0ac717185907
dd2fffa9814296156a6926cd17b65564187e424dcadce9b032246ad7e46448bb0f9e0ff3c64f987424b1a40bc694e2e9ac4fb1930d163582d7acf20653a1c44b97846c1c5fd8a7b19bb225fb39c30e25410483deaf8c2538d222b748c4d8103b11cec04f666a5c0dbcbf5d5f625f158f65746c3fafe6418145f7cffa5fadeeaf

View File

@@ -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 <gniibe@fsij.org>
@@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
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('<I', crc32code)
rsa_raw_pubkey = rsa.integer_to_bytes_256(rsa.key[KEYNO_FOR_AUTH][7])
rsa_key = rsa.read_key_from_file('rsa_example.key')
rsa_raw_pubkey = rsa.get_raw_pubkey(rsa_key)
gnuk = get_gnuk_device()
gnuk.cmd_verify(BY_ADMIN, passwd)
@@ -48,7 +50,7 @@ def main(passwd, data_regnual, data_upgrade):
gnuk.cmd_select_openpgp()
challenge = gnuk.cmd_get_challenge()
digestinfo = binascii.unhexlify(SHA256_OID_PREFIX) + challenge
signed = rsa.compute_signature(KEYNO_FOR_AUTH, digestinfo)
signed = rsa.compute_signature(rsa_key, digestinfo)
signed_bytes = rsa.integer_to_bytes_256(signed)
gnuk.cmd_external_authenticate(signed_bytes)
gnuk.stop_gnuk()
@@ -90,8 +92,6 @@ if __name__ == '__main__':
print "Please change working directory to: %s" % os.path.dirname(os.path.abspath(__file__))
exit(1)
import rsa_keys as rsa
passwd = DEFAULT_PW3
if len(sys.argv) > 1 and sys.argv[1] == '-p':
from getpass import getpass