Exemple #1
0
    def test_1_encode(self):
        msg = Message()
        msg.add_int(23)
        msg.add_int(123789456)
        msg.add_string("q")
        msg.add_string("hello")
        msg.add_string("x" * 1000)
        self.assertEqual(msg.asbytes(), self.__a)

        msg = Message()
        msg.add_boolean(True)
        msg.add_boolean(False)
        msg.add_byte(byte_chr(0xf3))

        msg.add_bytes(zero_byte + byte_chr(0x3f))
        msg.add_list(["huey", "dewey", "louie"])
        self.assertEqual(msg.asbytes(), self.__b)

        msg = Message()
        msg.add_int64(5)
        msg.add_int64(0xf5e4d3c2b109)
        msg.add_mpint(17)
        msg.add_mpint(0xf5e4d3c2b109)
        msg.add_mpint(-0x65e4d3c2b109)
        self.assertEqual(msg.asbytes(), self.__c)
Exemple #2
0
    def test_encode(self):
        msg = Message()
        msg.add_int(23)
        msg.add_int(123789456)
        msg.add_string('q')
        msg.add_string('hello')
        msg.add_string('x' * 1000)
        self.assertEqual(msg.asbytes(), self.__a)

        msg = Message()
        msg.add_boolean(True)
        msg.add_boolean(False)
        msg.add_byte(byte_chr(0xf3))

        msg.add_bytes(zero_byte + byte_chr(0x3f))
        msg.add_list(['huey', 'dewey', 'louie'])
        self.assertEqual(msg.asbytes(), self.__b)

        msg = Message()
        msg.add_int64(5)
        msg.add_int64(0xf5e4d3c2b109)
        msg.add_mpint(17)
        msg.add_mpint(0xf5e4d3c2b109)
        msg.add_mpint(-0x65e4d3c2b109)
        self.assertEqual(msg.asbytes(), self.__c)
Exemple #3
0
def make_certificate(ca_key, duration_hours, real_name, username, host, now, expiry):
    """http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=1.9"""
    pkey = paramiko.RSAKey.from_private_key(StringIO(ca_key))

    principals = Message()
    principals.add_string(username)
    principals = principals.asbytes()

    m = Message()
    m.add_string('*****@*****.**')
    m.add_string(sha1(str(random.random())).hexdigest())
    m.add_mpint(pkey.e)
    m.add_mpint(pkey.n)
    m.add_int64(0) # serial
    m.add_int(SSH_CERT_TYPE_USER)
    m.add_string(real_name)
    m.add_string(principals)
    m.add_int64(int(now.strftime("%s")))
    m.add_int64(int(expiry.strftime("%s")))
    m.add_string("") # critical_options
    m.add_string("") # extensions
    m.add_string("") # reserved
    m.add_string(pkey.asbytes())

    key = RSA.construct((long(pkey.n), long(pkey.e), long(pkey.d)))
    h = SHA.new(m.asbytes())
    signer = PKCS1_v1_5.new(key)
    signature = signer.sign(h)

    sig_message = Message()
    sig_message.add_string("ssh-rsa")
    sig_message.add_string(signature)
    m.add_string(sig_message.asbytes())

    return "[email protected] {0} {1}@{2}".format(base64.b64encode(m.asbytes()), username, host)
Exemple #4
0
    def _send_sign_data(self, msg):
        logger.debug('Sending signed data...')
        blob = msg.get_string()
        data = msg.get_string()
        flags = msg.get_int()

        logger.debug('Key blob:')
        for l in hexdump.hexdump(blob, result='generator'):
            logger.debug(l)

        # logger.debug('Data to be signed:')
        # for l in hexdump.hexdump(data, result='generator'):
        #     logger.debug(l)
        #

        # logger.debug('Flags: %X', flags)

        signed_data = self._sign_data(blob, data)

        if not signed_data:
            self._send_failure()
            return

        sign_blob = Message()
        sign_blob.add_string('ssh-rsa')
        sign_blob.add_string(signed_data)

        msg = Message()
        # add response byte
        msg.add_byte(byte_chr(SSH_AGENT_SIGN_RESPONSE))
        # add signed blob
        msg.add_string(sign_blob.asbytes())

        self._send_reply(msg)
