diff options
author | Jeff Forcier <jeff@bitprophet.org> | 2017-08-28 19:27:57 -0700 |
---|---|---|
committer | Jeff Forcier <jeff@bitprophet.org> | 2017-08-28 19:27:57 -0700 |
commit | c87cfdc48a54a8b715832ac53134e0a2b3e334bc (patch) | |
tree | 09787aca63bcb4dc98d62328a78cb0c5c120f2e3 | |
parent | d03c8b6e2f63cba2cb6d93ec3cd270bf49cda3da (diff) |
Factor out type checking & cert loading into PKey
-rw-r--r-- | paramiko/pkey.py | 32 | ||||
-rw-r--r-- | paramiko/rsakey.py | 27 |
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()) |