summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJeff Forcier <jeff@bitprophet.org>2017-08-28 19:27:57 -0700
committerJeff Forcier <jeff@bitprophet.org>2017-08-28 19:27:57 -0700
commitc87cfdc48a54a8b715832ac53134e0a2b3e334bc (patch)
tree09787aca63bcb4dc98d62328a78cb0c5c120f2e3
parentd03c8b6e2f63cba2cb6d93ec3cd270bf49cda3da (diff)
Factor out type checking & cert loading into PKey
-rw-r--r--paramiko/pkey.py32
-rw-r--r--paramiko/rsakey.py27
2 files changed, 37 insertions, 22 deletions
diff --git a/paramiko/pkey.py b/paramiko/pkey.py
index 1683c35c..c8a59ee2 100644
--- a/paramiko/pkey.py
+++ b/paramiko/pkey.py
@@ -365,6 +365,38 @@ class PKey(object):
encryption
).decode())
+ def _check_type_and_load_cert(self, msg, key_type, cert_type):
+ """
+ Perform message type-checking & optional certificate loading.
+
+ This includes fast-forwarding cert ``msg`` objects past the nonce, so
+ that the subsequent fields are the key numbers; thus the caller may
+ expect to treat the message as key material afterwards either way.
+ """
+ if msg is None:
+ raise SSHException('Key object may not be empty')
+ type_ = msg.get_text()
+ nonce = None
+ # Regular public key - nothing special to do besides the implicit
+ # type check.
+ if type_ == key_type:
+ pass
+ # OpenSSH-compatible certificate - store full copy as .public_blob
+ # (so signing works correctly) and then fast-forward past the
+ # nonce.
+ elif type_ == cert_type:
+ # This seems the cleanest way to 'clone' an already-being-read
+ # message; they're *IO objects at heart and their .getvalue()
+ # always returns the full value regardless of pointer position.
+ self.load_certificate(Message(msg.asbytes()))
+ # Read out nonce as it comes before the public numbers.
+ # TODO: usefully interpret it & other non-public-number fields
+ # (requires going back into per-type subclasses.)
+ nonce = msg.get_string()
+ else:
+ raise SSHException('Invalid key')
+
+
def load_certificate(self, value):
"""
Supplement the private key contents with data loaded from an OpenSSH
diff --git a/paramiko/rsakey.py b/paramiko/rsakey.py
index 3f28689a..1646fa4f 100644
--- a/paramiko/rsakey.py
+++ b/paramiko/rsakey.py
@@ -52,28 +52,11 @@ class RSAKey(PKey):
if key is not None:
self.key = key
else:
- if msg is None:
- raise SSHException('Key object may not be empty')
- type_ = msg.get_text()
- nonce = None
- # Regular public key - nothing special to do besides the implicit
- # type check.
- if type_ == 'ssh-rsa':
- pass
- # OpenSSH-compatible certificate - store full copy as .public_blob
- # (so signing works correctly) and then fast-forward past the
- # nonce.
- elif type_ == 'ssh-rsa-cert-v01@openssh.com':
- # This seems the cleanest way to 'clone' an already-being-read
- # message?
- self.load_certificate(Message(msg.asbytes()))
- # Read out nonce as it comes before the public numbers.
- # TODO: usefully interpret it & other non-public-number fields
- nonce = msg.get_string()
- else:
- raise SSHException('Invalid key')
- # Now that we've read type and (possibly) nonce, public numbers are
- # next in either case.
+ self._check_type_and_load_cert(
+ msg=msg,
+ key_type='ssh-rsa',
+ cert_type='ssh-rsa-cert-v01@openssh.com',
+ )
self.key = rsa.RSAPublicNumbers(
e=msg.get_mpint(), n=msg.get_mpint()
).public_key(default_backend())