Exemple #5
0
 def _parse_kexdh_gex_init(self, m):
     self.e = m.get_mpint()
     if (self.e < 1) or (self.e > self.p - 1):
         raise SSHException('Client kex "e" is out of range')
     self._generate_x()
     self.f = pow(self.g, self.x, self.p)
     K = pow(self.e, self.x, self.p)
     key = self.transport.get_server_key().asbytes()
     # okay, build up the hash H of (V_C || V_S || I_C || I_S || K_S || min || n || max || p || g || e || f || K)
     hm = Message()
     hm.add(self.transport.remote_version, self.transport.local_version,
            self.transport.remote_kex_init, self.transport.local_kex_init,
            key)
     if not self.old_style:
         hm.add_int(self.min_bits)
     hm.add_int(self.preferred_bits)
     if not self.old_style:
         hm.add_int(self.max_bits)
     hm.add_mpint(self.p)
     hm.add_mpint(self.g)
     hm.add_mpint(self.e)
     hm.add_mpint(self.f)
     hm.add_mpint(K)
     H = self.hash_algo(hm.asbytes()).digest()
     self.transport._set_K_H(K, H)
     # sign it
     sig = self.transport.get_server_key().sign_ssh_data(H)
     # send reply
     m = Message()
     m.add_byte(c_MSG_KEXDH_GEX_REPLY)
     m.add_string(key)
     m.add_mpint(self.f)
     m.add_string(sig)
     self.transport._send_message(m)
     self.transport._activate_outbound()
 def _parse_kexecdh_init(self, m):
     peer_key_bytes = m.get_string()
     peer_key = X25519PublicKey.from_public_bytes(peer_key_bytes)
     K = self._perform_exchange(peer_key)
     K = long(binascii.hexlify(K), 16)
     # compute exchange hash
     hm = Message()
     hm.add(
         self.transport.remote_version,
         self.transport.local_version,
         self.transport.remote_kex_init,
         self.transport.local_kex_init,
     )
     server_key_bytes = self.transport.get_server_key().asbytes()
     exchange_key_bytes = self.key.public_key().public_bytes(
         serialization.Encoding.Raw, serialization.PublicFormat.Raw)
     hm.add_string(server_key_bytes)
     hm.add_string(peer_key_bytes)
     hm.add_string(exchange_key_bytes)
     hm.add_mpint(K)
     H = self.hash_algo(hm.asbytes()).digest()
     self.transport._set_K_H(K, H)
     sig = self.transport.get_server_key().sign_ssh_data(H)
     # construct reply
     m = Message()
     m.add_byte(c_MSG_KEXECDH_REPLY)
     m.add_string(server_key_bytes)
     m.add_string(exchange_key_bytes)
     m.add_string(sig)
     self.transport._send_message(m)
     self.transport._activate_outbound()
Exemple #7
0
 def test_add(self):
     msg = Message()
     msg.add(5)
     msg.add(True)
     msg.add('cat')
     msg.add(['a', 'b'])
     self.assertEqual(msg.asbytes(), self.__d)
 def _parse_kexecdh_reply(self, m):
     K_S = m.get_string()
     Q_S_bytes = m.get_string()
     self.Q_S = ec.EllipticCurvePublicKey.from_encoded_point(
         self.curve, Q_S_bytes
     )
     sig = m.get_binary()
     K = self.P.exchange(ec.ECDH(), self.Q_S)
     K = long(hexlify(K), 16)
     # compute exchange hash and verify signature
     hm = Message()
     hm.add(
         self.transport.local_version,
         self.transport.remote_version,
         self.transport.local_kex_init,
         self.transport.remote_kex_init,
     )
     hm.add_string(K_S)
     # SEC1: V2.0  2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion
     hm.add_string(
         self.Q_C.public_bytes(
             serialization.Encoding.X962,
             serialization.PublicFormat.UncompressedPoint,
         )
     )
     hm.add_string(Q_S_bytes)
     hm.add_mpint(K)
     self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest())
     self.transport._verify_key(K_S, sig)
     self.transport._activate_outbound()
Exemple #9
0
 def _parse_kexdh_init(self, m):
     # server mode
     self.e = m.get_mpint()
     if (self.e < 1) or (self.e > P - 1):
         raise SSHException('Client kex "e" is out of range')
     K = pow(self.e, self.x, P)
     key = self.transport.get_server_key().asbytes()
     # okay, build up the hash H of (V_C || V_S || I_C || I_S || K_S || e || f || K)
     hm = Message()
     hm.add(self.transport.remote_version, self.transport.local_version,
            self.transport.remote_kex_init, self.transport.local_kex_init)
     hm.add_string(key)
     hm.add_mpint(self.e)
     hm.add_mpint(self.f)
     hm.add_mpint(K)
     H = SHA.new(hm.asbytes()).digest()
     self.transport._set_K_H(K, H)
     # sign it
     sig = self.transport.get_server_key().sign_ssh_data(
         self.transport.rng, H)
     # send reply
     m = Message()
     m.add_byte(c_MSG_KEXDH_REPLY)
     m.add_string(key)
     m.add_mpint(self.f)
     m.add_string(sig)
     self.transport._send_message(m)
     self.transport._activate_outbound()
