• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 22618661228

02 Mar 2026 09:33PM UTC coverage: 42.258% (-34.4%) from 76.611%
22618661228

push

github

victorjulien
github-actions: bump actions/download-artifact from 7.0.0 to 8.0.0

Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7.0.0 to 8.0.0.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/37930b1c2...70fc10c6e)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

91511 of 216553 relevant lines covered (42.26%)

3416852.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

39.42
/rust/src/ssh/parser.rs
1
/* Copyright (C) 2020 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17

18
use digest::Digest;
19
use digest::Update;
20
use md5::Md5;
21
use nom8::branch::alt;
22
use nom8::bytes::streaming::{is_not, tag, take, take_while};
23
use nom8::character::streaming::char;
24
use nom8::combinator::{complete, eof, not, rest, verify};
25
use nom8::multi::length_data;
26
use nom8::number::streaming::{be_u32, be_u8};
27
use nom8::sequence::terminated;
28
use nom8::{IResult, Parser};
29
use std::fmt;
30

31
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
32
pub enum MessageCode {
33
    Disconnect,
34
    Ignore,
35
    Unimplemented,
36
    Debug,
37
    ServiceRequest,
38
    ServiceAccept,
39
    Kexinit,
40
    NewKeys,
41
    KexdhInit,
42
    KexdhReply,
43

44
    Undefined(u8),
45
}
46

47
impl MessageCode {
48
    fn from_u8(value: u8) -> MessageCode {
92✔
49
        match value {
92✔
50
            1 => MessageCode::Disconnect,
×
51
            2 => MessageCode::Ignore,
×
52
            3 => MessageCode::Unimplemented,
×
53
            4 => MessageCode::Debug,
×
54
            5 => MessageCode::ServiceRequest,
×
55
            6 => MessageCode::ServiceAccept,
×
56
            20 => MessageCode::Kexinit,
27✔
57
            21 => MessageCode::NewKeys,
25✔
58
            30 => MessageCode::KexdhInit,
11✔
59
            31 => MessageCode::KexdhReply,
13✔
60
            _ => MessageCode::Undefined(value),
16✔
61
        }
62
    }
92✔
63
}
64

65
#[inline]
66
fn is_not_lineend(b: u8) -> bool {
1,689✔
67
    if b == 10 || b == 13 {
1,689✔
68
        return false;
36✔
69
    }
1,653✔
70
    return true;
1,653✔
71
}
1,689✔
72

73
//may leave \r at the end to be removed
74
pub fn ssh_parse_line(i: &[u8]) -> IResult<&[u8], &[u8]> {
37✔
75
    fn parser(i: &[u8]) -> IResult<&[u8], &[u8]> {
×
76
        let (i, bytes) = tag("\r")(i)?;
×
77
        let (i, _) = not(eof).parse(i)?;
×
78
        Ok((i, bytes))
×
79
    }
×
80
    terminated(
37✔
81
        take_while(is_not_lineend),
37✔
82
        alt((tag("\n"), tag("\r\n"), parser)),
37✔
83
    ).parse(i)
37✔
84
}
37✔
85

86
#[derive(PartialEq, Eq)]
87
pub struct SshBanner<'a> {
88
    pub protover: &'a [u8],
89
    pub swver: &'a [u8],
90
}
91

92
// Could be simplified adding dummy \n at the end
93
// or use nom5 nom::bytes::complete::is_not
94
pub fn ssh_parse_banner(i: &[u8]) -> IResult<&[u8], SshBanner<'_>> {
36✔
95
    let (i, _) = tag("SSH-")(i)?;
36✔
96
    let (i, protover) = is_not("-")(i)?;
36✔
97
    let (i, _) = char('-')(i)?;
36✔
98
    let (i, swver) = alt((complete(is_not(" \r\n")), rest)).parse(i)?;
36✔
99
    //remaining after space is comments
100
    Ok((i, SshBanner { protover, swver }))
36✔
101
}
36✔
102

103
#[derive(PartialEq, Eq)]
104
pub struct SshRecordHeader {
105
    pub pkt_len: u32,
106
    padding_len: u8,
107
    pub msg_code: MessageCode,
108
}
109

110
impl fmt::Display for SshRecordHeader {
111
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
×
112
        write!(
×
113
            f,
×
114
            "(pkt_len:{}, padding_len:{}, msg_code:{:?})",
×
115
            self.pkt_len, self.padding_len, self.msg_code
×
116
        )
×
117
    }
×
118
}
119

120
pub fn ssh_parse_record_header(i: &[u8]) -> IResult<&[u8], SshRecordHeader> {
14✔
121
    let (i, pkt_len) = verify(be_u32, |&val| val > 1).parse(i)?;
14✔
122
    let (i, padding_len) = be_u8(i)?;
14✔
123
    let (i, msg_code) = be_u8(i)?;
14✔
124
    Ok((
14✔
125
        i,
14✔
126
        SshRecordHeader {
14✔
127
            pkt_len,
14✔
128
            padding_len,
14✔
129
            msg_code: MessageCode::from_u8(msg_code),
14✔
130
        },
14✔
131
    ))
14✔
132
}
14✔
133

134
//test for evasion against pkt_len=0or1...
135
pub fn ssh_parse_record(i: &[u8]) -> IResult<&[u8], SshRecordHeader> {
92✔
136
    let (i, pkt_len) = verify(be_u32, |&val| val > 1).parse(i)?;
92✔
137
    let (i, padding_len) = be_u8(i)?;
92✔
138
    let (i, msg_code) = be_u8(i)?;
92✔
139
    let (i, _) = take((pkt_len - 2) as usize)(i)?;
92✔
140
    Ok((
78✔
141
        i,
78✔
142
        SshRecordHeader {
78✔
143
            pkt_len,
78✔
144
            padding_len,
78✔
145
            msg_code: MessageCode::from_u8(msg_code),
78✔
146
        },
78✔
147
    ))
78✔
148
}
92✔
149

150
#[derive(Debug, PartialEq, Eq)]
151
pub struct SshPacketKeyExchange<'a> {
152
    pub cookie: &'a [u8],
153
    pub kex_algs: &'a [u8],
154
    pub server_host_key_algs: &'a [u8],
155
    pub encr_algs_client_to_server: &'a [u8],
156
    pub encr_algs_server_to_client: &'a [u8],
157
    pub mac_algs_client_to_server: &'a [u8],
158
    pub mac_algs_server_to_client: &'a [u8],
159
    pub comp_algs_client_to_server: &'a [u8],
160
    pub comp_algs_server_to_client: &'a [u8],
161
    pub langs_client_to_server: &'a [u8],
162
    pub langs_server_to_client: &'a [u8],
163
    pub first_kex_packet_follows: u8,
164
    pub reserved: u32,
165
}
166

167
const SSH_HASSH_STRING_DELIMITER_SLICE: [u8; 1] = [b';'];
168

169
impl SshPacketKeyExchange<'_> {
170
    pub fn generate_hassh(
×
171
        &self, hassh_string: &mut Vec<u8>, hassh: &mut Vec<u8>, to_server: &bool,
×
172
    ) {
×
173
        let slices = if *to_server {
×
174
            [
×
175
                self.kex_algs,
×
176
                &SSH_HASSH_STRING_DELIMITER_SLICE,
×
177
                self.encr_algs_server_to_client,
×
178
                &SSH_HASSH_STRING_DELIMITER_SLICE,
×
179
                self.mac_algs_server_to_client,
×
180
                &SSH_HASSH_STRING_DELIMITER_SLICE,
×
181
                self.comp_algs_server_to_client,
×
182
            ]
×
183
        } else {
184
            [
×
185
                self.kex_algs,
×
186
                &SSH_HASSH_STRING_DELIMITER_SLICE,
×
187
                self.encr_algs_client_to_server,
×
188
                &SSH_HASSH_STRING_DELIMITER_SLICE,
×
189
                self.mac_algs_client_to_server,
×
190
                &SSH_HASSH_STRING_DELIMITER_SLICE,
×
191
                self.comp_algs_client_to_server,
×
192
            ]
×
193
        };
194
        // reserving memory
195
        hassh_string.reserve_exact(slices.iter().fold(0, |acc, x| acc + x.len()));
×
196
        // copying slices to hassh string
×
197
        slices
×
198
            .iter()
×
199
            .for_each(|&x| hassh_string.extend_from_slice(x));
×
200
        hassh.extend(format!("{:x}", Md5::new().chain(hassh_string).finalize()).as_bytes());
×
201
    }
×
202
}
203

204
#[inline]
205
fn parse_string(i: &[u8]) -> IResult<&[u8], &[u8]> {
×
206
    length_data(be_u32).parse(i)
×
207
}
×
208

209
pub fn ssh_parse_key_exchange(i: &[u8]) -> IResult<&[u8], SshPacketKeyExchange<'_>> {
×
210
    let (i, cookie) = take(16_usize)(i)?;
×
211
    let (i, kex_algs) = parse_string(i)?;
×
212
    let (i, server_host_key_algs) = parse_string(i)?;
×
213
    let (i, encr_algs_client_to_server) = parse_string(i)?;
×
214
    let (i, encr_algs_server_to_client) = parse_string(i)?;
×
215
    let (i, mac_algs_client_to_server) = parse_string(i)?;
×
216
    let (i, mac_algs_server_to_client) = parse_string(i)?;
×
217
    let (i, comp_algs_client_to_server) = parse_string(i)?;
×
218
    let (i, comp_algs_server_to_client) = parse_string(i)?;
×
219
    let (i, langs_client_to_server) = parse_string(i)?;
×
220
    let (i, langs_server_to_client) = parse_string(i)?;
×
221
    let (i, first_kex_packet_follows) = be_u8(i)?;
×
222
    let (i, reserved) = be_u32(i)?;
×
223
    Ok((
×
224
        i,
×
225
        SshPacketKeyExchange {
×
226
            cookie,
×
227
            kex_algs,
×
228
            server_host_key_algs,
×
229
            encr_algs_client_to_server,
×
230
            encr_algs_server_to_client,
×
231
            mac_algs_client_to_server,
×
232
            mac_algs_server_to_client,
×
233
            comp_algs_client_to_server,
×
234
            comp_algs_server_to_client,
×
235
            langs_client_to_server,
×
236
            langs_server_to_client,
×
237
            first_kex_packet_follows,
×
238
            reserved,
×
239
        },
×
240
    ))
×
241
}
×
242

243
#[cfg(test)]
244
mod tests {
245

246
    use super::*;
247
    use nom8::{Err, Needed};
248

249
    /// Simple test of some valid data.
250
    #[test]
251
    fn test_ssh_parse_banner() {
252
        let buf = b"SSH-Single-";
253
        let result = ssh_parse_banner(buf);
254
        match result {
255
            Ok((_, message)) => {
256
                // Check the first message.
257
                assert_eq!(message.protover, b"Single");
258
                assert_eq!(message.swver, b"");
259
            }
260
            Err(err) => {
261
                panic!("Result should not be an error: {:?}.", err);
262
            }
263
        }
264
        let buf2 = b"SSH-2.0-Soft";
265
        let result2 = ssh_parse_banner(buf2);
266
        match result2 {
267
            Ok((_, message)) => {
268
                // Check the first message.
269
                assert_eq!(message.protover, b"2.0");
270
                assert_eq!(message.swver, b"Soft");
271
            }
272
            Err(err) => {
273
                panic!("Result should not be an error: {:?}.", err);
274
            }
275
        }
276
    }
277

278
    #[test]
279
    fn test_parse_line() {
280
        let buf = b"SSH-Single\n";
281
        let result = ssh_parse_line(buf);
282
        match result {
283
            Ok((_, message)) => {
284
                // Check the first message.
285
                assert_eq!(message, b"SSH-Single");
286
            }
287
            Err(err) => {
288
                panic!("Result should not be an error: {:?}.", err);
289
            }
290
        }
291
        let buf2 = b"SSH-Double\r\n";
292
        let result2 = ssh_parse_line(buf2);
293
        match result2 {
294
            Ok((_, message)) => {
295
                // Check the first message.
296
                assert_eq!(message, b"SSH-Double");
297
            }
298
            Err(err) => {
299
                panic!("Result should not be an error: {:?}.", err);
300
            }
301
        }
302
        let buf3 = b"SSH-Oops\rMore\r\n";
303
        let result3 = ssh_parse_line(buf3);
304
        match result3 {
305
            Ok((rem, message)) => {
306
                // Check the first message.
307
                assert_eq!(message, b"SSH-Oops");
308
                assert_eq!(rem, b"More\r\n");
309
            }
310
            Err(err) => {
311
                panic!("Result should not be an error: {:?}.", err);
312
            }
313
        }
314
        let buf4 = b"SSH-Miss\r";
315
        let result4 = ssh_parse_line(buf4);
316
        match result4 {
317
            Ok((_, _)) => {
318
                panic!("Expected incomplete result");
319
            }
320
            Err(Err::Incomplete(_)) => {
321
                //OK
322
                assert_eq!(1, 1);
323
            }
324
            Err(err) => {
325
                panic!("Result should not be an error: {:?}.", err);
326
            }
327
        }
328
        let buf5 = b"\n";
329
        let result5 = ssh_parse_line(buf5);
330
        match result5 {
331
            Ok((_, message)) => {
332
                // Check empty line
333
                assert_eq!(message, b"");
334
            }
335
            Err(err) => {
336
                panic!("Result should not be an error: {:?}.", err);
337
            }
338
        }
339
    }
340
    #[test]
341
    fn test_parse_key_exchange() {
342
        let client_key_exchange = [
343
            0x18, 0x70, 0xCB, 0xA4, 0xA3, 0xD4, 0xDC, 0x88, 0x6F, 0xFD, 0x76, 0x06, 0xCF, 0x36,
344
            0x1B, 0xC6, 0x00, 0x00, 0x01, 0x0D, 0x63, 0x75, 0x72, 0x76, 0x65, 0x32, 0x35, 0x35,
345
            0x31, 0x39, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2C, 0x63, 0x75, 0x72, 0x76,
346
            0x65, 0x32, 0x35, 0x35, 0x31, 0x39, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x40,
347
            0x6C, 0x69, 0x62, 0x73, 0x73, 0x68, 0x2E, 0x6F, 0x72, 0x67, 0x2C, 0x65, 0x63, 0x64,
348
            0x68, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70, 0x32, 0x35,
349
            0x36, 0x2C, 0x65, 0x63, 0x64, 0x68, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69,
350
            0x73, 0x74, 0x70, 0x33, 0x38, 0x34, 0x2C, 0x65, 0x63, 0x64, 0x68, 0x2D, 0x73, 0x68,
351
            0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70, 0x35, 0x32, 0x31, 0x2C, 0x64, 0x69,
352
            0x66, 0x66, 0x69, 0x65, 0x2D, 0x68, 0x65, 0x6C, 0x6C, 0x6D, 0x61, 0x6E, 0x2D, 0x67,
353
            0x72, 0x6F, 0x75, 0x70, 0x2D, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6E, 0x67, 0x65, 0x2D,
354
            0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2C, 0x64, 0x69, 0x66, 0x66, 0x69, 0x65, 0x2D,
355
            0x68, 0x65, 0x6C, 0x6C, 0x6D, 0x61, 0x6E, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x31,
356
            0x36, 0x2D, 0x73, 0x68, 0x61, 0x35, 0x31, 0x32, 0x2C, 0x64, 0x69, 0x66, 0x66, 0x69,
357
            0x65, 0x2D, 0x68, 0x65, 0x6C, 0x6C, 0x6D, 0x61, 0x6E, 0x2D, 0x67, 0x72, 0x6F, 0x75,
358
            0x70, 0x31, 0x38, 0x2D, 0x73, 0x68, 0x61, 0x35, 0x31, 0x32, 0x2C, 0x64, 0x69, 0x66,
359
            0x66, 0x69, 0x65, 0x2D, 0x68, 0x65, 0x6C, 0x6C, 0x6D, 0x61, 0x6E, 0x2D, 0x67, 0x72,
360
            0x6F, 0x75, 0x70, 0x31, 0x34, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2C, 0x64,
361
            0x69, 0x66, 0x66, 0x69, 0x65, 0x2D, 0x68, 0x65, 0x6C, 0x6C, 0x6D, 0x61, 0x6E, 0x2D,
362
            0x67, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x34, 0x2D, 0x73, 0x68, 0x61, 0x31, 0x2C, 0x65,
363
            0x78, 0x74, 0x2D, 0x69, 0x6E, 0x66, 0x6F, 0x2D, 0x63, 0x00, 0x00, 0x01, 0x66, 0x65,
364
            0x63, 0x64, 0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74,
365
            0x70, 0x32, 0x35, 0x36, 0x2D, 0x63, 0x65, 0x72, 0x74, 0x2D, 0x76, 0x30, 0x31, 0x40,
366
            0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x65, 0x63,
367
            0x64, 0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70,
368
            0x33, 0x38, 0x34, 0x2D, 0x63, 0x65, 0x72, 0x74, 0x2D, 0x76, 0x30, 0x31, 0x40, 0x6F,
369
            0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x65, 0x63, 0x64,
370
            0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70, 0x35,
371
            0x32, 0x31, 0x2D, 0x63, 0x65, 0x72, 0x74, 0x2D, 0x76, 0x30, 0x31, 0x40, 0x6F, 0x70,
372
            0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x65, 0x63, 0x64, 0x73,
373
            0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70, 0x32, 0x35,
374
            0x36, 0x2C, 0x65, 0x63, 0x64, 0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E,
375
            0x69, 0x73, 0x74, 0x70, 0x33, 0x38, 0x34, 0x2C, 0x65, 0x63, 0x64, 0x73, 0x61, 0x2D,
376
            0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70, 0x35, 0x32, 0x31, 0x2C,
377
            0x73, 0x73, 0x68, 0x2D, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x2D, 0x63, 0x65,
378
            0x72, 0x74, 0x2D, 0x76, 0x30, 0x31, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68,
379
            0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x72, 0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D,
380
            0x35, 0x31, 0x32, 0x2D, 0x63, 0x65, 0x72, 0x74, 0x2D, 0x76, 0x30, 0x31, 0x40, 0x6F,
381
            0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x72, 0x73, 0x61,
382
            0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x32, 0x35, 0x36, 0x2D, 0x63, 0x65, 0x72, 0x74,
383
            0x2D, 0x76, 0x30, 0x31, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63,
384
            0x6F, 0x6D, 0x2C, 0x73, 0x73, 0x68, 0x2D, 0x72, 0x73, 0x61, 0x2D, 0x63, 0x65, 0x72,
385
            0x74, 0x2D, 0x76, 0x30, 0x31, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E,
386
            0x63, 0x6F, 0x6D, 0x2C, 0x73, 0x73, 0x68, 0x2D, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31,
387
            0x39, 0x2C, 0x72, 0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x35, 0x31, 0x32,
388
            0x2C, 0x72, 0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x32, 0x35, 0x36, 0x2C,
389
            0x73, 0x73, 0x68, 0x2D, 0x72, 0x73, 0x61, 0x00, 0x00, 0x00, 0x6C, 0x63, 0x68, 0x61,
390
            0x63, 0x68, 0x61, 0x32, 0x30, 0x2D, 0x70, 0x6F, 0x6C, 0x79, 0x31, 0x33, 0x30, 0x35,
391
            0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x61,
392
            0x65, 0x73, 0x31, 0x32, 0x38, 0x2D, 0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x31,
393
            0x39, 0x32, 0x2D, 0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x32, 0x35, 0x36, 0x2D,
394
            0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2D, 0x67, 0x63, 0x6D,
395
            0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x61,
396
            0x65, 0x73, 0x32, 0x35, 0x36, 0x2D, 0x67, 0x63, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E,
397
            0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x00, 0x00, 0x6C, 0x63, 0x68, 0x61,
398
            0x63, 0x68, 0x61, 0x32, 0x30, 0x2D, 0x70, 0x6F, 0x6C, 0x79, 0x31, 0x33, 0x30, 0x35,
399
            0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x61,
400
            0x65, 0x73, 0x31, 0x32, 0x38, 0x2D, 0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x31,
401
            0x39, 0x32, 0x2D, 0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x32, 0x35, 0x36, 0x2D,
402
            0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2D, 0x67, 0x63, 0x6D,
403
            0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x61,
404
            0x65, 0x73, 0x32, 0x35, 0x36, 0x2D, 0x67, 0x63, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E,
405
            0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x00, 0x00, 0xD5, 0x75, 0x6D, 0x61,
406
            0x63, 0x2D, 0x36, 0x34, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73,
407
            0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75, 0x6D, 0x61, 0x63, 0x2D, 0x31, 0x32,
408
            0x38, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E,
409
            0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D,
410
            0x32, 0x35, 0x36, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73,
411
            0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61,
412
            0x32, 0x2D, 0x35, 0x31, 0x32, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E,
413
            0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73,
414
            0x68, 0x61, 0x31, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73,
415
            0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75, 0x6D, 0x61, 0x63, 0x2D, 0x36, 0x34, 0x40,
416
            0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75, 0x6D,
417
            0x61, 0x63, 0x2D, 0x31, 0x32, 0x38, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68,
418
            0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32,
419
            0x2D, 0x32, 0x35, 0x36, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32,
420
            0x2D, 0x35, 0x31, 0x32, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x31,
421
            0x00, 0x00, 0x00, 0xD5, 0x75, 0x6D, 0x61, 0x63, 0x2D, 0x36, 0x34, 0x2D, 0x65, 0x74,
422
            0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C,
423
            0x75, 0x6D, 0x61, 0x63, 0x2D, 0x31, 0x32, 0x38, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F,
424
            0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61,
425
            0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x32, 0x35, 0x36, 0x2D, 0x65, 0x74, 0x6D,
426
            0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68,
427
            0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x35, 0x31, 0x32, 0x2D, 0x65,
428
            0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D,
429
            0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x31, 0x2D, 0x65, 0x74, 0x6D,
430
            0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75,
431
            0x6D, 0x61, 0x63, 0x2D, 0x36, 0x34, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68,
432
            0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75, 0x6D, 0x61, 0x63, 0x2D, 0x31, 0x32, 0x38, 0x40,
433
            0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D,
434
            0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x32, 0x35, 0x36, 0x2C, 0x68, 0x6D,
435
            0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x35, 0x31, 0x32, 0x2C, 0x68, 0x6D,
436
            0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x31, 0x00, 0x00, 0x00, 0x1A, 0x6E, 0x6F, 0x6E,
437
            0x65, 0x2C, 0x7A, 0x6C, 0x69, 0x62, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68,
438
            0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x7A, 0x6C, 0x69, 0x62, 0x00, 0x00, 0x00, 0x1A, 0x6E,
439
            0x6F, 0x6E, 0x65, 0x2C, 0x7A, 0x6C, 0x69, 0x62, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73,
440
            0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x7A, 0x6C, 0x69, 0x62, 0x00, 0x00, 0x00,
441
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442
        ];
443
        let cookie = [
444
            0x18, 0x70, 0xcb, 0xa4, 0xa3, 0xd4, 0xdc, 0x88, 0x6f, 0xfd, 0x76, 0x06, 0xcf, 0x36,
445
            0x1b, 0xc6,
446
        ];
447
        let key_exchange = SshPacketKeyExchange {
448
            cookie: &cookie,
449
            kex_algs: b"curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,ext-info-c",
450
            server_host_key_algs: b"ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa",
451
            encr_algs_client_to_server: b"chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com",
452
            encr_algs_server_to_client: b"chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com",
453
            mac_algs_client_to_server: b"umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1",
454
            mac_algs_server_to_client: b"umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1",
455
            comp_algs_client_to_server: b"none,zlib@openssh.com,zlib",
456
            comp_algs_server_to_client: b"none,zlib@openssh.com,zlib",
457
            langs_client_to_server: b"",
458
            langs_server_to_client: b"",
459
            first_kex_packet_follows: 0,
460
            reserved: 0,
461
        };
462

463
        let expected = Ok((b"" as &[u8], key_exchange));
464
        let res = ssh_parse_key_exchange(&client_key_exchange);
465
        assert_eq!(res, expected);
466
    }
467

468
    #[test]
469
    fn test_parse_hassh() {
470
        let client_key_exchange = [
471
            0x18, 0x70, 0xCB, 0xA4, 0xA3, 0xD4, 0xDC, 0x88, 0x6F, 0xFD, 0x76, 0x06, 0xCF, 0x36,
472
            0x1B, 0xC6, 0x00, 0x00, 0x01, 0x0D, 0x63, 0x75, 0x72, 0x76, 0x65, 0x32, 0x35, 0x35,
473
            0x31, 0x39, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2C, 0x63, 0x75, 0x72, 0x76,
474
            0x65, 0x32, 0x35, 0x35, 0x31, 0x39, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x40,
475
            0x6C, 0x69, 0x62, 0x73, 0x73, 0x68, 0x2E, 0x6F, 0x72, 0x67, 0x2C, 0x65, 0x63, 0x64,
476
            0x68, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70, 0x32, 0x35,
477
            0x36, 0x2C, 0x65, 0x63, 0x64, 0x68, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69,
478
            0x73, 0x74, 0x70, 0x33, 0x38, 0x34, 0x2C, 0x65, 0x63, 0x64, 0x68, 0x2D, 0x73, 0x68,
479
            0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70, 0x35, 0x32, 0x31, 0x2C, 0x64, 0x69,
480
            0x66, 0x66, 0x69, 0x65, 0x2D, 0x68, 0x65, 0x6C, 0x6C, 0x6D, 0x61, 0x6E, 0x2D, 0x67,
481
            0x72, 0x6F, 0x75, 0x70, 0x2D, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6E, 0x67, 0x65, 0x2D,
482
            0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2C, 0x64, 0x69, 0x66, 0x66, 0x69, 0x65, 0x2D,
483
            0x68, 0x65, 0x6C, 0x6C, 0x6D, 0x61, 0x6E, 0x2D, 0x67, 0x72, 0x6F, 0x75, 0x70, 0x31,
484
            0x36, 0x2D, 0x73, 0x68, 0x61, 0x35, 0x31, 0x32, 0x2C, 0x64, 0x69, 0x66, 0x66, 0x69,
485
            0x65, 0x2D, 0x68, 0x65, 0x6C, 0x6C, 0x6D, 0x61, 0x6E, 0x2D, 0x67, 0x72, 0x6F, 0x75,
486
            0x70, 0x31, 0x38, 0x2D, 0x73, 0x68, 0x61, 0x35, 0x31, 0x32, 0x2C, 0x64, 0x69, 0x66,
487
            0x66, 0x69, 0x65, 0x2D, 0x68, 0x65, 0x6C, 0x6C, 0x6D, 0x61, 0x6E, 0x2D, 0x67, 0x72,
488
            0x6F, 0x75, 0x70, 0x31, 0x34, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2C, 0x64,
489
            0x69, 0x66, 0x66, 0x69, 0x65, 0x2D, 0x68, 0x65, 0x6C, 0x6C, 0x6D, 0x61, 0x6E, 0x2D,
490
            0x67, 0x72, 0x6F, 0x75, 0x70, 0x31, 0x34, 0x2D, 0x73, 0x68, 0x61, 0x31, 0x2C, 0x65,
491
            0x78, 0x74, 0x2D, 0x69, 0x6E, 0x66, 0x6F, 0x2D, 0x63, 0x00, 0x00, 0x01, 0x66, 0x65,
492
            0x63, 0x64, 0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74,
493
            0x70, 0x32, 0x35, 0x36, 0x2D, 0x63, 0x65, 0x72, 0x74, 0x2D, 0x76, 0x30, 0x31, 0x40,
494
            0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x65, 0x63,
495
            0x64, 0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70,
496
            0x33, 0x38, 0x34, 0x2D, 0x63, 0x65, 0x72, 0x74, 0x2D, 0x76, 0x30, 0x31, 0x40, 0x6F,
497
            0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x65, 0x63, 0x64,
498
            0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70, 0x35,
499
            0x32, 0x31, 0x2D, 0x63, 0x65, 0x72, 0x74, 0x2D, 0x76, 0x30, 0x31, 0x40, 0x6F, 0x70,
500
            0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x65, 0x63, 0x64, 0x73,
501
            0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70, 0x32, 0x35,
502
            0x36, 0x2C, 0x65, 0x63, 0x64, 0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E,
503
            0x69, 0x73, 0x74, 0x70, 0x33, 0x38, 0x34, 0x2C, 0x65, 0x63, 0x64, 0x73, 0x61, 0x2D,
504
            0x73, 0x68, 0x61, 0x32, 0x2D, 0x6E, 0x69, 0x73, 0x74, 0x70, 0x35, 0x32, 0x31, 0x2C,
505
            0x73, 0x73, 0x68, 0x2D, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x2D, 0x63, 0x65,
506
            0x72, 0x74, 0x2D, 0x76, 0x30, 0x31, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68,
507
            0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x72, 0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D,
508
            0x35, 0x31, 0x32, 0x2D, 0x63, 0x65, 0x72, 0x74, 0x2D, 0x76, 0x30, 0x31, 0x40, 0x6F,
509
            0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x72, 0x73, 0x61,
510
            0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x32, 0x35, 0x36, 0x2D, 0x63, 0x65, 0x72, 0x74,
511
            0x2D, 0x76, 0x30, 0x31, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63,
512
            0x6F, 0x6D, 0x2C, 0x73, 0x73, 0x68, 0x2D, 0x72, 0x73, 0x61, 0x2D, 0x63, 0x65, 0x72,
513
            0x74, 0x2D, 0x76, 0x30, 0x31, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E,
514
            0x63, 0x6F, 0x6D, 0x2C, 0x73, 0x73, 0x68, 0x2D, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31,
515
            0x39, 0x2C, 0x72, 0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x35, 0x31, 0x32,
516
            0x2C, 0x72, 0x73, 0x61, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x32, 0x35, 0x36, 0x2C,
517
            0x73, 0x73, 0x68, 0x2D, 0x72, 0x73, 0x61, 0x00, 0x00, 0x00, 0x6C, 0x63, 0x68, 0x61,
518
            0x63, 0x68, 0x61, 0x32, 0x30, 0x2D, 0x70, 0x6F, 0x6C, 0x79, 0x31, 0x33, 0x30, 0x35,
519
            0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x61,
520
            0x65, 0x73, 0x31, 0x32, 0x38, 0x2D, 0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x31,
521
            0x39, 0x32, 0x2D, 0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x32, 0x35, 0x36, 0x2D,
522
            0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2D, 0x67, 0x63, 0x6D,
523
            0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x61,
524
            0x65, 0x73, 0x32, 0x35, 0x36, 0x2D, 0x67, 0x63, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E,
525
            0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x00, 0x00, 0x6C, 0x63, 0x68, 0x61,
526
            0x63, 0x68, 0x61, 0x32, 0x30, 0x2D, 0x70, 0x6F, 0x6C, 0x79, 0x31, 0x33, 0x30, 0x35,
527
            0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x61,
528
            0x65, 0x73, 0x31, 0x32, 0x38, 0x2D, 0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x31,
529
            0x39, 0x32, 0x2D, 0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x32, 0x35, 0x36, 0x2D,
530
            0x63, 0x74, 0x72, 0x2C, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2D, 0x67, 0x63, 0x6D,
531
            0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x61,
532
            0x65, 0x73, 0x32, 0x35, 0x36, 0x2D, 0x67, 0x63, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E,
533
            0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x00, 0x00, 0x00, 0xD5, 0x75, 0x6D, 0x61,
534
            0x63, 0x2D, 0x36, 0x34, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73,
535
            0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75, 0x6D, 0x61, 0x63, 0x2D, 0x31, 0x32,
536
            0x38, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E,
537
            0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D,
538
            0x32, 0x35, 0x36, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73,
539
            0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61,
540
            0x32, 0x2D, 0x35, 0x31, 0x32, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E,
541
            0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73,
542
            0x68, 0x61, 0x31, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73,
543
            0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75, 0x6D, 0x61, 0x63, 0x2D, 0x36, 0x34, 0x40,
544
            0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75, 0x6D,
545
            0x61, 0x63, 0x2D, 0x31, 0x32, 0x38, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68,
546
            0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32,
547
            0x2D, 0x32, 0x35, 0x36, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32,
548
            0x2D, 0x35, 0x31, 0x32, 0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x31,
549
            0x00, 0x00, 0x00, 0xD5, 0x75, 0x6D, 0x61, 0x63, 0x2D, 0x36, 0x34, 0x2D, 0x65, 0x74,
550
            0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C,
551
            0x75, 0x6D, 0x61, 0x63, 0x2D, 0x31, 0x32, 0x38, 0x2D, 0x65, 0x74, 0x6D, 0x40, 0x6F,
552
            0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D, 0x61,
553
            0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x32, 0x35, 0x36, 0x2D, 0x65, 0x74, 0x6D,
554
            0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68,
555
            0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x35, 0x31, 0x32, 0x2D, 0x65,
556
            0x74, 0x6D, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D,
557
            0x2C, 0x68, 0x6D, 0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x31, 0x2D, 0x65, 0x74, 0x6D,
558
            0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75,
559
            0x6D, 0x61, 0x63, 0x2D, 0x36, 0x34, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68,
560
            0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x75, 0x6D, 0x61, 0x63, 0x2D, 0x31, 0x32, 0x38, 0x40,
561
            0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x68, 0x6D,
562
            0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x32, 0x35, 0x36, 0x2C, 0x68, 0x6D,
563
            0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x32, 0x2D, 0x35, 0x31, 0x32, 0x2C, 0x68, 0x6D,
564
            0x61, 0x63, 0x2D, 0x73, 0x68, 0x61, 0x31, 0x00, 0x00, 0x00, 0x1A, 0x6E, 0x6F, 0x6E,
565
            0x65, 0x2C, 0x7A, 0x6C, 0x69, 0x62, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73, 0x73, 0x68,
566
            0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x7A, 0x6C, 0x69, 0x62, 0x00, 0x00, 0x00, 0x1A, 0x6E,
567
            0x6F, 0x6E, 0x65, 0x2C, 0x7A, 0x6C, 0x69, 0x62, 0x40, 0x6F, 0x70, 0x65, 0x6E, 0x73,
568
            0x73, 0x68, 0x2E, 0x63, 0x6F, 0x6D, 0x2C, 0x7A, 0x6C, 0x69, 0x62, 0x00, 0x00, 0x00,
569
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570
        ];
571
        let mut hassh_string: Vec<u8> = vec![];
572
        let mut hassh: Vec<u8> = vec![];
573
        if let Ok((_, key_exchange)) = ssh_parse_key_exchange(&client_key_exchange) {
574
            key_exchange.generate_hassh(&mut hassh_string, &mut hassh, &true);
575
        }
576

577
        assert_eq!(hassh_string, "curve25519-sha256,curve25519-sha256@libssh.org,\
578
                                  ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,\
579
                                  diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,\
580
                                  diffie-hellman-group14-sha1,ext-info-c;chacha20-poly1305@openssh.com,aes128-ctr,\
581
                                  aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com;umac-64-etm@openssh.com,\
582
                                  umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,\
583
                                  hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,\
584
                                  hmac-sha2-256,hmac-sha2-512,hmac-sha1;none,zlib@openssh.com,zlib".as_bytes().to_vec());
585

586
        assert_eq!(
587
            hassh,
588
            "ec7378c1a92f5a8dde7e8b7a1ddf33d1".as_bytes().to_vec()
589
        );
590
    }
591

592
    #[test]
593
    fn test_parse_hassh_server() {
594
        let server_key_exchange = [
595
            0x7d, 0x76, 0x4f, 0x78, 0x81, 0x9e, 0x10, 0xfa, 0x23, 0x72, 0xb5, 0x15, 0x56, 0xba,
596
            0xf9, 0x46, 0x00, 0x00, 0x01, 0x02, 0x63, 0x75, 0x72, 0x76, 0x65, 0x32, 0x35, 0x35,
597
            0x31, 0x39, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2c, 0x63, 0x75, 0x72, 0x76,
598
            0x65, 0x32, 0x35, 0x35, 0x31, 0x39, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x40,
599
            0x6c, 0x69, 0x62, 0x73, 0x73, 0x68, 0x2e, 0x6f, 0x72, 0x67, 0x2c, 0x65, 0x63, 0x64,
600
            0x68, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x2d, 0x6e, 0x69, 0x73, 0x74, 0x70, 0x32, 0x35,
601
            0x36, 0x2c, 0x65, 0x63, 0x64, 0x68, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x2d, 0x6e, 0x69,
602
            0x73, 0x74, 0x70, 0x33, 0x38, 0x34, 0x2c, 0x65, 0x63, 0x64, 0x68, 0x2d, 0x73, 0x68,
603
            0x61, 0x32, 0x2d, 0x6e, 0x69, 0x73, 0x74, 0x70, 0x35, 0x32, 0x31, 0x2c, 0x64, 0x69,
604
            0x66, 0x66, 0x69, 0x65, 0x2d, 0x68, 0x65, 0x6c, 0x6c, 0x6d, 0x61, 0x6e, 0x2d, 0x67,
605
            0x72, 0x6f, 0x75, 0x70, 0x2d, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2d,
606
            0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2c, 0x64, 0x69, 0x66, 0x66, 0x69, 0x65, 0x2d,
607
            0x68, 0x65, 0x6c, 0x6c, 0x6d, 0x61, 0x6e, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x31,
608
            0x36, 0x2d, 0x73, 0x68, 0x61, 0x35, 0x31, 0x32, 0x2c, 0x64, 0x69, 0x66, 0x66, 0x69,
609
            0x65, 0x2d, 0x68, 0x65, 0x6c, 0x6c, 0x6d, 0x61, 0x6e, 0x2d, 0x67, 0x72, 0x6f, 0x75,
610
            0x70, 0x31, 0x38, 0x2d, 0x73, 0x68, 0x61, 0x35, 0x31, 0x32, 0x2c, 0x64, 0x69, 0x66,
611
            0x66, 0x69, 0x65, 0x2d, 0x68, 0x65, 0x6c, 0x6c, 0x6d, 0x61, 0x6e, 0x2d, 0x67, 0x72,
612
            0x6f, 0x75, 0x70, 0x31, 0x34, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2c, 0x64,
613
            0x69, 0x66, 0x66, 0x69, 0x65, 0x2d, 0x68, 0x65, 0x6c, 0x6c, 0x6d, 0x61, 0x6e, 0x2d,
614
            0x67, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x34, 0x2d, 0x73, 0x68, 0x61, 0x31, 0x00, 0x00,
615
            0x00, 0x41, 0x73, 0x73, 0x68, 0x2d, 0x72, 0x73, 0x61, 0x2c, 0x72, 0x73, 0x61, 0x2d,
616
            0x73, 0x68, 0x61, 0x32, 0x2d, 0x35, 0x31, 0x32, 0x2c, 0x72, 0x73, 0x61, 0x2d, 0x73,
617
            0x68, 0x61, 0x32, 0x2d, 0x32, 0x35, 0x36, 0x2c, 0x65, 0x63, 0x64, 0x73, 0x61, 0x2d,
618
            0x73, 0x68, 0x61, 0x32, 0x2d, 0x6e, 0x69, 0x73, 0x74, 0x70, 0x32, 0x35, 0x36, 0x2c,
619
            0x73, 0x73, 0x68, 0x2d, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x00, 0x00, 0x00,
620
            0x6c, 0x63, 0x68, 0x61, 0x63, 0x68, 0x61, 0x32, 0x30, 0x2d, 0x70, 0x6f, 0x6c, 0x79,
621
            0x31, 0x33, 0x30, 0x35, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63,
622
            0x6f, 0x6d, 0x2c, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2d, 0x63, 0x74, 0x72, 0x2c,
623
            0x61, 0x65, 0x73, 0x31, 0x39, 0x32, 0x2d, 0x63, 0x74, 0x72, 0x2c, 0x61, 0x65, 0x73,
624
            0x32, 0x35, 0x36, 0x2d, 0x63, 0x74, 0x72, 0x2c, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38,
625
            0x2d, 0x67, 0x63, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63,
626
            0x6f, 0x6d, 0x2c, 0x61, 0x65, 0x73, 0x32, 0x35, 0x36, 0x2d, 0x67, 0x63, 0x6d, 0x40,
627
            0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00,
628
            0x6c, 0x63, 0x68, 0x61, 0x63, 0x68, 0x61, 0x32, 0x30, 0x2d, 0x70, 0x6f, 0x6c, 0x79,
629
            0x31, 0x33, 0x30, 0x35, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63,
630
            0x6f, 0x6d, 0x2c, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2d, 0x63, 0x74, 0x72, 0x2c,
631
            0x61, 0x65, 0x73, 0x31, 0x39, 0x32, 0x2d, 0x63, 0x74, 0x72, 0x2c, 0x61, 0x65, 0x73,
632
            0x32, 0x35, 0x36, 0x2d, 0x63, 0x74, 0x72, 0x2c, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38,
633
            0x2d, 0x67, 0x63, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63,
634
            0x6f, 0x6d, 0x2c, 0x61, 0x65, 0x73, 0x32, 0x35, 0x36, 0x2d, 0x67, 0x63, 0x6d, 0x40,
635
            0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00,
636
            0xd5, 0x75, 0x6d, 0x61, 0x63, 0x2d, 0x36, 0x34, 0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f,
637
            0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x75, 0x6d, 0x61,
638
            0x63, 0x2d, 0x31, 0x32, 0x38, 0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e,
639
            0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73,
640
            0x68, 0x61, 0x32, 0x2d, 0x32, 0x35, 0x36, 0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70,
641
            0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x68, 0x6d, 0x61, 0x63,
642
            0x2d, 0x73, 0x68, 0x61, 0x32, 0x2d, 0x35, 0x31, 0x32, 0x2d, 0x65, 0x74, 0x6d, 0x40,
643
            0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x68, 0x6d,
644
            0x61, 0x63, 0x2d, 0x73, 0x68, 0x61, 0x31, 0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70,
645
            0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x75, 0x6d, 0x61, 0x63,
646
            0x2d, 0x36, 0x34, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f,
647
            0x6d, 0x2c, 0x75, 0x6d, 0x61, 0x63, 0x2d, 0x31, 0x32, 0x38, 0x40, 0x6f, 0x70, 0x65,
648
            0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d,
649
            0x73, 0x68, 0x61, 0x32, 0x2d, 0x32, 0x35, 0x36, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d,
650
            0x73, 0x68, 0x61, 0x32, 0x2d, 0x35, 0x31, 0x32, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d,
651
            0x73, 0x68, 0x61, 0x31, 0x00, 0x00, 0x00, 0xd5, 0x75, 0x6d, 0x61, 0x63, 0x2d, 0x36,
652
            0x34, 0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e,
653
            0x63, 0x6f, 0x6d, 0x2c, 0x75, 0x6d, 0x61, 0x63, 0x2d, 0x31, 0x32, 0x38, 0x2d, 0x65,
654
            0x74, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d,
655
            0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x2d, 0x32, 0x35, 0x36,
656
            0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63,
657
            0x6f, 0x6d, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x2d, 0x35,
658
            0x31, 0x32, 0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68,
659
            0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x68, 0x61, 0x31,
660
            0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63,
661
            0x6f, 0x6d, 0x2c, 0x75, 0x6d, 0x61, 0x63, 0x2d, 0x36, 0x34, 0x40, 0x6f, 0x70, 0x65,
662
            0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x75, 0x6d, 0x61, 0x63, 0x2d,
663
            0x31, 0x32, 0x38, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f,
664
            0x6d, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x2d, 0x32, 0x35,
665
            0x36, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x2d, 0x35, 0x31,
666
            0x32, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x68, 0x61, 0x31, 0x00, 0x00, 0x00,
667
            0x15, 0x6e, 0x6f, 0x6e, 0x65, 0x2c, 0x7a, 0x6c, 0x69, 0x62, 0x40, 0x6f, 0x70, 0x65,
668
            0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x15, 0x6e, 0x6f,
669
            0x6e, 0x65, 0x2c, 0x7a, 0x6c, 0x69, 0x62, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73,
670
            0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672
        ];
673
        let mut hassh_server_string: Vec<u8> = vec![];
674
        let mut hassh_server: Vec<u8> = vec![];
675
        if let Ok((_, key_exchange)) = ssh_parse_key_exchange(&server_key_exchange) {
676
            key_exchange.generate_hassh(&mut hassh_server_string, &mut hassh_server, &true);
677
        }
678
        assert_eq!(
679
            hassh_server,
680
            "b12d2871a1189eff20364cf5333619ee".as_bytes().to_vec()
681
        );
682
    }
683

684
    #[test]
685
    fn test_parse_hassh_server_malicious() {
686
        let server_key_exchange = [
687
            0x7d, 0x76, 0x4f, 0x78, 0x81, 0x9e, 0x10, 0xfa, 0x23, 0x72, 0xb5, 0x15, 0x56, 0xba,
688
            0xf9, 0x46, 0x00, 0x00, 0x01, 0x02, 0x75, 0x72, 0x76, 0x65, 0x32, 0x35, 0x35, 0x31,
689
            0x39, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2c, 0x63, 0x75, 0x72, 0x76, 0x65,
690
            0x32, 0x35, 0x35, 0x31, 0x39, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x40, 0x6c,
691
            0x69, 0x62, 0x73, 0x73, 0x68, 0x2e, 0x6f, 0x72, 0x67, 0x2c, 0x65, 0x63, 0x64, 0x68,
692
            0x2d, 0x73, 0x68, 0x61, 0x32, 0x2d, 0x6e, 0x69, 0x73, 0x74, 0x70, 0x32, 0x35, 0x36,
693
            0x2c, 0x65, 0x63, 0x64, 0x68, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x2d, 0x6e, 0x69, 0x73,
694
            0x74, 0x70, 0x33, 0x38, 0x34, 0x2c, 0x65, 0x63, 0x64, 0x68, 0x2d, 0x73, 0x68, 0x61,
695
            0x32, 0x2d, 0x6e, 0x69, 0x73, 0x74, 0x70, 0x35, 0x32, 0x31, 0x2c, 0x64, 0x69, 0x66,
696
            0x66, 0x69, 0x65, 0x2d, 0x68, 0x65, 0x6c, 0x6c, 0x6d, 0x61, 0x6e, 0x2d, 0x67, 0x72,
697
            0x6f, 0x75, 0x70, 0x2d, 0x65, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x2d, 0x73,
698
            0x68, 0x61, 0x32, 0x35, 0x36, 0x2c, 0x64, 0x69, 0x66, 0x66, 0x69, 0x65, 0x2d, 0x68,
699
            0x65, 0x6c, 0x6c, 0x6d, 0x61, 0x6e, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x31, 0x36,
700
            0x2d, 0x73, 0x68, 0x61, 0x35, 0x31, 0x32, 0x2c, 0x64, 0x69, 0x66, 0x66, 0x69, 0x65,
701
            0x2d, 0x68, 0x65, 0x6c, 0x6c, 0x6d, 0x61, 0x6e, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70,
702
            0x31, 0x38, 0x2d, 0x73, 0x68, 0x61, 0x35, 0x31, 0x32, 0x2c, 0x64, 0x69, 0x66, 0x66,
703
            0x69, 0x65, 0x2d, 0x68, 0x65, 0x6c, 0x6c, 0x6d, 0x61, 0x6e, 0x2d, 0x67, 0x72, 0x6f,
704
            0x75, 0x70, 0x31, 0x34, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x2c, 0x64, 0x69,
705
            0x66, 0x66, 0x69, 0x65, 0x2d, 0x68, 0x65, 0x6c, 0x6c, 0x6d, 0x61, 0x6e, 0x2d, 0x67,
706
            0x72, 0x6f, 0x75, 0x70, 0x31, 0x34, 0x2d, 0x73, 0x68, 0x61, 0x31, 0x00, 0x00, 0x00,
707
            0x41, 0x73, 0x73, 0x68, 0x2d, 0x72, 0x73, 0x61, 0x2c, 0x72, 0x73, 0x61, 0x2d, 0x73,
708
            0x68, 0x61, 0x32, 0x2d, 0x35, 0x31, 0x32, 0x2c, 0x72, 0x73, 0x61, 0x2d, 0x73, 0x68,
709
            0x61, 0x32, 0x2d, 0x32, 0x35, 0x36, 0x2c, 0x65, 0x63, 0x64, 0x73, 0x61, 0x2d, 0x73,
710
            0x68, 0x61, 0x32, 0x2d, 0x6e, 0x69, 0x73, 0x74, 0x70, 0x32, 0x35, 0x36, 0x2c, 0x73,
711
            0x73, 0x68, 0x2d, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x00, 0x00, 0x00, 0x6c,
712
            0x63, 0x68, 0x61, 0x63, 0x68, 0x61, 0x32, 0x30, 0x2d, 0x70, 0x6f, 0x6c, 0x79, 0x31,
713
            0x33, 0x30, 0x35, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f,
714
            0x6d, 0x2c, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2d, 0x63, 0x74, 0x72, 0x2c, 0x61,
715
            0x65, 0x73, 0x31, 0x39, 0x32, 0x2d, 0x63, 0x74, 0x72, 0x2c, 0x61, 0x65, 0x73, 0x32,
716
            0x35, 0x36, 0x2d, 0x63, 0x74, 0x72, 0x2c, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2d,
717
            0x67, 0x63, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f,
718
            0x6d, 0x2c, 0x61, 0x65, 0x73, 0x32, 0x35, 0x36, 0x2d, 0x67, 0x63, 0x6d, 0x40, 0x6f,
719
            0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x6c,
720
            0x63, 0x68, 0x61, 0x63, 0x68, 0x61, 0x32, 0x30, 0x2d, 0x70, 0x6f, 0x6c, 0x79, 0x31,
721
            0x33, 0x30, 0x35, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f,
722
            0x6d, 0x2c, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2d, 0x63, 0x74, 0x72, 0x2c, 0x61,
723
            0x65, 0x73, 0x31, 0x39, 0x32, 0x2d, 0x63, 0x74, 0x72, 0x2c, 0x61, 0x65, 0x73, 0x32,
724
            0x35, 0x36, 0x2d, 0x63, 0x74, 0x72, 0x2c, 0x61, 0x65, 0x73, 0x31, 0x32, 0x38, 0x2d,
725
            0x67, 0x63, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f,
726
            0x6d, 0x2c, 0x61, 0x65, 0x73, 0x32, 0x35, 0x36, 0x2d, 0x67, 0x63, 0x6d, 0x40, 0x6f,
727
            0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0xd5,
728
            0x75, 0x6d, 0x61, 0x63, 0x2d, 0x36, 0x34, 0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70,
729
            0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x75, 0x6d, 0x61, 0x63,
730
            0x2d, 0x31, 0x32, 0x38, 0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73,
731
            0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x68,
732
            0x61, 0x32, 0x2d, 0x32, 0x35, 0x36, 0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70, 0x65,
733
            0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d,
734
            0x73, 0x68, 0x61, 0x32, 0x2d, 0x35, 0x31, 0x32, 0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f,
735
            0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x68, 0x6d, 0x61,
736
            0x63, 0x2d, 0x73, 0x68, 0x61, 0x31, 0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70, 0x65,
737
            0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x75, 0x6d, 0x61, 0x63, 0x2d,
738
            0x36, 0x34, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d,
739
            0x2c, 0x75, 0x6d, 0x61, 0x63, 0x2d, 0x31, 0x32, 0x38, 0x40, 0x6f, 0x70, 0x65, 0x6e,
740
            0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73,
741
            0x68, 0x61, 0x32, 0x2d, 0x32, 0x35, 0x36, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73,
742
            0x68, 0x61, 0x32, 0x2d, 0x35, 0x31, 0x32, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73,
743
            0x68, 0x61, 0x31, 0x00, 0x00, 0x00, 0xd5, 0x75, 0x6d, 0x61, 0x63, 0x2d, 0x36, 0x34,
744
            0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63,
745
            0x6f, 0x6d, 0x2c, 0x75, 0x6d, 0x61, 0x63, 0x2d, 0x31, 0x32, 0x38, 0x2d, 0x65, 0x74,
746
            0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c,
747
            0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x2d, 0x32, 0x35, 0x36, 0x2d,
748
            0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f,
749
            0x6d, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x2d, 0x35, 0x31,
750
            0x32, 0x2d, 0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e,
751
            0x63, 0x6f, 0x6d, 0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x68, 0x61, 0x31, 0x2d,
752
            0x65, 0x74, 0x6d, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f,
753
            0x6d, 0x2c, 0x75, 0x6d, 0x61, 0x63, 0x2d, 0x36, 0x34, 0x40, 0x6f, 0x70, 0x65, 0x6e,
754
            0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x75, 0x6d, 0x61, 0x63, 0x2d, 0x31,
755
            0x32, 0x38, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d,
756
            0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x2d, 0x32, 0x35, 0x36,
757
            0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x68, 0x61, 0x32, 0x2d, 0x35, 0x31, 0x32,
758
            0x2c, 0x68, 0x6d, 0x61, 0x63, 0x2d, 0x73, 0x68, 0x61, 0x31, 0x00, 0x00, 0x00, 0x15,
759
            0x6e, 0x6f, 0x6e, 0x65, 0x2c, 0x7a, 0x6c, 0x69, 0x62, 0x40, 0x6f, 0x70, 0x65, 0x6e,
760
            0x73, 0x73, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x15, 0x6e, 0x6f, 0x6e,
761
            0x65, 0x2c, 0x7a, 0x6c, 0x69, 0x62, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x73, 0x73, 0x68,
762
            0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
763
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
764
        ];
765

766
        if let Err(e) = ssh_parse_key_exchange(&server_key_exchange) {
767
            assert_eq!(e, Err::Incomplete(Needed::new(15964)));
768
        } else {
769
            panic!("ssh_parse_key_exchange() parsed malicious key_exchange");
770
        }
771
    }
772
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc