Send a SSH_MSG_EXT_INFO with server-sig-algs when the client indicates they support extensions by sending ext-info-c. This allows modern clients that don't do ssh-rsa anymore because of sha1 to still use RSA keys with sha2.

Robin_Jadoul
Apr 12, 2023, 1:05 PM
EUHO3DAZ4D3LMHYJDLVLXBHIFAUKXMNFNDLE5ZHG4T7SVJMG55EAC

Dependencies

  • [2] 7FRJYUI6 Reboot because of a bad change

Change contents

  • edit in thrussh/src/server/session.rs at line 119
    [2.191449]
    [2.191449]
    pub(crate) fn send_server_sig_algs(&mut self) {
    // This should be only ever called when this is valid
    if let Some(Kex::NewKeys(newkeys)) = &self.common.kex {
    let mut buf = CryptoVec::new();
    buf.push(msg::EXT_INFO);
    buf.push_u32_be(1); // nr-extensions
    buf.extend_ssh_string(b"server-sig-algs"); // extension-name
    let algs = self
    .common
    .config
    .preferred
    .key
    .iter()
    .map(|n| n.0)
    .collect::<Vec<_>>()
    .join(",");
    buf.extend_ssh_string(algs.as_bytes()); // extension-value
    newkeys.cipher.write(&buf, &mut self.common.write_buffer);
    } else {
    unreachable!(
    "Trying to send server-sig-algs SSH_MSG_EXT_INFO when we didn't just send NEWKEYS"
    );
    }
    }
  • edit in thrussh/src/server/mod.rs at line 662
    [2.224638]
    [2.224638]
    let client_supports_ext = kexdh.names.client_supports_ext;
  • edit in thrussh/src/server/mod.rs at line 669
    [2.224889]
    [2.224889]
    if client_supports_ext {
    // RFC 8308 (2.4): Send SSH_MSG_EXT_INFO as the next packet following the server's first SSH_MSG_NEWKEYS.
    // Since we have no session established, this should have been the first time
    session.send_server_sig_algs();
    }
  • edit in thrussh/src/negotiation.rs at line 34
    [2.269535]
    [2.269535]
    pub client_supports_ext: bool,
    pub server_supports_ext: bool,
  • edit in thrussh/src/negotiation.rs at line 141
    [2.272078]
    [2.272078]
    let client_supports_ext = Self::select(&[kex::CLIENT_SUPPORTS_EXT], kex_string).is_some();
    let server_supports_ext = Self::select(&[kex::SERVER_SUPPORTS_EXT], kex_string).is_some();
  • edit in thrussh/src/negotiation.rs at line 204
    [2.274587]
    [2.274587]
    client_supports_ext,
    server_supports_ext,
  • edit in thrussh/src/msg.rs at line 60
    [2.278630]
    // https://www.rfc-editor.org/rfc/rfc8308#section-2.3
    pub const EXT_INFO: u8 = 7;
  • edit in thrussh/src/kex.rs at line 48
    [2.308346]
    [2.308346]
    pub const CLIENT_SUPPORTS_EXT: Name = Name("ext-info-c");
    pub const SERVER_SUPPORTS_EXT: Name = Name("ext-info-s");