Exemple #10
0
 def _parse_kexdh_gex_init(self, m):
     self.e = m.get_mpint()
     if (self.e < 1) or (self.e > self.p - 1):
         raise SSHException('Client kex "e" is out of range')
     self._generate_x()
     self.f = pow(self.g, self.x, self.p)
     K = pow(self.e, self.x, self.p)
     key = self.transport.get_server_key().asbytes()
     # okay, build up the hash H of (V_C || V_S || I_C || I_S || K_S || min || n || max || p || g || e || f || K)
     hm = Message()
     hm.add(self.transport.remote_version, self.transport.local_version,
            self.transport.remote_kex_init, self.transport.local_kex_init,
            key)
     if not self.old_style:
         hm.add_int(self.min_bits)
     hm.add_int(self.preferred_bits)
     if not self.old_style:
         hm.add_int(self.max_bits)
     hm.add_mpint(self.p)
     hm.add_mpint(self.g)
     hm.add_mpint(self.e)
     hm.add_mpint(self.f)
     hm.add_mpint(K)
     H = self.hash_algo(hm.asbytes()).digest()
     self.transport._set_K_H(K, H)
     # sign it
     sig = self.transport.get_server_key().sign_ssh_data(H)
     # send reply
     m = Message()
     m.add_byte(c_MSG_KEXDH_GEX_REPLY)
     m.add_string(key)
     m.add_mpint(self.f)
     m.add_string(sig)
     self.transport._send_message(m)
     self.transport._activate_outbound()
 def _parse_kexecdh_init(self, m):
     Q_C_bytes = m.get_string()
     self.Q_C = ec.EllipticCurvePublicNumbers.from_encoded_point(
         self.curve, Q_C_bytes)
     K_S = self.transport.get_server_key().asbytes()
     K = self.P.exchange(ec.ECDH(), self.Q_C.public_key(default_backend()))
     K = long(hexlify(K), 16)
     # compute exchange hash
     hm = Message()
     hm.add(self.transport.remote_version, self.transport.local_version,
            self.transport.remote_kex_init, self.transport.local_kex_init)
     hm.add_string(K_S)
     hm.add_string(Q_C_bytes)
     # SEC1: V2.0  2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion
     hm.add_string(self.Q_S.public_numbers().encode_point())
     hm.add_mpint(long(K))
     H = self.hash_algo(hm.asbytes()).digest()
     self.transport._set_K_H(K, H)
     sig = self.transport.get_server_key().sign_ssh_data(H)
     # construct reply
     m = Message()
     m.add_byte(c_MSG_KEXECDH_REPLY)
     m.add_string(K_S)
     m.add_string(self.Q_S.public_numbers().encode_point())
     m.add_string(sig)
     self.transport._send_message(m)
     self.transport._activate_outbound()
    def _parse_kexecdh_reply(self, m):
        peer_host_key_bytes = m.get_string()
        peer_key_bytes = m.get_string()
        sig = m.get_binary()

        peer_key = X25519PublicKey.from_public_bytes(peer_key_bytes)

        K = self._perform_exchange(peer_key)
        K = long(binascii.hexlify(K), 16)
        # compute exchange hash and verify signature
        hm = Message()
        hm.add(
            self.transport.local_version,
            self.transport.remote_version,
            self.transport.local_kex_init,
            self.transport.remote_kex_init,
        )
        hm.add_string(peer_host_key_bytes)
        hm.add_string(self.key.public_key().public_bytes(
            serialization.Encoding.Raw, serialization.PublicFormat.Raw))
        hm.add_string(peer_key_bytes)
        hm.add_mpint(K)
        self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest())
        self.transport._verify_key(peer_host_key_bytes, sig)
        self.transport._activate_outbound()
Exemple #13
0
 def _parse_kexdh_init(self, m):
     # server mode
     self.e = m.get_mpint()
     if (self.e < 1) or (self.e > P - 1):
         raise SSHException('Client kex "e" is out of range')
     K = pow(self.e, self.x, P)
     key = self.transport.get_server_key().asbytes()
     # okay, build up the hash H of (V_C || V_S || I_C || I_S || K_S || e || f || K)
     hm = Message()
     hm.add(self.transport.remote_version, self.transport.local_version,
            self.transport.remote_kex_init, self.transport.local_kex_init)
     hm.add_string(key)
     hm.add_mpint(self.e)
     hm.add_mpint(self.f)
     hm.add_mpint(K)
     H = SHA.new(hm.asbytes()).digest()
     self.transport._set_K_H(K, H)
     # sign it
     sig = self.transport.get_server_key().sign_ssh_data(self.transport.rng, H)
     # send reply
     m = Message()
     m.add_byte(c_MSG_KEXDH_REPLY)
     m.add_string(key)
     m.add_mpint(self.f)
     m.add_string(sig)
     self.transport._send_message(m)
     self.transport._activate_outbound()
Exemple #14
0
 def _parse_kexdh_gex_reply(self, m):
     host_key = m.get_string()
     self.f = m.get_mpint()
     sig = m.get_string()
     if (self.f < 1) or (self.f > self.p - 1):
         raise SSHException('Server kex "f" is out of range')
     K = pow(self.f, self.x, self.p)
     # okay, build up the hash H of (V_C || V_S || I_C || I_S || K_S || min || n || max || p || g || e || f || K)
     hm = Message()
     hm.add(self.transport.local_version, self.transport.remote_version,
            self.transport.local_kex_init, self.transport.remote_kex_init,
            host_key)
     if not self.old_style:
         hm.add_int(self.min_bits)
     hm.add_int(self.preferred_bits)
     if not self.old_style:
         hm.add_int(self.max_bits)
     hm.add_mpint(self.p)
     hm.add_mpint(self.g)
     hm.add_mpint(self.e)
     hm.add_mpint(self.f)
     hm.add_mpint(K)
     self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest())
     self.transport._verify_key(host_key, sig)
     self.transport._activate_outbound()
Exemple #15
0
 def _parse_kexdh_gex_reply(self, m):
     host_key = m.get_string()
     self.f = m.get_mpint()
     sig = m.get_string()
     if (self.f < 1) or (self.f > self.p - 1):
         raise SSHException('Server kex "f" is out of range')
     K = pow(self.f, self.x, self.p)
     # okay, build up the hash H of
     # (V_C || V_S || I_C || I_S || K_S || min || n || max || p || g || e || f || K)  # noqa
     hm = Message()
     hm.add(
         self.transport.local_version,
         self.transport.remote_version,
         self.transport.local_kex_init,
         self.transport.remote_kex_init,
         host_key,
     )
     if not self.old_style:
         hm.add_int(self.min_bits)
     hm.add_int(self.preferred_bits)
     if not self.old_style:
         hm.add_int(self.max_bits)
     hm.add_mpint(self.p)
     hm.add_mpint(self.g)
     hm.add_mpint(self.e)
     hm.add_mpint(self.f)
     hm.add_mpint(K)
     self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest())
     self.transport._verify_key(host_key, sig)
     self.transport._activate_outbound()
