2 * Routines for ssh packet dissection
4 * Huagang XIE <huagang@intruvert.com>
5 * Kees Cook <kees@outflux.net>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-mysql.c
13 * SPDX-License-Identifier: GPL-2.0-or-later
16 * Note: support SSH v1 and v2 now.
20 /* SSH version 2 is defined in:
22 * RFC 4250: The Secure Shell (SSH) Protocol Assigned Numbers
23 * RFC 4251: The Secure Shell (SSH) Protocol Architecture
24 * RFC 4252: The Secure Shell (SSH) Authentication Protocol
25 * RFC 4253: The Secure Shell (SSH) Transport Layer Protocol
26 * RFC 4254: The Secure Shell (SSH) Connection Protocol
28 * SSH versions under 2 were never officially standardized.
30 * Diffie-Hellman Group Exchange is defined in:
32 * RFC 4419: Diffie-Hellman Group Exchange for
33 * the Secure Shell (SSH) Transport Layer Protocol
36 /* "SSH" prefixes are for version 2, whereas "SSH1" is for version 1 */
39 /* Start with WIRESHARK_LOG_DOMAINS=packet-ssh and WIRESHARK_LOG_LEVEL=debug to see messages. */
40 #define WS_LOG_DOMAIN "packet-ssh"
42 // Define this to get hex dumps more similar to what you get in openssh. If not defined, dumps look more like what you get with other dissectors.
47 #include <epan/packet.h>
48 #include <epan/exceptions.h>
49 #include <epan/sctpppids.h>
50 #include <epan/prefs.h>
51 #include <epan/expert.h>
52 #include <epan/proto_data.h>
53 #include <wsutil/strtoi.h>
54 #include <wsutil/to_str.h>
55 #include <wsutil/file_util.h>
56 #include <wsutil/filesystem.h>
57 #include <wsutil/wsgcrypt.h>
58 #include <wsutil/curve25519.h>
59 #include <wsutil/pint.h>
60 #include <wsutil/str_util.h>
61 #include <wsutil/wslog.h>
62 #include <epan/secrets.h>
63 #include <wiretap/secrets-types.h>
65 #if defined(HAVE_LIBGNUTLS)
66 #include <gnutls/abstract.h>
69 #include "packet-tcp.h"
71 void proto_register_ssh(void);
72 void proto_reg_handoff_ssh(void);
74 /* SSH Version 1 definition , from openssh ssh1.h */
75 #define SSH1_MSG_NONE 0 /* no message */
76 #define SSH1_MSG_DISCONNECT 1 /* cause (string) */
77 #define SSH1_SMSG_PUBLIC_KEY 2 /* ck,msk,srvk,hostk */
78 #define SSH1_CMSG_SESSION_KEY 3 /* key (BIGNUM) */
79 #define SSH1_CMSG_USER 4 /* user (string) */
82 #define SSH_VERSION_UNKNOWN 0
83 #define SSH_VERSION_1 1
84 #define SSH_VERSION_2 2
93 #define SSH_KEX_CURVE25519 0x00010000
94 #define SSH_KEX_DH_GEX 0x00020000
95 #define SSH_KEX_DH_GROUP1 0x00030001
96 #define SSH_KEX_DH_GROUP14 0x00030014
97 #define SSH_KEX_DH_GROUP16 0x00030016
98 #define SSH_KEX_DH_GROUP18 0x00030018
100 #define SSH_KEX_HASH_SHA1 1
101 #define SSH_KEX_HASH_SHA256 2
102 #define SSH_KEX_HASH_SHA512 4
104 #define DIGEST_MAX_SIZE 48
106 typedef struct _ssh_message_info_t
{
107 uint32_t sequence_number
;
108 unsigned char *plain_data
; /**< Decrypted data. */
109 unsigned data_len
; /**< Length of decrypted data. */
110 int id
; /**< Identifies the exact message within a frame
111 (there can be multiple records in a frame). */
113 uint32_t next_byte_seq
;
114 struct _ssh_message_info_t
* next
;
115 uint8_t calc_mac
[DIGEST_MAX_SIZE
];
116 } ssh_message_info_t
;
120 ssh_message_info_t
* messages
;
123 typedef struct _ssh_channel_info_t
{
126 wmem_tree_t
*multisegment_pdus
;
127 dissector_handle_t handle
;
128 } ssh_channel_info_t
;
130 struct ssh_peer_data
{
133 uint32_t frame_version_start
;
134 uint32_t frame_version_end
;
136 uint32_t frame_key_start
;
137 uint32_t frame_key_end
;
138 int frame_key_end_offset
;
142 /* For all subsequent proposals,
143 [0] is client-to-server and [1] is server-to-client. */
144 #define CLIENT_TO_SERVER_PROPOSAL 0
145 #define SERVER_TO_CLIENT_PROPOSAL 1
147 char* mac_proposals
[2];
151 char* enc_proposals
[2];
154 char* comp_proposals
[2];
157 int length_is_plaintext
;
159 // see libgcrypt source, gcrypt.h:gcry_cipher_algos
162 // chacha20 needs two cipher handles
163 gcry_cipher_hd_t cipher
, cipher_2
;
164 unsigned sequence_number
;
165 uint32_t seq_num_kex_init
;
166 // union ??? -- begin
167 uint32_t seq_num_gex_req
;
168 uint32_t seq_num_gex_grp
;
169 uint32_t seq_num_gex_ini
;
170 uint32_t seq_num_gex_rep
;
172 uint32_t seq_num_ecdh_ini
;
173 uint32_t seq_num_ecdh_rep
;
175 uint32_t seq_num_dh_ini
;
176 uint32_t seq_num_dh_rep
;
178 uint32_t seq_num_new_key
;
179 ssh_bignum
*bn_cookie
;
181 uint8_t hmac_iv
[DIGEST_MAX_SIZE
];
182 unsigned hmac_iv_len
;
184 wmem_map_t
*channel_info
; /**< Map of sender channel numbers to recipient numbers. */
185 wmem_map_t
*channel_handles
; /**< Map of recipient channel numbers to subdissector handles. */
186 struct ssh_flow_data
* global_data
;
189 struct ssh_flow_data
{
193 int (*kex_specific_dissector
)(uint8_t msg_code
, tvbuff_t
*tvb
,
194 packet_info
*pinfo
, int offset
, proto_tree
*tree
,
195 struct ssh_flow_data
*global_data
, unsigned *seq_num
);
197 /* [0] is client's, [1] is server's */
198 #define CLIENT_PEER_DATA 0
199 #define SERVER_PEER_DATA 1
200 struct ssh_peer_data peer_data
[2];
203 unsigned session_id_length
;
206 ssh_bignum
*kex_gex_p
; // Group modulo
207 ssh_bignum
*kex_gex_g
; // Group generator
209 wmem_array_t
*kex_client_version
;
210 wmem_array_t
*kex_server_version
;
211 wmem_array_t
*kex_client_key_exchange_init
;
212 wmem_array_t
*kex_server_key_exchange_init
;
213 wmem_array_t
*kex_server_host_key_blob
;
214 wmem_array_t
*kex_gex_bits_min
;
215 wmem_array_t
*kex_gex_bits_req
;
216 wmem_array_t
*kex_gex_bits_max
;
217 wmem_array_t
*kex_shared_secret
;
219 bool ext_ping_openssh_offered
;
220 ssh_bignum new_keys
[6];
225 ssh_bignum
*key_material
;
226 } ssh_key_map_entry_t
;
228 static GHashTable
* ssh_master_key_map
;
230 static int proto_ssh
;
232 /* Version exchange */
233 static int hf_ssh_protocol
;
236 static int hf_ssh_packet_length
;
237 static int hf_ssh_packet_length_encrypted
;
238 static int hf_ssh_padding_length
;
239 static int hf_ssh_payload
;
240 static int hf_ssh_encrypted_packet
;
241 static int hf_ssh_padding_string
;
242 static int hf_ssh_mac_string
;
243 static int hf_ssh_mac_status
;
244 static int hf_ssh_seq_num
;
245 static int hf_ssh_direction
;
248 static int hf_ssh_msg_code
;
249 static int hf_ssh2_msg_code
;
250 static int hf_ssh2_kex_dh_msg_code
;
251 static int hf_ssh2_kex_dh_gex_msg_code
;
252 static int hf_ssh2_kex_ecdh_msg_code
;
253 static int hf_ssh2_ext_ping_msg_code
;
255 /* Algorithm negotiation */
256 static int hf_ssh_cookie
;
257 static int hf_ssh_kex_algorithms
;
258 static int hf_ssh_server_host_key_algorithms
;
259 static int hf_ssh_encryption_algorithms_client_to_server
;
260 static int hf_ssh_encryption_algorithms_server_to_client
;
261 static int hf_ssh_mac_algorithms_client_to_server
;
262 static int hf_ssh_mac_algorithms_server_to_client
;
263 static int hf_ssh_compression_algorithms_client_to_server
;
264 static int hf_ssh_compression_algorithms_server_to_client
;
265 static int hf_ssh_languages_client_to_server
;
266 static int hf_ssh_languages_server_to_client
;
267 static int hf_ssh_kex_algorithms_length
;
268 static int hf_ssh_server_host_key_algorithms_length
;
269 static int hf_ssh_encryption_algorithms_client_to_server_length
;
270 static int hf_ssh_encryption_algorithms_server_to_client_length
;
271 static int hf_ssh_mac_algorithms_client_to_server_length
;
272 static int hf_ssh_mac_algorithms_server_to_client_length
;
273 static int hf_ssh_compression_algorithms_client_to_server_length
;
274 static int hf_ssh_compression_algorithms_server_to_client_length
;
275 static int hf_ssh_languages_client_to_server_length
;
276 static int hf_ssh_languages_server_to_client_length
;
277 static int hf_ssh_first_kex_packet_follows
;
278 static int hf_ssh_kex_reserved
;
279 static int hf_ssh_kex_hassh_algo
;
280 static int hf_ssh_kex_hassh
;
281 static int hf_ssh_kex_hasshserver_algo
;
282 static int hf_ssh_kex_hasshserver
;
284 /* Key exchange common elements */
285 static int hf_ssh_hostkey_length
;
286 static int hf_ssh_hostkey_type_length
;
287 static int hf_ssh_hostkey_type
;
288 static int hf_ssh_hostkey_data
;
289 static int hf_ssh_hostkey_rsa_n
;
290 static int hf_ssh_hostkey_rsa_e
;
291 static int hf_ssh_hostkey_dsa_p
;
292 static int hf_ssh_hostkey_dsa_q
;
293 static int hf_ssh_hostkey_dsa_g
;
294 static int hf_ssh_hostkey_dsa_y
;
295 static int hf_ssh_hostkey_ecdsa_curve_id
;
296 static int hf_ssh_hostkey_ecdsa_curve_id_length
;
297 static int hf_ssh_hostkey_ecdsa_q
;
298 static int hf_ssh_hostkey_ecdsa_q_length
;
299 static int hf_ssh_hostkey_eddsa_key
;
300 static int hf_ssh_hostkey_eddsa_key_length
;
301 static int hf_ssh_hostsig_length
;
302 static int hf_ssh_hostsig_type_length
;
303 static int hf_ssh_hostsig_type
;
304 static int hf_ssh_hostsig_rsa
;
305 static int hf_ssh_hostsig_dsa
;
306 static int hf_ssh_hostsig_data
;
308 /* Key exchange: Diffie-Hellman */
309 static int hf_ssh_dh_e
;
310 static int hf_ssh_dh_f
;
312 /* Key exchange: Diffie-Hellman Group Exchange */
313 static int hf_ssh_dh_gex_min
;
314 static int hf_ssh_dh_gex_nbits
;
315 static int hf_ssh_dh_gex_max
;
316 static int hf_ssh_dh_gex_p
;
317 static int hf_ssh_dh_gex_g
;
319 /* Key exchange: Elliptic Curve Diffie-Hellman */
320 static int hf_ssh_ecdh_q_c
;
321 static int hf_ssh_ecdh_q_c_length
;
322 static int hf_ssh_ecdh_q_s
;
323 static int hf_ssh_ecdh_q_s_length
;
325 /* Extension negotiation */
326 static int hf_ssh_ext_count
;
327 static int hf_ssh_ext_name_length
;
328 static int hf_ssh_ext_name
;
329 static int hf_ssh_ext_value_length
;
330 static int hf_ssh_ext_value
;
331 static int hf_ssh_ext_server_sig_algs_algorithms
;
332 static int hf_ssh_ext_delay_compression_algorithms_client_to_server_length
;
333 static int hf_ssh_ext_delay_compression_algorithms_client_to_server
;
334 static int hf_ssh_ext_delay_compression_algorithms_server_to_client_length
;
335 static int hf_ssh_ext_delay_compression_algorithms_server_to_client
;
336 static int hf_ssh_ext_no_flow_control_value
;
337 static int hf_ssh_ext_elevation_value
;
338 static int hf_ssh_ext_prop_publickey_algorithms_algorithms
;
341 static int hf_ssh_mpint_length
;
343 static int hf_ssh_ignore_data_length
;
344 static int hf_ssh_ignore_data
;
345 static int hf_ssh_debug_always_display
;
346 static int hf_ssh_debug_message_length
;
347 static int hf_ssh_debug_message
;
348 static int hf_ssh_service_name_length
;
349 static int hf_ssh_service_name
;
350 static int hf_ssh_userauth_user_name_length
;
351 static int hf_ssh_userauth_user_name
;
352 static int hf_ssh_userauth_change_password
;
353 static int hf_ssh_userauth_service_name_length
;
354 static int hf_ssh_userauth_service_name
;
355 static int hf_ssh_userauth_method_name_length
;
356 static int hf_ssh_userauth_method_name
;
357 static int hf_ssh_userauth_have_signature
;
358 static int hf_ssh_userauth_password_length
;
359 static int hf_ssh_userauth_password
;
360 static int hf_ssh_userauth_new_password_length
;
361 static int hf_ssh_userauth_new_password
;
362 static int hf_ssh_auth_failure_list_length
;
363 static int hf_ssh_auth_failure_list
;
364 static int hf_ssh_userauth_partial_success
;
365 static int hf_ssh_userauth_pka_name_len
;
366 static int hf_ssh_userauth_pka_name
;
367 static int hf_ssh_pk_blob_name_length
;
368 static int hf_ssh_pk_blob_name
;
369 static int hf_ssh_blob_length
;
370 static int hf_ssh_signature_length
;
371 static int hf_ssh_pk_sig_blob_name_length
;
372 static int hf_ssh_pk_sig_blob_name
;
373 static int hf_ssh_connection_type_name_len
;
374 static int hf_ssh_connection_type_name
;
375 static int hf_ssh_connection_sender_channel
;
376 static int hf_ssh_connection_recipient_channel
;
377 static int hf_ssh_connection_initial_window
;
378 static int hf_ssh_connection_maximum_packet_size
;
379 static int hf_ssh_global_request_name_len
;
380 static int hf_ssh_global_request_name
;
381 static int hf_ssh_global_request_want_reply
;
382 static int hf_ssh_global_request_hostkeys_array_len
;
383 static int hf_ssh_channel_request_name_len
;
384 static int hf_ssh_channel_request_name
;
385 static int hf_ssh_channel_request_want_reply
;
386 static int hf_ssh_subsystem_name_len
;
387 static int hf_ssh_subsystem_name
;
388 static int hf_ssh_channel_window_adjust
;
389 static int hf_ssh_channel_data_len
;
390 static int hf_ssh_exit_status
;
391 static int hf_ssh_disconnect_reason
;
392 static int hf_ssh_disconnect_description_length
;
393 static int hf_ssh_disconnect_description
;
394 static int hf_ssh_lang_tag_length
;
395 static int hf_ssh_lang_tag
;
396 static int hf_ssh_ping_data_length
;
397 static int hf_ssh_ping_data
;
398 static int hf_ssh_pong_data_length
;
399 static int hf_ssh_pong_data
;
401 static int hf_ssh_blob_p
;
402 static int hf_ssh_blob_e
;
404 static int hf_ssh_pk_sig_s_length
;
405 static int hf_ssh_pk_sig_s
;
407 static int hf_ssh_reassembled_in
;
408 static int hf_ssh_reassembled_length
;
409 static int hf_ssh_reassembled_data
;
410 static int hf_ssh_segments
;
411 static int hf_ssh_segment
;
412 static int hf_ssh_segment_overlap
;
413 static int hf_ssh_segment_overlap_conflict
;
414 static int hf_ssh_segment_multiple_tails
;
415 static int hf_ssh_segment_too_long_fragment
;
416 static int hf_ssh_segment_error
;
417 static int hf_ssh_segment_count
;
418 static int hf_ssh_segment_data
;
421 static int ett_key_exchange
;
422 static int ett_key_exchange_host_key
;
423 static int ett_key_exchange_host_sig
;
424 static int ett_extension
;
425 static int ett_userauth_pk_blob
;
426 static int ett_userauth_pk_signautre
;
427 static int ett_key_init
;
430 static int ett_ssh_segments
;
431 static int ett_ssh_segment
;
433 static expert_field ei_ssh_packet_length
;
434 static expert_field ei_ssh_packet_decode
;
435 static expert_field ei_ssh_channel_number
;
436 static expert_field ei_ssh_invalid_keylen
;
437 static expert_field ei_ssh_mac_bad
;
439 static bool ssh_desegment
= true;
441 static dissector_handle_t ssh_handle
;
442 static dissector_handle_t sftp_handle
;
444 static const char *pref_keylog_file
;
445 static FILE *ssh_keylog_file
;
447 static reassembly_table ssh_reassembly_table
;
449 static const fragment_items ssh_segment_items
= {
454 &hf_ssh_segment_overlap
,
455 &hf_ssh_segment_overlap_conflict
,
456 &hf_ssh_segment_multiple_tails
,
457 &hf_ssh_segment_too_long_fragment
,
458 &hf_ssh_segment_error
,
459 &hf_ssh_segment_count
,
460 &hf_ssh_reassembled_in
,
461 &hf_ssh_reassembled_length
,
462 &hf_ssh_reassembled_data
,
466 #define SSH_DECRYPT_DEBUG
468 #ifdef SSH_DECRYPT_DEBUG
469 static const char *ssh_debug_file_name
;
472 #define TCP_RANGE_SSH "22"
473 #define SCTP_PORT_SSH 22
475 /* Message Numbers (from RFC 4250) (1-255) */
477 /* Transport layer protocol: generic (1-19) */
478 #define SSH_MSG_DISCONNECT 1
479 #define SSH_MSG_IGNORE 2
480 #define SSH_MSG_UNIMPLEMENTED 3
481 #define SSH_MSG_DEBUG 4
482 #define SSH_MSG_SERVICE_REQUEST 5
483 #define SSH_MSG_SERVICE_ACCEPT 6
484 #define SSH_MSG_EXT_INFO 7
485 #define SSH_MSG_NEWCOMPRESS 8
487 /* Transport layer protocol: Algorithm negotiation (20-29) */
488 #define SSH_MSG_KEXINIT 20
489 #define SSH_MSG_NEWKEYS 21
491 /* Transport layer: Key exchange method specific (reusable) (30-49) */
492 #define SSH_MSG_KEXDH_INIT 30
493 #define SSH_MSG_KEXDH_REPLY 31
495 #define SSH_MSG_KEX_DH_GEX_REQUEST_OLD 30
496 #define SSH_MSG_KEX_DH_GEX_GROUP 31
497 #define SSH_MSG_KEX_DH_GEX_INIT 32
498 #define SSH_MSG_KEX_DH_GEX_REPLY 33
499 #define SSH_MSG_KEX_DH_GEX_REQUEST 34
501 #define SSH_MSG_KEX_ECDH_INIT 30
502 #define SSH_MSG_KEX_ECDH_REPLY 31
504 /* User authentication protocol: generic (50-59) */
505 #define SSH_MSG_USERAUTH_REQUEST 50
506 #define SSH_MSG_USERAUTH_FAILURE 51
507 #define SSH_MSG_USERAUTH_SUCCESS 52
508 #define SSH_MSG_USERAUTH_BANNER 53
510 /* User authentication protocol: method specific (reusable) (50-79) */
511 #define SSH_MSG_USERAUTH_PK_OK 60
513 /* Connection protocol: generic (80-89) */
514 #define SSH_MSG_GLOBAL_REQUEST 80
515 #define SSH_MSG_REQUEST_SUCCESS 81
516 #define SSH_MSG_REQUEST_FAILURE 82
518 /* Connection protocol: channel related messages (90-127) */
519 #define SSH_MSG_CHANNEL_OPEN 90
520 #define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91
521 #define SSH_MSG_CHANNEL_OPEN_FAILURE 92
522 #define SSH_MSG_CHANNEL_WINDOW_ADJUST 93
523 #define SSH_MSG_CHANNEL_DATA 94
524 #define SSH_MSG_CHANNEL_EXTENDED_DATA 95
525 #define SSH_MSG_CHANNEL_EOF 96
526 #define SSH_MSG_CHANNEL_CLOSE 97
527 #define SSH_MSG_CHANNEL_REQUEST 98
528 #define SSH_MSG_CHANNEL_SUCCESS 99
529 #define SSH_MSG_CHANNEL_FAILURE 100
531 /* 128-191 reserved for client protocols */
532 /* 192-255 local extensions */
533 #define SSH_MSG_PING 192
534 #define SSH_MSG_PONG 193
536 #define CIPHER_AES128_CTR 0x00010001
537 #define CIPHER_AES192_CTR 0x00010003
538 #define CIPHER_AES256_CTR 0x00010004
539 #define CIPHER_AES128_CBC 0x00020001
540 #define CIPHER_AES192_CBC 0x00020002
541 #define CIPHER_AES256_CBC 0x00020004
542 #define CIPHER_AES128_GCM 0x00040001
543 //#define CIPHER_AES192_GCM 0x00040002 -- does not exist
544 #define CIPHER_AES256_GCM 0x00040004
546 #define CIPHER_MAC_SHA2_256 0x00020001
548 static const value_string ssh_direction_vals
[] = {
549 { CLIENT_TO_SERVER_PROPOSAL
, "client-to-server" },
550 { SERVER_TO_CLIENT_PROPOSAL
, "server-to-client" },
554 static const value_string ssh2_msg_vals
[] = {
555 { SSH_MSG_DISCONNECT
, "Disconnect" },
556 { SSH_MSG_IGNORE
, "Ignore" },
557 { SSH_MSG_UNIMPLEMENTED
, "Unimplemented" },
558 { SSH_MSG_DEBUG
, "Debug" },
559 { SSH_MSG_SERVICE_REQUEST
, "Service Request" },
560 { SSH_MSG_SERVICE_ACCEPT
, "Service Accept" },
561 { SSH_MSG_EXT_INFO
, "Extension Information" },
562 { SSH_MSG_NEWCOMPRESS
, "New Compression" },
563 { SSH_MSG_KEXINIT
, "Key Exchange Init" },
564 { SSH_MSG_NEWKEYS
, "New Keys" },
565 { SSH_MSG_USERAUTH_REQUEST
, "User Authentication Request" },
566 { SSH_MSG_USERAUTH_FAILURE
, "User Authentication Failure" },
567 { SSH_MSG_USERAUTH_SUCCESS
, "User Authentication Success" },
568 { SSH_MSG_USERAUTH_BANNER
, "User Authentication Banner" },
569 { SSH_MSG_GLOBAL_REQUEST
, "Global Request" },
570 { SSH_MSG_REQUEST_SUCCESS
, "Request Success" },
571 { SSH_MSG_REQUEST_FAILURE
, "Request Failure" },
572 { SSH_MSG_CHANNEL_OPEN
, "Channel Open" },
573 { SSH_MSG_CHANNEL_OPEN_CONFIRMATION
, "Channel Open Confirmation" },
574 { SSH_MSG_CHANNEL_OPEN_FAILURE
, "Channel Open Failure" },
575 { SSH_MSG_CHANNEL_WINDOW_ADJUST
, "Window Adjust" },
576 { SSH_MSG_CHANNEL_DATA
, "Channel Data" },
577 { SSH_MSG_CHANNEL_EXTENDED_DATA
, "Channel Extended Data" },
578 { SSH_MSG_CHANNEL_EOF
, "Channel EOF" },
579 { SSH_MSG_CHANNEL_CLOSE
, "Channel Close" },
580 { SSH_MSG_CHANNEL_REQUEST
, "Channel Request" },
581 { SSH_MSG_CHANNEL_SUCCESS
, "Channel Success" },
582 { SSH_MSG_CHANNEL_FAILURE
, "Channel Failure" },
583 { SSH_MSG_USERAUTH_PK_OK
, "Public Key algorithm accepted" },
587 static const value_string ssh2_kex_dh_msg_vals
[] = {
588 { SSH_MSG_KEXDH_INIT
, "Diffie-Hellman Key Exchange Init" },
589 { SSH_MSG_KEXDH_REPLY
, "Diffie-Hellman Key Exchange Reply" },
593 static const value_string ssh2_kex_dh_gex_msg_vals
[] = {
594 { SSH_MSG_KEX_DH_GEX_REQUEST_OLD
, "Diffie-Hellman Group Exchange Request (Old)" },
595 { SSH_MSG_KEX_DH_GEX_GROUP
, "Diffie-Hellman Group Exchange Group" },
596 { SSH_MSG_KEX_DH_GEX_INIT
, "Diffie-Hellman Group Exchange Init" },
597 { SSH_MSG_KEX_DH_GEX_REPLY
, "Diffie-Hellman Group Exchange Reply" },
598 { SSH_MSG_KEX_DH_GEX_REQUEST
, "Diffie-Hellman Group Exchange Request" },
602 static const value_string ssh2_kex_ecdh_msg_vals
[] = {
603 { SSH_MSG_KEX_ECDH_INIT
, "Elliptic Curve Diffie-Hellman Key Exchange Init" },
604 { SSH_MSG_KEX_ECDH_REPLY
, "Elliptic Curve Diffie-Hellman Key Exchange Reply" },
608 static const value_string ssh2_ext_ping_msg_vals
[] = {
609 { SSH_MSG_PING
, "Ping" },
610 { SSH_MSG_PONG
, "Pong" },
614 static const value_string ssh1_msg_vals
[] = {
615 {SSH1_MSG_NONE
, "No Message"},
616 {SSH1_MSG_DISCONNECT
, "Disconnect"},
617 {SSH1_SMSG_PUBLIC_KEY
, "Public Key"},
618 {SSH1_CMSG_SESSION_KEY
, "Session Key"},
619 {SSH1_CMSG_USER
, "User"},
623 static int ssh_dissect_key_init(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
,
625 struct ssh_flow_data
*global_data
);
626 static int ssh_dissect_proposal(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
,
627 int hf_index_length
, int hf_index_value
, char **store
);
628 static int ssh_dissect_ssh1(tvbuff_t
*tvb
, packet_info
*pinfo
,
629 struct ssh_flow_data
*global_data
,
630 int offset
, proto_tree
*tree
, int is_response
,
631 bool *need_desegmentation
);
632 static int ssh_dissect_ssh2(tvbuff_t
*tvb
, packet_info
*pinfo
,
633 struct ssh_flow_data
*global_data
,
634 int offset
, proto_tree
*tree
, int is_response
,
635 bool *need_desegmentation
);
636 static int ssh_dissect_key_exchange(tvbuff_t
*tvb
, packet_info
*pinfo
,
637 struct ssh_flow_data
*global_data
,
638 int offset
, proto_tree
*tree
, int is_response
,
639 bool *need_desegmentation
);
640 static int ssh_dissect_kex_dh(uint8_t msg_code
, tvbuff_t
*tvb
,
641 packet_info
*pinfo
, int offset
, proto_tree
*tree
,
642 struct ssh_flow_data
*global_data
, unsigned *seq_num
);
643 static int ssh_dissect_kex_dh_gex(uint8_t msg_code
, tvbuff_t
*tvb
,
644 packet_info
*pinfo
, int offset
, proto_tree
*tree
,
645 struct ssh_flow_data
*global_data
, unsigned *seq_num
);
646 static int ssh_dissect_kex_ecdh(uint8_t msg_code
, tvbuff_t
*tvb
,
647 packet_info
*pinfo
, int offset
, proto_tree
*tree
,
648 struct ssh_flow_data
*global_data
, unsigned *seq_num
);
649 static int ssh_dissect_protocol(tvbuff_t
*tvb
, packet_info
*pinfo
,
650 struct ssh_flow_data
*global_data
,
651 int offset
, proto_tree
*tree
, int is_response
, unsigned *version
,
652 bool *need_desegmentation
);
653 static int ssh_try_dissect_encrypted_packet(tvbuff_t
*tvb
, packet_info
*pinfo
,
654 struct ssh_peer_data
*peer_data
, int offset
, proto_tree
*tree
);
655 static int ssh_dissect_encrypted_packet(tvbuff_t
*tvb
, packet_info
*pinfo
,
656 struct ssh_peer_data
*peer_data
,
657 int offset
, proto_tree
*tree
);
658 static void ssh_choose_algo(char *client
, char *server
, char **result
);
659 static void ssh_set_mac_length(struct ssh_peer_data
*peer_data
);
660 static void ssh_set_kex_specific_dissector(struct ssh_flow_data
*global_data
);
662 static void ssh_keylog_read_file(void);
663 static void ssh_keylog_process_line(const char *line
);
664 static void ssh_keylog_process_lines(const uint8_t *data
, unsigned datalen
);
665 static void ssh_keylog_reset(void);
666 static ssh_bignum
*ssh_kex_make_bignum(const uint8_t *data
, unsigned length
);
667 static bool ssh_read_e(tvbuff_t
*tvb
, int offset
,
668 struct ssh_flow_data
*global_data
);
669 static bool ssh_read_f(tvbuff_t
*tvb
, int offset
,
670 struct ssh_flow_data
*global_data
);
671 static ssh_bignum
* ssh_read_mpint(tvbuff_t
*tvb
, int offset
);
672 static void ssh_keylog_hash_write_secret(struct ssh_flow_data
*global_data
);
673 static ssh_bignum
*ssh_kex_shared_secret(int kex_type
, ssh_bignum
*pub
, ssh_bignum
*priv
, ssh_bignum
*modulo
);
674 static void ssh_hash_buffer_put_string(wmem_array_t
*buffer
, const char *string
,
676 static void ssh_hash_buffer_put_uint32(wmem_array_t
*buffer
, unsigned val
);
677 static char *ssh_string(const char *string
, unsigned len
);
678 static void ssh_derive_symmetric_keys(ssh_bignum
*shared_secret
,
679 char *exchange_hash
, unsigned hash_length
,
680 struct ssh_flow_data
*global_data
);
681 static void ssh_derive_symmetric_key(ssh_bignum
*shared_secret
,
682 char *exchange_hash
, unsigned hash_length
, char id
,
683 ssh_bignum
*result_key
, struct ssh_flow_data
*global_data
, unsigned we_need
);
685 static void ssh_choose_enc_mac(struct ssh_flow_data
*global_data
);
686 static void ssh_decryption_set_cipher_id(struct ssh_peer_data
*peer
);
687 static void ssh_decryption_setup_cipher(struct ssh_peer_data
*peer
,
688 ssh_bignum
*iv
, ssh_bignum
*key
);
689 static void ssh_decryption_set_mac_id(struct ssh_peer_data
*peer
);
690 static void ssh_decryption_setup_mac(struct ssh_peer_data
*peer
,
692 static void ssh_increment_message_number(packet_info
*pinfo
,
693 struct ssh_flow_data
*global_data
, bool is_response
);
694 static unsigned ssh_decrypt_packet(tvbuff_t
*tvb
, packet_info
*pinfo
,
695 struct ssh_peer_data
*peer_data
, int offset
);
696 static bool ssh_decrypt_chacha20(gcry_cipher_hd_t hd
, uint32_t seqnr
,
697 uint32_t counter
, const unsigned char *ctext
, unsigned ctext_len
,
698 unsigned char *plain
, unsigned plain_len
);
699 static proto_item
* ssh_tree_add_mac(proto_tree
*tree
, tvbuff_t
*tvb
, const unsigned offset
, const unsigned mac_len
,
700 const int hf_mac
, const int hf_mac_status
, struct expert_field
* bad_checksum_expert
,
701 packet_info
*pinfo
, const uint8_t * calc_mac
, const unsigned flags
);
703 static int ssh_dissect_decrypted_packet(tvbuff_t
*tvb
, packet_info
*pinfo
,
704 struct ssh_peer_data
*peer_data
, proto_tree
*tree
,
705 ssh_message_info_t
*message
);
706 static int ssh_dissect_transport_generic(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
707 int offset
, struct ssh_peer_data
*peer_data
, proto_item
*msg_type_tree
, unsigned msg_code
);
708 static int ssh_dissect_rfc8308_extension(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
709 int offset
, struct ssh_peer_data
*peer_data
, proto_item
*msg_type_tree
);
710 static int ssh_dissect_userauth_generic(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
711 int offset
, proto_item
*msg_type_tree
, unsigned msg_code
);
712 static int ssh_dissect_userauth_specific(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
713 int offset
, proto_item
*msg_type_tree
, unsigned msg_code
);
714 static int ssh_dissect_connection_specific(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
715 struct ssh_peer_data
*peer_data
, int offset
, proto_item
*msg_type_tree
,
716 unsigned msg_code
, ssh_message_info_t
*message
);
717 static int ssh_dissect_connection_generic(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
718 int offset
, proto_item
*msg_type_tree
, unsigned msg_code
);
719 static int ssh_dissect_local_extension(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
720 int offset
, struct ssh_peer_data
*peer_data
, proto_item
*msg_type_tree
, unsigned msg_code
);
721 static int ssh_dissect_public_key_blob(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
722 int offset
, proto_item
*msg_type_tree
);
723 static int ssh_dissect_public_key_signature(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
724 int offset
, proto_item
*msg_type_tree
);
726 static void create_channel(struct ssh_peer_data
*peer_data
, uint32_t recipient_channel
, uint32_t sender_channel
);
727 static ssh_channel_info_t
* get_channel_info_for_channel(struct ssh_peer_data
*peer_data
, uint32_t recipient_channel
);
728 static void set_subdissector_for_channel(struct ssh_peer_data
*peer_data
, uint32_t recipient_channel
, const uint8_t* subsystem_name
);
730 #define SSH_DEBUG_USE_STDERR "-"
732 #ifdef SSH_DECRYPT_DEBUG
734 ssh_debug_printf(const char* fmt
,...) G_GNUC_PRINTF(1,2);
736 ssh_print_data(const char* name
, const unsigned char* data
, size_t len
);
738 ssh_set_debug(const char* name
);
740 ssh_debug_flush(void);
743 /* No debug: nullify debug operation*/
744 static inline void G_GNUC_PRINTF(1,2)
745 ssh_debug_printf(const char* fmt _U_
,...)
748 #define ssh_print_data(a, b, c)
749 #define ssh_print_string(a, b)
750 #define ssh_set_debug(name)
751 #define ssh_debug_flush()
753 #endif /* SSH_DECRYPT_DEBUG */
756 dissect_ssh(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
758 proto_tree
*ssh_tree
;
760 conversation_t
*conversation
;
761 int last_offset
, offset
= 0;
763 bool is_response
= (pinfo
->destport
!= pinfo
->match_uint
),
767 struct ssh_flow_data
*global_data
= NULL
;
768 struct ssh_peer_data
*peer_data
;
770 ssh_debug_printf("\ndissect_ssh enter frame #%u (%s)\n", pinfo
->num
, (pinfo
->fd
->visited
)?"already visited":"first time");
772 conversation
= find_or_create_conversation(pinfo
);
774 global_data
= (struct ssh_flow_data
*)conversation_get_proto_data(conversation
, proto_ssh
);
776 global_data
= wmem_new0(wmem_file_scope(), struct ssh_flow_data
);
777 global_data
->version
= SSH_VERSION_UNKNOWN
;
778 global_data
->kex_specific_dissector
= ssh_dissect_kex_dh
;
779 global_data
->peer_data
[CLIENT_PEER_DATA
].mac_length
= -1;
780 global_data
->peer_data
[SERVER_PEER_DATA
].mac_length
= -1;
781 global_data
->peer_data
[CLIENT_PEER_DATA
].sequence_number
= 0;
782 global_data
->peer_data
[SERVER_PEER_DATA
].sequence_number
= 0;
783 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_kex_init
= 0;
784 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_kex_init
= 0;
785 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_gex_req
= 0;
786 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_gex_req
= 0;
787 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_gex_grp
= 0;
788 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_gex_grp
= 0;
789 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_gex_ini
= 0;
790 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_gex_ini
= 0;
791 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_gex_rep
= 0;
792 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_gex_rep
= 0;
793 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_ecdh_ini
= 0;
794 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_ecdh_ini
= 0;
795 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_ecdh_rep
= 0;
796 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_ecdh_rep
= 0;
797 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_dh_ini
= 0;
798 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_dh_ini
= 0;
799 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_dh_rep
= 0;
800 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_dh_rep
= 0;
801 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_new_key
= 0;
802 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_new_key
= 0;
803 global_data
->peer_data
[CLIENT_PEER_DATA
].bn_cookie
= NULL
;
804 global_data
->peer_data
[SERVER_PEER_DATA
].bn_cookie
= NULL
;
805 global_data
->peer_data
[CLIENT_PEER_DATA
].global_data
= global_data
;
806 global_data
->peer_data
[SERVER_PEER_DATA
].global_data
= global_data
;
807 global_data
->kex_client_version
= wmem_array_new(wmem_file_scope(), 1);
808 global_data
->kex_server_version
= wmem_array_new(wmem_file_scope(), 1);
809 global_data
->kex_client_key_exchange_init
= wmem_array_new(wmem_file_scope(), 1);
810 global_data
->kex_server_key_exchange_init
= wmem_array_new(wmem_file_scope(), 1);
811 global_data
->kex_server_host_key_blob
= wmem_array_new(wmem_file_scope(), 1);
812 global_data
->kex_gex_bits_min
= wmem_array_new(wmem_file_scope(), 1);
813 global_data
->kex_gex_bits_req
= wmem_array_new(wmem_file_scope(), 1);
814 global_data
->kex_gex_bits_max
= wmem_array_new(wmem_file_scope(), 1);
815 global_data
->kex_shared_secret
= wmem_array_new(wmem_file_scope(), 1);
816 global_data
->do_decrypt
= true;
817 global_data
->ext_ping_openssh_offered
= false;
819 conversation_add_proto_data(conversation
, proto_ssh
, global_data
);
822 peer_data
= &global_data
->peer_data
[is_response
];
824 ti
= proto_tree_add_item(tree
, proto_ssh
, tvb
, offset
, -1, ENC_NA
);
825 ssh_tree
= proto_item_add_subtree(ti
, ett_ssh
);
827 version
= global_data
->version
;
830 case SSH_VERSION_UNKNOWN
:
831 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "SSH");
834 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "SSHv1");
837 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "SSHv2");
842 col_clear(pinfo
->cinfo
, COL_INFO
);
844 while(tvb_reported_length_remaining(tvb
, offset
)> 0) {
845 bool after_version_start
= (peer_data
->frame_version_start
== 0 ||
846 pinfo
->num
>= peer_data
->frame_version_start
);
847 bool before_version_end
= (peer_data
->frame_version_end
== 0 ||
848 pinfo
->num
<= peer_data
->frame_version_end
);
850 need_desegmentation
= false;
851 last_offset
= offset
;
853 peer_data
->counter
++;
855 if (after_version_start
&& before_version_end
&&
856 (tvb_strncaseeql(tvb
, offset
, "SSH-", 4) == 0)) {
857 if (peer_data
->frame_version_start
== 0)
858 peer_data
->frame_version_start
= pinfo
->num
;
860 offset
= ssh_dissect_protocol(tvb
, pinfo
,
862 offset
, ssh_tree
, is_response
,
863 &version
, &need_desegmentation
);
865 if (!need_desegmentation
) {
866 peer_data
->frame_version_end
= pinfo
->num
;
867 global_data
->version
= version
;
872 case SSH_VERSION_UNKNOWN
:
873 offset
= ssh_try_dissect_encrypted_packet(tvb
, pinfo
,
874 &global_data
->peer_data
[is_response
], offset
, ssh_tree
);
878 offset
= ssh_dissect_ssh1(tvb
, pinfo
, global_data
,
879 offset
, ssh_tree
, is_response
,
880 &need_desegmentation
);
884 offset
= ssh_dissect_ssh2(tvb
, pinfo
, global_data
,
885 offset
, ssh_tree
, is_response
,
886 &need_desegmentation
);
891 if (need_desegmentation
)
892 return tvb_captured_length(tvb
);
893 if (offset
<= last_offset
) {
894 /* XXX - add an expert info in the function
895 that decrements offset */
900 col_prepend_fstr(pinfo
->cinfo
, COL_INFO
, "%s: ", is_response
? "Server" : "Client");
901 ti
= proto_tree_add_boolean_format_value(ssh_tree
, hf_ssh_direction
, tvb
, 0, 0, is_response
, "%s",
902 try_val_to_str(is_response
, ssh_direction_vals
));
903 proto_item_set_generated(ti
);
907 return tvb_captured_length(tvb
);
911 ssh_dissect_ssh2(tvbuff_t
*tvb
, packet_info
*pinfo
,
912 struct ssh_flow_data
*global_data
,
913 int offset
, proto_tree
*tree
, int is_response
,
914 bool *need_desegmentation
)
916 proto_item
*ssh2_tree
= NULL
;
919 struct ssh_peer_data
*peer_data
= &global_data
->peer_data
[is_response
];
921 remain_length
= tvb_captured_length_remaining(tvb
, offset
);
923 while(remain_length
>0){
924 int last_offset
= offset
;
926 wmem_strbuf_t
*title
= wmem_strbuf_new(pinfo
->pool
, "SSH Version 2");
928 if (peer_data
->enc
|| peer_data
->mac
|| peer_data
->comp
) {
929 wmem_strbuf_append_printf(title
, " (");
931 wmem_strbuf_append_printf(title
, "encryption:%s%s",
933 peer_data
->mac
|| peer_data
->comp
936 wmem_strbuf_append_printf(title
, "mac:%s%s",
938 peer_data
->comp
? " " : "");
940 wmem_strbuf_append_printf(title
, "compression:%s",
942 wmem_strbuf_append_printf(title
, ")");
945 ssh2_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1, ett_ssh2
, NULL
, wmem_strbuf_get_str(title
));
947 ws_noisy("....ssh_dissect_ssh2[%c]: frame_key_start=%d, pinfo->num=%d, frame_key_end=%d, offset=%d, frame_key_end_offset=%d ", is_response
==SERVER_PEER_DATA
?'S':'C', peer_data
->frame_key_start
, pinfo
->num
, peer_data
->frame_key_end
, offset
, peer_data
->frame_key_end_offset
);
948 if ((peer_data
->frame_key_start
== 0) ||
949 ((peer_data
->frame_key_start
<= pinfo
->num
) &&
950 ((peer_data
->frame_key_end
== 0) || (pinfo
->num
< peer_data
->frame_key_end
) ||
951 ((pinfo
->num
== peer_data
->frame_key_end
) && (offset
< peer_data
->frame_key_end_offset
))))) {
952 offset
= ssh_dissect_key_exchange(tvb
, pinfo
, global_data
,
953 offset
, ssh2_tree
, is_response
,
954 need_desegmentation
);
956 if (!*need_desegmentation
) {
957 ssh_increment_message_number(pinfo
, global_data
, is_response
);
962 if(!*need_desegmentation
){
963 offset
= ssh_try_dissect_encrypted_packet(tvb
, pinfo
,
964 &global_data
->peer_data
[is_response
], offset
, ssh2_tree
);
971 proto_item_set_len(ssh2_tree
, offset
- last_offset
);
974 remain_length
= tvb_captured_length_remaining(tvb
, offset
);
980 ssh_dissect_ssh1(tvbuff_t
*tvb
, packet_info
*pinfo
,
981 struct ssh_flow_data
*global_data
,
982 int offset
, proto_tree
*tree
, int is_response
,
983 bool *need_desegmentation
)
985 unsigned plen
, padding_length
, len
;
987 unsigned remain_length
;
989 proto_item
*ssh1_tree
;
991 struct ssh_peer_data
*peer_data
= &global_data
->peer_data
[is_response
];
993 ssh1_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1, ett_ssh1
, NULL
, "SSH Version 1");
996 * We use "tvb_ensure_captured_length_remaining()" to make sure there
997 * actually *is* data remaining.
999 * This means we're guaranteed that "remain_length" is positive.
1001 remain_length
= tvb_ensure_captured_length_remaining(tvb
, offset
);
1003 * Can we do reassembly?
1005 if (ssh_desegment
&& pinfo
->can_desegment
) {
1007 * Yes - would an SSH header starting at this offset be split
1008 * across segment boundaries?
1010 if (remain_length
< 4) {
1012 * Yes. Tell the TCP dissector where the data for
1013 * this message starts in the data it handed us and
1014 * that we need "some more data." Don't tell it
1015 * exactly how many bytes we need because if/when we
1016 * ask for even more (after the header) that will
1019 pinfo
->desegment_offset
= offset
;
1020 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
1021 *need_desegmentation
= true;
1025 plen
= tvb_get_ntohl(tvb
, offset
) ;
1026 padding_length
= 8 - plen
%8;
1029 if (ssh_desegment
&& pinfo
->can_desegment
) {
1030 if (plen
+4+padding_length
> remain_length
) {
1031 pinfo
->desegment_offset
= offset
;
1032 pinfo
->desegment_len
= plen
+padding_length
- remain_length
;
1033 *need_desegmentation
= true;
1038 if (plen
>= 0xffff) {
1039 if (ssh1_tree
&& plen
> 0) {
1040 proto_tree_add_uint_format(ssh1_tree
, hf_ssh_packet_length
, tvb
,
1041 offset
, 4, plen
, "Overly large length %x", plen
);
1043 plen
= remain_length
-4-padding_length
;
1045 if (ssh1_tree
&& plen
> 0) {
1046 proto_tree_add_uint(ssh1_tree
, hf_ssh_packet_length
, tvb
,
1051 /* padding length */
1053 proto_tree_add_uint(ssh1_tree
, hf_ssh_padding_length
, tvb
,
1054 offset
, padding_length
, padding_length
);
1055 offset
+= padding_length
;
1058 if ((peer_data
->frame_key_start
== 0) ||
1059 ((peer_data
->frame_key_start
>= pinfo
->num
) && (pinfo
->num
<= peer_data
->frame_key_end
))) {
1060 msg_code
= tvb_get_uint8(tvb
, offset
);
1062 proto_tree_add_item(ssh1_tree
, hf_ssh_msg_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1063 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
,
1064 val_to_str(msg_code
, ssh1_msg_vals
, "Unknown (%u)"));
1067 if (!pinfo
->fd
->visited
) {
1068 if (peer_data
->frame_key_start
== 0)
1069 peer_data
->frame_key_start
= pinfo
->num
;
1070 peer_data
->frame_key_end
= pinfo
->num
;
1074 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "Encrypted packet (len=%d)", len
);
1078 proto_tree_add_item(ssh1_tree
, hf_ssh_payload
,
1079 tvb
, offset
, len
, ENC_NA
);
1087 ssh_tree_add_mpint(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
,
1088 int hf_ssh_mpint_selection
)
1090 unsigned len
= tvb_get_ntohl(tvb
, offset
);
1091 proto_tree_add_uint(tree
, hf_ssh_mpint_length
, tvb
,
1094 proto_tree_add_item(tree
, hf_ssh_mpint_selection
,
1095 tvb
, offset
, len
, ENC_NA
);
1100 ssh_tree_add_string(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
,
1101 int hf_ssh_string
, int hf_ssh_string_length
)
1103 unsigned len
= tvb_get_ntohl(tvb
, offset
);
1104 proto_tree_add_uint(tree
, hf_ssh_string_length
, tvb
,
1107 proto_tree_add_item(tree
, hf_ssh_string
,
1108 tvb
, offset
, len
, ENC_NA
);
1113 ssh_tree_add_hostkey(tvbuff_t
*tvb
, int offset
, proto_tree
*parent_tree
,
1114 const char *tree_name
, int ett_idx
,
1115 struct ssh_flow_data
*global_data
)
1117 proto_tree
*tree
= NULL
;
1120 unsigned key_len
, type_len
;
1124 last_offset
= offset
;
1126 key_len
= tvb_get_ntohl(tvb
, offset
);
1129 /* Read the key type before creating the tree so we can append it as info. */
1130 type_len
= tvb_get_ntohl(tvb
, offset
);
1132 key_type
= (char *) tvb_get_string_enc(wmem_packet_scope(), tvb
, offset
, type_len
, ENC_ASCII
|ENC_NA
);
1134 tree_title
= wmem_strdup_printf(wmem_packet_scope(), "%s (type: %s)", tree_name
, key_type
);
1135 tree
= proto_tree_add_subtree(parent_tree
, tvb
, last_offset
, key_len
+ 4, ett_idx
, NULL
,
1138 proto_tree_add_uint(tree
, hf_ssh_hostkey_length
, tvb
, last_offset
, 4, key_len
);
1140 // server host key (K_S / Q)
1141 char *data
= (char *)tvb_memdup(wmem_packet_scope(), tvb
, last_offset
+ 4, key_len
);
1142 ssh_hash_buffer_put_string(global_data
->kex_server_host_key_blob
, data
, key_len
);
1145 proto_tree_add_uint(tree
, hf_ssh_hostkey_type_length
, tvb
, last_offset
, 4, type_len
);
1146 proto_tree_add_string(tree
, hf_ssh_hostkey_type
, tvb
, offset
, type_len
, key_type
);
1149 if (0 == strcmp(key_type
, "ssh-rsa")) {
1150 offset
+= ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_hostkey_rsa_e
);
1151 ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_hostkey_rsa_n
);
1152 } else if (0 == strcmp(key_type
, "ssh-dss")) {
1153 offset
+= ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_hostkey_dsa_p
);
1154 offset
+= ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_hostkey_dsa_q
);
1155 offset
+= ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_hostkey_dsa_g
);
1156 ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_hostkey_dsa_y
);
1157 } else if (g_str_has_prefix(key_type
, "ecdsa-sha2-")) {
1158 offset
+= ssh_tree_add_string(tvb
, offset
, tree
,
1159 hf_ssh_hostkey_ecdsa_curve_id
, hf_ssh_hostkey_ecdsa_curve_id_length
);
1160 ssh_tree_add_string(tvb
, offset
, tree
,
1161 hf_ssh_hostkey_ecdsa_q
, hf_ssh_hostkey_ecdsa_q_length
);
1162 } else if (g_str_has_prefix(key_type
, "ssh-ed")) {
1163 ssh_tree_add_string(tvb
, offset
, tree
,
1164 hf_ssh_hostkey_eddsa_key
, hf_ssh_hostkey_eddsa_key_length
);
1166 remaining_len
= key_len
- (type_len
+ 4);
1167 proto_tree_add_item(tree
, hf_ssh_hostkey_data
, tvb
, offset
, remaining_len
, ENC_NA
);
1174 ssh_tree_add_hostsignature(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*parent_tree
,
1175 const char *tree_name
, int ett_idx
,
1176 struct ssh_flow_data
*global_data
)
1179 proto_tree
*tree
= NULL
;
1180 proto_item
* ti
= NULL
;
1182 int offset0
= offset
;
1184 unsigned sig_len
, type_len
;
1188 last_offset
= offset
;
1190 sig_len
= tvb_get_ntohl(tvb
, offset
);
1193 /* Read the signature type before creating the tree so we can append it as info. */
1194 type_len
= tvb_get_ntohl(tvb
, offset
);
1196 sig_type
= tvb_get_string_enc(pinfo
->pool
, tvb
, offset
, type_len
, ENC_ASCII
|ENC_NA
);
1198 tree_title
= wmem_strdup_printf(pinfo
->pool
, "%s (type: %s)", tree_name
, sig_type
);
1199 tree
= proto_tree_add_subtree(parent_tree
, tvb
, last_offset
, sig_len
+ 4, ett_idx
, NULL
,
1202 ti
= proto_tree_add_uint(tree
, hf_ssh_hostsig_length
, tvb
, last_offset
, 4, sig_len
);
1205 proto_tree_add_uint(tree
, hf_ssh_hostsig_type_length
, tvb
, last_offset
, 4, type_len
);
1206 proto_tree_add_string(tree
, hf_ssh_hostsig_type
, tvb
, offset
, type_len
, sig_type
);
1209 if (0 == strcmp(sig_type
, "ssh-rsa")) {
1210 offset
+= ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_hostsig_rsa
);
1211 } else if (0 == strcmp(sig_type
, "ssh-dss")) {
1212 offset
+= ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_hostsig_dsa
);
1213 // } else if (g_str_has_prefix(sig_type, "ecdsa-sha2-")) {
1214 // offset += ssh_tree_add_string(tvb, offset, tree,
1215 // hf_ssh_hostkey_ecdsa_curve_id, hf_ssh_hostkey_ecdsa_curve_id_length);
1216 // ssh_tree_add_string(tvb, offset, tree,
1217 // hf_ssh_hostkey_ecdsa_q, hf_ssh_hostkey_ecdsa_q_length);
1218 // } else if (g_str_has_prefix(sig_type, "ssh-ed")) {
1219 // ssh_tree_add_string(tvb, offset, tree,
1220 // hf_ssh_hostkey_eddsa_key, hf_ssh_hostkey_eddsa_key_length);
1222 remaining_len
= sig_len
- (type_len
+ 4);
1223 proto_tree_add_item(tree
, hf_ssh_hostsig_data
, tvb
, offset
, remaining_len
, ENC_NA
);
1224 offset
+= remaining_len
;
1227 if(offset
-offset0
!=(int)(4+sig_len
)){
1228 expert_add_info_format(pinfo
, ti
, &ei_ssh_packet_decode
, "Decoded %d bytes, but packet length is %d bytes", offset
-offset0
, sig_len
);
1235 ssh_dissect_key_exchange(tvbuff_t
*tvb
, packet_info
*pinfo
,
1236 struct ssh_flow_data
*global_data
,
1237 int offset
, proto_tree
*tree
, int is_response
,
1238 bool *need_desegmentation
)
1241 uint8_t padding_length
;
1242 unsigned remain_length
;
1243 int last_offset
= offset
;
1245 unsigned seq_num
= 0;
1248 proto_item
*key_ex_tree
= NULL
;
1249 const char *key_ex_title
= "Key Exchange";
1251 struct ssh_peer_data
*peer_data
= &global_data
->peer_data
[is_response
];
1254 * We use "tvb_ensure_captured_length_remaining()" to make sure there
1255 * actually *is* data remaining.
1257 * This means we're guaranteed that "remain_length" is positive.
1259 remain_length
= tvb_ensure_captured_length_remaining(tvb
, offset
);
1261 * Can we do reassembly?
1263 if (ssh_desegment
&& pinfo
->can_desegment
) {
1265 * Yes - would an SSH header starting at this offset
1266 * be split across segment boundaries?
1268 if (remain_length
< 4) {
1270 * Yes. Tell the TCP dissector where the data for
1271 * this message starts in the data it handed us and
1272 * that we need "some more data." Don't tell it
1273 * exactly how many bytes we need because if/when we
1274 * ask for even more (after the header) that will
1277 pinfo
->desegment_offset
= offset
;
1278 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
1279 *need_desegmentation
= true;
1283 plen
= tvb_get_ntohl(tvb
, offset
) ;
1285 if (ssh_desegment
&& pinfo
->can_desegment
) {
1286 if (plen
+4 > remain_length
) {
1287 pinfo
->desegment_offset
= offset
;
1288 pinfo
->desegment_len
= plen
+4 - remain_length
;
1289 *need_desegmentation
= true;
1294 * Need to check plen > 0x80000000 here
1297 ti
= proto_tree_add_uint(tree
, hf_ssh_packet_length
, tvb
,
1299 if (plen
>= 0xffff) {
1300 expert_add_info_format(pinfo
, ti
, &ei_ssh_packet_length
, "Overly large number %d", plen
);
1301 plen
= remain_length
-4;
1305 /* padding length */
1306 padding_length
= tvb_get_uint8(tvb
, offset
);
1307 proto_tree_add_uint(tree
, hf_ssh_padding_length
, tvb
, offset
, 1, padding_length
);
1310 if (global_data
->kex
)
1311 key_ex_title
= wmem_strdup_printf(pinfo
->pool
, "%s (method:%s)", key_ex_title
, global_data
->kex
);
1312 key_ex_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, plen
-1, ett_key_exchange
, NULL
, key_ex_title
);
1315 msg_code
= tvb_get_uint8(tvb
, offset
);
1317 if (msg_code
>= 30 && msg_code
< 40) {
1318 offset
= global_data
->kex_specific_dissector(msg_code
, tvb
, pinfo
,
1319 offset
, key_ex_tree
, global_data
, &seq_num
);
1321 proto_tree_add_item(key_ex_tree
, hf_ssh2_msg_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1324 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
,
1325 val_to_str(msg_code
, ssh2_msg_vals
, "Unknown (%u)"));
1327 /* 16 bytes cookie */
1330 case SSH_MSG_KEXINIT
:
1331 offset
= ssh_dissect_key_init(tvb
, pinfo
, offset
, key_ex_tree
, is_response
, global_data
);
1332 if ((peer_data
->frame_key_start
== 0) || (peer_data
->frame_key_start
== pinfo
->num
)) {
1333 if (!PINFO_FD_VISITED(pinfo
)) {
1334 peer_data
->frame_key_start
= pinfo
->num
;
1335 if(global_data
->peer_data
[is_response
].seq_num_kex_init
== 0){
1336 global_data
->peer_data
[is_response
].seq_num_kex_init
= global_data
->peer_data
[is_response
].sequence_number
;
1337 global_data
->peer_data
[is_response
].sequence_number
++;
1338 ssh_debug_printf("%s->sequence_number{SSH_MSG_KEXINIT=%d}++ > %d\n", is_response
?"server":"client", global_data
->peer_data
[is_response
].seq_num_kex_init
, global_data
->peer_data
[is_response
].sequence_number
);
1342 seq_num
= global_data
->peer_data
[is_response
].seq_num_kex_init
;
1344 case SSH_MSG_NEWKEYS
:
1345 if (peer_data
->frame_key_end
== 0) {
1346 peer_data
->frame_key_end
= pinfo
->num
;
1347 peer_data
->frame_key_end_offset
= offset
;
1349 if(global_data
->peer_data
[is_response
].seq_num_new_key
== 0){
1350 global_data
->peer_data
[is_response
].seq_num_new_key
= global_data
->peer_data
[is_response
].sequence_number
;
1351 global_data
->peer_data
[is_response
].sequence_number
++;
1352 ssh_debug_printf("%s->sequence_number{SSH_MSG_NEWKEYS=%d}++ > %d\n", is_response
?"server":"client", global_data
->peer_data
[is_response
].seq_num_new_key
, global_data
->peer_data
[is_response
].sequence_number
);
1355 // the client sent SSH_MSG_NEWKEYS
1357 ssh_debug_printf("Activating new keys for CLIENT => SERVER\n");
1358 ssh_decryption_setup_cipher(&global_data
->peer_data
[CLIENT_PEER_DATA
], &global_data
->new_keys
[0], &global_data
->new_keys
[2]);
1359 ssh_decryption_setup_mac(&global_data
->peer_data
[CLIENT_PEER_DATA
], &global_data
->new_keys
[4]);
1361 ssh_debug_printf("Activating new keys for SERVER => CLIENT\n");
1362 ssh_decryption_setup_cipher(&global_data
->peer_data
[SERVER_PEER_DATA
], &global_data
->new_keys
[1], &global_data
->new_keys
[3]);
1363 ssh_decryption_setup_mac(&global_data
->peer_data
[SERVER_PEER_DATA
], &global_data
->new_keys
[5]);
1366 seq_num
= global_data
->peer_data
[is_response
].seq_num_new_key
;
1372 len
= plen
+4-padding_length
-(offset
-last_offset
);
1374 proto_tree_add_item(key_ex_tree
, hf_ssh_payload
, tvb
, offset
, len
, ENC_NA
);
1379 proto_tree_add_item(tree
, hf_ssh_padding_string
, tvb
, offset
, padding_length
, ENC_NA
);
1380 offset
+= padding_length
;
1381 ti
= proto_tree_add_uint(tree
, hf_ssh_seq_num
, tvb
, offset
, 0, seq_num
);
1382 proto_item_set_generated(ti
);
1387 static int ssh_dissect_kex_dh(uint8_t msg_code
, tvbuff_t
*tvb
,
1388 packet_info
*pinfo
, int offset
, proto_tree
*tree
,
1389 struct ssh_flow_data
*global_data
, unsigned *seq_num
)
1392 proto_tree_add_item(tree
, hf_ssh2_kex_dh_msg_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1395 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
,
1396 val_to_str(msg_code
, ssh2_kex_dh_msg_vals
, "Unknown (%u)"));
1399 case SSH_MSG_KEXDH_INIT
:
1400 // e (client ephemeral key public part)
1401 if (!ssh_read_e(tvb
, offset
, global_data
)) {
1402 proto_tree_add_expert_format(tree
, pinfo
, &ei_ssh_invalid_keylen
, tvb
, offset
, 2,
1403 "Invalid key length: %u", tvb_get_ntohl(tvb
, offset
));
1406 offset
+= ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_dh_e
);
1407 if(global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_dh_ini
== 0){
1408 global_data
->peer_data
[CLIENT_PEER_DATA
].sequence_number
++;
1409 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_dh_ini
= global_data
->peer_data
[CLIENT_PEER_DATA
].sequence_number
;
1410 ssh_debug_printf("%s->sequence_number{SSH_MSG_KEXDH_INIT}++ > %d\n", CLIENT_PEER_DATA
?"serveur":"client", global_data
->peer_data
[CLIENT_PEER_DATA
].sequence_number
);
1412 *seq_num
= global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_dh_ini
;
1415 case SSH_MSG_KEXDH_REPLY
:
1416 offset
+= ssh_tree_add_hostkey(tvb
, offset
, tree
, "KEX host key",
1417 ett_key_exchange_host_key
, global_data
);
1419 // f (server ephemeral key public part), K_S (host key)
1420 if (!ssh_read_f(tvb
, offset
, global_data
)) {
1421 proto_tree_add_expert_format(tree
, pinfo
, &ei_ssh_invalid_keylen
, tvb
, offset
, 2,
1422 "Invalid key length: %u", tvb_get_ntohl(tvb
, offset
));
1424 ssh_choose_enc_mac(global_data
);
1425 ssh_keylog_hash_write_secret(global_data
);
1427 offset
+= ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_dh_f
);
1428 offset
+= ssh_tree_add_hostsignature(tvb
, pinfo
, offset
, tree
, "KEX host signature",
1429 ett_key_exchange_host_sig
, global_data
);
1430 if(global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_dh_rep
== 0){
1431 global_data
->peer_data
[SERVER_PEER_DATA
].sequence_number
++;
1432 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_dh_rep
= global_data
->peer_data
[SERVER_PEER_DATA
].sequence_number
;
1433 ssh_debug_printf("%s->sequence_number{SSH_MSG_KEXDH_REPLY}++ > %d\n", SERVER_PEER_DATA
?"serveur":"client", global_data
->peer_data
[SERVER_PEER_DATA
].sequence_number
);
1435 *seq_num
= global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_dh_rep
;
1442 static int ssh_dissect_kex_dh_gex(uint8_t msg_code
, tvbuff_t
*tvb
,
1443 packet_info
*pinfo
, int offset
, proto_tree
*tree
,
1444 struct ssh_flow_data
*global_data
, unsigned *seq_num
)
1447 proto_tree_add_item(tree
, hf_ssh2_kex_dh_gex_msg_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1450 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
,
1451 val_to_str(msg_code
, ssh2_kex_dh_gex_msg_vals
, "Unknown (%u)"));
1454 case SSH_MSG_KEX_DH_GEX_REQUEST_OLD
:
1455 proto_tree_add_item(tree
, hf_ssh_dh_gex_nbits
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1459 case SSH_MSG_KEX_DH_GEX_GROUP
:
1461 global_data
->kex_gex_p
= ssh_read_mpint(tvb
, offset
);
1462 offset
+= ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_dh_gex_p
);
1463 // g (Group generator)
1464 global_data
->kex_gex_g
= ssh_read_mpint(tvb
, offset
);
1465 offset
+= ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_dh_gex_g
);
1466 if(global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_gex_grp
== 0){
1467 global_data
->peer_data
[SERVER_PEER_DATA
].sequence_number
++;
1468 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_gex_grp
= global_data
->peer_data
[SERVER_PEER_DATA
].sequence_number
;
1469 ssh_debug_printf("%s->sequence_number{SSH_MSG_KEX_DH_GEX_GROUP}++ > %d\n", SERVER_PEER_DATA
?"serveur":"client", global_data
->peer_data
[SERVER_PEER_DATA
].sequence_number
);
1471 *seq_num
= global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_gex_grp
;
1474 case SSH_MSG_KEX_DH_GEX_INIT
:
1475 // e (Client public key)
1476 if (!ssh_read_e(tvb
, offset
, global_data
)) {
1477 proto_tree_add_expert_format(tree
, pinfo
, &ei_ssh_invalid_keylen
, tvb
, offset
, 2,
1478 "Invalid key length: %u", tvb_get_ntohl(tvb
, offset
));
1480 offset
+= ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_dh_e
);
1481 if(global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_gex_ini
== 0){
1482 global_data
->peer_data
[CLIENT_PEER_DATA
].sequence_number
++;
1483 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_gex_ini
= global_data
->peer_data
[CLIENT_PEER_DATA
].sequence_number
;
1484 ssh_debug_printf("%s->sequence_number{SSH_MSG_KEX_DH_GEX_INIT}++ > %d\n", CLIENT_PEER_DATA
?"serveur":"client", global_data
->peer_data
[CLIENT_PEER_DATA
].sequence_number
);
1486 *seq_num
= global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_gex_ini
;
1489 case SSH_MSG_KEX_DH_GEX_REPLY
:
1490 offset
+= ssh_tree_add_hostkey(tvb
, offset
, tree
, "KEX host key",
1491 ett_key_exchange_host_key
, global_data
);
1492 if (!PINFO_FD_VISITED(pinfo
)) {
1493 ssh_read_f(tvb
, offset
, global_data
);
1494 // f (server ephemeral key public part), K_S (host key)
1495 ssh_choose_enc_mac(global_data
);
1496 ssh_keylog_hash_write_secret(global_data
);
1498 offset
+= ssh_tree_add_mpint(tvb
, offset
, tree
, hf_ssh_dh_f
);
1499 offset
+= ssh_tree_add_hostsignature(tvb
, pinfo
, offset
, tree
, "KEX host signature",
1500 ett_key_exchange_host_sig
, global_data
);
1501 if(global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_gex_rep
== 0){
1502 global_data
->peer_data
[SERVER_PEER_DATA
].sequence_number
++;
1503 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_gex_rep
= global_data
->peer_data
[SERVER_PEER_DATA
].sequence_number
;
1504 ssh_debug_printf("%s->sequence_number{SSH_MSG_KEX_DH_GEX_REPLY}++ > %d\n", SERVER_PEER_DATA
?"serveur":"client", global_data
->peer_data
[SERVER_PEER_DATA
].sequence_number
);
1506 *seq_num
= global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_gex_rep
;
1509 case SSH_MSG_KEX_DH_GEX_REQUEST
:{
1511 if (!PINFO_FD_VISITED(pinfo
)) {
1512 ssh_hash_buffer_put_uint32(global_data
->kex_gex_bits_min
, tvb_get_ntohl(tvb
, offset
));
1514 proto_tree_add_item(tree
, hf_ssh_dh_gex_min
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1516 if (!PINFO_FD_VISITED(pinfo
)) {
1517 ssh_hash_buffer_put_uint32(global_data
->kex_gex_bits_req
, tvb_get_ntohl(tvb
, offset
));
1519 proto_tree_add_item(tree
, hf_ssh_dh_gex_nbits
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1521 if (!PINFO_FD_VISITED(pinfo
)) {
1522 ssh_hash_buffer_put_uint32(global_data
->kex_gex_bits_max
, tvb_get_ntohl(tvb
, offset
));
1524 proto_tree_add_item(tree
, hf_ssh_dh_gex_max
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1526 if(global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_gex_req
== 0){
1527 global_data
->peer_data
[CLIENT_PEER_DATA
].sequence_number
++;
1528 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_gex_req
= global_data
->peer_data
[CLIENT_PEER_DATA
].sequence_number
;
1529 ssh_debug_printf("%s->sequence_number{SSH_MSG_KEX_DH_GEX_REQUEST}++ > %d\n", CLIENT_PEER_DATA
?"serveur":"client", global_data
->peer_data
[CLIENT_PEER_DATA
].sequence_number
);
1531 *seq_num
= global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_gex_req
;
1540 ssh_dissect_kex_ecdh(uint8_t msg_code
, tvbuff_t
*tvb
,
1541 packet_info
*pinfo
, int offset
, proto_tree
*tree
,
1542 struct ssh_flow_data
*global_data
, unsigned *seq_num
)
1544 proto_tree_add_item(tree
, hf_ssh2_kex_ecdh_msg_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1547 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
,
1548 val_to_str(msg_code
, ssh2_kex_ecdh_msg_vals
, "Unknown (%u)"));
1551 case SSH_MSG_KEX_ECDH_INIT
:
1552 if (!ssh_read_e(tvb
, offset
, global_data
)) {
1553 proto_tree_add_expert_format(tree
, pinfo
, &ei_ssh_invalid_keylen
, tvb
, offset
, 2,
1554 "Invalid key length: %u", tvb_get_ntohl(tvb
, offset
));
1557 if (!PINFO_FD_VISITED(pinfo
)) {
1558 if(global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_ecdh_ini
== 0){
1559 global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_ecdh_ini
= global_data
->peer_data
[CLIENT_PEER_DATA
].sequence_number
;
1560 global_data
->peer_data
[CLIENT_PEER_DATA
].sequence_number
++;
1561 ssh_debug_printf("%s->sequence_number{SSH_MSG_KEX_ECDH_INIT=%d}++ > %d\n", CLIENT_PEER_DATA
?"server":"client", global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_ecdh_ini
, global_data
->peer_data
[CLIENT_PEER_DATA
].sequence_number
);
1564 *seq_num
= global_data
->peer_data
[CLIENT_PEER_DATA
].seq_num_ecdh_ini
;
1566 offset
+= ssh_tree_add_string(tvb
, offset
, tree
, hf_ssh_ecdh_q_c
, hf_ssh_ecdh_q_c_length
);
1569 case SSH_MSG_KEX_ECDH_REPLY
:
1570 offset
+= ssh_tree_add_hostkey(tvb
, offset
, tree
, "KEX host key",
1571 ett_key_exchange_host_key
, global_data
);
1573 if (!ssh_read_f(tvb
, offset
, global_data
)){
1574 proto_tree_add_expert_format(tree
, pinfo
, &ei_ssh_invalid_keylen
, tvb
, offset
, 2,
1575 "Invalid key length: %u", tvb_get_ntohl(tvb
, offset
));
1578 ssh_choose_enc_mac(global_data
);
1579 ssh_keylog_hash_write_secret(global_data
);
1580 if(global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_ecdh_rep
== 0){
1581 global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_ecdh_rep
= global_data
->peer_data
[SERVER_PEER_DATA
].sequence_number
;
1582 global_data
->peer_data
[SERVER_PEER_DATA
].sequence_number
++;
1583 ssh_debug_printf("%s->sequence_number{SSH_MSG_KEX_ECDH_REPLY=%d}++ > %d\n", SERVER_PEER_DATA
?"server":"client", global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_ecdh_rep
, global_data
->peer_data
[SERVER_PEER_DATA
].sequence_number
);
1585 *seq_num
= global_data
->peer_data
[SERVER_PEER_DATA
].seq_num_ecdh_rep
;
1587 offset
+= ssh_tree_add_string(tvb
, offset
, tree
, hf_ssh_ecdh_q_s
, hf_ssh_ecdh_q_s_length
);
1588 offset
+= ssh_tree_add_hostsignature(tvb
, pinfo
, offset
, tree
, "KEX host signature",
1589 ett_key_exchange_host_sig
, global_data
);
1596 static ssh_message_info_t
*
1597 ssh_get_message(packet_info
*pinfo
, int record_id
)
1599 ssh_packet_info_t
*packet
= (ssh_packet_info_t
*)p_get_proto_data(
1600 wmem_file_scope(), pinfo
, proto_ssh
, 0);
1606 ssh_message_info_t
*message
= NULL
;
1607 for (message
= packet
->messages
; message
; message
= message
->next
) {
1608 ws_debug("%u:looking for message %d now %d", pinfo
->num
, record_id
, message
->id
);
1609 if (message
->id
== record_id
) {
1618 ssh_try_dissect_encrypted_packet(tvbuff_t
*tvb
, packet_info
*pinfo
,
1619 struct ssh_peer_data
*peer_data
, int offset
, proto_tree
*tree
)
1621 bool can_decrypt
= peer_data
->cipher
!= NULL
;
1622 ssh_message_info_t
*message
= NULL
;
1625 if (!PINFO_FD_VISITED(pinfo
)) {
1626 ssh_decrypt_packet(tvb
, pinfo
, peer_data
, offset
);
1629 int record_id
= tvb_raw_offset(tvb
) + offset
;
1630 message
= ssh_get_message(pinfo
, record_id
);
1633 offset
+= ssh_dissect_decrypted_packet(tvb_new_subset_remaining(tvb
, offset
), pinfo
, peer_data
, tree
, message
);
1638 return ssh_dissect_encrypted_packet(tvb
, pinfo
, peer_data
, offset
, tree
);
1642 ssh_dissect_encrypted_packet(tvbuff_t
*tvb
, packet_info
*pinfo
,
1643 struct ssh_peer_data
*peer_data
,
1644 int offset
, proto_tree
*tree
)
1649 len
= tvb_reported_length_remaining(tvb
, offset
);
1650 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "Encrypted packet (len=%d)", len
);
1653 int encrypted_len
= len
;
1655 if (len
> 4 && peer_data
->length_is_plaintext
) {
1656 plen
= tvb_get_ntohl(tvb
, offset
) ;
1657 proto_tree_add_uint(tree
, hf_ssh_packet_length
, tvb
, offset
, 4, plen
);
1661 proto_tree_add_item(tree
, hf_ssh_packet_length_encrypted
, tvb
, offset
, 4, ENC_NA
);
1665 if (peer_data
->mac_length
>0)
1666 encrypted_len
-= peer_data
->mac_length
;
1668 proto_tree_add_item(tree
, hf_ssh_encrypted_packet
,
1669 tvb
, offset
+4, encrypted_len
, ENC_NA
);
1671 if (peer_data
->mac_length
>0)
1672 proto_tree_add_item(tree
, hf_ssh_mac_string
,
1673 tvb
, offset
+4+encrypted_len
,
1674 peer_data
->mac_length
, ENC_NA
);
1681 ssh_dissect_protocol(tvbuff_t
*tvb
, packet_info
*pinfo
,
1682 struct ssh_flow_data
*global_data
,
1683 int offset
, proto_tree
*tree
, int is_response
, unsigned * version
,
1684 bool *need_desegmentation
)
1686 unsigned remain_length
;
1687 int linelen
, protolen
;
1690 * If the first packet do not contain the banner,
1691 * it is dump in the middle of a flow or not a ssh at all
1693 if (tvb_strncaseeql(tvb
, offset
, "SSH-", 4) != 0) {
1694 offset
= ssh_dissect_encrypted_packet(tvb
, pinfo
,
1695 &global_data
->peer_data
[is_response
], offset
, tree
);
1700 if (tvb_strncaseeql(tvb
, offset
, "SSH-2.", 6) == 0) {
1701 *(version
) = SSH_VERSION_2
;
1702 } else if (tvb_strncaseeql(tvb
, offset
, "SSH-1.99-", 9) == 0) {
1703 *(version
) = SSH_VERSION_2
;
1704 } else if (tvb_strncaseeql(tvb
, offset
, "SSH-1.", 6) == 0) {
1705 *(version
) = SSH_VERSION_1
;
1710 * We use "tvb_ensure_captured_length_remaining()" to make sure there
1711 * actually *is* data remaining.
1713 * This means we're guaranteed that "remain_length" is positive.
1715 remain_length
= tvb_ensure_captured_length_remaining(tvb
, offset
);
1716 /*linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, false);
1718 linelen
= tvb_find_uint8(tvb
, offset
, -1, '\n');
1720 if (ssh_desegment
&& pinfo
->can_desegment
) {
1721 if (linelen
== -1 || remain_length
< (unsigned)linelen
-offset
) {
1722 pinfo
->desegment_offset
= offset
;
1723 pinfo
->desegment_len
= linelen
-remain_length
;
1724 *need_desegmentation
= true;
1728 if (linelen
== -1) {
1729 /* XXX - reassemble across segment boundaries? */
1730 linelen
= remain_length
;
1733 linelen
= linelen
- offset
+ 1;
1735 if (linelen
> 1 && tvb_get_uint8(tvb
, offset
+ linelen
- 2) == '\r')
1736 protolen
= linelen
- 2;
1738 protolen
= linelen
- 1;
1741 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "Protocol (%s)",
1742 tvb_format_text(pinfo
->pool
, tvb
, offset
, protolen
));
1744 // V_C / V_S (client and server identification strings) RFC4253 4.2
1745 // format: SSH-protoversion-softwareversion SP comments [CR LF not incl.]
1746 if (!PINFO_FD_VISITED(pinfo
)) {
1747 char *data
= (char *)tvb_memdup(pinfo
->pool
, tvb
, offset
, protolen
);
1749 ssh_hash_buffer_put_string(global_data
->kex_client_version
, data
, protolen
);
1751 ssh_hash_buffer_put_string(global_data
->kex_server_version
, data
, protolen
);
1755 proto_tree_add_item(tree
, hf_ssh_protocol
,
1756 tvb
, offset
, protolen
, ENC_ASCII
);
1762 ssh_set_mac_length(struct ssh_peer_data
*peer_data
)
1766 char *mac_name
= peer_data
->mac
;
1772 /* wmem_strdup() never returns NULL */
1773 mac_name
= wmem_strdup(NULL
, (const char *)mac_name
);
1775 /* strip trailing "-etm@openssh.com" or "@openssh.com" */
1776 strip
= strstr(mac_name
, "-etm@openssh.com");
1778 peer_data
->length_is_plaintext
= 1;
1782 strip
= strstr(mac_name
, "@openssh.com");
1783 if (strip
) *strip
= '\0';
1786 size_str
= g_strrstr(mac_name
, "-");
1787 if (size_str
&& ws_strtou32(size_str
+ 1, NULL
, &size
) && size
> 0 && size
% 8 == 0) {
1788 peer_data
->mac_length
= size
/ 8;
1790 else if (strcmp(mac_name
, "hmac-sha1") == 0) {
1791 peer_data
->mac_length
= 20;
1793 else if (strcmp(mac_name
, "hmac-md5") == 0) {
1794 peer_data
->mac_length
= 16;
1796 else if (strcmp(mac_name
, "hmac-ripemd160") == 0) {
1797 peer_data
->mac_length
= 20;
1799 else if (strcmp(mac_name
, "none") == 0) {
1800 peer_data
->mac_length
= 0;
1803 wmem_free(NULL
, mac_name
);
1806 static void ssh_set_kex_specific_dissector(struct ssh_flow_data
*global_data
)
1808 const char *kex_name
= global_data
->kex
;
1810 if (!kex_name
) return;
1812 if (strcmp(kex_name
, "diffie-hellman-group-exchange-sha1") == 0 ||
1813 strcmp(kex_name
, "diffie-hellman-group-exchange-sha256") == 0)
1815 global_data
->kex_specific_dissector
= ssh_dissect_kex_dh_gex
;
1817 else if (g_str_has_prefix(kex_name
, "ecdh-sha2-") ||
1818 strcmp(kex_name
, "curve25519-sha256@libssh.org") == 0 ||
1819 strcmp(kex_name
, "curve25519-sha256") == 0 ||
1820 strcmp(kex_name
, "curve448-sha512") == 0)
1822 global_data
->kex_specific_dissector
= ssh_dissect_kex_ecdh
;
1824 else if (strcmp(kex_name
, "diffie-hellman-group14-sha256") == 0 ||
1825 strcmp(kex_name
, "diffie-hellman-group16-sha512") == 0 ||
1826 strcmp(kex_name
, "diffie-hellman-group18-sha512") == 0 ||
1827 strcmp(kex_name
, "diffie-hellman-group1-sha1") == 0 ||
1828 strcmp(kex_name
, "diffie-hellman-group14-sha1") == 0)
1830 global_data
->kex_specific_dissector
= ssh_dissect_kex_dh
;
1835 ssh_gslist_compare_strings(const void *a
, const void *b
)
1837 if (a
== NULL
&& b
== NULL
)
1843 return strcmp((const char*)a
, (const char*)b
);
1846 /* expects that *result is NULL */
1848 ssh_choose_algo(char *client
, char *server
, char **result
)
1850 char **server_strings
= NULL
;
1851 char **client_strings
= NULL
;
1853 GSList
*server_list
= NULL
;
1855 if (!client
|| !server
|| !result
|| *result
)
1858 server_strings
= g_strsplit(server
, ",", 0);
1859 for (step
= server_strings
; *step
; step
++) {
1860 server_list
= g_slist_append(server_list
, *step
);
1863 client_strings
= g_strsplit(client
, ",", 0);
1864 for (step
= client_strings
; *step
; step
++) {
1866 if ((agreed
= g_slist_find_custom(server_list
, *step
, ssh_gslist_compare_strings
))) {
1867 *result
= wmem_strdup(wmem_file_scope(), (const char *)agreed
->data
);
1872 g_strfreev(client_strings
);
1873 g_slist_free(server_list
);
1874 g_strfreev(server_strings
);
1878 ssh_dissect_key_init(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
,
1879 proto_tree
*tree
, int is_response
, struct ssh_flow_data
*global_data
)
1881 int start_offset
= offset
;
1883 wmem_strbuf_t
*hassh_algo
;
1886 proto_item
*tf
, *ti
;
1887 proto_tree
*key_init_tree
;
1889 struct ssh_peer_data
*peer_data
= &global_data
->peer_data
[is_response
];
1891 key_init_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1, ett_key_init
, &tf
, "Algorithms");
1892 if (!PINFO_FD_VISITED(pinfo
)) {
1893 peer_data
->bn_cookie
= ssh_kex_make_bignum(tvb_get_ptr(tvb
, offset
, 16), 16);
1895 proto_tree_add_item(key_init_tree
, hf_ssh_cookie
,
1896 tvb
, offset
, 16, ENC_NA
);
1899 offset
= ssh_dissect_proposal(tvb
, offset
, key_init_tree
,
1900 hf_ssh_kex_algorithms_length
, hf_ssh_kex_algorithms
,
1901 &peer_data
->kex_proposal
);
1902 offset
= ssh_dissect_proposal(tvb
, offset
, key_init_tree
,
1903 hf_ssh_server_host_key_algorithms_length
,
1904 hf_ssh_server_host_key_algorithms
, NULL
);
1905 offset
= ssh_dissect_proposal(tvb
, offset
, key_init_tree
,
1906 hf_ssh_encryption_algorithms_client_to_server_length
,
1907 hf_ssh_encryption_algorithms_client_to_server
,
1908 &peer_data
->enc_proposals
[CLIENT_TO_SERVER_PROPOSAL
]);
1909 offset
= ssh_dissect_proposal(tvb
, offset
, key_init_tree
,
1910 hf_ssh_encryption_algorithms_server_to_client_length
,
1911 hf_ssh_encryption_algorithms_server_to_client
,
1912 &peer_data
->enc_proposals
[SERVER_TO_CLIENT_PROPOSAL
]);
1913 offset
= ssh_dissect_proposal(tvb
, offset
, key_init_tree
,
1914 hf_ssh_mac_algorithms_client_to_server_length
,
1915 hf_ssh_mac_algorithms_client_to_server
,
1916 &peer_data
->mac_proposals
[CLIENT_TO_SERVER_PROPOSAL
]);
1917 offset
= ssh_dissect_proposal(tvb
, offset
, key_init_tree
,
1918 hf_ssh_mac_algorithms_server_to_client_length
,
1919 hf_ssh_mac_algorithms_server_to_client
,
1920 &peer_data
->mac_proposals
[SERVER_TO_CLIENT_PROPOSAL
]);
1921 offset
= ssh_dissect_proposal(tvb
, offset
, key_init_tree
,
1922 hf_ssh_compression_algorithms_client_to_server_length
,
1923 hf_ssh_compression_algorithms_client_to_server
,
1924 &peer_data
->comp_proposals
[CLIENT_TO_SERVER_PROPOSAL
]);
1925 offset
= ssh_dissect_proposal(tvb
, offset
, key_init_tree
,
1926 hf_ssh_compression_algorithms_server_to_client_length
,
1927 hf_ssh_compression_algorithms_server_to_client
,
1928 &peer_data
->comp_proposals
[SERVER_TO_CLIENT_PROPOSAL
]);
1929 offset
= ssh_dissect_proposal(tvb
, offset
, key_init_tree
,
1930 hf_ssh_languages_client_to_server_length
,
1931 hf_ssh_languages_client_to_server
, NULL
);
1932 offset
= ssh_dissect_proposal(tvb
, offset
, key_init_tree
,
1933 hf_ssh_languages_server_to_client_length
,
1934 hf_ssh_languages_server_to_client
, NULL
);
1936 proto_tree_add_item(key_init_tree
, hf_ssh_first_kex_packet_follows
,
1937 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1940 proto_tree_add_item(key_init_tree
, hf_ssh_kex_reserved
,
1941 tvb
, offset
, 4, ENC_NA
);
1944 hassh_algo
= wmem_strbuf_new(pinfo
->pool
, "");
1946 wmem_strbuf_append_printf(hassh_algo
, "%s;%s;%s;%s", peer_data
->kex_proposal
, peer_data
->enc_proposals
[CLIENT_TO_SERVER_PROPOSAL
],
1947 peer_data
->mac_proposals
[CLIENT_TO_SERVER_PROPOSAL
], peer_data
->comp_proposals
[CLIENT_TO_SERVER_PROPOSAL
]);
1948 hassh
= g_compute_checksum_for_string(G_CHECKSUM_MD5
, wmem_strbuf_get_str(hassh_algo
), wmem_strbuf_get_len(hassh_algo
));
1949 ti
= proto_tree_add_string(key_init_tree
, hf_ssh_kex_hassh_algo
, tvb
, offset
, 0, wmem_strbuf_get_str(hassh_algo
));
1950 proto_item_set_generated(ti
);
1951 ti
= proto_tree_add_string(key_init_tree
, hf_ssh_kex_hassh
, tvb
, offset
, 0, hassh
);
1952 proto_item_set_generated(ti
);
1955 wmem_strbuf_append_printf(hassh_algo
, "%s;%s;%s;%s", peer_data
->kex_proposal
, peer_data
->enc_proposals
[SERVER_TO_CLIENT_PROPOSAL
],
1956 peer_data
->mac_proposals
[SERVER_TO_CLIENT_PROPOSAL
], peer_data
->comp_proposals
[SERVER_TO_CLIENT_PROPOSAL
]);
1957 hassh
= g_compute_checksum_for_string(G_CHECKSUM_MD5
, wmem_strbuf_get_str(hassh_algo
), wmem_strbuf_get_len(hassh_algo
));
1958 ti
= proto_tree_add_string(key_init_tree
, hf_ssh_kex_hasshserver_algo
, tvb
, offset
, 0, wmem_strbuf_get_str(hassh_algo
));
1959 proto_item_set_generated(ti
);
1960 ti
= proto_tree_add_string(key_init_tree
, hf_ssh_kex_hasshserver
, tvb
, offset
, 0, hassh
);
1961 proto_item_set_generated(ti
);
1965 if (global_data
->peer_data
[CLIENT_PEER_DATA
].kex_proposal
&&
1966 global_data
->peer_data
[SERVER_PEER_DATA
].kex_proposal
&&
1969 /* Note: we're ignoring first_kex_packet_follows. */
1971 global_data
->peer_data
[CLIENT_PEER_DATA
].kex_proposal
,
1972 global_data
->peer_data
[SERVER_PEER_DATA
].kex_proposal
,
1974 ssh_set_kex_specific_dissector(global_data
);
1977 payload_length
= offset
- start_offset
;
1980 proto_item_set_len(tf
, payload_length
);
1983 // I_C / I_S (client and server SSH_MSG_KEXINIT payload) RFC4253 4.2
1984 if (!PINFO_FD_VISITED(pinfo
)) {
1985 char *data
= (char *)wmem_alloc(pinfo
->pool
, payload_length
+ 1);
1986 tvb_memcpy(tvb
, data
+ 1, start_offset
, payload_length
);
1987 data
[0] = SSH_MSG_KEXINIT
;
1989 ssh_hash_buffer_put_string(global_data
->kex_server_key_exchange_init
, data
, payload_length
+ 1);
1991 ssh_hash_buffer_put_string(global_data
->kex_client_key_exchange_init
, data
, payload_length
+ 1);
1999 ssh_dissect_proposal(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
,
2000 int hf_index_length
, int hf_index_value
, char **store
)
2002 uint32_t len
= tvb_get_ntohl(tvb
, offset
);
2003 proto_tree_add_uint(tree
, hf_index_length
, tvb
, offset
, 4, len
);
2006 proto_tree_add_item(tree
, hf_index_value
, tvb
, offset
, len
,
2009 *store
= (char *) tvb_get_string_enc(wmem_file_scope(), tvb
, offset
, len
, ENC_ASCII
);
2016 ssh_keylog_read_file(void)
2018 if (!pref_keylog_file
|| !*pref_keylog_file
) {
2019 ws_debug("no keylog file preference set");
2023 if (ssh_keylog_file
&& file_needs_reopen(ws_fileno(ssh_keylog_file
),
2024 pref_keylog_file
)) {
2026 g_hash_table_remove_all(ssh_master_key_map
);
2029 if (!ssh_keylog_file
) {
2030 ssh_keylog_file
= ws_fopen(pref_keylog_file
, "r");
2031 if (!ssh_keylog_file
) {
2032 ws_debug("ssh: failed to open key log file %s: %s",
2033 pref_keylog_file
, g_strerror(errno
));
2038 /* File format: each line follows the format "<cookie> <type> <key>".
2039 * <cookie> is the hex-encoded (client or server) 16 bytes cookie
2040 * (32 characters) found in the SSH_MSG_KEXINIT of the endpoint whose
2041 * private random is disclosed.
2042 * <type> is either SHARED_SECRET or PRIVATE_KEY depending on the
2043 * type of key provided. PRIVAT_KEY is only supported for DH,
2044 * DH group exchange, and ECDH (including Curve25519) key exchanges.
2045 * <key> is the private random number that is used to generate the DH
2046 * negotiation (length depends on algorithm). In RFC4253 it is called
2047 * x for the client and y for the server.
2048 * For openssh and DH group exchange, it can be retrieved using
2049 * DH_get0_key(kex->dh, NULL, &server_random)
2050 * for groupN in file kexdh.c function kex_dh_compute_key
2051 * for custom group in file kexgexs.c function input_kex_dh_gex_init
2052 * For openssh and curve25519, it can be found in function kex_c25519_enc
2053 * in variable server_key. One may also provide the shared secret
2054 * directly if <type> is set to SHARED_SECRET.
2057 * 90d886612f9c35903db5bb30d11f23c2 PRIVATE_KEY DEF830C22F6C927E31972FFB20B46C96D0A5F2D5E7BE5A3A8804D6BFC431619ED10AF589EEDFF4750DEA00EFD7AFDB814B6F3528729692B1F2482041521AE9DC
2063 if (!fgets(buf
, sizeof(buf
), ssh_keylog_file
)) {
2064 if (ferror(ssh_keylog_file
)) {
2065 ws_debug("Error while reading %s, closing it.", pref_keylog_file
);
2067 g_hash_table_remove_all(ssh_master_key_map
);
2072 size_t len
= strlen(buf
);
2073 while(len
>0 && (buf
[len
-1]=='\r' || buf
[len
-1]=='\n')){len
-=1;buf
[len
]=0;}
2075 ssh_keylog_process_line(buf
);
2080 ssh_keylog_process_lines(const uint8_t *data
, unsigned datalen
)
2082 const char *next_line
= (const char *)data
;
2083 const char *line_end
= next_line
+ datalen
;
2084 while (next_line
&& next_line
< line_end
) {
2085 const char *line
= next_line
;
2086 next_line
= (const char *)memchr(line
, '\n', line_end
- line
);
2090 linelen
= next_line
- line
;
2091 next_line
++; /* drop LF */
2093 linelen
= (ssize_t
)(line_end
- line
);
2095 if (linelen
> 0 && line
[linelen
- 1] == '\r') {
2096 linelen
--; /* drop CR */
2099 ssh_debug_printf(" checking keylog line: %.*s\n", (int)linelen
, line
);
2101 char * strippedline
= g_strndup(line
, linelen
);
2102 ssh_keylog_process_line(strippedline
);
2103 g_free(strippedline
);
2108 ssh_keylog_process_line(const char *line
)
2110 ws_noisy("ssh: process line: %s", line
);
2112 char **split
= g_strsplit(line
, " ", 3);
2113 char *cookie
, *type
, *key
;
2114 size_t cookie_len
, key_len
;
2116 if (g_strv_length(split
) == 3) {
2117 // New format: [hex-encoded cookie] [key type] [hex-encoded key material]
2121 } else if (g_strv_length(split
) == 2) {
2122 // Old format: [hex-encoded cookie] [hex-encoded private key]
2123 ws_debug("ssh keylog: detected old keylog format without explicit key type");
2124 type
= "PRIVATE_KEY";
2128 ws_debug("ssh keylog: invalid format");
2133 key_len
= strlen(key
);
2134 cookie_len
= strlen(cookie
);
2136 ws_debug("ssh keylog: invalid format (key could at least be even!)");
2141 ws_debug("ssh keylog: invalid format (cookie could at least be even!)");
2145 ssh_bignum
* bn_cookie
= ssh_kex_make_bignum(NULL
, (unsigned)(cookie_len
/2));
2146 ssh_bignum
* bn_priv
= ssh_kex_make_bignum(NULL
, (unsigned)(key_len
/2));
2148 for (size_t i
= 0; i
< key_len
/2; i
++) {
2149 char v0
= key
[i
* 2];
2150 int8_t h0
= (v0
>='0' && v0
<='9')?v0
-'0':(v0
>='a' && v0
<='f')?v0
-'a'+10:(v0
>='A' && v0
<='F')?v0
-'A'+10:-1;
2151 char v1
= key
[i
* 2 + 1];
2152 int8_t h1
= (v1
>='0' && v1
<='9')?v1
-'0':(v1
>='a' && v1
<='f')?v1
-'a'+10:(v1
>='A' && v1
<='F')?v1
-'A'+10:-1;
2154 if (h0
==-1 || h1
==-1) {
2155 ws_debug("ssh: can't process key, invalid hex number: %c%c", v0
, v1
);
2162 bn_priv
->data
[i
] = c
;
2164 for (size_t i
= 0; i
< cookie_len
/2; i
++) {
2165 char v0
= cookie
[i
* 2];
2166 int8_t h0
= (v0
>='0' && v0
<='9')?v0
-'0':(v0
>='a' && v0
<='f')?v0
-'a'+10:(v0
>='A' && v0
<='F')?v0
-'A'+10:-1;
2167 char v1
= cookie
[i
* 2 + 1];
2168 int8_t h1
= (v1
>='0' && v1
<='9')?v1
-'0':(v1
>='a' && v1
<='f')?v1
-'a'+10:(v1
>='A' && v1
<='F')?v1
-'A'+10:-1;
2170 if (h0
==-1 || h1
==-1) {
2171 ws_debug("ssh: can't process cookie, invalid hex number: %c%c", v0
, v1
);
2178 bn_cookie
->data
[i
] = c
;
2180 ssh_bignum
* bn_priv_ht
= g_new(ssh_bignum
, 1);
2181 bn_priv_ht
->length
= bn_priv
->length
;
2182 bn_priv_ht
->data
= (uint8_t *) g_memdup2(bn_priv
->data
, bn_priv
->length
);
2183 ssh_bignum
* bn_cookie_ht
= g_new(ssh_bignum
, 1);
2184 bn_cookie_ht
->length
= bn_cookie
->length
;
2185 bn_cookie_ht
->data
= (uint8_t *) g_memdup2(bn_cookie
->data
, bn_cookie
->length
);
2187 char * type_ht
= (char *) g_memdup2(type
, strlen(type
) + 1);
2188 ssh_key_map_entry_t
* entry_ht
= g_new(ssh_key_map_entry_t
, 1);
2189 entry_ht
->type
= type_ht
;
2190 entry_ht
->key_material
= bn_priv_ht
;
2191 g_hash_table_insert(ssh_master_key_map
, bn_cookie_ht
, entry_ht
);
2196 ssh_keylog_reset(void)
2198 if (ssh_keylog_file
) {
2199 fclose(ssh_keylog_file
);
2200 ssh_keylog_file
= NULL
;
2205 ssh_kex_type(char *type
)
2208 if (g_str_has_prefix(type
, "curve25519")) {
2209 return SSH_KEX_CURVE25519
;
2210 }else if (g_str_has_prefix(type
, "diffie-hellman-group-exchange")) {
2211 return SSH_KEX_DH_GEX
;
2212 }else if (g_str_has_prefix(type
, "diffie-hellman-group14")) {
2213 return SSH_KEX_DH_GROUP14
;
2214 }else if (g_str_has_prefix(type
, "diffie-hellman-group16")) {
2215 return SSH_KEX_DH_GROUP16
;
2216 }else if (g_str_has_prefix(type
, "diffie-hellman-group18")) {
2217 return SSH_KEX_DH_GROUP18
;
2218 }else if (g_str_has_prefix(type
, "diffie-hellman-group1")) {
2219 return SSH_KEX_DH_GROUP1
;
2227 ssh_kex_hash_type(char *type_string
)
2229 if (type_string
&& g_str_has_suffix(type_string
, "sha1")) {
2230 return SSH_KEX_HASH_SHA1
;
2231 }else if (type_string
&& g_str_has_suffix(type_string
, "sha256")) {
2232 return SSH_KEX_HASH_SHA256
;
2233 }else if (type_string
&& g_str_has_suffix(type_string
, "sha256@libssh.org")) {
2234 return SSH_KEX_HASH_SHA256
;
2235 }else if (type_string
&& g_str_has_suffix(type_string
, "sha512")) {
2236 return SSH_KEX_HASH_SHA512
;
2238 ws_debug("hash type %s not supported", type_string
);
2244 ssh_kex_make_bignum(const uint8_t *data
, unsigned length
)
2246 // 512 bytes (4096 bits) is the maximum bignum size we're supporting
2247 // Actually we need 513 bytes, to make provision for signed values
2248 // Diffie-Hellman group 18 has 8192 bits
2249 if (length
== 0 || length
> 1025) {
2253 ssh_bignum
*bn
= wmem_new0(wmem_file_scope(), ssh_bignum
);
2254 bn
->data
= (uint8_t *)wmem_alloc0(wmem_file_scope(), length
);
2257 memcpy(bn
->data
, data
, length
);
2260 bn
->length
= length
;
2265 ssh_read_e(tvbuff_t
*tvb
, int offset
, struct ssh_flow_data
*global_data
)
2267 // store the client's public part (e) for later usage
2268 uint32_t length
= tvb_get_ntohl(tvb
, offset
);
2269 global_data
->kex_e
= ssh_kex_make_bignum(NULL
, length
);
2270 if (!global_data
->kex_e
) {
2273 tvb_memcpy(tvb
, global_data
->kex_e
->data
, offset
+ 4, length
);
2278 ssh_read_f(tvbuff_t
*tvb
, int offset
, struct ssh_flow_data
*global_data
)
2280 // store the server's public part (f) for later usage
2281 uint32_t length
= tvb_get_ntohl(tvb
, offset
);
2282 global_data
->kex_f
= ssh_kex_make_bignum(NULL
, length
);
2283 if (!global_data
->kex_f
) {
2286 tvb_memcpy(tvb
, global_data
->kex_f
->data
, offset
+ 4, length
);
2291 ssh_read_mpint(tvbuff_t
*tvb
, int offset
)
2293 // store the DH group modulo (p) for later usage
2294 int length
= tvb_get_ntohl(tvb
, offset
);
2295 ssh_bignum
* bn
= ssh_kex_make_bignum(NULL
, length
);
2297 ws_debug("invalid bignum length %u", length
);
2300 tvb_memcpy(tvb
, bn
->data
, offset
+ 4, length
);
2305 ssh_keylog_hash_write_secret(struct ssh_flow_data
*global_data
)
2308 * This computation is defined differently for each key exchange method:
2309 * https://tools.ietf.org/html/rfc4253#page-23
2310 * https://tools.ietf.org/html/rfc5656#page-8
2311 * https://tools.ietf.org/html/rfc4419#page-4
2312 * All key exchange methods:
2313 * https://www.iana.org/assignments/ssh-parameters/ssh-parameters.xhtml#ssh-parameters-16
2317 ssh_key_map_entry_t
*entry
;
2318 ssh_bignum
*secret
= NULL
;
2320 bool client_cookie
= false;
2322 ssh_keylog_read_file();
2324 unsigned kex_type
= ssh_kex_type(global_data
->kex
);
2325 unsigned kex_hash_type
= ssh_kex_hash_type(global_data
->kex
);
2327 entry
= (ssh_key_map_entry_t
*)g_hash_table_lookup(ssh_master_key_map
, global_data
->peer_data
[SERVER_PEER_DATA
].bn_cookie
);
2329 entry
= (ssh_key_map_entry_t
*)g_hash_table_lookup(ssh_master_key_map
, global_data
->peer_data
[CLIENT_PEER_DATA
].bn_cookie
);
2330 client_cookie
= true;
2333 ws_debug("ssh decryption: no entry in keylog file for this session");
2334 global_data
->do_decrypt
= false;
2338 if (!strcmp(entry
->type
, "PRIVATE_KEY")) {
2339 if (client_cookie
) {
2340 secret
= ssh_kex_shared_secret(kex_type
, global_data
->kex_f
, entry
->key_material
, global_data
->kex_gex_p
);
2342 secret
= ssh_kex_shared_secret(kex_type
, global_data
->kex_e
, entry
->key_material
, global_data
->kex_gex_p
);
2344 } else if (!strcmp(entry
->type
, "SHARED_SECRET")) {
2345 secret
= ssh_kex_make_bignum(entry
->key_material
->data
, entry
->key_material
->length
);
2347 ws_debug("ssh decryption: unknown key type in keylog file");
2348 global_data
->do_decrypt
= false;
2353 ws_debug("ssh decryption: no key material for this session");
2354 global_data
->do_decrypt
= false;
2358 // shared secret data needs to be written as an mpint, and we need it later
2359 if (secret
->data
[0] & 0x80) { // Stored in Big endian
2360 length
= secret
->length
+ 1;
2361 char *tmp
= (char *)wmem_alloc0(wmem_packet_scope(), length
);
2362 memcpy(tmp
+ 1, secret
->data
, secret
->length
);
2365 secret
->length
= length
;
2367 ssh_hash_buffer_put_string(global_data
->kex_shared_secret
, secret
->data
, secret
->length
);
2369 wmem_array_t
* kex_gex_p
= wmem_array_new(wmem_packet_scope(), 1);
2370 if(global_data
->kex_gex_p
){ssh_hash_buffer_put_string(kex_gex_p
, global_data
->kex_gex_p
->data
, global_data
->kex_gex_p
->length
);}
2371 wmem_array_t
* kex_gex_g
= wmem_array_new(wmem_packet_scope(), 1);
2372 if(global_data
->kex_gex_g
){ssh_hash_buffer_put_string(kex_gex_g
, global_data
->kex_gex_g
->data
, global_data
->kex_gex_g
->length
);}
2373 wmem_array_t
* kex_e
= wmem_array_new(wmem_packet_scope(), 1);
2374 if(global_data
->kex_e
){ssh_hash_buffer_put_string(kex_e
, global_data
->kex_e
->data
, global_data
->kex_e
->length
);}
2375 wmem_array_t
* kex_f
= wmem_array_new(wmem_packet_scope(), 1);
2376 if(global_data
->kex_f
){ssh_hash_buffer_put_string(kex_f
, global_data
->kex_f
->data
, global_data
->kex_f
->length
);}
2378 wmem_array_t
* kex_hash_buffer
= wmem_array_new(wmem_packet_scope(), 1);
2379 ssh_print_data("client_version", (const unsigned char *)wmem_array_get_raw(global_data
->kex_client_version
), wmem_array_get_count(global_data
->kex_client_version
));
2380 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(global_data
->kex_client_version
), wmem_array_get_count(global_data
->kex_client_version
));
2381 ssh_print_data("server_version", (const unsigned char *)wmem_array_get_raw(global_data
->kex_server_version
), wmem_array_get_count(global_data
->kex_server_version
));
2382 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(global_data
->kex_server_version
), wmem_array_get_count(global_data
->kex_server_version
));
2383 ssh_print_data("client_key_exchange_init", (const unsigned char *)wmem_array_get_raw(global_data
->kex_client_key_exchange_init
), wmem_array_get_count(global_data
->kex_client_key_exchange_init
));
2384 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(global_data
->kex_client_key_exchange_init
), wmem_array_get_count(global_data
->kex_client_key_exchange_init
));
2385 ssh_print_data("server_key_exchange_init", (const unsigned char *)wmem_array_get_raw(global_data
->kex_server_key_exchange_init
), wmem_array_get_count(global_data
->kex_server_key_exchange_init
));
2386 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(global_data
->kex_server_key_exchange_init
), wmem_array_get_count(global_data
->kex_server_key_exchange_init
));
2387 ssh_print_data("kex_server_host_key_blob", (const unsigned char *)wmem_array_get_raw(global_data
->kex_server_host_key_blob
), wmem_array_get_count(global_data
->kex_server_host_key_blob
));
2388 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(global_data
->kex_server_host_key_blob
), wmem_array_get_count(global_data
->kex_server_host_key_blob
));
2389 if(kex_type
==SSH_KEX_DH_GEX
){
2390 ssh_print_data("kex_gex_bits_min", (const unsigned char *)wmem_array_get_raw(global_data
->kex_gex_bits_min
), wmem_array_get_count(global_data
->kex_gex_bits_min
));
2391 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(global_data
->kex_gex_bits_min
), wmem_array_get_count(global_data
->kex_gex_bits_min
));
2392 ssh_print_data("kex_gex_bits_req", (const unsigned char *)wmem_array_get_raw(global_data
->kex_gex_bits_req
), wmem_array_get_count(global_data
->kex_gex_bits_req
));
2393 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(global_data
->kex_gex_bits_req
), wmem_array_get_count(global_data
->kex_gex_bits_req
));
2394 ssh_print_data("kex_gex_bits_max", (const unsigned char *)wmem_array_get_raw(global_data
->kex_gex_bits_max
), wmem_array_get_count(global_data
->kex_gex_bits_max
));
2395 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(global_data
->kex_gex_bits_max
), wmem_array_get_count(global_data
->kex_gex_bits_max
));
2396 ssh_print_data("key modulo (p)", (const unsigned char *)wmem_array_get_raw(kex_gex_p
), wmem_array_get_count(kex_gex_p
));
2397 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(kex_gex_p
), wmem_array_get_count(kex_gex_p
));
2398 ssh_print_data("key base (g)", (const unsigned char *)wmem_array_get_raw(kex_gex_g
), wmem_array_get_count(kex_gex_g
));
2399 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(kex_gex_g
), wmem_array_get_count(kex_gex_g
));
2400 ssh_print_data("key client (e)", (const unsigned char *)wmem_array_get_raw(kex_e
), wmem_array_get_count(kex_e
));
2401 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(kex_e
), wmem_array_get_count(kex_e
));
2402 ssh_print_data("key server (f)", (const unsigned char *)wmem_array_get_raw(kex_f
), wmem_array_get_count(kex_f
));
2403 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(kex_f
), wmem_array_get_count(kex_f
));
2405 if(kex_type
==SSH_KEX_DH_GROUP1
|| kex_type
==SSH_KEX_DH_GROUP14
|| kex_type
==SSH_KEX_DH_GROUP16
|| kex_type
==SSH_KEX_DH_GROUP18
){
2406 ssh_print_data("key client (e)", (const unsigned char *)wmem_array_get_raw(kex_e
), wmem_array_get_count(kex_e
));
2407 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(kex_e
), wmem_array_get_count(kex_e
));
2408 ssh_print_data("key server (f)", (const unsigned char *)wmem_array_get_raw(kex_f
), wmem_array_get_count(kex_f
));
2409 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(kex_f
), wmem_array_get_count(kex_f
));
2411 if(kex_type
==SSH_KEX_CURVE25519
){
2412 ssh_print_data("key client (Q_C)", (const unsigned char *)wmem_array_get_raw(kex_e
), wmem_array_get_count(kex_e
));
2413 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(kex_e
), wmem_array_get_count(kex_e
));
2414 ssh_print_data("key server (Q_S)", (const unsigned char *)wmem_array_get_raw(kex_f
), wmem_array_get_count(kex_f
));
2415 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(kex_f
), wmem_array_get_count(kex_f
));
2417 ssh_print_data("shared secret", (const unsigned char *)wmem_array_get_raw(global_data
->kex_shared_secret
), wmem_array_get_count(global_data
->kex_shared_secret
));
2418 wmem_array_append(kex_hash_buffer
, wmem_array_get_raw(global_data
->kex_shared_secret
), wmem_array_get_count(global_data
->kex_shared_secret
));
2420 ssh_print_data("exchange", (const unsigned char *)wmem_array_get_raw(kex_hash_buffer
), wmem_array_get_count(kex_hash_buffer
));
2422 unsigned hash_len
= 32;
2423 if(kex_hash_type
==SSH_KEX_HASH_SHA1
) {
2424 gcry_md_open(&hd
, GCRY_MD_SHA1
, 0);
2426 } else if(kex_hash_type
==SSH_KEX_HASH_SHA256
) {
2427 gcry_md_open(&hd
, GCRY_MD_SHA256
, 0);
2429 } else if(kex_hash_type
==SSH_KEX_HASH_SHA512
) {
2430 gcry_md_open(&hd
, GCRY_MD_SHA512
, 0);
2433 ws_debug("kex_hash_type type %d not supported", kex_hash_type
);
2436 char *exchange_hash
= (char *)wmem_alloc0(wmem_file_scope(), hash_len
);
2437 gcry_md_write(hd
, wmem_array_get_raw(kex_hash_buffer
), wmem_array_get_count(kex_hash_buffer
));
2438 memcpy(exchange_hash
, gcry_md_read(hd
, 0), hash_len
);
2440 ssh_print_data("hash", exchange_hash
, hash_len
);
2441 global_data
->secret
= secret
;
2442 ssh_derive_symmetric_keys(secret
, exchange_hash
, hash_len
, global_data
);
2445 // the purpose of this function is to deal with all different kex methods
2447 ssh_kex_shared_secret(int kex_type
, ssh_bignum
*pub
, ssh_bignum
*priv
, ssh_bignum
*modulo
)
2449 DISSECTOR_ASSERT(pub
!= NULL
);
2450 DISSECTOR_ASSERT(priv
!= NULL
);
2452 ssh_bignum
*secret
= ssh_kex_make_bignum(NULL
, pub
->length
);
2454 ws_debug("invalid key length %u", pub
->length
);
2458 if(kex_type
==SSH_KEX_DH_GEX
){
2459 gcry_mpi_t b
= NULL
;
2460 gcry_mpi_scan(&b
, GCRYMPI_FMT_USG
, pub
->data
, pub
->length
, NULL
);
2461 gcry_mpi_t d
= NULL
, e
= NULL
, m
= NULL
;
2462 size_t result_len
= 0;
2463 d
= gcry_mpi_new(pub
->length
*8);
2464 gcry_mpi_scan(&e
, GCRYMPI_FMT_USG
, priv
->data
, priv
->length
, NULL
);
2465 gcry_mpi_scan(&m
, GCRYMPI_FMT_USG
, modulo
->data
, modulo
->length
, NULL
);
2466 gcry_mpi_powm(d
, b
, e
, m
); // gcry_mpi_powm(d, b, e, m) => d = b^e % m
2467 gcry_mpi_print(GCRYMPI_FMT_USG
, secret
->data
, secret
->length
, &result_len
, d
);
2468 secret
->length
= (unsigned)result_len
; // Should not be larger than what fits in a 32-bit unsigned integer...
2469 gcry_mpi_release(d
);
2470 gcry_mpi_release(b
);
2471 gcry_mpi_release(e
);
2472 gcry_mpi_release(m
);
2474 }else if(kex_type
==SSH_KEX_DH_GROUP1
|| kex_type
==SSH_KEX_DH_GROUP14
|| kex_type
==SSH_KEX_DH_GROUP16
|| kex_type
==SSH_KEX_DH_GROUP18
){
2475 gcry_mpi_t m
= NULL
;
2476 if(kex_type
==SSH_KEX_DH_GROUP1
){
2477 static const uint8_t p
[] = {
2478 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
2479 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
2480 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
2481 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
2482 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
2483 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
2484 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
2485 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,};
2486 gcry_mpi_scan(&m
, GCRYMPI_FMT_USG
, p
, sizeof(p
), NULL
);
2487 }else if(kex_type
==SSH_KEX_DH_GROUP14
){
2488 //p:FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF
2489 static const uint8_t p
[] = {
2490 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
2491 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
2492 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
2493 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
2494 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
2495 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
2496 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
2497 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
2498 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
2499 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
2500 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
2501 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
2502 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
2503 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
2504 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
2505 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2506 gcry_mpi_scan(&m
, GCRYMPI_FMT_USG
, p
, sizeof(p
), NULL
);
2507 }else if(kex_type
==SSH_KEX_DH_GROUP16
){
2508 //p:FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF
2509 static const uint8_t p
[] = {
2510 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
2511 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
2512 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
2513 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
2514 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
2515 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
2516 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
2517 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
2518 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
2519 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
2520 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
2521 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
2522 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
2523 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
2524 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
2525 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
2526 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
2527 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
2528 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
2529 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
2530 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
2531 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
2532 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
2533 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
2534 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
2535 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
2536 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
2537 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
2538 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
2539 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
2540 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
2541 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,};
2542 gcry_mpi_scan(&m
, GCRYMPI_FMT_USG
, p
, sizeof(p
), NULL
);
2543 }else if(kex_type
==SSH_KEX_DH_GROUP18
){
2544 //p:FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1BDB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AACC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E438777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851DF9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F924009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF
2545 static const uint8_t p
[] = {
2546 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34,
2547 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74,
2548 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
2549 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37,
2550 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6,
2551 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
2552 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6,
2553 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05,
2554 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
2555 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB,
2556 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04,
2557 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
2558 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F,
2559 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18,
2560 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
2561 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33,
2562 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A,
2563 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
2564 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D,
2565 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64,
2566 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
2567 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2,
2568 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E,
2569 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
2570 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C,
2571 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8,
2572 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
2573 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2,
2574 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF,
2575 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
2576 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F,
2577 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26,
2578 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
2579 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE,
2580 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18,
2581 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
2582 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42,
2583 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC,
2584 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
2585 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E,
2586 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE,
2587 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
2588 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0,
2589 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76,
2590 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
2591 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68,
2592 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6,
2593 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xBE, 0x11, 0x59, 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4,
2594 0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, 0xD8, 0xBE, 0xC4, 0xD0, 0x73, 0xB9, 0x31, 0xBA,
2595 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00, 0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED,
2596 0x25, 0x76, 0xF6, 0x93, 0x6B, 0xA4, 0x24, 0x66, 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68,
2597 0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, 0x23, 0x8F, 0x16, 0xCB, 0xE3, 0x9D, 0x65, 0x2D,
2598 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9, 0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07,
2599 0x13, 0xEB, 0x57, 0xA8, 0x1A, 0x23, 0xF0, 0xC7, 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B,
2600 0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, 0xFA, 0x9D, 0x4B, 0x7F, 0xA2, 0xC0, 0x87, 0xE8,
2601 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A, 0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6,
2602 0x6D, 0x2A, 0x13, 0xF8, 0x3F, 0x44, 0xF8, 0x2D, 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36,
2603 0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, 0x64, 0xF3, 0x1C, 0xC5, 0x08, 0x46, 0x85, 0x1D,
2604 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1, 0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73,
2605 0xFA, 0xF3, 0x6B, 0xC3, 0x1E, 0xCF, 0xA2, 0x68, 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92,
2606 0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, 0x88, 0x9A, 0x00, 0x2E, 0xD5, 0xEE, 0x38, 0x2B,
2607 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47, 0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA,
2608 0x9E, 0x30, 0x50, 0xE2, 0x76, 0x56, 0x94, 0xDF, 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71,
2609 0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,};
2610 gcry_mpi_scan(&m
, GCRYMPI_FMT_USG
, p
, sizeof(p
), NULL
);
2613 gcry_mpi_t b
= NULL
;
2614 gcry_mpi_scan(&b
, GCRYMPI_FMT_USG
, pub
->data
, pub
->length
, NULL
);
2615 gcry_mpi_t d
= NULL
, e
= NULL
;
2616 size_t result_len
= 0;
2617 d
= gcry_mpi_new(pub
->length
*8);
2618 gcry_mpi_scan(&e
, GCRYMPI_FMT_USG
, priv
->data
, priv
->length
, NULL
);
2619 gcry_mpi_powm(d
, b
, e
, m
); // gcry_mpi_powm(d, b, e, m) => d = b^e % m
2620 gcry_mpi_print(GCRYMPI_FMT_USG
, secret
->data
, secret
->length
, &result_len
, d
);
2621 secret
->length
= (unsigned)result_len
; // Should not be larger than what fits in a 32-bit unsigned integer...
2622 gcry_mpi_release(d
);
2623 gcry_mpi_release(b
);
2624 gcry_mpi_release(e
);
2625 gcry_mpi_release(m
);
2626 }else if(kex_type
==SSH_KEX_CURVE25519
){
2627 if (crypto_scalarmult_curve25519(secret
->data
, priv
->data
, pub
->data
)) {
2628 ws_debug("curve25519: can't compute shared secret");
2632 ws_debug("kex_type type %d not supported", kex_type
);
2640 ssh_string(const char *string
, unsigned length
)
2642 char *ssh_string
= (char *)wmem_alloc(wmem_packet_scope(), length
+ 4);
2643 ssh_string
[0] = (length
>> 24) & 0xff;
2644 ssh_string
[1] = (length
>> 16) & 0xff;
2645 ssh_string
[2] = (length
>> 8) & 0xff;
2646 ssh_string
[3] = length
& 0xff;
2647 memcpy(ssh_string
+ 4, string
, length
);
2652 ssh_hash_buffer_put_string(wmem_array_t
*buffer
, const char *string
,
2659 char *string_with_length
= ssh_string(string
, length
);
2660 wmem_array_append(buffer
, string_with_length
, length
+ 4);
2664 ssh_hash_buffer_put_uint32(wmem_array_t
*buffer
, unsigned val
)
2671 buf
[0] = (val
>> 24); buf
[1] = (val
>> 16); buf
[2] = (val
>> 8); buf
[3] = (val
>> 0);
2672 wmem_array_append(buffer
, buf
, 4);
2675 static void ssh_derive_symmetric_keys(ssh_bignum
*secret
, char *exchange_hash
,
2676 unsigned hash_length
, struct ssh_flow_data
*global_data
)
2678 if (!global_data
->session_id
) {
2679 global_data
->session_id
= exchange_hash
;
2680 global_data
->session_id_length
= hash_length
;
2683 unsigned int we_need
= 0;
2684 for(int peer_cnt
=0;peer_cnt
<2;peer_cnt
++){
2685 struct ssh_peer_data
* peer_data
= &global_data
->peer_data
[peer_cnt
];
2686 // required size of key depends on cipher used. chacha20 wants 64 bytes
2688 if (GCRY_CIPHER_CHACHA20
== peer_data
->cipher_id
) {
2690 } else if (CIPHER_AES128_CBC
== peer_data
->cipher_id
|| CIPHER_AES128_CTR
== peer_data
->cipher_id
|| CIPHER_AES128_GCM
== peer_data
->cipher_id
) {
2692 } else if (CIPHER_AES192_CBC
== peer_data
->cipher_id
|| CIPHER_AES192_CTR
== peer_data
->cipher_id
) {
2694 } else if (CIPHER_AES256_CBC
== peer_data
->cipher_id
|| CIPHER_AES256_CTR
== peer_data
->cipher_id
|| CIPHER_AES256_GCM
== peer_data
->cipher_id
) {
2697 ssh_debug_printf("ssh: cipher (%d) is unknown or not set\n", peer_data
->cipher_id
);
2700 if(peer_data
->mac_id
== CIPHER_MAC_SHA2_256
){
2703 ssh_debug_printf("ssh: MAC (%d) is unknown or not set\n", peer_data
->mac_id
);
2711 for (int i
= 0; i
< 6; i
++) {
2712 ssh_derive_symmetric_key(secret
, exchange_hash
, hash_length
,
2713 'A' + i
, &global_data
->new_keys
[i
], global_data
, we_need
);
2714 if(i
==0){ ssh_print_data("Initial IV client to server", global_data
->new_keys
[i
].data
, global_data
->new_keys
[i
].length
);
2715 }else if(i
==1){ ssh_print_data("Initial IV server to client", global_data
->new_keys
[i
].data
, global_data
->new_keys
[i
].length
);
2716 }else if(i
==2){ ssh_print_data("Encryption key client to server", global_data
->new_keys
[i
].data
, global_data
->new_keys
[i
].length
);
2717 }else if(i
==3){ ssh_print_data("Encryption key server to client", global_data
->new_keys
[i
].data
, global_data
->new_keys
[i
].length
);
2718 }else if(i
==4){ ssh_print_data("Integrity key client to server", global_data
->new_keys
[i
].data
, global_data
->new_keys
[i
].length
);
2719 }else if(i
==5){ ssh_print_data("Integrity key server to client", global_data
->new_keys
[i
].data
, global_data
->new_keys
[i
].length
);
2724 static void ssh_derive_symmetric_key(ssh_bignum
*secret
, char *exchange_hash
,
2725 unsigned hash_length
, char id
, ssh_bignum
*result_key
,
2726 struct ssh_flow_data
*global_data
, unsigned we_need
)
2730 unsigned kex_hash_type
= ssh_kex_hash_type(global_data
->kex
);
2731 int algo
= GCRY_MD_SHA256
;
2732 if(kex_hash_type
==SSH_KEX_HASH_SHA1
){
2733 algo
= GCRY_MD_SHA1
;
2734 }else if(kex_hash_type
==SSH_KEX_HASH_SHA256
){
2735 algo
= GCRY_MD_SHA256
;
2736 }else if(kex_hash_type
==SSH_KEX_HASH_SHA512
){
2737 algo
= GCRY_MD_SHA512
;
2739 unsigned len
= gcry_md_get_algo_dlen(algo
);
2741 result_key
->data
= (unsigned char *)wmem_alloc(wmem_file_scope(), we_need
);
2743 char *secret_with_length
= ssh_string(secret
->data
, secret
->length
);
2745 if (gcry_md_open(&hd
, algo
, 0) == 0) {
2746 gcry_md_write(hd
, secret_with_length
, secret
->length
+ 4);
2747 gcry_md_write(hd
, exchange_hash
, hash_length
);
2748 gcry_md_putc(hd
, id
);
2749 gcry_md_write(hd
, global_data
->session_id
, hash_length
);
2750 unsigned add_length
= MIN(len
, we_need
);
2751 memcpy(result_key
->data
, gcry_md_read(hd
, 0), add_length
);
2756 for (unsigned have
= len
; have
< we_need
; have
+= len
) {
2757 if (gcry_md_open(&hd
, algo
, 0) == 0) {
2758 gcry_md_write(hd
, secret_with_length
, secret
->length
+ 4);
2759 gcry_md_write(hd
, exchange_hash
, hash_length
);
2760 gcry_md_write(hd
, result_key
->data
+have
-len
, len
);
2761 unsigned add_length
= MIN(len
, we_need
- have
);
2762 memcpy(result_key
->data
+have
, gcry_md_read(hd
, 0), add_length
);
2767 result_key
->length
= we_need
;
2771 ssh_choose_enc_mac(struct ssh_flow_data
*global_data
)
2773 for(int peer_cnt
=0;peer_cnt
<2;peer_cnt
++){
2774 struct ssh_peer_data
* peer_data
= &global_data
->peer_data
[peer_cnt
];
2775 ssh_choose_algo(global_data
->peer_data
[CLIENT_PEER_DATA
].enc_proposals
[peer_cnt
],
2776 global_data
->peer_data
[SERVER_PEER_DATA
].enc_proposals
[peer_cnt
],
2778 /* some ciphers have their own MAC so the "negotiated" one is meaningless */
2779 if(peer_data
->enc
&& (0 == strcmp(peer_data
->enc
, "aes128-gcm@openssh.com") ||
2780 0 == strcmp(peer_data
->enc
, "aes256-gcm@openssh.com"))) {
2781 peer_data
->mac
= wmem_strdup(wmem_file_scope(), (const char *)"<implicit>");
2782 peer_data
->mac_length
= 16;
2783 peer_data
->length_is_plaintext
= 1;
2785 else if(peer_data
->enc
&& 0 == strcmp(peer_data
->enc
, "chacha20-poly1305@openssh.com")) {
2786 peer_data
->mac
= wmem_strdup(wmem_file_scope(), (const char *)"<implicit>");
2787 peer_data
->mac_length
= 16;
2790 ssh_choose_algo(global_data
->peer_data
[CLIENT_PEER_DATA
].mac_proposals
[peer_cnt
],
2791 global_data
->peer_data
[SERVER_PEER_DATA
].mac_proposals
[peer_cnt
],
2793 ssh_set_mac_length(peer_data
);
2795 ssh_choose_algo(global_data
->peer_data
[CLIENT_PEER_DATA
].comp_proposals
[peer_cnt
],
2796 global_data
->peer_data
[SERVER_PEER_DATA
].comp_proposals
[peer_cnt
],
2800 ssh_decryption_set_cipher_id(&global_data
->peer_data
[CLIENT_PEER_DATA
]);
2801 ssh_decryption_set_mac_id(&global_data
->peer_data
[CLIENT_PEER_DATA
]);
2802 ssh_decryption_set_cipher_id(&global_data
->peer_data
[SERVER_PEER_DATA
]);
2803 ssh_decryption_set_mac_id(&global_data
->peer_data
[SERVER_PEER_DATA
]);
2807 ssh_decryption_set_cipher_id(struct ssh_peer_data
*peer
)
2809 char *cipher_name
= peer
->enc
;
2812 peer
->cipher
= NULL
;
2813 ws_debug("ERROR: cipher_name is NULL");
2814 } else if (0 == strcmp(cipher_name
, "chacha20-poly1305@openssh.com")) {
2815 peer
->cipher_id
= GCRY_CIPHER_CHACHA20
;
2816 } else if (0 == strcmp(cipher_name
, "aes128-gcm@openssh.com")) {
2817 peer
->cipher_id
= CIPHER_AES128_GCM
;
2818 } else if (0 == strcmp(cipher_name
, "aes128-gcm")) {
2819 peer
->cipher_id
= CIPHER_AES128_GCM
;
2820 } else if (0 == strcmp(cipher_name
, "aes256-gcm@openssh.com")) {
2821 peer
->cipher_id
= CIPHER_AES256_GCM
;
2822 } else if (0 == strcmp(cipher_name
, "aes256-gcm")) {
2823 peer
->cipher_id
= CIPHER_AES256_GCM
;
2824 } else if (0 == strcmp(cipher_name
, "aes128-cbc")) {
2825 peer
->cipher_id
= CIPHER_AES128_CBC
;
2826 } else if (0 == strcmp(cipher_name
, "aes192-cbc")) {
2827 peer
->cipher_id
= CIPHER_AES192_CBC
;
2828 } else if (0 == strcmp(cipher_name
, "aes256-cbc")) {
2829 peer
->cipher_id
= CIPHER_AES256_CBC
;
2830 } else if (0 == strcmp(cipher_name
, "aes128-ctr")) {
2831 peer
->cipher_id
= CIPHER_AES128_CTR
;
2832 } else if (0 == strcmp(cipher_name
, "aes192-ctr")) {
2833 peer
->cipher_id
= CIPHER_AES192_CTR
;
2834 } else if (0 == strcmp(cipher_name
, "aes256-ctr")) {
2835 peer
->cipher_id
= CIPHER_AES256_CTR
;
2837 peer
->cipher
= NULL
;
2838 ws_debug("decryption not supported: %s", cipher_name
);
2843 ssh_decryption_set_mac_id(struct ssh_peer_data
*peer
)
2845 char *mac_name
= peer
->mac
;
2849 ws_debug("ERROR: mac_name is NULL");
2850 } else if (0 == strcmp(mac_name
, "hmac-sha2-256")) {
2851 peer
->mac_id
= CIPHER_MAC_SHA2_256
;
2853 ws_debug("decryption MAC not supported: %s", mac_name
);
2858 gcry_cipher_destroy_cb(wmem_allocator_t
*allocator _U_
, wmem_cb_event_t event _U_
, void *user_data
)
2860 gcry_cipher_hd_t hd
= (gcry_cipher_hd_t
)user_data
;
2862 gcry_cipher_close(hd
);
2868 ssh_decryption_setup_cipher(struct ssh_peer_data
*peer_data
,
2869 ssh_bignum
*iv
, ssh_bignum
*key
)
2872 gcry_cipher_hd_t
*hd1
, *hd2
;
2874 hd1
= &peer_data
->cipher
;
2875 hd2
= &peer_data
->cipher_2
;
2877 if (GCRY_CIPHER_CHACHA20
== peer_data
->cipher_id
) {
2878 if (gcry_cipher_open(hd1
, GCRY_CIPHER_CHACHA20
, GCRY_CIPHER_MODE_STREAM
, 0) ||
2879 gcry_cipher_open(hd2
, GCRY_CIPHER_CHACHA20
, GCRY_CIPHER_MODE_STREAM
, 0)) {
2880 gcry_cipher_close(*hd1
);
2881 gcry_cipher_close(*hd2
);
2882 ws_debug("ssh: can't open chacha20 cipher handles");
2889 memcpy(k1
, key
->data
, 32);
2890 memcpy(k2
, key
->data
+ 32, 32);
2896 ssh_debug_printf("ssh: cipher is chacha20\n");
2897 ssh_print_data("key 1", k1
, 32);
2898 ssh_print_data("key 2", k2
, 32);
2900 if ((err
= gcry_cipher_setkey(*hd1
, k1
, 32))) {
2901 gcry_cipher_close(*hd1
);
2902 ws_debug("ssh: can't set chacha20 cipher key %s", gcry_strerror(err
));
2906 if ((err
= gcry_cipher_setkey(*hd2
, k2
, 32))) {
2907 gcry_cipher_close(*hd1
);
2908 gcry_cipher_close(*hd2
);
2909 ws_debug("ssh: can't set chacha20 cipher key %s", gcry_strerror(err
));
2913 wmem_register_callback(wmem_file_scope(), gcry_cipher_destroy_cb
, *hd1
);
2914 wmem_register_callback(wmem_file_scope(), gcry_cipher_destroy_cb
, *hd2
);
2916 } else if (CIPHER_AES128_CBC
== peer_data
->cipher_id
|| CIPHER_AES192_CBC
== peer_data
->cipher_id
|| CIPHER_AES256_CBC
== peer_data
->cipher_id
) {
2917 int iKeyLen
= CIPHER_AES128_CBC
== peer_data
->cipher_id
?16:CIPHER_AES192_CBC
== peer_data
->cipher_id
?24:32;
2918 if (gcry_cipher_open(hd1
, CIPHER_AES128_CBC
== peer_data
->cipher_id
?GCRY_CIPHER_AES128
:CIPHER_AES192_CBC
== peer_data
->cipher_id
?GCRY_CIPHER_AES192
:GCRY_CIPHER_AES256
, GCRY_CIPHER_MODE_CBC
, 0)) {
2919 gcry_cipher_close(*hd1
);
2920 ws_debug("ssh: can't open aes%d cipher handle", iKeyLen
*8);
2923 char k1
[32], iv1
[16];
2925 memcpy(k1
, key
->data
, iKeyLen
);
2927 memset(k1
, 0, iKeyLen
);
2930 memcpy(iv1
, iv
->data
, 16);
2935 ssh_debug_printf("ssh: cipher is aes%d-cbc\n", iKeyLen
*8);
2936 ssh_print_data("key", k1
, iKeyLen
);
2937 ssh_print_data("iv", iv1
, 16);
2939 if ((err
= gcry_cipher_setkey(*hd1
, k1
, iKeyLen
))) {
2940 gcry_cipher_close(*hd1
);
2941 ws_debug("ssh: can't set aes%d cipher key", iKeyLen
*8);
2942 ws_debug("libgcrypt: %d %s %s", gcry_err_code(err
), gcry_strsource(err
), gcry_strerror(err
));
2946 if ((err
= gcry_cipher_setiv(*hd1
, iv1
, 16))) {
2947 gcry_cipher_close(*hd1
);
2948 ws_debug("ssh: can't set aes%d cipher iv", iKeyLen
*8);
2949 ws_debug("libgcrypt: %d %s %s", gcry_err_code(err
), gcry_strsource(err
), gcry_strerror(err
));
2953 wmem_register_callback(wmem_file_scope(), gcry_cipher_destroy_cb
, *hd1
);
2955 } else if (CIPHER_AES128_CTR
== peer_data
->cipher_id
|| CIPHER_AES192_CTR
== peer_data
->cipher_id
|| CIPHER_AES256_CTR
== peer_data
->cipher_id
) {
2956 int iKeyLen
= CIPHER_AES128_CTR
== peer_data
->cipher_id
?16:CIPHER_AES192_CTR
== peer_data
->cipher_id
?24:32;
2957 if (gcry_cipher_open(hd1
, CIPHER_AES128_CTR
== peer_data
->cipher_id
?GCRY_CIPHER_AES128
:CIPHER_AES192_CTR
== peer_data
->cipher_id
?GCRY_CIPHER_AES192
:GCRY_CIPHER_AES256
, GCRY_CIPHER_MODE_CTR
, 0)) {
2958 gcry_cipher_close(*hd1
);
2959 ws_debug("ssh: can't open aes%d cipher handle", iKeyLen
*8);
2962 char k1
[32], iv1
[16];
2964 memcpy(k1
, key
->data
, iKeyLen
);
2966 memset(k1
, 0, iKeyLen
);
2969 memcpy(iv1
, iv
->data
, 16);
2974 ssh_debug_printf("ssh: cipher is aes%d-ctr\n", iKeyLen
*8);
2975 ssh_print_data("key", k1
, iKeyLen
);
2976 ssh_print_data("iv", iv1
, 16);
2978 if ((err
= gcry_cipher_setkey(*hd1
, k1
, iKeyLen
))) {
2979 gcry_cipher_close(*hd1
);
2980 ws_debug("ssh: can't set aes%d cipher key", iKeyLen
*8);
2981 ws_debug("libgcrypt: %d %s %s", gcry_err_code(err
), gcry_strsource(err
), gcry_strerror(err
));
2985 if ((err
= gcry_cipher_setctr(*hd1
, iv1
, 16))) {
2986 gcry_cipher_close(*hd1
);
2987 ws_debug("ssh: can't set aes%d cipher iv", iKeyLen
*8);
2988 ws_debug("libgcrypt: %d %s %s", gcry_err_code(err
), gcry_strsource(err
), gcry_strerror(err
));
2992 wmem_register_callback(wmem_file_scope(), gcry_cipher_destroy_cb
, *hd1
);
2994 } else if (CIPHER_AES128_GCM
== peer_data
->cipher_id
|| CIPHER_AES256_GCM
== peer_data
->cipher_id
) {
2995 int iKeyLen
= CIPHER_AES128_GCM
== peer_data
->cipher_id
?16:32;
2996 if (gcry_cipher_open(hd1
, CIPHER_AES128_GCM
== peer_data
->cipher_id
?GCRY_CIPHER_AES128
:GCRY_CIPHER_AES256
, GCRY_CIPHER_MODE_GCM
, 0)) {
2997 gcry_cipher_close(*hd1
);
2998 ws_debug("ssh: can't open aes%d cipher handle", iKeyLen
*8);
3002 char k1
[32], iv2
[12];
3004 memcpy(k1
, key
->data
, iKeyLen
);
3006 memset(k1
, 0, iKeyLen
);
3009 memcpy(peer_data
->iv
, iv
->data
, 12);
3014 ssh_debug_printf("ssh: cipher is aes%d-gcm\n", iKeyLen
*8);
3015 ssh_print_data("key", k1
, iKeyLen
);
3016 ssh_print_data("iv", peer_data
->iv
, 12);
3018 if ((err
= gcry_cipher_setkey(*hd1
, k1
, iKeyLen
))) {
3019 gcry_cipher_close(*hd1
);
3020 ws_debug("ssh: can't set aes%d cipher key", iKeyLen
*8);
3021 ws_debug("libgcrypt: %d %s %s", gcry_err_code(err
), gcry_strsource(err
), gcry_strerror(err
));
3025 wmem_register_callback(wmem_file_scope(), gcry_cipher_destroy_cb
, *hd1
);
3028 ssh_debug_printf("ssh: cipher (%d) is unknown or not set\n", peer_data
->cipher_id
);
3033 ssh_decryption_setup_mac(struct ssh_peer_data
*peer_data
,
3036 if(peer_data
->mac_id
== CIPHER_MAC_SHA2_256
){
3038 memcpy(peer_data
->hmac_iv
, iv
->data
, 32);
3040 memset(peer_data
->hmac_iv
, 0, 32);
3042 peer_data
->hmac_iv_len
= 32;
3043 ssh_debug_printf("ssh: mac is hmac-sha2-256\n");
3044 ssh_print_data("iv", peer_data
->hmac_iv
, peer_data
->hmac_iv_len
);
3046 ws_debug("ssh: unsupported MAC");
3050 /* libgcrypt wrappers for HMAC/message digest operations {{{ */
3051 /* hmac abstraction layer */
3052 #define SSH_HMAC gcry_md_hd_t
3055 ssh_hmac_init(SSH_HMAC
* md
, const void * key
, int len
, int algo
)
3058 const char *err_str
, *err_src
;
3060 err
= gcry_md_open(md
,algo
, GCRY_MD_FLAG_HMAC
);
3062 err_str
= gcry_strerror(err
);
3063 err_src
= gcry_strsource(err
);
3064 ssh_debug_printf("ssh_hmac_init(): gcry_md_open failed %s/%s", err_str
, err_src
);
3067 err
= gcry_md_setkey(*(md
), key
, len
);
3069 err_str
= gcry_strerror(err
);
3070 err_src
= gcry_strsource(err
);
3071 ssh_debug_printf("ssh_hmac_init(): gcry_md_setkey(..., ..., %d) failed %s/%s", len
, err_str
, err_src
);
3078 ssh_hmac_update(SSH_HMAC
* md
, const void* data
, int len
)
3080 gcry_md_write(*(md
), data
, len
);
3084 ssh_hmac_final(SSH_HMAC
* md
, unsigned char* data
, unsigned* datalen
)
3089 algo
= gcry_md_get_algo (*(md
));
3090 len
= gcry_md_get_algo_dlen(algo
);
3091 DISSECTOR_ASSERT(len
<= *datalen
);
3092 memcpy(data
, gcry_md_read(*(md
), algo
), len
);
3097 ssh_hmac_cleanup(SSH_HMAC
* md
)
3099 gcry_md_close(*(md
));
3101 /* libgcrypt wrappers for HMAC/message digest operations }}} */
3103 /* Decryption integrity check {{{ */
3106 ssh_get_digest_by_id(unsigned mac_id
)
3108 if(mac_id
==CIPHER_MAC_SHA2_256
){
3109 return GCRY_MD_SHA256
;
3115 ssh_calc_mac(struct ssh_peer_data
*peer_data
, uint32_t seqnr
, uint8_t* data
, uint32_t datalen
, uint8_t* calc_mac
)
3120 uint8_t buf
[DIGEST_MAX_SIZE
];
3122 md
=ssh_get_digest_by_id(peer_data
->mac_id
);
3123 // ssl_debug_printf("ssh_check_mac mac type:%s md %d\n",
3124 // ssl_cipher_suite_dig(decoder->cipher_suite)->name, md);
3126 memset(calc_mac
, 0, DIGEST_MAX_SIZE
);
3128 if (ssh_hmac_init(&hm
, peer_data
->hmac_iv
, peer_data
->hmac_iv_len
,md
) != 0)
3131 /* hash sequence number */
3132 phton32(buf
, seqnr
);
3134 ssh_print_data("Mac IV", peer_data
->hmac_iv
, peer_data
->hmac_iv_len
);
3135 ssh_print_data("Mac seq", buf
, 4);
3136 ssh_print_data("Mac data", data
, datalen
);
3138 ssh_hmac_update(&hm
,buf
,4);
3140 ssh_hmac_update(&hm
,data
,datalen
);
3142 /* get digest and digest len*/
3144 ssh_hmac_final(&hm
,buf
,&len
);
3145 ssh_hmac_cleanup(&hm
);
3146 ssh_print_data("Mac", buf
, len
);
3147 memcpy(calc_mac
, buf
, len
);
3151 /* Decryption integrity check }}} */
3154 ssh_increment_message_number(packet_info
*pinfo
, struct ssh_flow_data
*global_data
,
3157 if (!PINFO_FD_VISITED(pinfo
)) {
3158 ssh_packet_info_t
* packet
= (ssh_packet_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_ssh
, 0);
3160 packet
= wmem_new0(wmem_file_scope(), ssh_packet_info_t
);
3161 packet
->from_server
= is_response
;
3162 packet
->messages
= NULL
;
3163 p_add_proto_data(wmem_file_scope(), pinfo
, proto_ssh
, 0, packet
);
3170 ssh_decrypt_packet(tvbuff_t
*tvb
, packet_info
*pinfo
,
3171 struct ssh_peer_data
*peer_data
, int offset
)
3173 bool is_response
= (pinfo
->destport
!= pinfo
->match_uint
);
3176 unsigned message_length
= 0, seqnr
;
3177 char *plain
= NULL
, *mac
;
3178 unsigned mac_len
, data_len
= 0;
3179 uint8_t calc_mac
[DIGEST_MAX_SIZE
];
3180 memset(calc_mac
, 0, DIGEST_MAX_SIZE
);
3182 mac_len
= peer_data
->mac_length
;
3183 seqnr
= peer_data
->sequence_number
;
3185 if (GCRY_CIPHER_CHACHA20
== peer_data
->cipher_id
) {
3186 const char *ctext
= (const char *)tvb_get_ptr(tvb
, offset
, 4);
3187 uint8_t plain_length_buf
[4];
3189 if (!ssh_decrypt_chacha20(peer_data
->cipher_2
, seqnr
, 0, ctext
, 4,
3190 plain_length_buf
, 4)) {
3191 ws_debug("ERROR: could not decrypt packet len");
3192 return tvb_captured_length(tvb
);
3195 message_length
= pntoh32(plain_length_buf
);
3197 ssh_debug_printf("chachapoly_crypt seqnr=%d [%u]\n", seqnr
, message_length
);
3199 ssh_debug_printf("%s plain for seq = %d len = %u\n", is_response
?"s2c":"c2s", seqnr
, message_length
);
3200 if(message_length
>32768){
3201 ws_debug("ssh: unreasonable message length %u", message_length
);
3202 return tvb_captured_length(tvb
);
3205 plain
= (char *)wmem_alloc0(pinfo
->pool
, message_length
+4);
3206 memcpy(plain
, plain_length_buf
, 4);
3207 const char *ctext2
= (const char *)tvb_get_ptr(tvb
, offset
+4,
3210 if (!ssh_decrypt_chacha20(peer_data
->cipher
, seqnr
, 1, ctext2
,
3211 message_length
, plain
+4, message_length
)) {
3212 ws_debug("ERROR: could not decrypt packet payload");
3213 return tvb_captured_length(tvb
);
3216 mac
= (char *)tvb_get_ptr(tvb
, offset
+ 4 + message_length
, mac_len
);
3217 char poly_key
[32], iv
[16];
3219 memset(poly_key
, 0, 32);
3221 phton64(iv
+8, (uint64_t)seqnr
);
3222 gcry_cipher_setiv(peer_data
->cipher
, iv
, mac_len
);
3223 gcry_cipher_encrypt(peer_data
->cipher
, poly_key
, 32, poly_key
, 32);
3225 gcry_mac_hd_t mac_hd
;
3226 gcry_mac_open(&mac_hd
, GCRY_MAC_POLY1305
, 0, NULL
);
3227 gcry_mac_setkey(mac_hd
, poly_key
, 32);
3228 gcry_mac_write(mac_hd
, ctext
, 4);
3229 gcry_mac_write(mac_hd
, ctext2
, message_length
);
3230 if (gcry_mac_verify(mac_hd
, mac
, mac_len
)) {
3231 ws_debug("ssh: MAC does not match");
3233 size_t buflen
= DIGEST_MAX_SIZE
;
3234 gcry_mac_read(mac_hd
, calc_mac
, &buflen
);
3235 gcry_mac_close(mac_hd
);
3237 data_len
= message_length
+ 4;
3239 // ssh_print_data(is_response?"s2c encrypted":"c2s encrypted", ctext2, message_length+4+mac_len);
3240 ssh_debug_printf("%s plain text seq=%d", is_response
?"s2c":"c2s",seqnr
);
3241 ssh_print_data("", plain
, message_length
+4);
3242 } else if (CIPHER_AES128_GCM
== peer_data
->cipher_id
|| CIPHER_AES256_GCM
== peer_data
->cipher_id
) {
3244 /* AES GCM for Secure Shell [RFC 5647] */
3245 /* The message length is Additional Authenticated Data */
3246 /* XXX: If there are fewer than 4 octets available, we need to
3247 * ask the TCP dissector for DESEGMENT_ONE_MORE_SEGMENT instead
3248 * of throwing an exception here, if we're desegmenting.
3250 message_length
= tvb_get_uint32(tvb
, offset
, ENC_BIG_ENDIAN
);
3251 unsigned remaining
= tvb_reported_length_remaining(tvb
, offset
);
3252 ssh_debug_printf("length: %d, remaining: %d\n", message_length
, remaining
);
3253 /* The minimum size of a packet (not counting mac) is 16. */
3254 if (message_length
< 16) {
3255 ws_debug("ssh: unreasonable message length %u", message_length
);
3256 return tvb_captured_length(tvb
);
3259 /* SSH requires that the data to be encrypted (not including the AAD,
3260 * so message_length) be a multiple of the block size, 16 octets */
3261 if (message_length
% 16 != 0) {
3262 ssh_debug_printf("length not a multiple of block length (16)!\n");
3265 /* If tvb_reported_length_remaining(tvb, offset + 4) is less
3266 * than message_length + mac_len, then we should ask the TCP
3267 * dissector for more data if we're desegmenting. That is
3268 * simpler than trying to handle fragmentation ourselves.
3270 const char *ctext
= (const char *)tvb_get_ptr(tvb
, offset
+ 4,
3272 plain
= (char *)wmem_alloc(pinfo
->pool
, message_length
+4);
3273 phton32(plain
, message_length
);
3275 /* gcry_cipher_setiv(peer_data->cipher, iv, 12); */
3276 if ((err
= gcry_cipher_setiv(peer_data
->cipher
, peer_data
->iv
, 12))) {
3277 //gcry_cipher_close(peer_data->cipher);
3278 //Don't close this unless we also remove the wmem callback
3279 // TODO: temporary work-around as long as a Windows python bug is triggered by automated tests
3281 ws_debug("ssh: can't set aes128 cipher iv");
3282 ws_debug("libgcrypt: %d %s %s", gcry_err_code(err
), gcry_strsource(err
), gcry_strerror(err
));
3283 #endif //ndef _WIN32
3284 return tvb_captured_length(tvb
);
3289 peer_data
->iv
[idx
] += 1;
3290 }while(idx
>4 && peer_data
->iv
[idx
]==0);
3292 if ((err
= gcry_cipher_authenticate(peer_data
->cipher
, plain
, 4))) {
3293 // TODO: temporary work-around as long as a Windows python bug is triggered by automated tests
3295 ws_debug("can't authenticate using aes128-gcm: %s\n", gpg_strerror(err
));
3296 #endif //ndef _WIN32
3297 return tvb_captured_length(tvb
);
3300 if ((err
= gcry_cipher_decrypt(peer_data
->cipher
, plain
+4, message_length
,
3301 ctext
, message_length
))) {
3302 // TODO: temporary work-around as long as a Windows python bug is triggered by automated tests
3304 ws_debug("can't decrypt aes-gcm %d %s %s", gcry_err_code(err
), gcry_strsource(err
), gcry_strerror(err
));
3306 #endif //ndef _WIN32
3307 return tvb_captured_length(tvb
);
3310 if (gcry_cipher_gettag (peer_data
->cipher
, calc_mac
, 16)) {
3311 // TODO: temporary work-around as long as a Windows python bug is triggered by automated tests
3313 ws_debug ("aes128-gcm, gcry_cipher_gettag() failed\n");
3314 #endif //ndef _WIN32
3315 return tvb_captured_length(tvb
);
3318 if ((err
= gcry_cipher_reset(peer_data
->cipher
))) {
3319 // TODO: temporary work-around as long as a Windows python bug is triggered by automated tests
3321 ws_debug("aes-gcm, gcry_cipher_reset failed: %s\n", gpg_strerror (err
));
3322 #endif //ndef _WIN32
3323 return tvb_captured_length(tvb
);
3326 data_len
= message_length
+ 4;
3328 // ssh_print_data(is_response?"s2c encrypted":"c2s encrypted", ctl, message_length+4+mac_len);
3329 ssh_debug_printf("%s plain text seq=%d", is_response
?"s2c":"c2s",seqnr
);
3330 ssh_print_data("", plain
, message_length
+4);
3332 } else if (CIPHER_AES128_CBC
== peer_data
->cipher_id
|| CIPHER_AES128_CTR
== peer_data
->cipher_id
||
3333 CIPHER_AES192_CBC
== peer_data
->cipher_id
|| CIPHER_AES192_CTR
== peer_data
->cipher_id
||
3334 CIPHER_AES256_CBC
== peer_data
->cipher_id
|| CIPHER_AES256_CTR
== peer_data
->cipher_id
) {
3336 message_length
= tvb_reported_length_remaining(tvb
, offset
) - 4 - mac_len
;
3338 // TODO: see how to handle fragmentation...
3339 ws_noisy("Getting raw bytes of length %d", tvb_reported_length_remaining(tvb
, offset
));
3340 /* In CBC and CTR mode, the message length is encrypted as well.
3341 * We need to decrypt one block to get the length.
3342 * If we have fewer than 16 octets, and we're doing desegmentation,
3343 * we should tell the TCP dissector we need ONE_MORE_SEGMENT.
3345 const char *cypher_buf0
= (const char *)tvb_get_ptr(tvb
, offset
, 16);
3348 if (gcry_cipher_decrypt(peer_data
->cipher
, plain0
, 16, cypher_buf0
, 16))
3350 ws_debug("can\'t decrypt aes128");
3351 return tvb_captured_length(tvb
);
3354 unsigned message_length_decrypted
= pntoh32(plain0
);
3355 unsigned remaining
= tvb_reported_length_remaining(tvb
, offset
);
3357 /* The message_length value doesn't include the length of the
3358 * message_length field itself, so it must be at least 12 bytes.
3360 if(message_length_decrypted
>32768 || message_length_decrypted
< 12){
3361 ws_debug("ssh: unreasonable message length %u/%u", message_length_decrypted
, message_length
);
3362 return tvb_captured_length(tvb
);
3365 message_length
= message_length_decrypted
;
3366 /* SSH requires that the data to be encrypted (message_length+4)
3367 * be a multiple of the block size, 16 octets. */
3368 if (message_length
% 16 != 12) {
3369 ssh_debug_printf("total length not a multiple of block length (16)!\n");
3371 plain
= (char *)wmem_alloc(pinfo
->pool
, message_length
+4);
3372 memcpy(plain
, plain0
, 16);
3374 /* If we're desegmenting, we want to test if we have enough
3375 * remaining bytes here. It's easier to have the TCP
3376 * dissector put together a PDU based on our length.
3379 if (message_length
- 12 > 0) {
3380 /* All of these functions actually do handle the case where
3381 * there is no data left, so the check is unnecessary.
3383 char *ct
= (char *)tvb_get_ptr(tvb
, offset
+ 16, message_length
- 12);
3384 if ((err
= gcry_cipher_decrypt(peer_data
->cipher
, plain
+ 16, message_length
- 12, ct
, message_length
- 12)))
3386 ws_debug("can't decrypt aes-cbc/ctr %d %s %s", gcry_err_code(err
), gcry_strsource(err
), gcry_strerror(err
));
3387 return tvb_captured_length(tvb
);
3391 /* XXX: Need to test if we have enough data above if we're
3392 * doing desegmentation; the tvb_get_ptr() calls will throw
3393 * exceptions if there's not enough data before we get here.
3395 if(message_length_decrypted
>remaining
){
3396 // Need desegmentation
3397 ws_noisy(" need_desegmentation: offset = %d, reported_length_remaining = %d\n",
3398 offset
, tvb_reported_length_remaining(tvb
, offset
));
3399 /* Make data available to ssh_follow_tap_listener */
3400 return tvb_captured_length(tvb
);
3403 // ssh_print_data(is_response?"s2c encrypted":"c2s encrypted", ctext, message_length+4+mac_len);
3404 ssh_debug_printf("%s plain text seq=%d", is_response
?"s2c":"c2s",seqnr
);
3405 ssh_print_data("", plain
, message_length
+4);
3407 // TODO: process fragments
3408 data_len
= message_length
+ 4;
3410 ssh_calc_mac(peer_data
, seqnr
, plain
, data_len
, calc_mac
);
3413 if (mac_len
&& data_len
) {
3414 mac
= (char *)tvb_get_ptr(tvb
, offset
+ data_len
, mac_len
);
3415 if (!memcmp(mac
, calc_mac
, mac_len
)){
3418 ws_debug("MAC ERR");
3419 /* Bad MAC, just show the packet as encrypted. We can get
3420 * this for a known encryption type with no keys currently. */
3421 /* XXX: The TLS dissector has a preference to show the attempt
3422 * anyway if it failed.
3424 return tvb_captured_length(tvb
);
3431 ssh_packet_info_t
*packet
= (ssh_packet_info_t
*)p_get_proto_data(
3432 wmem_file_scope(), pinfo
, proto_ssh
, 0);
3434 packet
= wmem_new0(wmem_file_scope(), ssh_packet_info_t
);
3435 packet
->from_server
= is_response
;
3436 packet
->messages
= NULL
;
3437 p_add_proto_data(wmem_file_scope(), pinfo
, proto_ssh
, 0, packet
);
3440 int record_id
= tvb_raw_offset(tvb
)+offset
;
3441 ssh_message_info_t
*message
;
3443 message
= wmem_new(wmem_file_scope(), ssh_message_info_t
);
3444 message
->sequence_number
= peer_data
->sequence_number
++;
3445 message
->plain_data
= wmem_memdup(wmem_file_scope(), plain
, data_len
);
3446 message
->data_len
= data_len
;
3447 message
->id
= record_id
;
3448 message
->next
= NULL
;
3449 memcpy(message
->calc_mac
, calc_mac
, DIGEST_MAX_SIZE
);
3450 ssh_debug_printf("%s->sequence_number++ > %d\n", is_response
?"server":"client", peer_data
->sequence_number
);
3452 ssh_message_info_t
**pmessage
= &packet
->messages
;
3454 pmessage
= &(*pmessage
)->next
;
3456 *pmessage
= message
;
3459 offset
+= message_length
+ mac_len
+ 4;
3464 ssh_tree_add_mac(proto_tree
*tree
, tvbuff_t
*tvb
, const unsigned offset
, const unsigned mac_len
,
3465 const int hf_mac
, const int hf_mac_status
, struct expert_field
* bad_checksum_expert
,
3466 packet_info
*pinfo
, const uint8_t * calc_mac
, const unsigned flags
)
3468 // header_field_info *hfinfo = proto_registrar_get_nth(hf_checksum);
3469 proto_item
* ti
= NULL
;
3471 bool incorrect_mac
= true;
3474 // DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3476 if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
3477 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
3478 proto_item_set_generated(ti);
3479 if (hf_checksum_status > 0) {
3480 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
3481 proto_item_set_generated(ti2);
3486 mac
= (char *)tvb_get_ptr(tvb
, offset
, mac_len
);
3487 if (flags
& PROTO_CHECKSUM_GENERATED
) {
3488 // ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
3489 // proto_item_set_generated(ti);
3491 ti
= proto_tree_add_item(tree
, hf_mac
, tvb
, offset
, mac_len
, ENC_NA
);
3492 if (flags
& PROTO_CHECKSUM_VERIFY
) {
3493 if (flags
& (PROTO_CHECKSUM_IN_CKSUM
|PROTO_CHECKSUM_ZERO
)) {
3494 if (!memcmp(mac
, calc_mac
, mac_len
)) {
3495 proto_item_append_text(ti
, " [correct]");
3496 if (hf_mac_status
!= -1) {
3497 ti2
= proto_tree_add_uint(tree
, hf_mac_status
, tvb
, offset
, 0, PROTO_CHECKSUM_E_GOOD
);
3498 proto_item_set_generated(ti2
);
3500 incorrect_mac
= false;
3501 } else if (flags
& PROTO_CHECKSUM_IN_CKSUM
) {
3502 // computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
3505 if (!memcmp(mac
, calc_mac
, mac_len
)) {
3506 proto_item_append_text(ti
, " [correct]");
3507 if (hf_mac_status
!= -1) {
3508 ti2
= proto_tree_add_uint(tree
, hf_mac_status
, tvb
, offset
, 0, PROTO_CHECKSUM_E_GOOD
);
3509 proto_item_set_generated(ti2
);
3511 incorrect_mac
= false;
3515 if (incorrect_mac
) {
3516 if (hf_mac_status
!= -1) {
3517 ti2
= proto_tree_add_uint(tree
, hf_mac_status
, tvb
, offset
, 0, PROTO_CHECKSUM_E_BAD
);
3518 proto_item_set_generated(ti2
);
3520 if (flags
& PROTO_CHECKSUM_ZERO
) {
3521 proto_item_append_text(ti
, " [incorrect]");
3522 if (bad_checksum_expert
!= NULL
)
3523 expert_add_info_format(pinfo
, ti
, bad_checksum_expert
, "%s", expert_get_summary(bad_checksum_expert
));
3525 char *data
= (char *)wmem_alloc(pinfo
->pool
, mac_len
*2 + 1);
3526 *bytes_to_hexstr(data
, calc_mac
, mac_len
) = 0;
3527 proto_item_append_text(ti
, " incorrect, computed %s", data
);
3528 if (bad_checksum_expert
!= NULL
)
3529 expert_add_info_format(pinfo
, ti
, bad_checksum_expert
, "%s", expert_get_summary(bad_checksum_expert
));
3533 if (hf_mac_status
!= -1) {
3534 proto_item_append_text(ti
, " [unverified]");
3535 ti2
= proto_tree_add_uint(tree
, hf_mac_status
, tvb
, offset
, 0, PROTO_CHECKSUM_E_UNVERIFIED
);
3536 proto_item_set_generated(ti2
);
3545 ssh_decrypt_chacha20(gcry_cipher_hd_t hd
,
3546 uint32_t seqnr
, uint32_t counter
, const unsigned char *ctext
, unsigned ctext_len
,
3547 unsigned char *plain
, unsigned plain_len
)
3549 unsigned char seq
[8];
3550 unsigned char iv
[16];
3552 phton64(seq
, (uint64_t)seqnr
);
3554 // chacha20 uses a different cipher handle for the packet payload & length
3555 // the payload uses a block counter
3557 unsigned char ctr
[8] = {1,0,0,0,0,0,0,0};
3559 memcpy(iv
+8, seq
, 8);
3562 return ((!counter
&& gcry_cipher_setiv(hd
, seq
, 8) == 0) ||
3563 (counter
&& gcry_cipher_setiv(hd
, iv
, 16) == 0)) &&
3564 gcry_cipher_decrypt(hd
, plain
, plain_len
, ctext
, ctext_len
) == 0;
3568 ssh_dissect_decrypted_packet(tvbuff_t
*tvb
, packet_info
*pinfo
,
3569 struct ssh_peer_data
*peer_data
, proto_tree
*tree
,
3570 ssh_message_info_t
*message
)
3572 int offset
= 0; // TODO:
3573 int dissected_len
= 0;
3575 char* plaintext
= message
->plain_data
;
3576 unsigned plaintext_len
= message
->data_len
;
3578 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, NULL
, "Encrypted packet (plaintext_len=%d)", plaintext_len
);
3580 tvbuff_t
*packet_tvb
= tvb_new_child_real_data(tvb
, plaintext
, plaintext_len
, plaintext_len
);
3581 add_new_data_source(pinfo
, packet_tvb
, "Decrypted Packet");
3584 uint8_t padding_length
;
3585 unsigned remain_length
;
3586 int last_offset
=offset
;
3590 proto_item
*msg_type_tree
= NULL
;
3593 * We use "tvb_ensure_captured_length_remaining()" to make sure there
3594 * actually *is* data remaining.
3596 * This means we're guaranteed that "remain_length" is positive.
3598 remain_length
= tvb_ensure_captured_length_remaining(packet_tvb
, offset
);
3600 * Can we do reassembly?
3602 if (ssh_desegment
&& pinfo
->can_desegment
) {
3604 * Yes - would an SSH header starting at this offset
3605 * be split across segment boundaries?
3607 if (remain_length
< 4) {
3609 * Yes. Tell the TCP dissector where the data for
3610 * this message starts in the data it handed us and
3611 * that we need "some more data." Don't tell it
3612 * exactly how many bytes we need because if/when we
3613 * ask for even more (after the header) that will
3616 pinfo
->desegment_offset
= offset
;
3617 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
3621 plen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3623 if (ssh_desegment
&& pinfo
->can_desegment
) {
3624 if (plen
+4 > remain_length
) {
3625 pinfo
->desegment_offset
= offset
;
3626 pinfo
->desegment_len
= plen
+4 - remain_length
;
3631 * Need to check plen > 0x80000000 here
3634 ti
= proto_tree_add_uint(tree
, hf_ssh_packet_length
, packet_tvb
,
3636 if (plen
>= 0xffff) {
3637 expert_add_info_format(pinfo
, ti
, &ei_ssh_packet_length
, "Overly large number %d", plen
);
3638 plen
= remain_length
-4;
3642 /* padding length */
3643 padding_length
= tvb_get_uint8(packet_tvb
, offset
);
3644 proto_tree_add_uint(tree
, hf_ssh_padding_length
, packet_tvb
, offset
, 1, padding_length
);
3648 msg_code
= tvb_get_uint8(packet_tvb
, offset
);
3650 /* Transport layer protocol */
3651 /* Generic (1-19) */
3652 if(msg_code
>= 1 && msg_code
<= 19) {
3653 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, val_to_str(msg_code
, ssh2_msg_vals
, "Unknown (%u)"));
3654 msg_type_tree
= proto_tree_add_subtree(tree
, packet_tvb
, offset
, plen
-1, ett_key_exchange
, NULL
, "Message: Transport (generic)");
3655 proto_tree_add_item(msg_type_tree
, hf_ssh2_msg_code
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3656 dissected_len
= ssh_dissect_transport_generic(packet_tvb
, pinfo
, offset
+1, peer_data
, msg_type_tree
, msg_code
) - offset
;
3657 // offset = ssh_dissect_transport_generic(packet_tvb, pinfo, global_data, offset, msg_type_tree, is_response, msg_code);
3659 /* Algorithm negotiation (20-29) */
3660 else if(msg_code
>=20 && msg_code
<= 29) {
3661 msg_type_tree
= proto_tree_add_subtree(tree
, packet_tvb
, offset
, plen
-1, ett_key_exchange
, NULL
, "Message: Transport (algorithm negotiation)");
3662 //TODO: See if the complete dissector should be refactored to always got through here first offset = ssh_dissect_transport_algorithm_negotiation(packet_tvb, pinfo, global_data, offset, msg_type_tree, is_response, msg_code);
3664 /* Key exchange method specific (reusable) (30-49) */
3665 else if (msg_code
>=30 && msg_code
<= 49) {
3666 msg_type_tree
= proto_tree_add_subtree(tree
, packet_tvb
, offset
, plen
-1, ett_key_exchange
, NULL
, "Message: Transport (key exchange method specific)");
3667 //TODO: See if the complete dissector should be refactored to always got through here first offset = global_data->kex_specific_dissector(msg_code, packet_tvb, pinfo, offset, msg_type_tree);
3670 /* User authentication protocol */
3671 /* Generic (50-59) */
3672 else if (msg_code
>= 50 && msg_code
<= 59) {
3673 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, val_to_str(msg_code
, ssh2_msg_vals
, "Unknown (%u)"));
3674 msg_type_tree
= proto_tree_add_subtree(tree
, packet_tvb
, offset
, plen
-1, ett_key_exchange
, NULL
, "Message: User Authentication (generic)");
3675 proto_tree_add_item(msg_type_tree
, hf_ssh2_msg_code
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3676 dissected_len
= ssh_dissect_userauth_generic(packet_tvb
, pinfo
, offset
+1, msg_type_tree
, msg_code
) - offset
;
3677 // TODO: offset = ssh_dissect_userauth_generic(packet_tvb, pinfo, global_data, offset, msg_type_tree, is_response, msg_code);
3679 /* User authentication method specific (reusable) (60-79) */
3680 else if (msg_code
>= 60 && msg_code
<= 79) {
3681 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, val_to_str(msg_code
, ssh2_msg_vals
, "Unknown (%u)"));
3682 msg_type_tree
= proto_tree_add_subtree(tree
, packet_tvb
, offset
, plen
-1, ett_key_exchange
, NULL
, "Message: User Authentication: (method specific)");
3683 proto_tree_add_item(msg_type_tree
, hf_ssh2_msg_code
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3684 // TODO: offset = ssh_dissect_userauth_specific(packet_tvb, pinfo, global_data, offset, msg_type_tree, is_response, msg_code);
3685 dissected_len
= ssh_dissect_userauth_specific(packet_tvb
, pinfo
, offset
+1, msg_type_tree
, msg_code
) - offset
;
3688 /* Connection protocol */
3689 /* Generic (80-89) */
3690 else if (msg_code
>= 80 && msg_code
<= 89) {
3691 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, val_to_str(msg_code
, ssh2_msg_vals
, "Unknown (%u)"));
3692 msg_type_tree
= proto_tree_add_subtree(tree
, packet_tvb
, offset
, plen
-1, ett_key_exchange
, NULL
, "Message: Connection (generic)");
3693 proto_tree_add_item(msg_type_tree
, hf_ssh2_msg_code
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3694 // TODO: offset = ssh_dissect_connection_generic(packet_tvb, pinfo, global_data, offset, msg_type_tree, is_response, msg_code);
3695 dissected_len
= ssh_dissect_connection_generic(packet_tvb
, pinfo
, offset
+1, msg_type_tree
, msg_code
) - offset
;
3697 /* Channel related messages (90-127) */
3698 else if (msg_code
>= 90 && msg_code
<= 127) {
3699 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, val_to_str(msg_code
, ssh2_msg_vals
, "Unknown (%u)"));
3700 msg_type_tree
= proto_tree_add_subtree(tree
, packet_tvb
, offset
, plen
-1, ett_key_exchange
, NULL
, "Message: Connection: (channel related message)");
3701 proto_tree_add_item(msg_type_tree
, hf_ssh2_msg_code
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3702 // TODO: offset = ssh_dissect_connection_channel(packet_tvb, pinfo, global_data, offset, msg_type_tree, is_response, msg_code);
3703 dissected_len
= ssh_dissect_connection_specific(packet_tvb
, pinfo
, peer_data
, offset
+1, msg_type_tree
, msg_code
, message
) - offset
;
3706 /* Reserved for client protocols (128-191) */
3707 else if (msg_code
>= 128 && msg_code
<= 191) {
3708 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, val_to_str(msg_code
, ssh2_msg_vals
, "Unknown (%u)"));
3709 msg_type_tree
= proto_tree_add_subtree(tree
, packet_tvb
, offset
, plen
-1, ett_key_exchange
, NULL
, "Message: Client protocol");
3710 proto_tree_add_item(msg_type_tree
, hf_ssh2_msg_code
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3712 // TODO: offset = ssh_dissect_client(packet_tvb, pinfo, global_data, offset, msg_type_tree, is_response, msg_code);
3715 /* Local extensions (192-255) */
3716 else if (msg_code
>= 192 && msg_code
<= 255) {
3717 msg_type_tree
= proto_tree_add_subtree(tree
, packet_tvb
, offset
, plen
-1, ett_key_exchange
, NULL
, "Message: Local extension");
3718 dissected_len
= ssh_dissect_local_extension(packet_tvb
, pinfo
, offset
, peer_data
, msg_type_tree
, msg_code
) - offset
;
3721 len
= plen
+4-padding_length
-(offset
-last_offset
);
3723 proto_tree_add_item(msg_type_tree
, hf_ssh_payload
, packet_tvb
, offset
, len
, ENC_NA
);
3725 if(dissected_len
!=(int)len
){
3726 // expert_add_info_format(pinfo, ti, &ei_ssh_packet_decode, "Decoded %d bytes, but packet length is %d bytes", dissected_len, len);
3727 expert_add_info_format(pinfo
, ti
, &ei_ssh_packet_decode
, "Decoded %d bytes, but packet length is %d bytes [%d]", dissected_len
, len
, msg_code
);
3732 proto_tree_add_item(tree
, hf_ssh_padding_string
, packet_tvb
, offset
, padding_length
, ENC_NA
);
3733 offset
+= padding_length
;
3735 if (peer_data
->mac_length
) {
3736 ssh_tree_add_mac(tree
, tvb
, offset
, peer_data
->mac_length
, hf_ssh_mac_string
, hf_ssh_mac_status
, &ei_ssh_mac_bad
, pinfo
, message
->calc_mac
,
3737 PROTO_CHECKSUM_VERIFY
|PROTO_CHECKSUM_IN_CKSUM
);
3738 offset
+= peer_data
->mac_length
;
3740 ti
= proto_tree_add_uint(tree
, hf_ssh_seq_num
, tvb
, offset
, 0, message
->sequence_number
);
3741 proto_item_set_generated(ti
);
3746 ssh_dissect_transport_generic(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
3747 int offset
, struct ssh_peer_data
*peer_data
, proto_item
*msg_type_tree
, unsigned msg_code
)
3750 if(msg_code
==SSH_MSG_DISCONNECT
){
3751 proto_tree_add_item(msg_type_tree
, hf_ssh_disconnect_reason
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3754 nlen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3755 proto_tree_add_item(msg_type_tree
, hf_ssh_disconnect_description_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3757 proto_tree_add_item(msg_type_tree
, hf_ssh_disconnect_description
, packet_tvb
, offset
, nlen
, ENC_ASCII
);
3759 nlen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3760 proto_tree_add_item(msg_type_tree
, hf_ssh_lang_tag_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3762 proto_tree_add_item(msg_type_tree
, hf_ssh_lang_tag
, packet_tvb
, offset
, nlen
, ENC_ASCII
);
3764 }else if(msg_code
==SSH_MSG_IGNORE
){
3765 offset
+= ssh_tree_add_string(packet_tvb
, offset
, msg_type_tree
, hf_ssh_ignore_data
, hf_ssh_ignore_data_length
);
3766 }else if(msg_code
==SSH_MSG_DEBUG
){
3768 proto_tree_add_item(msg_type_tree
, hf_ssh_debug_always_display
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3770 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3771 proto_tree_add_item(msg_type_tree
, hf_ssh_debug_message_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3773 proto_tree_add_item(msg_type_tree
, hf_ssh_debug_message
, packet_tvb
, offset
, slen
, ENC_UTF_8
);
3775 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3776 proto_tree_add_item(msg_type_tree
, hf_ssh_lang_tag_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3778 proto_tree_add_item(msg_type_tree
, hf_ssh_lang_tag
, packet_tvb
, offset
, slen
, ENC_ASCII
);
3780 }else if(msg_code
==SSH_MSG_SERVICE_REQUEST
){
3782 nlen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3783 proto_tree_add_item(msg_type_tree
, hf_ssh_service_name_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3785 proto_tree_add_item(msg_type_tree
, hf_ssh_service_name
, packet_tvb
, offset
, nlen
, ENC_ASCII
);
3787 }else if(msg_code
==SSH_MSG_SERVICE_ACCEPT
){
3789 nlen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3790 proto_tree_add_item(msg_type_tree
, hf_ssh_service_name_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3792 proto_tree_add_item(msg_type_tree
, hf_ssh_service_name
, packet_tvb
, offset
, nlen
, ENC_ASCII
);
3794 }else if(msg_code
==SSH_MSG_EXT_INFO
){
3796 ext_cnt
= tvb_get_ntohl(packet_tvb
, offset
);
3797 proto_tree_add_item(msg_type_tree
, hf_ssh_ext_count
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3799 for(unsigned ext_index
= 0; ext_index
< ext_cnt
; ext_index
++) {
3800 offset
= ssh_dissect_rfc8308_extension(packet_tvb
, pinfo
, offset
, peer_data
, msg_type_tree
);
3807 ssh_dissect_rfc8308_extension(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
3808 int offset
, struct ssh_peer_data
*peer_data
, proto_item
*msg_type_tree
)
3811 unsigned ext_name_slen
= tvb_get_ntohl(packet_tvb
, offset
);
3812 uint8_t *ext_name
= tvb_get_string_enc(pinfo
->pool
, packet_tvb
, offset
+ 4, ext_name_slen
, ENC_ASCII
);
3813 unsigned ext_value_slen
= tvb_get_ntohl(packet_tvb
, offset
+ 4 + ext_name_slen
);
3814 unsigned ext_len
= 8 + ext_name_slen
+ ext_value_slen
;
3815 proto_item
*ext_tree
= proto_tree_add_subtree_format(msg_type_tree
, packet_tvb
, offset
, ext_len
, ett_extension
, NULL
, "Extension: %s", ext_name
);
3817 proto_tree_add_item(ext_tree
, hf_ssh_ext_name_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3819 proto_tree_add_item(ext_tree
, hf_ssh_ext_name
, packet_tvb
, offset
, ext_name_slen
, ENC_ASCII
);
3820 offset
+= ext_name_slen
;
3821 proto_tree_add_item(ext_tree
, hf_ssh_ext_value_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3823 proto_tree_add_item(ext_tree
, hf_ssh_ext_value
, packet_tvb
, offset
, ext_value_slen
, ENC_NA
);
3825 if (g_str_equal(ext_name
, "server-sig-algs")) {
3826 // server-sig-algs (RFC8308 Sec. 3.1)
3827 proto_tree_add_item(ext_tree
, hf_ssh_ext_server_sig_algs_algorithms
, packet_tvb
, offset
, ext_value_slen
, ENC_ASCII
);
3828 offset
+= ext_value_slen
;
3829 } else if (g_str_equal(ext_name
, "delay-compression")) {
3830 // delay-compression (RFC8308 Sec 3.2)
3832 slen
= tvb_get_ntohl(packet_tvb
, offset
);
3833 proto_tree_add_item(ext_tree
, hf_ssh_ext_delay_compression_algorithms_client_to_server_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3835 proto_tree_add_item(ext_tree
, hf_ssh_ext_delay_compression_algorithms_client_to_server
, packet_tvb
, offset
, slen
, ENC_ASCII
);
3837 slen
= tvb_get_ntohl(packet_tvb
, offset
);
3838 proto_tree_add_item(ext_tree
, hf_ssh_ext_delay_compression_algorithms_server_to_client_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3840 proto_tree_add_item(ext_tree
, hf_ssh_ext_delay_compression_algorithms_server_to_client
, packet_tvb
, offset
, slen
, ENC_ASCII
);
3842 } else if (g_str_equal(ext_name
, "no-flow-control")) {
3843 // no-flow-control (RFC 8308 Sec 3.3)
3844 proto_tree_add_item(ext_tree
, hf_ssh_ext_no_flow_control_value
, packet_tvb
, offset
, ext_value_slen
, ENC_ASCII
);
3845 offset
+= ext_value_slen
;
3846 } else if (g_str_equal(ext_name
, "elevation")) {
3847 // elevation (RFC 8308 Sec 3.4)
3848 proto_tree_add_item(ext_tree
, hf_ssh_ext_elevation_value
, packet_tvb
, offset
, ext_value_slen
, ENC_ASCII
);
3849 offset
+= ext_value_slen
;
3850 } else if (g_str_equal(ext_name
, "publickey-algorithms@roumenpetrov.info")) {
3851 // publickey-algorithms@roumenpetrov.info (proprietary)
3852 proto_tree_add_item(ext_tree
, hf_ssh_ext_prop_publickey_algorithms_algorithms
, packet_tvb
, offset
, ext_value_slen
, ENC_ASCII
);
3853 offset
+= ext_value_slen
;
3854 } else if (g_str_equal(ext_name
, "ping@openssh.com")) {
3855 // ping@openssh.com (proprietary w/ primitive extension value)
3856 peer_data
->global_data
->ext_ping_openssh_offered
= true;
3857 offset
+= ext_value_slen
;
3859 offset
+= ext_value_slen
;
3862 // The following extensions do not require advanced dissection:
3863 // - global-requests-ok
3865 // - publickey-hostbound@openssh.com
3866 // - ext-info-in-auth@openssh.com
3872 ssh_dissect_userauth_generic(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
3873 int offset
, proto_item
*msg_type_tree
, unsigned msg_code
)
3875 if(msg_code
==SSH_MSG_USERAUTH_REQUEST
){
3877 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3878 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_user_name_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3880 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_user_name
, packet_tvb
, offset
, slen
, ENC_ASCII
);
3882 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3883 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_service_name_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3885 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_service_name
, packet_tvb
, offset
, slen
, ENC_ASCII
);
3887 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3888 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_method_name_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3890 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_method_name
, packet_tvb
, offset
, slen
, ENC_ASCII
);
3893 key_type
= tvb_get_string_enc(pinfo
->pool
, packet_tvb
, offset
, slen
, ENC_ASCII
|ENC_NA
);
3895 if (0 == strcmp(key_type
, "none")) {
3896 }else if (0 == strcmp(key_type
, "publickey")) {
3897 uint8_t bHaveSignature
= tvb_get_uint8(packet_tvb
, offset
);
3898 int dissected_len
= 0;
3899 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_have_signature
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3901 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3902 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_pka_name_len
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3904 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_pka_name
, packet_tvb
, offset
, slen
, ENC_ASCII
);
3906 proto_item
*blob_tree
= NULL
;
3907 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3908 proto_tree_add_item(msg_type_tree
, hf_ssh_blob_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3910 blob_tree
= proto_tree_add_subtree(msg_type_tree
, packet_tvb
, offset
, slen
, ett_userauth_pk_blob
, NULL
, "Public key blob");
3911 // proto_tree_add_item(blob_tree, hf_ssh2_msg_code, packet_tvb, offset, 1, ENC_BIG_ENDIAN);
3912 dissected_len
= ssh_dissect_public_key_blob(packet_tvb
, pinfo
, offset
, blob_tree
) - offset
;
3913 if(dissected_len
!=(int)slen
){
3914 expert_add_info_format(pinfo
, blob_tree
, &ei_ssh_packet_decode
, "Decoded %d bytes, but packet length is %d bytes", dissected_len
, slen
);
3918 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3919 proto_tree_add_item(msg_type_tree
, hf_ssh_signature_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3921 proto_item
*signature_tree
= NULL
;
3922 signature_tree
= proto_tree_add_subtree(msg_type_tree
, packet_tvb
, offset
, slen
, ett_userauth_pk_signautre
, NULL
, "Public key signature");
3923 dissected_len
= ssh_dissect_public_key_signature(packet_tvb
, pinfo
, offset
, signature_tree
) - offset
;
3924 if(dissected_len
!=(int)slen
){
3925 expert_add_info_format(pinfo
, signature_tree
, &ei_ssh_packet_decode
, "Decoded %d bytes, but packet length is %d bytes", dissected_len
, slen
);
3929 }else if (0 == strcmp(key_type
, "password")) {
3930 uint8_t bChangePassword
= tvb_get_uint8(packet_tvb
, offset
);
3931 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_change_password
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3933 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3934 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_password_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3936 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_password
, packet_tvb
, offset
, slen
, ENC_ASCII
);
3938 if(bChangePassword
){
3939 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3940 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_new_password_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3942 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_new_password
, packet_tvb
, offset
, slen
, ENC_ASCII
);
3948 }else if(msg_code
==SSH_MSG_USERAUTH_FAILURE
){
3950 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3951 proto_tree_add_item(msg_type_tree
, hf_ssh_auth_failure_list_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3953 proto_tree_add_item(msg_type_tree
, hf_ssh_auth_failure_list
, packet_tvb
, offset
, slen
, ENC_ASCII
);
3955 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_partial_success
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
3962 ssh_dissect_userauth_specific(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
3963 int offset
, proto_item
*msg_type_tree
, unsigned msg_code
)
3965 if(msg_code
==SSH_MSG_USERAUTH_PK_OK
){
3967 int dissected_len
= 0;
3969 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3970 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_pka_name_len
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3972 proto_tree_add_item(msg_type_tree
, hf_ssh_userauth_pka_name
, packet_tvb
, offset
, slen
, ENC_ASCII
);
3974 proto_item
*blob_tree
= NULL
;
3975 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
3976 ti
= proto_tree_add_item(msg_type_tree
, hf_ssh_blob_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
3978 blob_tree
= proto_tree_add_subtree(msg_type_tree
, packet_tvb
, offset
, slen
, ett_userauth_pk_blob
, NULL
, "Public key blob");
3979 dissected_len
= ssh_dissect_public_key_blob(packet_tvb
, pinfo
, offset
, blob_tree
) - offset
;
3980 if(dissected_len
!=(int)slen
){
3981 expert_add_info_format(pinfo
, ti
, &ei_ssh_packet_decode
, "Decoded %d bytes, but packet length is %d bytes", dissected_len
, slen
);
3989 ssh_process_payload(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, proto_tree
*tree
, ssh_channel_info_t
*channel
)
3991 tvbuff_t
*next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
3992 if (channel
->handle
) {
3993 call_dissector(channel
->handle
, next_tvb
, pinfo
, proto_tree_get_root(tree
));
3995 call_data_dissector(next_tvb
, pinfo
, proto_tree_get_root(tree
));
4000 print_ssh_fragment_tree(fragment_head
*ipfd_head
, proto_tree
*tree
, proto_tree
*ssh_tree
, packet_info
*pinfo
, tvbuff_t
*next_tvb
)
4002 proto_item
*ssh_tree_item
, *frag_tree_item
;
4005 * The subdissector thought it was completely
4006 * desegmented (although the stuff at the
4007 * end may, in turn, require desegmentation),
4008 * so we show a tree with all segments.
4010 show_fragment_tree(ipfd_head
, &ssh_segment_items
,
4011 tree
, pinfo
, next_tvb
, &frag_tree_item
);
4013 * The toplevel fragment subtree is now
4014 * behind all desegmented data; move it
4015 * right behind the SSH tree.
4017 ssh_tree_item
= proto_tree_get_parent(ssh_tree
);
4018 /* The SSH protocol item is up a few levels from the message tree */
4019 ssh_tree_item
= proto_item_get_parent_nth(ssh_tree_item
, 2);
4020 if (frag_tree_item
&& ssh_tree_item
) {
4021 proto_tree_move_item(tree
, ssh_tree_item
, frag_tree_item
);
4026 ssh_msp_fragment_id(struct tcp_multisegment_pdu
*msp
)
4029 * If a frame contains multiple PDUs, then "first_frame" is not
4030 * sufficient to uniquely identify groups of fragments. Therefore we use
4031 * the tcp reassembly functions that also test msp->seq (the position of
4032 * the initial fragment in the SSH channel).
4034 return msp
->first_frame
;
4038 ssh_proto_tree_add_segment_data(
4045 proto_tree_add_bytes_format(
4047 hf_ssh_segment_data
,
4052 "%sSSH segment data (%u %s)",
4053 prefix
!= NULL
? prefix
: "",
4054 length
== -1 ? tvb_reported_length_remaining(tvb
, offset
) : length
,
4055 plurality(length
, "byte", "bytes"));
4059 desegment_ssh(tvbuff_t
*tvb
, packet_info
*pinfo
, uint32_t seq
,
4060 uint32_t nxtseq
, proto_tree
*tree
, ssh_channel_info_t
*channel
)
4062 fragment_head
*ipfd_head
;
4063 bool must_desegment
;
4064 bool called_dissector
;
4065 int another_pdu_follows
;
4066 bool another_segment_in_frame
= false;
4067 int deseg_offset
, offset
= 0;
4071 struct tcp_multisegment_pdu
*msp
;
4072 bool first_pdu
= true;
4076 must_desegment
= false;
4077 called_dissector
= false;
4078 another_pdu_follows
= 0;
4082 * Initialize these to assume no desegmentation.
4083 * If that's not the case, these will be set appropriately
4084 * by the subdissector.
4086 pinfo
->desegment_offset
= 0;
4087 pinfo
->desegment_len
= 0;
4090 * Initialize this to assume that this segment will just be
4091 * added to the middle of a desegmented chunk of data, so
4092 * that we should show it all as data.
4093 * If that's not the case, it will be set appropriately.
4095 deseg_offset
= offset
;
4097 /* If we've seen this segment before (e.g., it's a retransmission),
4098 * there's nothing for us to do. Certainly, don't add it to the list
4099 * of multisegment_pdus (that would cause subsequent lookups to find
4100 * the retransmission instead of the original transmission, breaking
4101 * dissection of the desegmented pdu if we'd already seen the end of
4104 if ((msp
= (struct tcp_multisegment_pdu
*)wmem_tree_lookup32(channel
->multisegment_pdus
, seq
))) {
4106 bool is_retransmission
= false;
4108 if (msp
->first_frame
== pinfo
->num
) {
4109 /* This must be after the first pass. */
4111 if (msp
->last_frame
== pinfo
->num
) {
4112 col_clear(pinfo
->cinfo
, COL_INFO
);
4115 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, " ", "[SSH segment of a reassembled PDU]");
4119 prefix
= "Retransmitted ";
4120 is_retransmission
= true;
4123 if (!is_retransmission
) {
4124 ipfd_head
= fragment_get(&ssh_reassembly_table
, pinfo
, msp
->first_frame
, msp
);
4125 if (ipfd_head
!= NULL
&& ipfd_head
->reassembled_in
!=0 &&
4126 ipfd_head
->reassembled_in
!= pinfo
->num
) {
4127 /* Show what frame this was reassembled in if not this one. */
4128 item
=proto_tree_add_uint(tree
, *ssh_segment_items
.hf_reassembled_in
,
4129 tvb
, 0, 0, ipfd_head
->reassembled_in
);
4130 proto_item_set_generated(item
);
4133 nbytes
= tvb_reported_length_remaining(tvb
, offset
);
4134 ssh_proto_tree_add_segment_data(tree
, tvb
, offset
, nbytes
, prefix
);
4138 /* Else, find the most previous PDU starting before this sequence number */
4139 msp
= (struct tcp_multisegment_pdu
*)wmem_tree_lookup32_le(channel
->multisegment_pdus
, seq
-1);
4140 if (msp
&& msp
->seq
<= seq
&& msp
->nxtpdu
> seq
) {
4143 if (!PINFO_FD_VISITED(pinfo
)) {
4144 msp
->last_frame
= pinfo
->num
;
4145 msp
->last_frame_time
= pinfo
->abs_ts
;
4148 /* OK, this PDU was found, which means the segment continues
4149 * a higher-level PDU and that we must desegment it.
4151 if (msp
->flags
& MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT
) {
4152 /* The dissector asked for the entire segment */
4153 len
= MAX(0, tvb_reported_length_remaining(tvb
, offset
));
4155 len
= MIN(nxtseq
, msp
->nxtpdu
) - seq
;
4158 ipfd_head
= fragment_add(&ssh_reassembly_table
, tvb
, offset
,
4159 pinfo
, ssh_msp_fragment_id(msp
), msp
,
4161 len
, (LT_SEQ (nxtseq
,msp
->nxtpdu
)));
4163 if (!PINFO_FD_VISITED(pinfo
)
4164 && msp
->flags
& MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT
) {
4165 msp
->flags
&= (~MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT
);
4167 /* If we consumed the entire segment there is no
4168 * other pdu starting anywhere inside this segment.
4169 * So update nxtpdu to point at least to the start
4170 * of the next segment.
4171 * (If the subdissector asks for even more data we
4172 * will advance nxtpdu even further later down in
4175 msp
->nxtpdu
= nxtseq
;
4178 if ( (msp
->nxtpdu
< nxtseq
)
4179 && (msp
->nxtpdu
>= seq
)
4181 another_pdu_follows
= msp
->nxtpdu
- seq
;
4184 /* This segment was not found in our table, so it doesn't
4185 * contain a continuation of a higher-level PDU.
4186 * Call the normal subdissector.
4188 ssh_process_payload(tvb
, offset
, pinfo
, tree
, channel
);
4189 called_dissector
= true;
4191 /* Did the subdissector ask us to desegment some more data
4192 * before it could handle the packet?
4193 * If so we have to create some structures in our table but
4194 * this is something we only do the first time we see this
4197 if (pinfo
->desegment_len
) {
4198 if (!PINFO_FD_VISITED(pinfo
))
4199 must_desegment
= true;
4202 * Set "deseg_offset" to the offset in "tvb"
4203 * of the first byte of data that the
4204 * subdissector didn't process.
4206 deseg_offset
= offset
+ pinfo
->desegment_offset
;
4209 /* Either no desegmentation is necessary, or this is
4210 * segment contains the beginning but not the end of
4211 * a higher-level PDU and thus isn't completely
4217 /* is it completely desegmented? */
4218 if (ipfd_head
&& ipfd_head
->reassembled_in
== pinfo
->num
) {
4220 * Yes, we think it is.
4221 * We only call subdissector for the last segment.
4222 * Note that the last segment may include more than what
4225 if (nxtseq
< msp
->nxtpdu
) {
4227 * This is *not* the last segment. It is part of a PDU in the same
4228 * frame, so no another PDU can follow this one.
4229 * Do not reassemble SSH yet, it will be done in the final segment.
4230 * (If we are reassembling at FIN, we will do that in dissect_ssl()
4231 * after iterating through all the records.)
4232 * Clear the Info column and avoid displaying [SSH segment of a
4233 * reassembled PDU], the payload dissector will typically set it.
4234 * (This is needed here for the second pass.)
4236 another_pdu_follows
= 0;
4237 col_clear(pinfo
->cinfo
, COL_INFO
);
4238 another_segment_in_frame
= true;
4241 * OK, this is the last segment of the PDU and also the
4242 * last segment in this frame.
4243 * Let's call the subdissector with the desegmented
4250 * Reset column in case multiple SSH segments form the PDU
4251 * and this last SSH segment is not in the first TCP segment of
4253 * XXX prevent clearing the column if the last layer is not SSH?
4255 /* Clear column during the first pass. */
4256 col_clear(pinfo
->cinfo
, COL_INFO
);
4258 /* create a new TVB structure for desegmented data */
4259 next_tvb
= tvb_new_chain(tvb
, ipfd_head
->tvb_data
);
4261 /* add desegmented data to the data source list */
4262 add_new_data_source(pinfo
, next_tvb
, "Reassembled SSH");
4264 /* call subdissector */
4265 ssh_process_payload(next_tvb
, 0, pinfo
, tree
, channel
);
4266 called_dissector
= true;
4269 * OK, did the subdissector think it was completely
4270 * desegmented, or does it think we need even more
4273 old_len
= (int)(tvb_reported_length(next_tvb
) - tvb_reported_length_remaining(tvb
, offset
));
4274 if (pinfo
->desegment_len
&& pinfo
->desegment_offset
<= old_len
) {
4276 * "desegment_len" isn't 0, so it needs more
4277 * data for something - and "desegment_offset"
4278 * is before "old_len", so it needs more data
4279 * to dissect the stuff we thought was
4280 * completely desegmented (as opposed to the
4281 * stuff at the beginning being completely
4282 * desegmented, but the stuff at the end
4283 * being a new higher-level PDU that also
4284 * needs desegmentation).
4286 fragment_set_partial_reassembly(&ssh_reassembly_table
,
4287 pinfo
, ssh_msp_fragment_id(msp
), msp
);
4288 /* Update msp->nxtpdu to point to the new next
4291 if (pinfo
->desegment_len
== DESEGMENT_ONE_MORE_SEGMENT
) {
4292 /* We want reassembly of at least one
4293 * more segment so set the nxtpdu
4294 * boundary to one byte into the next
4296 * This means that the next segment
4297 * will complete reassembly even if it
4298 * is only one single byte in length.
4300 msp
->nxtpdu
= seq
+ tvb_reported_length_remaining(tvb
, offset
) + 1;
4301 msp
->flags
|= MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT
;
4302 } else if (pinfo
->desegment_len
== DESEGMENT_UNTIL_FIN
) {
4303 /* This is not the first segment, and we thought reassembly
4304 * would be done now, but now we know we desegment at FIN.
4305 * E.g., a HTTP response where the headers were split
4306 * across segments (so previous ONE_MORE_SEGMENT) and
4307 * also no Content-Length (so now DESEGMENT_UNTIL_FIN).
4309 channel
->flags
|= TCP_FLOW_REASSEMBLE_UNTIL_FIN
;
4310 msp
->nxtpdu
= nxtseq
+ 0x40000000;
4312 msp
->nxtpdu
= seq
+ tvb_reported_length_remaining(tvb
, offset
) + pinfo
->desegment_len
;
4314 /* Since we need at least some more data
4315 * there can be no pdu following in the
4316 * tail of this segment.
4318 another_pdu_follows
= 0;
4321 * Show the stuff in this TCP segment as
4322 * just raw TCP segment data.
4324 nbytes
= another_pdu_follows
> 0
4325 ? another_pdu_follows
4326 : tvb_reported_length_remaining(tvb
, offset
);
4327 ssh_proto_tree_add_segment_data(tree
, tvb
, offset
, nbytes
, NULL
);
4329 /* Show details of the reassembly */
4330 print_ssh_fragment_tree(ipfd_head
, proto_tree_get_root(tree
), tree
, pinfo
, next_tvb
);
4332 /* Did the subdissector ask us to desegment
4333 * some more data? This means that the data
4334 * at the beginning of this segment completed
4335 * a higher-level PDU, but the data at the
4336 * end of this segment started a higher-level
4337 * PDU but didn't complete it.
4339 * If so, we have to create some structures
4340 * in our table, but this is something we
4341 * only do the first time we see this packet.
4343 if (pinfo
->desegment_len
) {
4344 if (!PINFO_FD_VISITED(pinfo
))
4345 must_desegment
= true;
4347 /* The stuff we couldn't dissect
4348 * must have come from this segment,
4349 * so it's all in "tvb".
4351 * "pinfo->desegment_offset" is
4352 * relative to the beginning of
4353 * "next_tvb"; we want an offset
4354 * relative to the beginning of "tvb".
4356 * First, compute the offset relative
4357 * to the *end* of "next_tvb" - i.e.,
4358 * the number of bytes before the end
4359 * of "next_tvb" at which the
4360 * subdissector stopped. That's the
4361 * length of "next_tvb" minus the
4362 * offset, relative to the beginning
4363 * of "next_tvb, at which the
4364 * subdissector stopped.
4366 deseg_offset
= ipfd_head
->datalen
- pinfo
->desegment_offset
;
4368 /* "tvb" and "next_tvb" end at the
4369 * same byte of data, so the offset
4370 * relative to the end of "next_tvb"
4371 * of the byte at which we stopped
4372 * is also the offset relative to
4373 * the end of "tvb" of the byte at
4376 * Convert that back into an offset
4377 * relative to the beginning of
4378 * "tvb", by taking the length of
4379 * "tvb" and subtracting the offset
4380 * relative to the end.
4382 deseg_offset
= tvb_reported_length(tvb
) - deseg_offset
;
4388 if (must_desegment
) {
4389 /* If the dissector requested "reassemble until FIN"
4390 * just set this flag for the flow and let reassembly
4391 * proceed at normal. We will check/pick up these
4392 * reassembled PDUs later down in dissect_tcp() when checking
4395 if (pinfo
->desegment_len
== DESEGMENT_UNTIL_FIN
) {
4396 channel
->flags
|= TCP_FLOW_REASSEMBLE_UNTIL_FIN
;
4399 * The sequence number at which the stuff to be desegmented
4400 * starts is the sequence number of the byte at an offset
4401 * of "deseg_offset" into "tvb".
4403 * The sequence number of the byte at an offset of "offset"
4404 * is "seq", i.e. the starting sequence number of this
4405 * segment, so the sequence number of the byte at
4406 * "deseg_offset" is "seq + (deseg_offset - offset)".
4408 deseg_seq
= seq
+ (deseg_offset
- offset
);
4410 if (((nxtseq
- deseg_seq
) <= 1024*1024)
4411 && (!PINFO_FD_VISITED(pinfo
))) {
4412 if (pinfo
->desegment_len
== DESEGMENT_ONE_MORE_SEGMENT
) {
4413 /* The subdissector asked to reassemble using the
4414 * entire next segment.
4415 * Just ask reassembly for one more byte
4416 * but set this msp flag so we can pick it up
4419 msp
= pdu_store_sequencenumber_of_next_pdu(pinfo
,
4420 deseg_seq
, nxtseq
+1, channel
->multisegment_pdus
);
4421 msp
->flags
|= MSP_FLAGS_REASSEMBLE_ENTIRE_SEGMENT
;
4422 } else if (pinfo
->desegment_len
== DESEGMENT_UNTIL_FIN
) {
4423 /* Set nxtseq very large so that reassembly won't happen
4424 * until we force it at the end of the stream in dissect_ssl()
4425 * outside this function.
4427 msp
= pdu_store_sequencenumber_of_next_pdu(pinfo
,
4428 deseg_seq
, nxtseq
+0x40000000, channel
->multisegment_pdus
);
4430 msp
= pdu_store_sequencenumber_of_next_pdu(pinfo
,
4431 deseg_seq
, nxtseq
+pinfo
->desegment_len
, channel
->multisegment_pdus
);
4434 /* add this segment as the first one for this new pdu */
4435 fragment_add(&ssh_reassembly_table
, tvb
, deseg_offset
,
4436 pinfo
, ssh_msp_fragment_id(msp
), msp
,
4437 0, nxtseq
- deseg_seq
,
4438 LT_SEQ(nxtseq
, msp
->nxtpdu
));
4442 if (!called_dissector
|| pinfo
->desegment_len
!= 0) {
4443 if (ipfd_head
!= NULL
&& ipfd_head
->reassembled_in
!= 0 &&
4444 ipfd_head
->reassembled_in
!= pinfo
->num
&&
4445 !(ipfd_head
->flags
& FD_PARTIAL_REASSEMBLY
)) {
4447 * We know what other frame this PDU is reassembled in;
4448 * let the user know.
4450 item
=proto_tree_add_uint(tree
, *ssh_segment_items
.hf_reassembled_in
,
4451 tvb
, 0, 0, ipfd_head
->reassembled_in
);
4452 proto_item_set_generated(item
);
4456 * Either we didn't call the subdissector at all (i.e.,
4457 * this is a segment that contains the middle of a
4458 * higher-level PDU, but contains neither the beginning
4459 * nor the end), or the subdissector couldn't dissect it
4460 * all, as some data was missing (i.e., it set
4461 * "pinfo->desegment_len" to the amount of additional
4464 if (!another_segment_in_frame
&& pinfo
->desegment_offset
== 0) {
4466 * It couldn't, in fact, dissect any of it (the
4467 * first byte it couldn't dissect is at an offset
4468 * of "pinfo->desegment_offset" from the beginning
4469 * of the payload, and that's 0).
4470 * Just mark this as SSH.
4473 /* SFTP checks the length before setting the protocol column.
4474 * If other subdissectors don't do this, we'd want to set the
4475 * protocol column back - but we want to get the SSH version
4477 //col_set_str(pinfo->cinfo, COL_PROTOCOL,
4478 // val_to_str_const(session->version, ssl_version_short_names, "SSH"));
4480 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, " ", "[SSH segment of a reassembled PDU]");
4485 * Show what's left in the packet as just raw SSH segment data.
4486 * XXX - remember what protocol the last subdissector
4487 * was, and report it as a continuation of that, instead?
4489 nbytes
= tvb_reported_length_remaining(tvb
, deseg_offset
);
4490 ssh_proto_tree_add_segment_data(tree
, tvb
, deseg_offset
, nbytes
, NULL
);
4492 pinfo
->can_desegment
= 0;
4493 pinfo
->desegment_offset
= 0;
4494 pinfo
->desegment_len
= 0;
4496 if (another_pdu_follows
) {
4497 /* there was another pdu following this one. */
4498 pinfo
->can_desegment
=2;
4499 /* we also have to prevent the dissector from changing the
4500 * PROTOCOL and INFO colums since what follows may be an
4501 * incomplete PDU and we don't want it be changed back from
4502 * <Protocol> to <SSH>
4504 col_set_fence(pinfo
->cinfo
, COL_INFO
);
4505 col_set_writable(pinfo
->cinfo
, COL_PROTOCOL
, false);
4507 offset
+= another_pdu_follows
;
4508 seq
+= another_pdu_follows
;
4514 ssh_dissect_channel_data(tvbuff_t
*tvb
, packet_info
*pinfo
,
4515 struct ssh_peer_data
*peer_data _U_
, proto_tree
*tree
,
4516 ssh_message_info_t
*message _U_
, ssh_channel_info_t
*channel
)
4519 uint16_t save_can_desegment
= pinfo
->can_desegment
;
4521 if (ssh_desegment
) {
4522 pinfo
->can_desegment
= 2;
4523 desegment_ssh(tvb
, pinfo
, message
->byte_seq
, message
->next_byte_seq
, tree
, channel
);
4525 pinfo
->can_desegment
= 0;
4526 bool save_fragmented
= pinfo
->fragmented
;
4527 pinfo
->fragmented
= true;
4529 ssh_process_payload(tvb
, 0, pinfo
, tree
, channel
);
4530 pinfo
->fragmented
= save_fragmented
;
4533 pinfo
->can_desegment
= save_can_desegment
;
4537 ssh_dissect_connection_specific(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
4538 struct ssh_peer_data
*peer_data
, int offset
, proto_tree
*msg_type_tree
,
4539 unsigned msg_code
, ssh_message_info_t
*message
)
4541 uint32_t recipient_channel
, sender_channel
;
4543 if(msg_code
==SSH_MSG_CHANNEL_OPEN
){
4545 proto_tree_add_item_ret_uint(msg_type_tree
, hf_ssh_connection_type_name_len
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
, &slen
);
4547 proto_tree_add_item(msg_type_tree
, hf_ssh_connection_type_name
, packet_tvb
, offset
, slen
, ENC_UTF_8
);
4549 proto_tree_add_item(msg_type_tree
, hf_ssh_connection_sender_channel
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4551 proto_tree_add_item(msg_type_tree
, hf_ssh_connection_initial_window
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4553 proto_tree_add_item(msg_type_tree
, hf_ssh_connection_maximum_packet_size
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4555 }else if(msg_code
==SSH_MSG_CHANNEL_OPEN_CONFIRMATION
){
4556 proto_tree_add_item_ret_uint(msg_type_tree
, hf_ssh_connection_recipient_channel
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
, &recipient_channel
);
4558 proto_tree_add_item_ret_uint(msg_type_tree
, hf_ssh_connection_sender_channel
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
, &sender_channel
);
4560 if (!PINFO_FD_VISITED(pinfo
)) {
4561 create_channel(peer_data
, recipient_channel
, sender_channel
);
4563 proto_tree_add_item(msg_type_tree
, hf_ssh_connection_initial_window
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4565 proto_tree_add_item(msg_type_tree
, hf_ssh_connection_maximum_packet_size
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4567 }else if(msg_code
==SSH_MSG_CHANNEL_WINDOW_ADJUST
){
4568 proto_tree_add_item(msg_type_tree
, hf_ssh_connection_recipient_channel
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4570 proto_tree_add_item(msg_type_tree
, hf_ssh_channel_window_adjust
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
); // TODO: maintain count of transferred bytes and window size
4572 }else if(msg_code
==SSH_MSG_CHANNEL_DATA
){
4573 proto_item
*ti
= proto_tree_add_item_ret_uint(msg_type_tree
, hf_ssh_connection_recipient_channel
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
, &recipient_channel
);
4575 // TODO: process according to the type of channel
4577 proto_tree_add_item_ret_uint(msg_type_tree
, hf_ssh_channel_data_len
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
, &slen
);
4579 tvbuff_t
*next_tvb
= tvb_new_subset_length(packet_tvb
, offset
, slen
);
4581 ssh_channel_info_t
*channel
= get_channel_info_for_channel(peer_data
, recipient_channel
);
4583 if (!PINFO_FD_VISITED(pinfo
)) {
4584 message
->byte_seq
= channel
->byte_seq
;
4585 channel
->byte_seq
+= slen
;
4586 message
->next_byte_seq
= channel
->byte_seq
;
4588 ssh_dissect_channel_data(next_tvb
, pinfo
, peer_data
, msg_type_tree
, message
, channel
);
4590 expert_add_info_format(pinfo
, ti
, &ei_ssh_channel_number
, "Could not find configuration for channel %d", recipient_channel
);
4593 }else if(msg_code
==SSH_MSG_CHANNEL_EOF
){
4594 proto_tree_add_item(msg_type_tree
, hf_ssh_connection_recipient_channel
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4596 }else if(msg_code
==SSH_MSG_CHANNEL_CLOSE
){
4597 proto_tree_add_item(msg_type_tree
, hf_ssh_connection_recipient_channel
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4599 }else if(msg_code
==SSH_MSG_CHANNEL_REQUEST
){
4600 proto_tree_add_item_ret_uint(msg_type_tree
, hf_ssh_connection_recipient_channel
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
, &recipient_channel
);
4602 const uint8_t* request_name
;
4604 proto_tree_add_item_ret_uint(msg_type_tree
, hf_ssh_channel_request_name_len
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
, &slen
);
4606 proto_tree_add_item_ret_string(msg_type_tree
, hf_ssh_channel_request_name
, packet_tvb
, offset
, slen
, ENC_UTF_8
, pinfo
->pool
, &request_name
);
4608 proto_tree_add_item(msg_type_tree
, hf_ssh_channel_request_want_reply
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4610 /* RFC 4254 6.5: "Only one of these requests ["shell", "exec",
4611 * or "subsystem"] can succeed per channel." Set up the
4612 * appropriate handler for future CHANNEL_DATA and
4613 * CHANNEL_EXTENDED_DATA messages on the channel.
4615 if (0 == strcmp(request_name
, "subsystem")) {
4616 proto_tree_add_item_ret_uint(msg_type_tree
, hf_ssh_subsystem_name_len
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
, &slen
);
4618 const uint8_t* subsystem_name
;
4619 proto_tree_add_item_ret_string(msg_type_tree
, hf_ssh_subsystem_name
, packet_tvb
, offset
, slen
, ENC_UTF_8
, pinfo
->pool
, &subsystem_name
);
4620 set_subdissector_for_channel(peer_data
, recipient_channel
, subsystem_name
);
4622 }else if (0 == strcmp(request_name
, "exit-status")) {
4623 proto_tree_add_item(msg_type_tree
, hf_ssh_exit_status
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4626 }else if(msg_code
==SSH_MSG_CHANNEL_SUCCESS
){
4627 proto_tree_add_item(msg_type_tree
, hf_ssh_connection_recipient_channel
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4633 /* Channel mapping {{{ */
4636 * 1. client sends SSH_MSG_CHANNEL_OPEN with its (sender) channel number
4637 * 2. server responds with SSH_MSG_CHANNEL_OPEN_CONFIRMATION with
4638 * its channel number and echoing the client's number, creating
4640 * 3. client sends SSH_MSG_CHANNEL_REQUEST which has the name of
4641 * the shell, command, or subsystem to start. This has the recipient's
4642 * channel number (i.e. the server's)
4643 * 4. server may send back a SSG_MSG_CHANNEL_SUCCESS (or _FAILURE) with
4644 * the the recipient (i.e., client) channel number, but this does not
4645 * contain the subsystem name or anything identifying the request to
4646 * which it responds. It MUST be sent in the same order as the
4647 * corresponding request message (RFC 4254 4 Global Requests), so we
4648 * could track it that way, but for our purposes we just treat all
4649 * requests as successes. (If not, either there won't be data or another
4650 * request will supercede it later.)
4652 * Either side can open a channel (RFC 4254 5 Channel Mechanism). The
4653 * typical flow is the client opening a channel, but in the case of
4654 * remote port forwarding (7 TCP/IP Port Forwarding) the directions are
4655 * swapped. For port forwarding, all the information is contained in the
4656 * SSH_MSG_CHANNEL_OPEN, there is no SSH_MSG_CHANNEL_REQUEST.
4658 * XXX: Channel numbers can be re-used after being closed (5.3 Closing a
4659 * Channel), but not necessarily mapped to the same channel number on the
4660 * other side. If that actually happens, the right way to handle this is
4661 * to track the state changes over time for random packet access (e.g.,
4662 * using a multimap with the packet number instead of maps.)
4665 static struct ssh_peer_data
*
4666 get_other_peer_data(struct ssh_peer_data
*peer_data
)
4668 bool is_server
= &peer_data
->global_data
->peer_data
[SERVER_PEER_DATA
]==peer_data
;
4670 return &peer_data
->global_data
->peer_data
[CLIENT_PEER_DATA
];
4672 return &peer_data
->global_data
->peer_data
[SERVER_PEER_DATA
];
4676 /* Create pairings between a recipient channel and the sender's channel,
4677 * from a SSH_MSG_CHANNEL_OPEN_CONFIRMATION. */
4679 create_channel(struct ssh_peer_data
*peer_data
, uint32_t recipient_channel
, uint32_t sender_channel
)
4681 if (peer_data
->channel_info
== NULL
) {
4682 peer_data
->channel_info
= wmem_map_new(wmem_file_scope(), g_direct_hash
, g_direct_equal
);
4684 wmem_map_insert(peer_data
->channel_info
, GUINT_TO_POINTER(sender_channel
), GUINT_TO_POINTER(recipient_channel
));
4686 if (peer_data
->channel_handles
== NULL
) {
4687 peer_data
->channel_handles
= wmem_map_new(wmem_file_scope(), g_direct_hash
, g_direct_equal
);
4690 ssh_channel_info_t
*new_channel
= wmem_new0(wmem_file_scope(), ssh_channel_info_t
);
4691 new_channel
->multisegment_pdus
= wmem_tree_new(wmem_file_scope());
4692 wmem_map_insert(peer_data
->channel_handles
, GUINT_TO_POINTER(recipient_channel
), new_channel
);
4694 /* If the recipient channel is already configured in the other direction,
4695 * set the handle. We need this if we eventually handle port forwarding,
4696 * where all the information to handle the traffic is sent in the
4697 * SSH_MSG_CHANNEL_OPEN message before the CONFIRMATION. It might also
4698 * help if the packets are out of order (i.e. we get the client
4699 * CHANNEL_REQUEST before the CHANNEL_OPEN_CONFIRMATION.)
4701 struct ssh_peer_data
*other_peer_data
= get_other_peer_data(peer_data
);
4702 if (other_peer_data
->channel_handles
) {
4703 ssh_channel_info_t
*peer_channel
= wmem_map_lookup(other_peer_data
->channel_handles
, GUINT_TO_POINTER(sender_channel
));
4705 new_channel
->handle
= peer_channel
->handle
;
4710 static ssh_channel_info_t
*
4711 get_channel_info_for_channel(struct ssh_peer_data
*peer_data
, uint32_t recipient_channel
)
4713 if (peer_data
->channel_handles
== NULL
) {
4716 ssh_channel_info_t
*channel
= wmem_map_lookup(peer_data
->channel_handles
, GUINT_TO_POINTER(recipient_channel
));
4722 set_subdissector_for_channel(struct ssh_peer_data
*peer_data
, uint32_t recipient_channel
, const uint8_t* subsystem_name
)
4724 dissector_handle_t handle
= NULL
;
4725 if(0 == strcmp(subsystem_name
, "sftp")) {
4726 handle
= sftp_handle
;
4730 /* Map this handle to the recipient channel */
4731 ssh_channel_info_t
*channel
= NULL
;
4732 if (peer_data
->channel_handles
== NULL
) {
4733 peer_data
->channel_handles
= wmem_map_new(wmem_file_scope(), g_direct_hash
, g_direct_equal
);
4735 channel
= wmem_map_lookup(peer_data
->channel_handles
, GUINT_TO_POINTER(recipient_channel
));
4737 if (channel
== NULL
) {
4738 channel
= wmem_new0(wmem_file_scope(), ssh_channel_info_t
);
4739 channel
->multisegment_pdus
= wmem_tree_new(wmem_file_scope());
4740 wmem_map_insert(peer_data
->channel_handles
, GUINT_TO_POINTER(recipient_channel
), channel
);
4742 channel
->handle
= handle
;
4744 /* This recipient channel is the sender channel for the other side.
4745 * Do we know what the recipient channel on the other side is? */
4746 struct ssh_peer_data
*other_peer_data
= get_other_peer_data(peer_data
);
4748 wmem_map_t
*channel_info
= other_peer_data
->channel_info
;
4750 uint32_t sender_channel
;
4751 if (wmem_map_lookup_extended(channel_info
, GUINT_TO_POINTER(recipient_channel
), NULL
, (void**)&sender_channel
)) {
4752 /* Yes. See the handle for the other side too. */
4753 if (other_peer_data
->channel_handles
== NULL
) {
4754 other_peer_data
->channel_handles
= wmem_map_new(wmem_file_scope(), g_direct_hash
, g_direct_equal
);
4757 channel
= wmem_map_lookup(other_peer_data
->channel_handles
, GUINT_TO_POINTER(sender_channel
));
4759 if (channel
== NULL
) {
4760 channel
= wmem_new0(wmem_file_scope(), ssh_channel_info_t
);
4761 channel
->multisegment_pdus
= wmem_tree_new(wmem_file_scope());
4762 wmem_map_insert(other_peer_data
->channel_handles
, GUINT_TO_POINTER(sender_channel
), channel
);
4764 channel
->handle
= handle
;
4770 /* Channel mapping. }}} */
4773 ssh_dissect_connection_generic(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
4774 int offset
, proto_item
*msg_type_tree
, unsigned msg_code
)
4777 if(msg_code
==SSH_MSG_GLOBAL_REQUEST
){
4778 uint8_t* request_name
;
4780 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
4781 proto_tree_add_item(msg_type_tree
, hf_ssh_global_request_name_len
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4783 request_name
= tvb_get_string_enc(pinfo
->pool
, packet_tvb
, offset
, slen
, ENC_ASCII
|ENC_NA
);
4784 proto_tree_add_item(msg_type_tree
, hf_ssh_global_request_name
, packet_tvb
, offset
, slen
, ENC_ASCII
);
4786 proto_tree_add_item(msg_type_tree
, hf_ssh_global_request_want_reply
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4788 if (0 == strcmp(request_name
, "hostkeys-00@openssh.com")) {
4791 int dissected_len
= 0;
4792 alen
= tvb_get_ntohl(packet_tvb
, offset
) ;
4793 ti
= proto_tree_add_item(msg_type_tree
, hf_ssh_global_request_hostkeys_array_len
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4795 proto_item
*blob_tree
= NULL
;
4796 blob_tree
= proto_tree_add_subtree(msg_type_tree
, packet_tvb
, offset
, alen
, ett_userauth_pk_blob
, NULL
, "Public key blob");
4797 dissected_len
= ssh_dissect_public_key_blob(packet_tvb
, pinfo
, offset
, blob_tree
) - offset
;
4798 if(dissected_len
!=(int)alen
){
4799 expert_add_info_format(pinfo
, ti
, &ei_ssh_packet_decode
, "Decoded %d bytes, but packet length is %d bytes", dissected_len
, alen
);
4808 ssh_dissect_local_extension(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
4809 int offset
, struct ssh_peer_data
*peer_data
, proto_item
*msg_type_tree
, unsigned msg_code
) {
4811 if (peer_data
->global_data
->ext_ping_openssh_offered
&& msg_code
>= SSH_MSG_PING
&& msg_code
<= SSH_MSG_PONG
) {
4812 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, val_to_str(msg_code
, ssh2_ext_ping_msg_vals
, "Unknown (%u)"));
4813 proto_tree_add_item(msg_type_tree
, hf_ssh2_ext_ping_msg_code
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4815 if (msg_code
== SSH_MSG_PING
) {
4816 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
4817 proto_tree_add_item(msg_type_tree
, hf_ssh_ping_data_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4819 proto_tree_add_item(msg_type_tree
, hf_ssh_ping_data
, packet_tvb
, offset
, slen
, ENC_NA
);
4821 } else if (msg_code
== SSH_MSG_PONG
) {
4822 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
4823 proto_tree_add_item(msg_type_tree
, hf_ssh_pong_data_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4825 proto_tree_add_item(msg_type_tree
, hf_ssh_pong_data
, packet_tvb
, offset
, slen
, ENC_NA
);
4829 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, NULL
, val_to_str(msg_code
, ssh2_msg_vals
, "Unknown (%u)"));
4830 proto_tree_add_item(msg_type_tree
, hf_ssh2_msg_code
, packet_tvb
, offset
, 1, ENC_BIG_ENDIAN
);
4837 ssh_dissect_public_key_blob(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
4838 int offset
, proto_item
*msg_type_tree
)
4842 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
4843 proto_tree_add_item(msg_type_tree
, hf_ssh_pk_blob_name_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4845 proto_tree_add_item(msg_type_tree
, hf_ssh_pk_blob_name
, packet_tvb
, offset
, slen
, ENC_ASCII
);
4847 offset
+= ssh_tree_add_mpint(packet_tvb
, offset
, msg_type_tree
, hf_ssh_blob_e
);
4848 offset
+= ssh_tree_add_mpint(packet_tvb
, offset
, msg_type_tree
, hf_ssh_blob_p
);
4853 ssh_dissect_public_key_signature(tvbuff_t
*packet_tvb
, packet_info
*pinfo
,
4854 int offset
, proto_item
*msg_type_tree
)
4858 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
4859 proto_tree_add_item(msg_type_tree
, hf_ssh_pk_sig_blob_name_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4861 proto_tree_add_item(msg_type_tree
, hf_ssh_pk_sig_blob_name
, packet_tvb
, offset
, slen
, ENC_ASCII
);
4863 slen
= tvb_get_ntohl(packet_tvb
, offset
) ;
4864 proto_tree_add_item(msg_type_tree
, hf_ssh_pk_sig_s_length
, packet_tvb
, offset
, 4, ENC_BIG_ENDIAN
);
4866 proto_tree_add_item(msg_type_tree
, hf_ssh_pk_sig_s
, packet_tvb
, offset
, slen
, ENC_NA
);
4871 #ifdef SSH_DECRYPT_DEBUG /* {{{ */
4873 static FILE* ssh_debug_file
;
4876 ssh_prefs_apply_cb(void)
4878 ssh_set_debug(ssh_debug_file_name
);
4882 ssh_set_debug(const char* name
)
4884 static int debug_file_must_be_closed
;
4887 use_stderr
= name
?(strcmp(name
, SSH_DEBUG_USE_STDERR
) == 0):0;
4889 if (debug_file_must_be_closed
)
4890 fclose(ssh_debug_file
);
4893 ssh_debug_file
= stderr
;
4894 else if (!name
|| (strcmp(name
, "") ==0))
4895 ssh_debug_file
= NULL
;
4897 ssh_debug_file
= ws_fopen(name
, "w");
4899 if (!use_stderr
&& ssh_debug_file
)
4900 debug_file_must_be_closed
= 1;
4902 debug_file_must_be_closed
= 0;
4904 ssh_debug_printf("Wireshark SSH debug log \n\n");
4905 #ifdef HAVE_LIBGNUTLS
4906 ssh_debug_printf("GnuTLS version: %s\n", gnutls_check_version(NULL
));
4908 ssh_debug_printf("Libgcrypt version: %s\n", gcry_check_version(NULL
));
4909 ssh_debug_printf("\n");
4913 ssh_debug_flush(void)
4916 fflush(ssh_debug_file
);
4920 ssh_debug_printf(const char* fmt
, ...)
4924 if (!ssh_debug_file
)
4928 vfprintf(ssh_debug_file
, fmt
, ap
);
4933 ssh_print_data(const char* name
, const unsigned char* data
, size_t len
)
4936 if (!ssh_debug_file
)
4938 #ifdef OPENSSH_STYLE
4939 fprintf(ssh_debug_file
,"%s[%d]\n",name
, (int) len
);
4941 fprintf(ssh_debug_file
,"%s[%d]:\n",name
, (int) len
);
4943 for (i
=0; i
<len
; i
+=16) {
4944 #ifdef OPENSSH_STYLE
4945 fprintf(ssh_debug_file
,"%04u: ", (unsigned int)i
);
4947 fprintf(ssh_debug_file
,"| ");
4949 for (j
=i
, k
=0; k
<16 && j
<len
; ++j
, ++k
)
4950 fprintf(ssh_debug_file
,"%.2x ",data
[j
]);
4952 fprintf(ssh_debug_file
," ");
4953 #ifdef OPENSSH_STYLE
4954 fputc(' ', ssh_debug_file
);
4956 fputc('|', ssh_debug_file
);
4958 for (j
=i
, k
=0; k
<16 && j
<len
; ++j
, ++k
) {
4959 unsigned char c
= data
[j
];
4960 if (!g_ascii_isprint(c
) || (c
=='\t')) c
= '.';
4961 fputc(c
, ssh_debug_file
);
4963 #ifdef OPENSSH_STYLE
4964 fprintf(ssh_debug_file
,"\n");
4967 fputc(' ', ssh_debug_file
);
4968 fprintf(ssh_debug_file
,"|\n");
4973 #endif /* SSH_DECRYPT_DEBUG }}} */
4976 ssh_secrets_block_callback(const void *secrets
, unsigned size
)
4978 ssh_keylog_process_lines((const uint8_t *)secrets
, size
);
4981 /* Functions for SSH random hashtables. {{{ */
4983 ssh_equal (const void *v
, const void *v2
)
4985 if (v
== NULL
|| v2
== NULL
) {
4989 const ssh_bignum
*val1
;
4990 const ssh_bignum
*val2
;
4991 val1
= (const ssh_bignum
*)v
;
4992 val2
= (const ssh_bignum
*)v2
;
4994 if (val1
->length
== val2
->length
&&
4995 !memcmp(val1
->data
, val2
->data
, val2
->length
)) {
5002 ssh_hash (const void *v
)
5005 const ssh_bignum
* id
;
5006 const unsigned* cur
;
5013 id
= (const ssh_bignum
*) v
;
5015 /* id and id->data are mallocated in ssh_save_master_key(). As such 'data'
5016 * should be aligned for any kind of access (for example as a unsigned as
5017 * is done below). The intermediate void* cast is to prevent "cast
5018 * increases required alignment of target type" warnings on CPUs (such
5019 * as SPARCs) that do not allow misaligned memory accesses.
5021 cur
= (const unsigned*)(void*) id
->data
;
5023 for (l
=4; (l
< id
->length
); l
+=4, cur
++)
5024 hash
= hash
^ (*cur
);
5030 ssh_free_glib_allocated_bignum(void *data
)
5032 ssh_bignum
* bignum
;
5037 bignum
= (ssh_bignum
*) data
;
5038 g_free(bignum
->data
);
5043 ssh_free_glib_allocated_entry(void *data
)
5045 ssh_key_map_entry_t
* entry
;
5050 entry
= (ssh_key_map_entry_t
*) data
;
5051 g_free(entry
->type
);
5052 ssh_free_glib_allocated_bignum(entry
->key_material
);
5055 /* Functions for SSH random hashtables. }}} */
5058 ssh_shutdown(void) {
5059 g_hash_table_destroy(ssh_master_key_map
);
5063 proto_register_ssh(void)
5065 static hf_register_info hf
[] = {
5067 { "Protocol", "ssh.protocol",
5068 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5071 { &hf_ssh_packet_length
,
5072 { "Packet Length", "ssh.packet_length",
5073 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5076 { &hf_ssh_packet_length_encrypted
,
5077 { "Packet Length (encrypted)", "ssh.packet_length_encrypted",
5078 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5081 { &hf_ssh_padding_length
,
5082 { "Padding Length", "ssh.padding_length",
5083 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5087 { "Payload", "ssh.payload",
5088 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5091 { &hf_ssh_encrypted_packet
,
5092 { "Encrypted Packet", "ssh.encrypted_packet",
5093 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5096 { &hf_ssh_padding_string
,
5097 { "Padding String", "ssh.padding_string",
5098 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5102 { "Sequence number", "ssh.seq_num",
5103 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5106 { &hf_ssh_mac_string
,
5108 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5109 "Message authentication code", HFILL
}},
5111 { &hf_ssh_mac_status
,
5112 { "MAC Status", "ssh.mac.status", FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0x0,
5115 { &hf_ssh_direction
,
5116 { "Direction", "ssh.direction",
5117 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5118 "Message direction", HFILL
}},
5121 { "Message Code", "ssh.message_code",
5122 FT_UINT8
, BASE_DEC
, VALS(ssh1_msg_vals
), 0x0,
5125 { &hf_ssh2_msg_code
,
5126 { "Message Code", "ssh.message_code",
5127 FT_UINT8
, BASE_DEC
, VALS(ssh2_msg_vals
), 0x0,
5130 { &hf_ssh2_kex_dh_msg_code
,
5131 { "Message Code", "ssh.message_code",
5132 FT_UINT8
, BASE_DEC
, VALS(ssh2_kex_dh_msg_vals
), 0x0,
5135 { &hf_ssh2_kex_dh_gex_msg_code
,
5136 { "Message Code", "ssh.message_code",
5137 FT_UINT8
, BASE_DEC
, VALS(ssh2_kex_dh_gex_msg_vals
), 0x0,
5140 { &hf_ssh2_kex_ecdh_msg_code
,
5141 { "Message Code", "ssh.message_code",
5142 FT_UINT8
, BASE_DEC
, VALS(ssh2_kex_ecdh_msg_vals
), 0x0,
5145 { &hf_ssh2_ext_ping_msg_code
,
5146 { "Message Code", "ssh.message_code",
5147 FT_UINT8
, BASE_DEC
, VALS(ssh2_ext_ping_msg_vals
), 0x0,
5151 { "Cookie", "ssh.cookie",
5152 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5155 { &hf_ssh_kex_algorithms
,
5156 { "kex_algorithms string", "ssh.kex_algorithms",
5157 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5160 { &hf_ssh_server_host_key_algorithms
,
5161 { "server_host_key_algorithms string", "ssh.server_host_key_algorithms",
5162 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5165 { &hf_ssh_encryption_algorithms_client_to_server
,
5166 { "encryption_algorithms_client_to_server string", "ssh.encryption_algorithms_client_to_server",
5167 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5170 { &hf_ssh_encryption_algorithms_server_to_client
,
5171 { "encryption_algorithms_server_to_client string", "ssh.encryption_algorithms_server_to_client",
5172 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5175 { &hf_ssh_mac_algorithms_client_to_server
,
5176 { "mac_algorithms_client_to_server string", "ssh.mac_algorithms_client_to_server",
5177 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5180 { &hf_ssh_mac_algorithms_server_to_client
,
5181 { "mac_algorithms_server_to_client string", "ssh.mac_algorithms_server_to_client",
5182 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5185 { &hf_ssh_compression_algorithms_client_to_server
,
5186 { "compression_algorithms_client_to_server string", "ssh.compression_algorithms_client_to_server",
5187 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5190 { &hf_ssh_compression_algorithms_server_to_client
,
5191 { "compression_algorithms_server_to_client string", "ssh.compression_algorithms_server_to_client",
5192 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5195 { &hf_ssh_languages_client_to_server
,
5196 { "languages_client_to_server string", "ssh.languages_client_to_server",
5197 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5200 { &hf_ssh_languages_server_to_client
,
5201 { "languages_server_to_client string", "ssh.languages_server_to_client",
5202 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5205 { &hf_ssh_kex_algorithms_length
,
5206 { "kex_algorithms length", "ssh.kex_algorithms_length",
5207 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5210 { &hf_ssh_server_host_key_algorithms_length
,
5211 { "server_host_key_algorithms length", "ssh.server_host_key_algorithms_length",
5212 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5215 { &hf_ssh_encryption_algorithms_client_to_server_length
,
5216 { "encryption_algorithms_client_to_server length", "ssh.encryption_algorithms_client_to_server_length",
5217 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5220 { &hf_ssh_encryption_algorithms_server_to_client_length
,
5221 { "encryption_algorithms_server_to_client length", "ssh.encryption_algorithms_server_to_client_length",
5222 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5225 { &hf_ssh_mac_algorithms_client_to_server_length
,
5226 { "mac_algorithms_client_to_server length", "ssh.mac_algorithms_client_to_server_length",
5227 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5230 { &hf_ssh_mac_algorithms_server_to_client_length
,
5231 { "mac_algorithms_server_to_client length", "ssh.mac_algorithms_server_to_client_length",
5232 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5235 { &hf_ssh_compression_algorithms_client_to_server_length
,
5236 { "compression_algorithms_client_to_server length", "ssh.compression_algorithms_client_to_server_length",
5237 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5240 { &hf_ssh_compression_algorithms_server_to_client_length
,
5241 { "compression_algorithms_server_to_client length", "ssh.compression_algorithms_server_to_client_length",
5242 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5245 { &hf_ssh_languages_client_to_server_length
,
5246 { "languages_client_to_server length", "ssh.languages_client_to_server_length",
5247 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5250 { &hf_ssh_languages_server_to_client_length
,
5251 { "languages_server_to_client length", "ssh.languages_server_to_client_length",
5252 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5255 { &hf_ssh_first_kex_packet_follows
,
5256 { "First KEX Packet Follows", "ssh.first_kex_packet_follows",
5257 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5260 { &hf_ssh_kex_reserved
,
5261 { "Reserved", "ssh.kex.reserved",
5262 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5265 { &hf_ssh_kex_hassh_algo
,
5266 { "hasshAlgorithms", "ssh.kex.hassh_algorithms",
5267 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5270 { &hf_ssh_kex_hassh
,
5271 { "hassh", "ssh.kex.hassh",
5272 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5275 { &hf_ssh_kex_hasshserver_algo
,
5276 { "hasshServerAlgorithms", "ssh.kex.hasshserver_algorithms",
5277 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5280 { &hf_ssh_kex_hasshserver
,
5281 { "hasshServer", "ssh.kex.hasshserver",
5282 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5285 { &hf_ssh_hostkey_length
,
5286 { "Host key length", "ssh.host_key.length",
5287 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5290 { &hf_ssh_hostkey_type_length
,
5291 { "Host key type length", "ssh.host_key.type_length",
5292 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5295 { &hf_ssh_hostkey_type
,
5296 { "Host key type", "ssh.host_key.type",
5297 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5300 { &hf_ssh_hostkey_data
,
5301 { "Host key data", "ssh.host_key.data",
5302 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5305 { &hf_ssh_hostkey_rsa_n
,
5306 { "RSA modulus (N)", "ssh.host_key.rsa.n",
5307 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5310 { &hf_ssh_hostkey_rsa_e
,
5311 { "RSA public exponent (e)", "ssh.host_key.rsa.e",
5312 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5315 { &hf_ssh_hostkey_dsa_p
,
5316 { "DSA prime modulus (p)", "ssh.host_key.dsa.p",
5317 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5320 { &hf_ssh_hostkey_dsa_q
,
5321 { "DSA prime divisor (q)", "ssh.host_key.dsa.q",
5322 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5325 { &hf_ssh_hostkey_dsa_g
,
5326 { "DSA subgroup generator (g)", "ssh.host_key.dsa.g",
5327 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5330 { &hf_ssh_hostkey_dsa_y
,
5331 { "DSA public key (y)", "ssh.host_key.dsa.y",
5332 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5335 { &hf_ssh_hostkey_ecdsa_curve_id
,
5336 { "ECDSA elliptic curve identifier", "ssh.host_key.ecdsa.id",
5337 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5340 { &hf_ssh_hostkey_ecdsa_curve_id_length
,
5341 { "ECDSA elliptic curve identifier length", "ssh.host_key.ecdsa.id_length",
5342 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5345 { &hf_ssh_hostkey_ecdsa_q
,
5346 { "ECDSA public key (Q)", "ssh.host_key.ecdsa.q",
5347 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5350 { &hf_ssh_hostkey_ecdsa_q_length
,
5351 { "ECDSA public key length", "ssh.host_key.ecdsa.q_length",
5352 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5355 { &hf_ssh_hostkey_eddsa_key
,
5356 { "EdDSA public key", "ssh.host_key.eddsa.key",
5357 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5360 { &hf_ssh_hostkey_eddsa_key_length
,
5361 { "EdDSA public key length", "ssh.host_key.eddsa.key_length",
5362 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5365 { &hf_ssh_hostsig_length
,
5366 { "Host signature length", "ssh.host_sig.length",
5367 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5370 { &hf_ssh_hostsig_type_length
,
5371 { "Host signature type length", "ssh.host_sig.type_length",
5372 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5375 { &hf_ssh_hostsig_type
,
5376 { "Host signature type", "ssh.host_sig.type",
5377 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5380 { &hf_ssh_hostsig_data
,
5381 { "Host signature data", "ssh.host_sig.data",
5382 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5385 { &hf_ssh_hostsig_rsa
,
5386 { "RSA signature", "ssh.host_sig.rsa",
5387 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5390 { &hf_ssh_hostsig_dsa
,
5391 { "DSA signature", "ssh.host_sig.dsa",
5392 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5396 { "DH client e", "ssh.dh.e",
5397 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5401 { "DH server f", "ssh.dh.f",
5402 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5405 { &hf_ssh_dh_gex_min
,
5406 { "DH GEX Min", "ssh.dh_gex.min",
5407 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5408 "Minimal acceptable group size", HFILL
}},
5410 { &hf_ssh_dh_gex_nbits
,
5411 { "DH GEX Number of Bits", "ssh.dh_gex.nbits",
5412 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5413 "Preferred group size", HFILL
}},
5415 { &hf_ssh_dh_gex_max
,
5416 { "DH GEX Max", "ssh.dh_gex.max",
5417 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5418 "Maximal acceptable group size", HFILL
}},
5421 { "DH GEX modulus (P)", "ssh.dh_gex.p",
5422 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5426 { "DH GEX base (G)", "ssh.dh_gex.g",
5427 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5431 { "ECDH client's ephemeral public key (Q_C)", "ssh.ecdh.q_c",
5432 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5435 { &hf_ssh_ecdh_q_c_length
,
5436 { "ECDH client's ephemeral public key length", "ssh.ecdh.q_c_length",
5437 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5441 { "ECDH server's ephemeral public key (Q_S)", "ssh.ecdh.q_s",
5442 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5445 { &hf_ssh_ecdh_q_s_length
,
5446 { "ECDH server's ephemeral public key length", "ssh.ecdh.q_s_length",
5447 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5450 { &hf_ssh_mpint_length
,
5451 { "Multi Precision Integer Length", "ssh.mpint_length",
5452 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5455 { &hf_ssh_ignore_data_length
,
5456 { "Debug message length", "ssh.ignore_data_length",
5457 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5460 { &hf_ssh_ignore_data
,
5461 { "Ignore data", "ssh.ignore_data",
5462 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5465 { &hf_ssh_debug_always_display
,
5466 { "Always Display", "ssh.debug_always_display",
5467 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5470 { &hf_ssh_debug_message_length
,
5471 { "Debug message length", "ssh.debug_name_length",
5472 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5475 { &hf_ssh_debug_message
,
5476 { "Debug message", "ssh.debug_name",
5477 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5480 { &hf_ssh_service_name_length
,
5481 { "Service Name length", "ssh.service_name_length",
5482 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5485 { &hf_ssh_service_name
,
5486 { "Service Name", "ssh.service_name",
5487 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5490 { &hf_ssh_disconnect_reason
,
5491 { "Disconnect reason", "ssh.disconnect_reason",
5492 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
5495 { &hf_ssh_disconnect_description_length
,
5496 { "Disconnect description length", "ssh.disconnect_description_length",
5497 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5500 { &hf_ssh_disconnect_description
,
5501 { "Disconnect description", "ssh.disconnect_description",
5502 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5505 { &hf_ssh_ext_count
,
5506 { "Extension count", "ssh.extension.count",
5507 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5510 { &hf_ssh_ext_name_length
,
5511 { "Extension name length", "ssh.extension.name_length",
5512 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5516 { "Extension name", "ssh.extension.name",
5517 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5520 { &hf_ssh_ext_value_length
,
5521 { "Extension value length", "ssh.extension.value_length",
5522 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5525 { &hf_ssh_ext_value
,
5526 { "Extension value", "ssh.extension.value",
5527 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5530 { &hf_ssh_ext_server_sig_algs_algorithms
,
5531 { "Accepted signature algorithms", "ssh.extension.server_sig_algs.algorithms",
5532 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5535 { &hf_ssh_ext_delay_compression_algorithms_client_to_server_length
,
5536 { "Compression algorithms (client to server) length", "ssh.extension.delay_compression.compression_algorithms_client_to_server_length",
5537 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5540 { &hf_ssh_ext_delay_compression_algorithms_client_to_server
,
5541 { "Compression algorithms (client to server)", "ssh.extension.delay_compression.compression_algorithms_client_to_server",
5542 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5545 { &hf_ssh_ext_delay_compression_algorithms_server_to_client_length
,
5546 { "Compression algorithms (server to client) length", "ssh.extension.delay_compression.compression_algorithms_server_to_client_length",
5547 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5550 { &hf_ssh_ext_delay_compression_algorithms_server_to_client
,
5551 { "Compression algorithms (server to client)", "ssh.extension.delay_compression.compression_algorithms_server_to_client",
5552 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5555 { &hf_ssh_ext_no_flow_control_value
,
5556 { "No flow control flag", "ssh.extension.no_flow_control.value",
5557 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5560 { &hf_ssh_ext_elevation_value
,
5561 { "Elevation flag", "ssh.extension.elevation.value",
5562 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5565 { &hf_ssh_ext_prop_publickey_algorithms_algorithms
,
5566 { "Public key algorithms", "ssh.extension.prop_publickey_algorithms.algorithms",
5567 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5570 { &hf_ssh_lang_tag_length
,
5571 { "Language tag length", "ssh.lang_tag_length",
5572 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5576 { "Language tag", "ssh.lang_tag",
5577 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5580 { &hf_ssh_ping_data_length
,
5581 { "Data length", "ssh.ping_data_length",
5582 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5585 { &hf_ssh_ping_data
,
5586 { "Data", "ssh.ping_data",
5587 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5590 { &hf_ssh_pong_data_length
,
5591 { "Data length", "ssh.pong_data_length",
5592 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5595 { &hf_ssh_pong_data
,
5596 { "Data", "ssh.pong_data",
5597 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5601 { &hf_ssh_userauth_user_name_length
,
5602 { "User Name length", "ssh.userauth_user_name_length",
5603 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5606 { &hf_ssh_userauth_user_name
,
5607 { "User Name", "ssh.userauth_user_name",
5608 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5611 { &hf_ssh_userauth_change_password
,
5612 { "Change password", "ssh.userauth.change_password",
5613 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5616 { &hf_ssh_userauth_service_name_length
,
5617 { "Service Name length", "ssh.userauth_service_name_length",
5618 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5621 { &hf_ssh_userauth_service_name
,
5622 { "Service Name", "ssh.userauth_service_name",
5623 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5626 { &hf_ssh_userauth_method_name_length
,
5627 { "Method Name length", "ssh.userauth_method_name_length",
5628 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5631 { &hf_ssh_userauth_method_name
,
5632 { "Method Name", "ssh.userauth_method_name",
5633 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5636 { &hf_ssh_userauth_have_signature
,
5637 { "Have signature", "ssh.userauth.have_signature",
5638 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5641 { &hf_ssh_userauth_password_length
,
5642 { "Password length", "ssh.userauth_password_length",
5643 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5646 { &hf_ssh_userauth_password
,
5647 { "Password", "ssh.userauth_password",
5648 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5651 { &hf_ssh_userauth_new_password_length
,
5652 { "New password length", "ssh.userauth_new_password_length",
5653 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5656 { &hf_ssh_userauth_new_password
,
5657 { "New password", "ssh.userauth_new_password",
5658 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5661 { &hf_ssh_auth_failure_list_length
,
5662 { "Authentications that can continue list len", "ssh.auth_failure_cont_list_length",
5663 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5666 { &hf_ssh_auth_failure_list
,
5667 { "Authentications that can continue list", "ssh.auth_failure_cont_list",
5668 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5671 { &hf_ssh_userauth_partial_success
,
5672 { "Partial success", "ssh.userauth.partial_success",
5673 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5676 { &hf_ssh_userauth_pka_name_len
,
5677 { "Public key algorithm name length", "ssh.userauth_pka_name_length",
5678 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5681 { &hf_ssh_userauth_pka_name
,
5682 { "Public key algorithm name", "ssh.userauth_pka_name",
5683 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5686 { &hf_ssh_pk_blob_name_length
,
5687 { "Public key blob algorithm name length", "ssh.pk_blob_name_length",
5688 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5691 { &hf_ssh_pk_blob_name
,
5692 { "Public key blob algorithm name", "ssh.pk_blob_name",
5693 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5696 { &hf_ssh_blob_length
,
5697 { "Public key blob length", "ssh.pk_blob_length",
5698 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5702 { "ssh-rsa modulus (n)", "ssh.blob.ssh-rsa.n",
5703 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5707 { "ssh-rsa public exponent (e)", "ssh.blob.ssh-rsa.e",
5708 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5711 { &hf_ssh_signature_length
,
5712 { "Public key signature blob length", "ssh.pk_sig_blob_length",
5713 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5716 { &hf_ssh_pk_sig_blob_name_length
,
5717 { "Public key signature blob algorithm name length", "ssh.pk_sig_blob_name_length",
5718 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5721 { &hf_ssh_pk_sig_blob_name
,
5722 { "Public key signature blob algorithm name", "ssh.pk_sig_blob_name",
5723 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5726 { &hf_ssh_pk_sig_s_length
,
5727 { "ssh-rsa signature length", "ssh.sig.ssh-rsa.length",
5728 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5732 { "ssh-rsa signature (s)", "ssh.sig.ssh-rsa.s",
5733 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
5736 { &hf_ssh_connection_type_name_len
,
5737 { "Channel type name length", "ssh.connection_type_name_length",
5738 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5741 { &hf_ssh_connection_type_name
,
5742 { "Channel type name", "ssh.connection_type_name",
5743 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5746 { &hf_ssh_connection_sender_channel
,
5747 { "Sender channel", "ssh.connection_sender_channel",
5748 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5751 { &hf_ssh_connection_recipient_channel
,
5752 { "Recipient channel", "ssh.connection_recipient_channel",
5753 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5756 { &hf_ssh_connection_initial_window
,
5757 { "Initial window size", "ssh.connection_initial_window_size",
5758 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5761 { &hf_ssh_connection_maximum_packet_size
,
5762 { "Maximum packet size", "ssh.userauth_maximum_packet_size",
5763 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5766 { &hf_ssh_global_request_name_len
,
5767 { "Global request name length", "ssh.global_request_name_length",
5768 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5771 { &hf_ssh_global_request_name
,
5772 { "Global request name", "ssh.global_request_name",
5773 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5776 { &hf_ssh_global_request_want_reply
,
5777 { "Global request want reply", "ssh.global_request_want_reply",
5778 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5781 { &hf_ssh_global_request_hostkeys_array_len
,
5782 { "Host keys array length", "ssh.global_request_hostkeys",
5783 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5786 { &hf_ssh_channel_request_name_len
,
5787 { "Channel request name length", "ssh.channel_request_name_length",
5788 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5791 { &hf_ssh_channel_request_name
,
5792 { "Channel request name", "ssh.channel_request_name",
5793 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5796 { &hf_ssh_channel_request_want_reply
,
5797 { "Channel request want reply", "ssh.channel_request_want_reply",
5798 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
5801 { &hf_ssh_subsystem_name_len
,
5802 { "Subsystem name length", "ssh.subsystem_name_length",
5803 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5806 { &hf_ssh_subsystem_name
,
5807 { "Subsystem name", "ssh.subsystem_name",
5808 FT_STRING
, BASE_NONE
, NULL
, 0x0,
5811 { &hf_ssh_exit_status
,
5812 { "Exit status", "ssh.exit_status",
5813 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
5816 { &hf_ssh_channel_window_adjust
,
5817 { "Bytes to add", "ssh.channel_window_adjust",
5818 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5821 { &hf_ssh_channel_data_len
,
5822 { "Data length", "ssh.channel_data_length",
5823 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5826 { &hf_ssh_reassembled_in
,
5827 { "Reassembled PDU in frame", "ssh.reassembled_in",
5828 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
5829 "The PDU that doesn't end in this segment is reassembled in this frame", HFILL
}},
5831 { &hf_ssh_reassembled_length
,
5832 { "Reassembled PDU length", "ssh.reassembled.length",
5833 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5834 "The total length of the reassembled payload", HFILL
}},
5836 { &hf_ssh_reassembled_data
,
5837 { "Reassembled PDU data", "ssh.reassembled.data",
5838 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
5839 "The payload of multiple reassembled SSH segments", HFILL
}},
5842 { "Reassembled SSH segments", "ssh.segments",
5843 FT_NONE
, BASE_NONE
, NULL
, 0x0,
5847 { "SSH segment", "ssh.segment",
5848 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
5851 { &hf_ssh_segment_overlap
,
5852 { "Segment overlap", "ssh.segment.overlap",
5853 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5854 "Segment overlaps with other segments", HFILL
}},
5856 { &hf_ssh_segment_overlap_conflict
,
5857 { "Conflicting data in segment overlap", "ssh.segment.overlap.conflict",
5858 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5859 "Overlapping segments contained conflicting data", HFILL
}},
5861 { &hf_ssh_segment_multiple_tails
,
5862 { "Multiple tail segments found", "ssh.segment.multipletails",
5863 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5864 "Several tails were found when reassembling the pdu", HFILL
}},
5866 { &hf_ssh_segment_too_long_fragment
,
5867 { "Segment too long", "ssh.segment.toolongfragment",
5868 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
5869 "Segment contained data past end of the pdu", HFILL
}},
5871 { &hf_ssh_segment_error
,
5872 { "Reassembling error", "ssh.segment.error",
5873 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
5874 "Reassembling error due to illegal segments", HFILL
}},
5876 { &hf_ssh_segment_count
,
5877 { "Segment count", "ssh.segment.count",
5878 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
5881 { &hf_ssh_segment_data
,
5882 { "SSH segment data", "ssh.segment.data",
5883 FT_BYTES
, BASE_NONE
, NULL
, 0x00,
5884 "The payload of a single SSH segment", HFILL
}
5889 static int *ett
[] = {
5892 &ett_key_exchange_host_key
,
5893 &ett_key_exchange_host_sig
,
5895 &ett_userauth_pk_blob
,
5896 &ett_userauth_pk_signautre
,
5904 static ei_register_info ei
[] = {
5905 { &ei_ssh_packet_length
, { "ssh.packet_length.error", PI_PROTOCOL
, PI_WARN
, "Overly large number", EXPFILL
}},
5906 { &ei_ssh_packet_decode
, { "ssh.packet_decode.error", PI_PROTOCOL
, PI_WARN
, "Packet decoded length not equal to packet length", EXPFILL
}},
5907 { &ei_ssh_channel_number
, { "ssh.channel_number.error", PI_PROTOCOL
, PI_WARN
, "Coud not find channel", EXPFILL
}},
5908 { &ei_ssh_invalid_keylen
, { "ssh.key_length.error", PI_PROTOCOL
, PI_ERROR
, "Invalid key length", EXPFILL
}},
5909 { &ei_ssh_mac_bad
, { "ssh.mac_bad.expert", PI_CHECKSUM
, PI_ERROR
, "Bad MAC", EXPFILL
}},
5912 module_t
*ssh_module
;
5913 expert_module_t
*expert_ssh
;
5915 proto_ssh
= proto_register_protocol("SSH Protocol", "SSH", "ssh");
5916 proto_register_field_array(proto_ssh
, hf
, array_length(hf
));
5917 proto_register_subtree_array(ett
, array_length(ett
));
5918 expert_ssh
= expert_register_protocol(proto_ssh
);
5919 expert_register_field_array(expert_ssh
, ei
, array_length(ei
));
5921 #ifdef SSH_DECRYPT_DEBUG
5922 ssh_module
= prefs_register_protocol(proto_ssh
, ssh_prefs_apply_cb
);
5924 ssh_module
= prefs_register_protocol(proto_ssh
, NULL
);
5926 prefs_register_bool_preference(ssh_module
, "desegment_buffers",
5927 "Reassemble SSH buffers spanning multiple TCP segments",
5928 "Whether the SSH dissector should reassemble SSH buffers spanning multiple TCP segments. "
5929 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
5932 ssh_master_key_map
= g_hash_table_new_full(ssh_hash
, ssh_equal
, ssh_free_glib_allocated_bignum
, ssh_free_glib_allocated_entry
);
5933 prefs_register_filename_preference(ssh_module
, "keylog_file", "Key log filename",
5934 "The path to the file which contains a list of key exchange secrets in the following format:\n"
5935 "\"<hex-encoded-cookie> <PRIVATE_KEY|SHARED_SECRET> <hex-encoded-key>\" (without quotes or leading spaces).\n",
5936 &pref_keylog_file
, false);
5938 prefs_register_filename_preference(ssh_module
, "debug_file", "SSH debug file",
5939 "Redirect SSH debug to the file specified. Leave empty to disable debugging "
5940 "or use \"" SSH_DEBUG_USE_STDERR
"\" to redirect output to stderr.",
5941 &ssh_debug_file_name
, true);
5943 secrets_register_type(SECRETS_TYPE_SSH
, ssh_secrets_block_callback
);
5945 ssh_handle
= register_dissector("ssh", dissect_ssh
, proto_ssh
);
5946 reassembly_table_register(&ssh_reassembly_table
, &tcp_reassembly_table_functions
);
5947 register_shutdown_routine(ssh_shutdown
);
5951 proto_reg_handoff_ssh(void)
5953 #ifdef SSH_DECRYPT_DEBUG
5954 ssh_set_debug(ssh_debug_file_name
);
5956 dissector_add_uint_range_with_preference("tcp.port", TCP_RANGE_SSH
, ssh_handle
);
5957 dissector_add_uint("sctp.port", SCTP_PORT_SSH
, ssh_handle
);
5958 dissector_add_uint("sctp.ppi", SSH_PAYLOAD_PROTOCOL_ID
, ssh_handle
);
5959 sftp_handle
= find_dissector("sftp");
5963 * Editor modelines - https://www.wireshark.org/tools/modelines.html
5968 * indent-tabs-mode: nil
5971 * vi: set shiftwidth=4 tabstop=8 expandtab:
5972 * :indentSize=4:tabSize=8:noTabs=true: