Library
The library defines a single class Ssh2Key() in the ssh2_parse_key module:
Main module for ssh2_parse_key - provides Ssh2Key()
Ssh2Key
Encapsulates an ssh public key
An Ssh2Key object is immutable after creation. Typically you would create
Ssh2Key objects by using parse() or parse_file() class methods.
Attributes:
| Name | Type | Description |
|---|---|---|
key |
str |
The ssh key itself, Base64 string |
type |
str |
one of |
encryption |
str |
one of |
headers |
|
Any headers for the key - eg Comment. |
__delattr__(self, name)
special
Attached to frozen classes as delattr.
Source code in ssh2_parse_key/ssh2_parse_key.py
def _frozen_delattrs(self, name):
"""
Attached to frozen classes as __delattr__.
"""
raise FrozenInstanceError()
__eq__(self, other)
special
Method generated by attrs for class Ssh2Key.
Source code in ssh2_parse_key/ssh2_parse_key.py
def __eq__(self, other):
if other.__class__ is not self.__class__:
return NotImplemented
return (
self.key,
self.type,
self.encryption,
self.headers,
) == (
other.key,
other.type,
other.encryption,
other.headers,
)
__ge__(self, other)
special
Method generated by attrs for class Ssh2Key.
Source code in ssh2_parse_key/ssh2_parse_key.py
def __ge__(self, other):
"""
Automatically created by attrs.
"""
if other.__class__ is self.__class__:
return attrs_to_tuple(self) >= attrs_to_tuple(other)
return NotImplemented
__getstate__(self)
special
Automatically created by attrs.
Source code in ssh2_parse_key/ssh2_parse_key.py
def slots_getstate(self):
"""
Automatically created by attrs.
"""
return tuple(getattr(self, name) for name in state_attr_names)
__gt__(self, other)
special
Method generated by attrs for class Ssh2Key.
Source code in ssh2_parse_key/ssh2_parse_key.py
def __gt__(self, other):
"""
Automatically created by attrs.
"""
if other.__class__ is self.__class__:
return attrs_to_tuple(self) > attrs_to_tuple(other)
return NotImplemented
__hash__(self)
special
Method generated by attrs for class Ssh2Key.
Source code in ssh2_parse_key/ssh2_parse_key.py
def __hash__(self):
return hash((
-1733517508299951301,
self.key,
self.type,
self.encryption,
self.headers,
))
__init__(self, *, key, type='public', encryption='ssh-rsa', headers=NOTHING)
special
Method generated by attrs for class Ssh2Key.
Source code in ssh2_parse_key/ssh2_parse_key.py
def __init__(self, *, key, type=attr_dict['type'].default, encryption=attr_dict['encryption'].default, headers=NOTHING):
_setattr = _cached_setattr.__get__(self, self.__class__)
_setattr('key', key)
_setattr('type', type)
_setattr('encryption', encryption)
if headers is not NOTHING:
_setattr('headers', headers)
else:
_setattr('headers', __attr_factory_headers())
if _config._run_validators is True:
__attr_validator_type(self, __attr_type, self.type)
__attr_validator_encryption(self, __attr_encryption, self.encryption)
__le__(self, other)
special
Method generated by attrs for class Ssh2Key.
Source code in ssh2_parse_key/ssh2_parse_key.py
def __le__(self, other):
"""
Automatically created by attrs.
"""
if other.__class__ is self.__class__:
return attrs_to_tuple(self) <= attrs_to_tuple(other)
return NotImplemented
__lt__(self, other)
special
Method generated by attrs for class Ssh2Key.
Source code in ssh2_parse_key/ssh2_parse_key.py
def __lt__(self, other):
"""
Automatically created by attrs.
"""
if other.__class__ is self.__class__:
return attrs_to_tuple(self) < attrs_to_tuple(other)
return NotImplemented
__ne__(self, other)
special
Method generated by attrs for class Ssh2Key.
Source code in ssh2_parse_key/ssh2_parse_key.py
def __ne__(self, other):
"""
Check equality and either forward a NotImplemented or
return the result negated.
"""
result = self.__eq__(other)
if result is NotImplemented:
return NotImplemented
return not result
__repr__(self)
special
Method generated by attrs for class Ssh2Key.
Source code in ssh2_parse_key/ssh2_parse_key.py
def __repr__(self):
"""
Automatically created by attrs.
"""
try:
working_set = _already_repring.working_set
except AttributeError:
working_set = set()
_already_repring.working_set = working_set
if id(self) in working_set:
return "..."
real_cls = self.__class__
if ns is None:
qualname = getattr(real_cls, "__qualname__", None)
if qualname is not None:
class_name = qualname.rsplit(">.", 1)[-1]
else:
class_name = real_cls.__name__
else:
class_name = ns + "." + real_cls.__name__
# Since 'self' remains on the stack (i.e.: strongly referenced) for the
# duration of this call, it's safe to depend on id(...) stability, and
# not need to track the instance and therefore worry about properties
# like weakref- or hash-ability.
working_set.add(id(self))
try:
result = [class_name, "("]
first = True
for name, attr_repr in attr_names_with_reprs:
if first:
first = False
else:
result.append(", ")
result.extend(
(name, "=", attr_repr(getattr(self, name, NOTHING)))
)
return "".join(result) + ")"
finally:
working_set.remove(id(self))
__setattr__(self, name, value)
special
Attached to frozen classes as setattr.
Source code in ssh2_parse_key/ssh2_parse_key.py
def _frozen_setattrs(self, name, value):
"""
Attached to frozen classes as __setattr__.
"""
raise FrozenInstanceError()
__setstate__(self, state)
special
Automatically created by attrs.
Source code in ssh2_parse_key/ssh2_parse_key.py
def slots_setstate(self, state):
"""
Automatically created by attrs.
"""
__bound_setattr = _obj_setattr.__get__(self, Attribute)
for name, value in zip(state_attr_names, state):
__bound_setattr(name, value)
# The hash code cache is not included when the object is
# serialized, but it still needs to be initialized to None to
# indicate that the first call to __hash__ should be a cache
# miss.
if hash_caching_enabled:
__bound_setattr(_hash_cache_field, None)
comment(self)
Returns the comment header from a ssh key object.
Returns:
| Type | Description |
|---|---|
str |
string: Comment field or an empty string. |
Source code in ssh2_parse_key/ssh2_parse_key.py
def comment(self) -> str:
"""
Returns the comment header from a ssh key object.
Arguments:
Returns:
string: Comment field or an empty string.
"""
if "Comment" in self.headers:
return self.headers["Comment"]
else:
return ""
openssh(self)
Returns an SSH public/private key in OpenSSH format. Preserves 'comment' field parsed from either SECSH or OpenSSH. Returned as a single string including newlines and with terminating newline.
Exceptions:
| Type | Description |
|---|---|
ValueError |
Unable to output openssh format private keys |
Returns:
| Type | Description |
|---|---|
str |
string: Single openssh key as a string including newlines and with terminating newline. |
Source code in ssh2_parse_key/ssh2_parse_key.py
def openssh(self) -> str:
"""
Returns an SSH public/private key in OpenSSH format. Preserves 'comment'
field parsed from either SECSH or OpenSSH. Returned as a single
string including newlines and with terminating newline.
Arguments:
Raises:
ValueError: Unable to output openssh format private keys
Returns:
string: Single openssh key as a string including newlines and with terminating newline.
"""
lines: "List[str]" = []
if self.type == "public":
lines.append(" ".join([self.encryption, self.key, self.comment()]))
else:
# ## Initial code to deal with private keys not used
# # private key - obviously!
# # add the wrapping header
# lines.append(f"---- BEGIN {self.encryption} PRIVATE KEY ----")
#
# # add the headers, if any
# if len(self.headers):
# for header, value in self.headers.items():
# self._encode_header(lines, header, value, 64)
#
# # add the key content
# lines.extend(textwrap.wrap(self.key, 64))
#
# # add the wrapping footer
# lines.append(f"---- END {self.encryption} PRIVATE KEY ----")
raise ValueError("Unable to output openssh format private keys")
lines.append("") # force terminating newline
# return the assembled string
return "\n".join(lines)
parse(data)
classmethod
Creates a set of Ssh2Key objects from a string of ssh key data
Accepts a block of text containing SSH2 public keys (in either OpenSSH or
SECSH format) and parses out SSH2 public keys returning them as Ssh2Key
Objects.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data |
str |
A multiline string of ssh key data in OpenSSH or SECSH format |
required |
Exceptions:
| Type | Description |
|---|---|
ValueError |
Unrecognised type of ssh key |
ValueError |
No valid ssh keys found |
Returns:
| Type | Description |
|---|---|
List[Ssh2Key] |
keys: A list of |
Source code in ssh2_parse_key/ssh2_parse_key.py
@classmethod
def parse(cls, data: str) -> "List[Ssh2Key]":
"""
Creates a set of `Ssh2Key` objects from a string of ssh key data
Accepts a block of text containing SSH2 public keys (in either OpenSSH or
SECSH format) and parses out SSH2 public keys returning them as `Ssh2Key`
Objects.
Arguments:
data: A multiline string of ssh key data in OpenSSH or SECSH format
Raises:
ValueError: Unrecognised type of ssh key
ValueError: No valid ssh keys found
Returns:
keys: A list of `Ssh2Key` objects
"""
lines = data.splitlines() # break the input into lines
keys: "List[Ssh2Key]" = []
inside_keyblock = False # where we are
keyblock: "List[str]" = []
keytype = ""
pubpriv = ""
for line in lines:
matches = KEY_BOUNDARY_PATTERN.match(line)
if inside_keyblock and matches and matches.group("beginend") == "END":
inside_keyblock = False # no longer within a keyblock
if keytype == matches.group("keytype") and pubpriv == matches.group(
"pubpriv",
):
if keytype in ["OPENSSH", "DSA", "EC", "RSA"]:
key = cls._parse_openssh(keyblock, keytype, pubpriv)
elif keytype == "SSH2":
key = cls._parse_secsh(keyblock, pubpriv)
else:
raise ValueError(
f"Unrecognised type of ssh key {keytype}",
)
if key:
keys.append(key)
keyblock = [] # fresh keyblock for next key
elif inside_keyblock:
keyblock.append(line)
elif matches and matches.group("beginend") == "BEGIN":
keytype = matches.group("keytype")
pubpriv = matches.group("pubpriv")
inside_keyblock = True # inside a new keyblock
else:
# check for OpenSSH format -- all on one line
matches = OPENSSH_PUBKEY_PATTERN.match(line)
if matches:
keys.append(cls._parse_openssh_oneline(matches))
else:
# raise ValueError("Unrecognised type of ssh key")
pass # ignore for now
if len(keys) == 0:
raise ValueError("No valid ssh keys found")
# return the assemblage of keys
return keys
parse_file(filepath)
classmethod
Creates a set of Ssh2Key objects from a file of ssh key data
Accepts a block of text containing SSH2 public keys (in either OpenSSH or
SECSH format) and parses out SSH2 public keys returning them as Ssh2Key
Objects.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filepath |
PathLike[str] |
Pathname of a file of ssh key data in OpenSSH or SECSH format |
required |
Exceptions:
| Type | Description |
|---|---|
IOError |
From underlying open/read |
ValueError |
Unrecognised type of ssh key |
ValueError |
No valid ssh keys found |
Returns:
| Type | Description |
|---|---|
List[Ssh2Key] |
keys: A list of |
Source code in ssh2_parse_key/ssh2_parse_key.py
@classmethod
def parse_file(cls, filepath: "PathLike[str]") -> "List[Ssh2Key]":
"""
Creates a set of `Ssh2Key` objects from a file of ssh key data
Accepts a block of text containing SSH2 public keys (in either OpenSSH or
SECSH format) and parses out SSH2 public keys returning them as `Ssh2Key`
Objects.
Arguments:
filepath: Pathname of a file of ssh key data in OpenSSH or SECSH format
Raises:
IOError: From underlying open/read
ValueError: Unrecognised type of ssh key
ValueError: No valid ssh keys found
Returns:
keys: A list of `Ssh2Key` objects
"""
with open(filepath) as f:
data = f.read()
return cls.parse(data)
rfc4716(self)
Returns an SSH public key in SECSH format (as specified in RFC4716). Preserves headers and the order of headers. Returned as a single string including newlines and with terminating newline.
Alias - rfc4716() just calls secsh()
See http://tools.ietf.org/html/rfc4716
Exceptions:
| Type | Description |
|---|---|
ValueError |
Unable to output secsh format private keys |
Returns:
| Type | Description |
|---|---|
str |
string: Single secsh key as a string including newlines and with terminating newline. |
Source code in ssh2_parse_key/ssh2_parse_key.py
def rfc4716(self) -> str:
"""
Returns an SSH public key in SECSH format (as specified in RFC4716).
Preserves headers and the order of headers. Returned as a single
string including newlines and with terminating newline.
Alias - ``rfc4716()`` just calls ``secsh()``
See http://tools.ietf.org/html/rfc4716
Arguments:
Raises:
ValueError: Unable to output secsh format private keys
Returns:
string: Single secsh key as a string including newlines and with terminating newline.
"""
return self.secsh()
secsh(self)
Returns an SSH public key in SECSH format (as specified in RFC4716). Preserves headers and the order of headers. Returned as a single string including newlines and with terminating newline.
See http://tools.ietf.org/html/rfc4716
Exceptions:
| Type | Description |
|---|---|
ValueError |
Unable to output secsh format private keys |
Returns:
| Type | Description |
|---|---|
str |
string: Single secsh key as a string including newlines and with terminating newline. |
Source code in ssh2_parse_key/ssh2_parse_key.py
def secsh(self) -> str:
"""
Returns an SSH public key in SECSH format (as specified in RFC4716).
Preserves headers and the order of headers. Returned as a single
string including newlines and with terminating newline.
See http://tools.ietf.org/html/rfc4716
Arguments:
Raises:
ValueError: Unable to output secsh format private keys
Returns:
string: Single secsh key as a string including newlines and with terminating newline.
"""
lines: "List[str]" = []
if self.type == "public":
key_header_chunk = "SSH2 PUBLIC KEY"
else:
raise ValueError("Unable to output secsh format private keys")
key_header_chunk = "SSH2 ENCRYPTED PRIVATE KEY"
# add the wrapping header
lines.append(f"---- BEGIN {key_header_chunk} ----")
# add the headers, if any
if len(self.headers):
for header, value in self.headers.items():
self._encode_header(lines, header, value, 74)
# add the key content
lines.extend(textwrap.wrap(self.key, 70))
# add the wrapping footer
lines.append(f"---- END {key_header_chunk} ----")
lines.append("") # force terminating newline
# return the assembled string
return "\n".join(lines)
subject(self)
Returns the subject header from a ssh key object.
Returns:
| Type | Description |
|---|---|
Union[str, None] |
string: Subject field or |
Source code in ssh2_parse_key/ssh2_parse_key.py
def subject(self) -> "typing.Union[str, None]":
"""
Returns the subject header from a ssh key object.
Arguments:
Returns:
string: Subject field or `None`.
"""
if "Subject" in self.headers:
return self.headers["Subject"]
return None