Exemple #16
0
 def _gen_pem(self):
     msg = Message()
     msg.add_string('ssh-rsa')
     exp, mod = self._fetch_material()
     msg.add_string(bigint_to_bytes(exp))
     msg.add_string(bigint_to_bytes(mod, extra_bytes=1))
     self._pub_key_bytes = msg.asbytes()
Exemple #17
0
 def _parse_kexecdh_reply(self, m):
     K_S = m.get_string()
     Q_S_bytes = m.get_string()
     self.Q_S = ec.EllipticCurvePublicNumbers.from_encoded_point(
         self.curve, Q_S_bytes
     )
     sig = m.get_binary()
     K = self.P.exchange(ec.ECDH(), self.Q_S.public_key(default_backend()))
     K = long(hexlify(K), 16)
     # compute exchange hash and verify signature
     hm = Message()
     hm.add(
         self.transport.local_version,
         self.transport.remote_version,
         self.transport.local_kex_init,
         self.transport.remote_kex_init,
     )
     hm.add_string(K_S)
     # SEC1: V2.0  2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion
     hm.add_string(self.Q_C.public_numbers().encode_point())
     hm.add_string(Q_S_bytes)
     hm.add_mpint(K)
     self.transport._set_K_H(K, self.hash_algo(hm.asbytes()).digest())
     self.transport._verify_key(K_S, sig)
     self.transport._activate_outbound()
 def _parse_kexecdh_init(self, m):
     Q_C_bytes = m.get_string()
     self.Q_C = ec.EllipticCurvePublicNumbers.from_encoded_point(
         self.curve, Q_C_bytes
     )
     K_S = self.transport.get_server_key().asbytes()
     K = self.P.exchange(ec.ECDH(), self.Q_C.public_key(default_backend()))
     K = long(hexlify(K), 16)
     # compute exchange hash
     hm = Message()
     hm.add(self.transport.remote_version, self.transport.local_version,
            self.transport.remote_kex_init, self.transport.local_kex_init)
     hm.add_string(K_S)
     hm.add_string(Q_C_bytes)
     # SEC1: V2.0  2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion
     hm.add_string(self.Q_S.public_numbers().encode_point())
     hm.add_mpint(long(K))
     H = self.hash_algo(hm.asbytes()).digest()
     self.transport._set_K_H(K, H)
     sig = self.transport.get_server_key().sign_ssh_data(H)
     # construct reply
     m = Message()
     m.add_byte(c_MSG_KEXECDH_REPLY)
     m.add_string(K_S)
     m.add_string(self.Q_S.public_numbers().encode_point())
     m.add_string(sig)
     self.transport._send_message(m)
     self.transport._activate_outbound()
Exemple #19
0
    def _parse_kexgss_gex_init(self, m):
        """
        Parse the SSH2_MSG_KEXGSS_INIT message (server mode).

        :param `Message` m: The content of the SSH2_MSG_KEXGSS_INIT message
        """
        client_token = m.get_string()
        self.e = m.get_mpint()
        if (self.e < 1) or (self.e > self.p - 1):
            raise SSHException('Client kex "e" is out of range')
        self._generate_x()
        self.f = pow(self.g, self.x, self.p)
        K = pow(self.e, self.x, self.p)
        self.transport.host_key = NullHostKey()
        key = self.transport.host_key.__str__()
        # okay, build up the hash H of
        # (V_C || V_S || I_C || I_S || K_S || min || n || max || p || g || e || f || K)  # noqa
        hm = Message()
        hm.add(
            self.transport.remote_version,
            self.transport.local_version,
            self.transport.remote_kex_init,
            self.transport.local_kex_init,
            key,
        )
        hm.add_int(self.min_bits)
        hm.add_int(self.preferred_bits)
        hm.add_int(self.max_bits)
        hm.add_mpint(self.p)
        hm.add_mpint(self.g)
        hm.add_mpint(self.e)
        hm.add_mpint(self.f)
        hm.add_mpint(K)
        H = sha1(hm.asbytes()).digest()
        self.transport._set_K_H(K, H)
        srv_token = self.kexgss.ssh_accept_sec_context(self.gss_host,
                                                       client_token)
        m = Message()
        if self.kexgss._gss_srv_ctxt_status:
            mic_token = self.kexgss.ssh_get_mic(self.transport.session_id,
                                                gss_kex=True)
            m.add_byte(c_MSG_KEXGSS_COMPLETE)
            m.add_mpint(self.f)
            m.add_string(mic_token)
            if srv_token is not None:
                m.add_boolean(True)
                m.add_string(srv_token)
            else:
                m.add_boolean(False)
            self.transport._send_message(m)
            self.transport.gss_kex_used = True
            self.transport._activate_outbound()
        else:
            m.add_byte(c_MSG_KEXGSS_CONTINUE)
            m.add_string(srv_token)
            self.transport._send_message(m)
            self.transport._expect_packet(MSG_KEXGSS_CONTINUE,
                                          MSG_KEXGSS_COMPLETE,
                                          MSG_KEXGSS_ERROR)
