From 9fadbf450732b94a723471b80bfa6e10a710b85c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bar=C4=B1=C5=9F=20Metin?= Date: Tue, 29 Jun 2010 12:53:13 +0000 Subject: [PATCH] implement keyconvert in python. Problems with DSA keys, M2Crypto doesn't allow us to give set the pub key parameter. --- keyconvert/keyconvert.py | 101 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100755 keyconvert/keyconvert.py diff --git a/keyconvert/keyconvert.py b/keyconvert/keyconvert.py new file mode 100755 index 00000000..af12b1f4 --- /dev/null +++ b/keyconvert/keyconvert.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python + +import sys +import base64 +import struct +import binascii +from M2Crypto import RSA, DSA + + +def decode_key(fname): + """Convert base64 encoded openssh key to binary""" + contents = open(fname).read() + fields = contents.split() + + in_key = False + for f in fields: + f = f.strip() + if f.startswith("ssh-"): + in_key = True + continue + elif in_key: + return base64.b64decode(f) + + return None + + +# openssh binary key format +# +# a section: +# length = 4 bytes (32-bit big-endian integer) +# data = length bytes of string +# +# sections of the key ( for RSA ) +# [key-type (in ASCII)] [public exponent (bignum)] [primes (bignum)] +# +# sections of the key ( for DSA ) +# [key-type (in ASCII)] [p (bignum)] [q (bignum)] [g (bignum)] [y (bignum)] +# +# - baris +def read_key(key): + + def read_length(key): + length = key[0:4] + length = struct.unpack(">l", length)[0] + return length, key + + def read_values(key, count): + v = [] + for i in range(count): + length, key = read_length(key) + size = 4 + length + v.append(key[:size]) + key = key[size:] + return v + + length, key = read_length(key) + key = key[4:] + key_type = key[:length] + key = key[length:] + + if key_type == "ssh-rsa": + # prepare parameters for RSA.new_pub_key + v = read_values(key, 2) + e, n = v[0], v[1] + return key_type, e, n + + elif key_type == "ssh-dss": + # prepare parameters for DSA.set_params + v = read_values(key, 4) + p, q, g, y = v[0], v[1], v[2], v[3] + return key_type, p, q, g, y + + +def convert(fin, fout): + key = decode_key(fin) + ret = read_key(key) + key_type = ret[0] + + if key_type == "ssh-rsa": + e, n = ret[1:] + rsa = RSA.new_pub_key((e, n)) + rsa.save_pem(fout) + + elif key_type == "ssh-dss": + p, q, g, y = ret[1:] + dsa = DSA.set_params(p, q, g) + dsa.gen_key() + dsa.save_pub_key(fout) + # FIXME: This is wrong. + # M2Crypto doesn't allow us to set the public key parameter + raise(Exception, "DSA keys are not supported yet: M2Crypto doesn't allow us to set the public key parameter") + + +if __name__ == "__main__": + if len(sys.argv) != 3: + print "Usage: %s " + sys.exit(1) + + fin = sys.argv[1] + fout = sys.argv[2] + convert(fin, fout) -- 2.43.0