summaryrefslogtreecommitdiff
path: root/hgsshsign/keys.py
diff options
context:
space:
mode:
Diffstat (limited to 'hgsshsign/keys.py')
-rw-r--r--hgsshsign/keys.py88
1 files changed, 88 insertions, 0 deletions
diff --git a/hgsshsign/keys.py b/hgsshsign/keys.py
new file mode 100644
index 0000000..d15af08
--- /dev/null
+++ b/hgsshsign/keys.py
@@ -0,0 +1,88 @@
1# vim: set filencoding=utf8
2"""
3Key Loader Functions
4
5@author: Mike Crute (mcrute@gmail.com)
6@organization: SoftGroup Interactive, Inc.
7@date: May 05, 2010
8"""
9
10import os
11from M2Crypto import RSA, DSA
12from M2Crypto.EVP import MessageDigest
13from M2Crypto.RSA import RSAError
14from M2Crypto.DSA import DSAError
15from structutils import unpack_string, get_packed_mp_ints, int_to_bytes
16
17
18class PublicKey(object):
19
20 def __init__(self, hashed=None, instance=None, key_type=None):
21 self.instance = instance
22 self.hashed = hashed
23 self.key_type = key_type
24
25 @property
26 def blob(self):
27 return self.hashed.decode('base64')
28
29 def verify(self, data, signature):
30 try:
31 return bool(self.instance.verify(data, signature))
32 except (RSAError, DSAError):
33 return False
34
35 def sign(self, data):
36 return self.instance.sign(data)
37
38 @classmethod
39 def from_string(cls, key):
40 """
41 Loads an RFC 4716 formatted public key.
42 """
43 pubkey = cls()
44
45 if key.startswith('ssh-'):
46 pubkey.hashed = key.split()[1]
47 else:
48 pubkey.hashed = key
49
50 pubkey.key_type, remainder = unpack_string(pubkey.blob)
51
52 if pubkey.key_type == 'ssh-rsa':
53 e, n = get_packed_mp_ints(remainder, 2)
54 pubkey.instance = RSA.new_pub_key((e, n))
55 elif pubkey.key_type == 'ssh-dss':
56 p, q, g, y = get_packed_mp_ints(remainder, 4)
57 pubkey.instance = DSA.set_params(p, q, g)
58
59 return pubkey
60
61 @classmethod
62 def from_file(cls, filename):
63 fp = open(filename)
64 try:
65 return cls.from_string(fp.read())
66 finally:
67 fp.close()
68
69
70def load_private_key(filename):
71 fp = open(filename)
72 try:
73 first_line = fp.readline()
74 finally:
75 fp.close()
76
77 type = DSA if 'DSA' in first_line else RSA
78 return type.load_key(filename)
79
80
81def sign_like_agent(data, key):
82 """
83 Emulates the signing behavior of an ssh key agent.
84 """
85 digest = MessageDigest('sha1')
86 digest.update(data)
87 my_data = digest.final()
88 return key.sign(data)