Exemple #20
0
 def asbytes(self):
     m = Message()
     m.add_string('ssh-dss')
     m.add_mpint(self.p)
     m.add_mpint(self.q)
     m.add_mpint(self.g)
     m.add_mpint(self.y)
     return m.asbytes()
Exemple #21
0
 def asbytes(self):
     m = Message()
     m.add_string('ssh-dss')
     m.add_mpint(self.p)
     m.add_mpint(self.q)
     m.add_mpint(self.g)
     m.add_mpint(self.y)
     return m.asbytes()
Exemple #22
0
 def asbytes(self):
     if self.can_sign():
         v = self._signing_key.verify_key
     else:
         v = self._verifying_key
     m = Message()
     m.add_string("ssh-ed25519")
     m.add_string(v.encode())
     return m.asbytes()
 def test_3_add(self):
     msg = Message()
     msg.add(5)
     msg.add(0x1122334455)
     msg.add(0xf00000000000000000)
     msg.add(True)
     msg.add('cat')
     msg.add(['a', 'b'])
     self.assertEqual(msg.asbytes(), self.__d)
Exemple #24
0
 def test_3_add(self):
     msg = Message()
     msg.add(5)
     msg.add(0x1122334455)
     msg.add(0xf00000000000000000)
     msg.add(True)
     msg.add("cat")
     msg.add(["a", "b"])
     self.assertEqual(msg.asbytes(), self.__d)
Exemple #25
0
 def asbytes(self):
     public_bytes = self._verifying_key.public_bytes(
         serialization.Encoding.Raw,
         serialization.PublicFormat.Raw,
     )
     m = Message()
     m.add_string("ssh-ed25519")
     m.add_string(public_bytes)
     return m.asbytes()
Exemple #26
0
 def test_3_add(self):
     msg = Message()
     msg.add(5)
     msg.add(0x1122334455)
     msg.add(0xf00000000000000000)
     msg.add(True)
     msg.add('cat')
     msg.add(['a', 'b'])
     self.assertEqual(msg.asbytes(), self.__d)
Exemple #27
0
 def asbytes(self):
     if self.can_sign():
         v = self._signing_key.verify_key
     else:
         v = self._verifying_key
     m = Message()
     m.add_string("ssh-ed25519")
     m.add_string(v.encode())
     return m.asbytes()
Exemple #28
0
 def asagentbytes(self):
     m = Message()
     m.add_string('ssh-rsa')
     m.add_mpint(self.public_numbers.n)
     m.add_mpint(self.public_numbers.e)
     m.add_mpint(self.key.private_numbers().d)
     m.add_mpint(self.key.private_numbers().iqmp)
     m.add_mpint(self.key.private_numbers().p)
     m.add_mpint(self.key.private_numbers().q)
     return m.asbytes()
Exemple #29
0
    def asbytes(self):
        key = self.verifying_key
        m = Message()
        m.add_string('ecdsa-sha2-nistp256')
        m.add_string('nistp256')

        point_str = four_byte + key.to_string()

        m.add_string(point_str)
        return m.asbytes()
Exemple #30
0
    def asbytes(self):
        key = self.verifying_key
        m = Message()
        m.add_string('ecdsa-sha2-nistp256')
        m.add_string('nistp256')

        point_str = four_byte + key.to_string()

        m.add_string(point_str)
        return m.asbytes()
Exemple #31
0
    def _parse_kexgss_gex_init(self, m):
        """
        Parse the SSH2_MSG_KEXGSS_INIT message (server mode).

        :param `Message` m: The content of the SSH2_MSG_KEXGSS_INIT message
        """
        client_token = m.get_string()
        self.e = m.get_mpint()
        if (self.e < 1) or (self.e > self.p - 1):
            raise SSHException('Client kex "e" is out of range')
        self._generate_x()
        self.f = pow(self.g, self.x, self.p)
        K = pow(self.e, self.x, self.p)
        self.transport.host_key = NullHostKey()
        key = self.transport.host_key.__str__()
        # okay, build up the hash H of
        # (V_C || V_S || I_C || I_S || K_S || min || n || max || p || g || e || f || K)  # noqa
        hm = Message()
        hm.add(self.transport.remote_version, self.transport.local_version,
               self.transport.remote_kex_init, self.transport.local_kex_init,
               key)
        hm.add_int(self.min_bits)
        hm.add_int(self.preferred_bits)
        hm.add_int(self.max_bits)
        hm.add_mpint(self.p)
        hm.add_mpint(self.g)
        hm.add_mpint(self.e)
        hm.add_mpint(self.f)
        hm.add_mpint(K)
        H = sha1(hm.asbytes()).digest()
        self.transport._set_K_H(K, H)
        srv_token = self.kexgss.ssh_accept_sec_context(self.gss_host,
                                                       client_token)
        m = Message()
        if self.kexgss._gss_srv_ctxt_status:
            mic_token = self.kexgss.ssh_get_mic(self.transport.session_id,
                                                gss_kex=True)
            m.add_byte(c_MSG_KEXGSS_COMPLETE)
            m.add_mpint(self.f)
            m.add_string(mic_token)
            if srv_token is not None:
                m.add_boolean(True)
                m.add_string(srv_token)
            else:
                m.add_boolean(False)
            self.transport._send_message(m)
            self.transport.gss_kex_used = True
            self.transport._activate_outbound()
        else:
            m.add_byte(c_MSG_KEXGSS_CONTINUE)
            m.add_string(srv_token)
            self.transport._send_message(m)
            self.transport._expect_packet(MSG_KEXGSS_CONTINUE,
                                          MSG_KEXGSS_COMPLETE,
                                          MSG_KEXGSS_ERROR)
