upgrade_by_passwd.py
This commit is contained in:
10
ChangeLog
10
ChangeLog
@@ -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
2
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
|
||||
|
||||
70
tool/rsa.py
Normal file
70
tool/rsa.py
Normal 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
4
tool/rsa_example.key
Normal file
@@ -0,0 +1,4 @@
|
||||
9cf7192b51a574d1ad3ccb08ba09b87f228573893eee355529ff243e90fd4b86f79a82097cc7922c0485bed1616b1656a9b0b19ef78ea8ec34c384019adc5d5bf4db2d2a0a2d9cf14277bdcb7056f48b81214e3f7f7742231e29673966f9b1106862112cc798dba8d4a138bb5abfc6d4c12d53a5d39b2f783da916da20852ee139bbafda61d429caf2a4f30847ce7e7ae32ab4061e27dd9e4d00d60910249db8d8559dd85f7ca59659ef400c8f6318700f4e97f0c6f4165de80641490433c88da8682befe68eb311f54af2b07d97ac74edb5399cf054764211694fbb8d1d333f3269f235abe025067f811ff83a2224826219b309ea3e6c968f42b3e52f245dc9
|
||||
010001
|
||||
b5ab7b159220b18e363258f61ebde08bae83d6ce2dbfe4adc143628c527887acde9de09bf9b49f438019004d71855f30c2d69b6c29bb9882ab641b3387409fe9199464a7faa4b5230c56d9e17cd9ed074bc00180ebed62bae3af28e6ff2ac2654ad968834c5d5c88f8d9d3cc5e167b10453b049d4e454a5761fb0ac717185907
|
||||
dd2fffa9814296156a6926cd17b65564187e424dcadce9b032246ad7e46448bb0f9e0ff3c64f987424b1a40bc694e2e9ac4fb1930d163582d7acf20653a1c44b97846c1c5fd8a7b19bb225fb39c30e25410483deaf8c2538d222b748c4d8103b11cec04f666a5c0dbcbf5d5f625f158f65746c3fafe6418145f7cffa5fadeeaf
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user