7 from M2Crypto import RSA, DSA, m2
10 ###### Workaround for bug in m2crypto-0.18 (on Fedora 8)
11 class RSA_pub_fix(RSA.RSA_pub):
12 def save_key_bio(self, bio, *args, **kw):
13 return self.save_pub_key_bio(bio)
15 def rsa_new_pub_key((e, n)):
19 return RSA_pub_fix(rsa, 1)
21 #rsa_new_pub_key = RSA.new_pub_key
24 def decode_key(fname):
25 """Convert base64 encoded openssh key to binary"""
26 contents = open(fname).read()
27 fields = contents.split()
32 if f.startswith("ssh-"):
36 return base64.b64decode(f)
41 # openssh binary key format
44 # length = 4 bytes (32-bit big-endian integer)
45 # data = length bytes of string
47 # sections of the key ( for RSA )
48 # [key-type (in ASCII)] [public exponent (bignum)] [primes (bignum)]
50 # sections of the key ( for DSA )
51 # [key-type (in ASCII)] [p (bignum)] [q (bignum)] [g (bignum)] [y (bignum)]
58 length = struct.unpack(">l", length)[0]
61 def read_values(key, count):
63 for i in range(count):
64 length, key = read_length(key)
70 length, key = read_length(key)
72 key_type = key[:length]
75 if key_type == "ssh-rsa":
76 # prepare parameters for RSA.new_pub_key
77 v = read_values(key, 2)
81 elif key_type == "ssh-dss":
82 # prepare parameters for DSA.set_params
83 v = read_values(key, 4)
84 p, q, g, y = v[0], v[1], v[2], v[3]
85 return key_type, p, q, g, y
88 def convert(fin, fout):
93 if key_type == "ssh-rsa":
95 rsa = rsa_new_pub_key((e, n))
98 elif key_type == "ssh-dss":
100 dsa = DSA.set_params(p, q, g)
102 dsa.save_pub_key(fout)
103 # FIXME: This is wrong.
104 # M2Crypto doesn't allow us to set the public key parameter
105 raise(Exception, "DSA keys are not supported yet: M2Crypto doesn't allow us to set the public key parameter")
108 if __name__ == "__main__":
109 if len(sys.argv) != 3:
110 print "Usage: %s <input-file> <output-file>"