Exemple #32
0
 def _get_session_blob(self, key, service, username):
     m = Message()
     m.add_string(self.transport.session_id)
     m.add_byte(cMSG_USERAUTH_REQUEST)
     m.add_string(username)
     m.add_string(service)
     m.add_string('publickey')
     m.add_boolean(True)
     m.add_string(key.get_name())
     m.add_string(key)
     return m.asbytes()
 def _get_session_blob(self, key, service, username):
     m = Message()
     m.add_string(self.transport.session_id)
     m.add_byte(cMSG_USERAUTH_REQUEST)
     m.add_string(username)
     m.add_string(service)
     m.add_string('publickey')
     m.add_boolean(True)
     m.add_string(key.get_name())
     m.add_string(key)
     return m.asbytes()
 def _get_session_blob(self, key, service, username, algorithm):
     m = Message()
     m.add_string(self.transport.session_id)
     m.add_byte(cMSG_USERAUTH_REQUEST)
     m.add_string(username)
     m.add_string(service)
     m.add_string("publickey")
     m.add_boolean(True)
     _, bits = self._get_key_type_and_bits(key)
     m.add_string(algorithm)
     m.add_string(bits)
     return m.asbytes()
Exemple #35
0
    def _parse_kexgss_complete(self, m):
        """
        Parse the SSH2_MSG_KEXGSS_COMPLETE message (client mode).

        :param `Message` m: The content of the SSH2_MSG_KEXGSS_COMPLETE message
        """
        if self.transport.host_key is None:
            self.transport.host_key = NullHostKey()
        self.f = m.get_mpint()
        mic_token = m.get_string()
        # This must be TRUE, if there is a GSS-API token in this message.
        bool = m.get_boolean()
        srv_token = None
        if bool:
            srv_token = m.get_string()
        if (self.f < 1) or (self.f > self.p - 1):
            raise SSHException('Server kex "f" is out of range')
        K = pow(self.f, self.x, self.p)
        # okay, build up the hash H of
        # (V_C || V_S || I_C || I_S || K_S || min || n || max || p || g || e || f || K)  # noqa
        hm = Message()
        hm.add(
            self.transport.local_version,
            self.transport.remote_version,
            self.transport.local_kex_init,
            self.transport.remote_kex_init,
            self.transport.host_key.__str__(),
        )
        if not self.old_style:
            hm.add_int(self.min_bits)
        hm.add_int(self.preferred_bits)
        if not self.old_style:
            hm.add_int(self.max_bits)
        hm.add_mpint(self.p)
        hm.add_mpint(self.g)
        hm.add_mpint(self.e)
        hm.add_mpint(self.f)
        hm.add_mpint(K)
        H = sha1(hm.asbytes()).digest()
        self.transport._set_K_H(K, H)
        if srv_token is not None:
            self.kexgss.ssh_init_sec_context(
                target=self.gss_host, recv_token=srv_token
            )
            self.kexgss.ssh_check_mic(mic_token, H)
        else:
            self.kexgss.ssh_check_mic(mic_token, H)
        self.transport.gss_kex_used = True
        self.transport._activate_outbound()
Exemple #36
0
    def _parse_kexgss_complete(self, m):
        """
        Parse the SSH2_MSG_KEXGSS_COMPLETE message (client mode).

        :param `Message` m: The content of the SSH2_MSG_KEXGSS_COMPLETE message
        """
        if self.transport.host_key is None:
            self.transport.host_key = NullHostKey()
        self.f = m.get_mpint()
        mic_token = m.get_string()
        # This must be TRUE, if there is a GSS-API token in this message.
        bool = m.get_boolean()
        srv_token = None
        if bool:
            srv_token = m.get_string()
        if (self.f < 1) or (self.f > self.p - 1):
            raise SSHException('Server kex "f" is out of range')
        K = pow(self.f, self.x, self.p)
        # okay, build up the hash H of
        # (V_C || V_S || I_C || I_S || K_S || min || n || max || p || g || e || f || K)  # noqa
        hm = Message()
        hm.add(
            self.transport.local_version,
            self.transport.remote_version,
            self.transport.local_kex_init,
            self.transport.remote_kex_init,
            self.transport.host_key.__str__(),
        )
        if not self.old_style:
            hm.add_int(self.min_bits)
        hm.add_int(self.preferred_bits)
        if not self.old_style:
            hm.add_int(self.max_bits)
        hm.add_mpint(self.p)
        hm.add_mpint(self.g)
        hm.add_mpint(self.e)
        hm.add_mpint(self.f)
        hm.add_mpint(K)
        H = sha1(hm.asbytes()).digest()
        self.transport._set_K_H(K, H)
        if srv_token is not None:
            self.kexgss.ssh_init_sec_context(target=self.gss_host,
                                             recv_token=srv_token)
            self.kexgss.ssh_check_mic(mic_token, H)
        else:
            self.kexgss.ssh_check_mic(mic_token, H)
        self.transport.gss_kex_used = True
        self.transport._activate_outbound()
