Skip to content

Commit

Permalink
Support SSH2 public keys. Better checks for ED25519 keys.
Browse files Browse the repository at this point in the history
Fixes #6
  • Loading branch information
ojarva committed Jan 2, 2015
1 parent 9c650e6 commit 12627d0
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 6 deletions.
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

setup(
name='sshpubkeys',
version='1.0.5',
version='1.0.6',
description='SSH public key parser',
long_description=long_description,
url='https://github.com/ojarva/python-sshpubkeys',
Expand All @@ -31,6 +31,7 @@
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: Implementation :: PyPy',
],
keywords='ssh pubkey public key openssh ssh-rsa ssh-dss ssh-ed25519',
packages=["sshpubkeys"],
Expand Down
23 changes: 19 additions & 4 deletions sshpubkeys/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,27 @@ def decode_key(cls, pubkey_content):

def parse(self):
self.current_position = 0
key_parts = self.split_key(self.keydata)

key_type = key_parts[0]
pubkey_content = key_parts[1]
if self.keydata.startswith("---- BEGIN SSH2 PUBLIC KEY ----"):
# SSH2 key format
key_type = None
pubkey_content = ""
for line in self.keydata.split("\n"):
if ":" in line: # key-value lines
continue
if "----" in line: # begin/end lines
continue
pubkey_content += line
else:
key_parts = self.split_key(self.keydata)
key_type = key_parts[0]
pubkey_content = key_parts[1]

self.decoded_key = self.decode_key(pubkey_content)

# Check key type
unpacked_key_type = self.unpack_by_int()
if key_type != unpacked_key_type.decode():
if key_type is not None and key_type != unpacked_key_type.decode():
raise InvalidTypeException("Keytype mismatch: %s != %s" % (key_type, unpacked_key_type))

self.key_type = unpacked_key_type
Expand Down Expand Up @@ -160,6 +171,10 @@ def parse(self):
# the key in any way.
verifying_key = self.unpack_by_int()
verifying_key_length = len(verifying_key) * 8
verifying_key = self.parse_long(verifying_key)

if verifying_key < 0:
raise InvalidKeyException("ed25519 verifying must be >0.")

min_length = max_length = 256
self.bits = verifying_key_length
Expand Down
4 changes: 3 additions & 1 deletion tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import unittest
from sshpubkeys import *
from .valid_keys import keys as list_of_valid_keys
from .valid_keys_rfc4716 import keys as list_of_valid_keys_rfc4716
from .invalid_keys import keys as list_of_invalid_keys

class TestKeys(unittest.TestCase):
Expand All @@ -20,7 +21,7 @@ def check_fail(self, pubkey, expected_error):
""" Checks that key check raises specified exception """
# Don't use with statement here - it does not work with Python 2.6 unittest module
self.assertRaises(expected_error, SSHKey, pubkey)

def loop_valid(keyset, prefix):
""" Loop over list of valid keys and dynamically create tests """
for i, items in enumerate(keyset):
Expand All @@ -44,6 +45,7 @@ def ch(pubkey, expected_error):
setattr(TestKeys, "test_%s" % prefix_tmp, ch(pubkey, expected_error))

loop_valid(list_of_valid_keys, "valid_key")
loop_valid(list_of_valid_keys_rfc4716, "valid_key_rfc4716")
loop_invalid(list_of_invalid_keys, "invalid_key")

if __name__ == '__main__':
Expand Down

0 comments on commit 12627d0

Please sign in to comment.