Exemple #37
0
 def _get_session_blob(self, key, service, username):
     m = Message()
     m.add_string(self.transport.session_id)
     m.add_byte(cMSG_USERAUTH_REQUEST)
     m.add_string(username)
     m.add_string(service)
     m.add_string('publickey')
     m.add_boolean(True)
     # Use certificate contents, if available, plain pubkey otherwise
     if key.public_blob:
         m.add_string(key.public_blob.key_type)
         m.add_string(key.public_blob.key_blob)
     else:
         m.add_string(key.get_name())
         m.add_string(key)
     return m.asbytes()
Exemple #38
0
 def _get_session_blob(self, key, service, username):
     m = Message()
     m.add_string(self.transport.session_id)
     m.add_byte(cMSG_USERAUTH_REQUEST)
     m.add_string(username)
     m.add_string(service)
     m.add_string('publickey')
     m.add_boolean(True)
     # Use certificate contents, if available, plain pubkey otherwise
     if key.public_blob:
         m.add_string(key.public_blob.key_type)
         m.add_string(key.public_blob.key_blob)
     else:
         m.add_string(key.get_name())
         m.add_string(key)
     return m.asbytes()
Exemple #39
0
    def asbytes(self):
        key = self.verifying_key
        m = Message()
        m.add_string('ecdsa-sha2-nistp256')
        m.add_string('nistp256')

        numbers = key.public_numbers()

        x_bytes = deflate_long(numbers.x, add_sign_padding=False)
        x_bytes = b'\x00' * (len(x_bytes) - key.curve.key_size // 8) + x_bytes

        y_bytes = deflate_long(numbers.y, add_sign_padding=False)
        y_bytes = b'\x00' * (len(y_bytes) - key.curve.key_size // 8) + y_bytes

        point_str = four_byte + x_bytes + y_bytes
        m.add_string(point_str)
        return m.asbytes()
Exemple #40
0
    def asbytes(self):
        key = self.verifying_key
        numbers = key.public_numbers()
        key_size_bytes = (key.curve.key_size + 7) // 8

        x_bytes = deflate_long(numbers.x, add_sign_padding=False)
        x_bytes = b'\x00' * (key_size_bytes - len(x_bytes)) + x_bytes
        y_bytes = deflate_long(numbers.y, add_sign_padding=False)
        y_bytes = b'\x00' * (key_size_bytes - len(y_bytes)) + y_bytes

        point_str = four_byte + x_bytes + y_bytes

        m = Message()
        m.add_string(self.ecdsa_curve.key_format_identifier)
        m.add_string(self.ecdsa_curve.nist_name)
        m.add_string(point_str)
        return m.asbytes()
Exemple #41
0
    def asbytes(self):
        key = self.verifying_key
        m = Message()
        m.add_string('ecdsa-sha2-nistp256')
        m.add_string('nistp256')

        numbers = key.public_numbers()

        x_bytes = deflate_long(numbers.x, add_sign_padding=False)
        x_bytes = b'\x00' * (len(x_bytes) - key.curve.key_size // 8) + x_bytes

        y_bytes = deflate_long(numbers.y, add_sign_padding=False)
        y_bytes = b'\x00' * (len(y_bytes) - key.curve.key_size // 8) + y_bytes

        point_str = four_byte + x_bytes + y_bytes
        m.add_string(point_str)
        return m.asbytes()
Exemple #42
0
    def _parse_kexc25519_init(self, m):
        # server mode

        # Only one field in the client's message, which is their public key
        Q_C_bytes = m.get_string()
        self.Q_C = x25519.X25519PublicKey.from_public_bytes(Q_C_bytes)

        # Compute shared secret
        K = self.P.exchange(self.Q_C)
        K = long(hexlify(K), 16)

        # Prepare hostkey
        K_S = self.transport.get_server_key().asbytes()

        # Compute initial transport key
        hm = Message()
        hm.add(
            self.transport.remote_version,
            self.transport.local_version,
            self.transport.remote_kex_init,
            self.transport.local_kex_init,
        )

        hm.add_string(K_S)
        hm.add_string(Q_C_bytes)
        hm.add_string(
            self.Q_S.public_bytes(encoding=Encoding.Raw,
                                  format=PublicFormat.Raw))
        hm.add_mpint(K)
        H = self.hash_algo(hm.asbytes()).digest()
        self.transport._set_K_H(K, H)

        # Compute signature
        sig = self.transport.get_server_key().sign_ssh_data(H)
        # construct reply
        m = Message()
        m.add_byte(c_MSG_KEXC25519_REPLY)
        m.add_string(K_S)
        m.add_string(
            self.Q_S.public_bytes(encoding=Encoding.Raw,
                                  format=PublicFormat.Raw))
        m.add_string(sig)
        self.transport._send_message(m)
        self.transport._activate_outbound()
Exemple #43
0
    def asbytes(self):
        key = self.verifying_key
        m = Message()
        m.add_string(self.ecdsa_curve.key_format_identifier)
        m.add_string(self.ecdsa_curve.nist_name)

        numbers = key.public_numbers()

        key_size_bytes = (key.curve.key_size + 7) // 8

        x_bytes = deflate_long(numbers.x, add_sign_padding=False)
        x_bytes = b'\x00' * (key_size_bytes - len(x_bytes)) + x_bytes

        y_bytes = deflate_long(numbers.y, add_sign_padding=False)
        y_bytes = b'\x00' * (key_size_bytes - len(y_bytes)) + y_bytes

        point_str = four_byte + x_bytes + y_bytes
        m.add_string(point_str)
        return m.asbytes()
Exemple #44
0
 def _parse_kexdh_reply(self, m):
     # client mode
     host_key = m.get_string()
     self.f = m.get_mpint()
     if (self.f < 1) or (self.f > P - 1):
         raise SSHException('Server kex "f" is out of range')
     sig = m.get_binary()
     K = pow(self.f, self.x, P)
     # okay, build up the hash H of (V_C || V_S || I_C || I_S || K_S || e || f || K)
     hm = Message()
     hm.add(self.transport.local_version, self.transport.remote_version,
            self.transport.local_kex_init, self.transport.remote_kex_init)
     hm.add_string(host_key)
     hm.add_mpint(self.e)
     hm.add_mpint(self.f)
     hm.add_mpint(K)
     self.transport._set_K_H(K, SHA.new(hm.asbytes()).digest())
     self.transport._verify_key(host_key, sig)
     self.transport._activate_outbound()
Exemple #45
0
 def _parse_kexdh_reply(self, m):
     # client mode
     host_key = m.get_string()
     self.f = m.get_mpint()
     if (self.f < 1) or (self.f > P - 1):
         raise SSHException('Server kex "f" is out of range')
     sig = m.get_binary()
     K = pow(self.f, self.x, P)
     # okay, build up the hash H of (V_C || V_S || I_C || I_S || K_S || e || f || K)
     hm = Message()
     hm.add(self.transport.local_version, self.transport.remote_version,
            self.transport.local_kex_init, self.transport.remote_kex_init)
     hm.add_string(host_key)
     hm.add_mpint(self.e)
     hm.add_mpint(self.f)
     hm.add_mpint(K)
     self.transport._set_K_H(K, SHA.new(hm.asbytes()).digest())
     self.transport._verify_key(host_key, sig)
     self.transport._activate_outbound()
Exemple #46
0
 def _parse_kexecdh_init(self, m):
     Q_C_bytes = m.get_string()
     self.Q_C = ec.EllipticCurvePublicKey.from_encoded_point(
         self.curve, Q_C_bytes)
     K_S = self.transport.get_server_key().asbytes()
     K = self.P.exchange(ec.ECDH(), self.Q_C)
     K = long(hexlify(K), 16)
     # compute exchange hash
     hm = Message()
     hm.add(
         self.transport.remote_version,
         self.transport.local_version,
         self.transport.remote_kex_init,
         self.transport.local_kex_init,
     )
     hm.add_string(K_S)
     hm.add_string(Q_C_bytes)
     # SEC1: V2.0  2.3.3 Elliptic-Curve-Point-to-Octet-String Conversion
     hm.add_string(
         self.Q_S.public_bytes(
             serialization.Encoding.X962,
             serialization.PublicFormat.UncompressedPoint,
         ))
     hm.add_mpint(long(K))
     H = self.hash_algo(hm.asbytes()).digest()
     self.transport._set_K_H(K, H)
     sig = self.transport.get_server_key().sign_ssh_data(
         H, self.transport.host_key_type)
     # construct reply
     m = Message()
     m.add_byte(c_MSG_KEXECDH_REPLY)
     m.add_string(K_S)
     m.add_string(
         self.Q_S.public_bytes(
             serialization.Encoding.X962,
             serialization.PublicFormat.UncompressedPoint,
         ))
     m.add_string(sig)
     self.transport._send_message(m)
     self.transport._activate_outbound()
Exemple #47
0
    def sign(self, ca_key, nonce):
        """
        Sign this certificate with the specified ``ca_key``. The ``ca_key``
        must include a private key and be able to sign data. The ``nonce``
        must be provided. Usually this would be something random, i.e. from
        os.urandom(32), but can any string. Testing re-used the nonce from
        the existing certificate to verify that re-signing results in the
        same certificate

        :param .PKey ca_key:
            The key to use as a CA for signing the certificate
        :param str nonce:
            A string to random data to use in the signing of the certificate

        :raises SSHException:
            If the ca_key cannot be used for signing.
        """
        if not ca_key.can_sign():
            err = "Provided key cannot be used for signing"
            raise SSHException(err)

        new_bytes = self.generate_body(ca_key, nonce)
        sig = ca_key.sign_ssh_data(new_bytes)
        # If the key used to sign the data was a paramiko.Agent.AgentKey, the
        # results are a string/binary sequence. If a paramiko.pkey.PKey was
        # used, then the result is a Message. Convert to a string as needed.
        if type(sig) == Message:
            sig = sig.asbytes()

        msg = Message()
        msg.add_bytes(new_bytes)
        msg.add_string(sig)

        # Set new values on self after the signing process has been completed
        # and the new certificate is ready.
        self.nonce = nonce
        self.signature = sig
        self.signature_key = ca_key.asbytes()
        self._body_bytes = new_bytes
        self._bytes = msg.asbytes()
Exemple #48
0
 def asbytes(self):
     m = Message()
     m.add_string('ssh-rsa')
     m.add_mpint(self.e)
     m.add_mpint(self.n)
     return m.asbytes()
Exemple #49
0
 def asbytes(self):
     m = Message()
     m.add_string('ssh-rsa')
     m.add_mpint(self.public_numbers.e)
     m.add_mpint(self.public_numbers.n)
     return m.asbytes()
Exemple #50
0
 def _sigencode(self, r, s, order):
     msg = Message()
     msg.add_mpint(r)
     msg.add_mpint(s)
     return msg.asbytes()