2 * ssl manipulation functions
3 * By Paolo Abeni <paolo.abeni@email.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #ifndef __SSL_UTILS_H_
27 #define __SSL_UTILS_H_
29 #include <stdio.h> /* some APIs we declare take a stdio stream as an argument */
32 #include <epan/packet.h>
33 #include <epan/wmem/wmem.h>
36 #include <wsutil/wsgcrypt.h>
37 #include <gnutls/x509.h>
38 #include <gnutls/pkcs12.h>
40 #include <epan/conversation.h>
41 #include "ws_symbol_export.h"
43 /* #define SSL_FAST 1 */
44 #define SSL_DECRYPT_DEBUG
46 #define SSL_CIPHER_CTX gcry_cipher_hd_t
47 #define SSL_PSK_KEY guchar
49 #define SSL_PRIVATE_KEY gcry_mpi_t
51 #define SSL_PRIVATE_KEY struct gcry_sexp
53 #else /* HAVE_LIBGNUTLS */
54 #define SSL_CIPHER_CTX void*
55 #define SSL_PRIVATE_KEY void
56 #define SSL_PSK_KEY void
57 #endif /* HAVE_LIBGNUTLS */
60 /* version state tables */
61 #define SSL_VER_UNKNOWN 0
62 #define SSL_VER_SSLv2 1
63 #define SSL_VER_SSLv3 2
65 #define SSL_VER_TLSv1DOT1 4
66 #define SSL_VER_DTLS 5
67 #define SSL_VER_DTLS1DOT2 8
69 #define SSL_VER_TLSv1DOT2 7
72 #define SSL_ID_CHG_CIPHER_SPEC 0x14
73 #define SSL_ID_ALERT 0x15
74 #define SSL_ID_HANDSHAKE 0x16
75 #define SSL_ID_APP_DATA 0x17
76 #define SSL_ID_HEARTBEAT 0x18
78 #define SSL_HND_HELLO_REQUEST 0
79 #define SSL_HND_CLIENT_HELLO 1
80 #define SSL_HND_SERVER_HELLO 2
81 #define SSL_HND_HELLO_VERIFY_REQUEST 3
82 #define SSL_HND_NEWSESSION_TICKET 4
83 #define SSL_HND_CERTIFICATE 11
84 #define SSL_HND_SERVER_KEY_EXCHG 12
85 #define SSL_HND_CERT_REQUEST 13
86 #define SSL_HND_SVR_HELLO_DONE 14
87 #define SSL_HND_CERT_VERIFY 15
88 #define SSL_HND_CLIENT_KEY_EXCHG 16
89 #define SSL_HND_FINISHED 20
90 #define SSL_HND_CERT_STATUS 22
92 #define SSL2_HND_ERROR 0x00
93 #define SSL2_HND_CLIENT_HELLO 0x01
94 #define SSL2_HND_CLIENT_MASTER_KEY 0x02
95 #define SSL2_HND_CLIENT_FINISHED 0x03
96 #define SSL2_HND_SERVER_HELLO 0x04
97 #define SSL2_HND_SERVER_VERIFY 0x05
98 #define SSL2_HND_SERVER_FINISHED 0x06
99 #define SSL2_HND_REQUEST_CERTIFICATE 0x07
100 #define SSL2_HND_CLIENT_CERTIFICATE 0x08
102 #define PCT_VERSION_1 0x8001
104 #define PCT_MSG_CLIENT_HELLO 0x01
105 #define PCT_MSG_SERVER_HELLO 0x02
106 #define PCT_MSG_CLIENT_MASTER_KEY 0x03
107 #define PCT_MSG_SERVER_VERIFY 0x04
108 #define PCT_MSG_ERROR 0x05
110 #define PCT_CH_OFFSET_V1 0xa
112 #define PCT_CIPHER_DES 0x01
113 #define PCT_CIPHER_IDEA 0x02
114 #define PCT_CIPHER_RC2 0x03
115 #define PCT_CIPHER_RC4 0x04
116 #define PCT_CIPHER_DES_112 0x05
117 #define PCT_CIPHER_DES_168 0x06
119 #define PCT_HASH_MD5 0x0001
120 #define PCT_HASH_MD5_TRUNC_64 0x0002
121 #define PCT_HASH_SHA 0x0003
122 #define PCT_HASH_SHA_TRUNC_80 0x0004
123 #define PCT_HASH_DES_DM 0x0005
125 #define PCT_CERT_NONE 0x00
126 #define PCT_CERT_X509 0x01
127 #define PCT_CERT_PKCS7 0x02
129 #define PCT_SIG_NONE 0x0000
130 #define PCT_SIG_RSA_MD5 0x0001
131 #define PCT_SIG_RSA_SHA 0x0002
132 #define PCT_SIG_DSA_SHA 0x0003
134 #define PCT_EXCH_RSA_PKCS1 0x01
135 #define PCT_EXCH_RSA_PKCS1_TOKEN_DES 0x02
136 #define PCT_EXCH_RSA_PKCS1_TOKEN_DES3 0x03
137 #define PCT_EXCH_RSA_PKCS1_TOKEN_RC2 0x04
138 #define PCT_EXCH_RSA_PKCS1_TOKEN_RC4 0x05
139 #define PCT_EXCH_DH_PKCS3 0x06
140 #define PCT_EXCH_DH_PKCS3_TOKEN_DES 0x07
141 #define PCT_EXCH_DH_PKCS3_TOKEN_DES3 0x08
142 #define PCT_EXCH_FORTEZZA_TOKEN 0x09
144 #define PCT_ERR_BAD_CERTIFICATE 0x01
145 #define PCT_ERR_CLIENT_AUTH_FAILED 0x02
146 #define PCT_ERR_ILLEGAL_MESSAGE 0x03
147 #define PCT_ERR_INTEGRITY_CHECK_FAILED 0x04
148 #define PCT_ERR_SERVER_AUTH_FAILED 0x05
149 #define PCT_ERR_SPECS_MISMATCH 0x06
151 #define SSL_HND_HELLO_EXT_SERVER_NAME 0x0
152 #define SSL_HND_HELLO_EXT_ELLIPTIC_CURVES 0x000a
153 #define SSL_HND_HELLO_EXT_EC_POINT_FORMATS 0x000b
154 #define SSL_HND_HELLO_EXT_SIG_HASH_ALGS 0x000d
155 #define SSL_HND_HELLO_EXT_HEARTBEAT 0x000f
156 #define SSL_HND_HELLO_EXT_ALPN 0x0010
157 #define SSL_HND_HELLO_EXT_RENEG_INFO 0xff01
158 #define SSL_HND_HELLO_EXT_NPN 0x3374
159 #define SSL_HND_CERT_STATUS_TYPE_OCSP 1
164 extern const value_string ssl_version_short_names
[];
165 extern const value_string ssl_20_msg_types
[];
166 extern value_string_ext ssl_20_cipher_suites_ext
;
167 extern const value_string ssl_20_certificate_type
[];
168 extern const value_string ssl_31_content_type
[];
169 extern const value_string ssl_versions
[];
170 extern const value_string ssl_31_change_cipher_spec
[];
171 extern const value_string ssl_31_alert_level
[];
172 extern const value_string ssl_31_alert_description
[];
173 extern const value_string ssl_31_handshake_type
[];
174 extern const value_string tls_heartbeat_type
[];
175 extern const value_string tls_heartbeat_mode
[];
176 extern const value_string ssl_31_compression_method
[];
177 extern const value_string ssl_31_key_exchange_algorithm
[];
178 extern const value_string ssl_31_signature_algorithm
[];
179 extern const value_string ssl_31_client_certificate_type
[];
180 extern const value_string ssl_31_public_value_encoding
[];
181 extern value_string_ext ssl_31_ciphersuite_ext
;
182 extern const value_string pct_msg_types
[];
183 extern const value_string pct_cipher_type
[];
184 extern const value_string pct_hash_type
[];
185 extern const value_string pct_cert_type
[];
186 extern const value_string pct_sig_type
[];
187 extern const value_string pct_exch_type
[];
188 extern const value_string pct_error_code
[];
189 extern const value_string tls_hello_extension_types
[];
190 extern const value_string tls_hash_algorithm
[];
191 extern const value_string tls_signature_algorithm
[];
192 extern const value_string tls_certificate_type
[];
193 extern const value_string tls_cert_status_type
[];
194 extern const value_string ssl_extension_curves
[];
195 extern const value_string ssl_extension_ec_point_formats
[];
196 extern const value_string ssl_curve_types
[];
197 extern const value_string tls_hello_ext_server_name_type_vs
[];
199 /* XXX Should we use GByteArray instead? */
200 typedef struct _StringInfo
{
205 #define SSL_WRITE_KEY 1
207 #define SSLV3_VERSION 0x300
208 #define TLSV1_VERSION 0x301
209 #define TLSV1DOT1_VERSION 0x302
210 #define TLSV1DOT2_VERSION 0x303
211 #define DTLSV1DOT0_VERSION 0xfeff
212 #define DTLSV1DOT0_VERSION_NOT 0x100
213 #define DTLSV1DOT2_VERSION 0xfefd
215 #define SSL_CLIENT_RANDOM (1<<0)
216 #define SSL_SERVER_RANDOM (1<<1)
217 #define SSL_CIPHER (1<<2)
218 #define SSL_HAVE_SESSION_KEY (1<<3)
219 #define SSL_VERSION (1<<4)
220 #define SSL_MASTER_SECRET (1<<5)
221 #define SSL_PRE_MASTER_SECRET (1<<6)
223 #define SSL_CIPHER_MODE_STREAM 0 /* GenericStreamCipher */
224 #define SSL_CIPHER_MODE_CBC 1 /* GenericBlockCipher */
225 #define SSL_CIPHER_MODE_GCM 2 /* GenericAEADCipher */
227 /* Explicit nonce length */
228 #define SSL_EX_NONCE_LEN_GCM 8 /* RFC 5288 - section 3 */
230 #define SSL_DEBUG_USE_STDERR "-"
232 #define SSLV2_MAX_SESSION_ID_LENGTH_IN_BYTES 16
234 typedef struct _SslCipherSuite
{
239 gint block
; /* IV block size */
246 typedef struct _SslFlow
{
249 wmem_tree_t
*multisegment_pdus
;
252 typedef struct _SslDecompress SslDecompress
;
254 typedef struct _SslDecoder
{
255 SslCipherSuite
* cipher_suite
;
257 guchar _mac_key_or_write_iv
[48];
258 StringInfo mac_key
; /* for block and stream ciphers */
259 StringInfo write_iv
; /* for AEAD ciphers (at least GCM, CCM) */
261 SslDecompress
*decomp
;
270 #define KEX_ECDH 0x13
271 #define KEX_RSA_PSK 0x14
275 #define SIG_NONE 0x22
278 #define ENC_3DES 0x31
281 #define ENC_IDEA 0x34
283 #define ENC_AES256 0x36
284 #define ENC_CAMELLIA128 0x37
285 #define ENC_CAMELLIA256 0x38
286 #define ENC_SEED 0x39
287 #define ENC_NULL 0x3A
291 #define DIG_SHA256 0x42
292 #define DIG_SHA384 0x43
299 typedef struct _SslRecordInfo
{
303 struct _SslRecordInfo
* next
;
306 typedef struct _SslDataInfo
{
308 StringInfo plain_data
;
312 struct _SslDataInfo
*next
;
316 SslDataInfo
*appl_data
;
317 SslRecordInfo
* handshake_data
;
320 typedef struct _SslDecryptSession
{
321 guchar _master_secret
[48];
322 guchar _session_id
[256];
323 guchar _client_random
[32];
324 guchar _server_random
[32];
325 StringInfo session_id
;
326 StringInfo server_random
;
327 StringInfo client_random
;
328 StringInfo master_secret
;
329 /* the data store for this StringInfo must be allocated explicitly with a capture lifetime scope */
330 StringInfo pre_master_secret
;
331 guchar _server_data_for_iv
[24];
332 StringInfo server_data_for_iv
;
333 guchar _client_data_for_iv
[24];
334 StringInfo client_data_for_iv
;
339 SslCipherSuite cipher_suite
;
342 SslDecoder
*server_new
;
343 SslDecoder
*client_new
;
344 SSL_PRIVATE_KEY
* private_key
;
347 guint16 version_netorder
;
348 StringInfo app_data_segment
;
356 typedef struct _SslAssociation
{
359 dissector_handle_t handle
;
361 gboolean from_key_list
;
364 typedef struct _SslService
{
369 typedef struct _Ssl_private_key
{
370 #ifdef HAVE_LIBGNUTLS
371 gnutls_x509_crt_t x509_cert
;
372 gnutls_x509_privkey_t x509_pkey
;
374 SSL_PRIVATE_KEY
*sexp_pkey
;
377 /* User Access Table */
378 typedef struct _ssldecrypt_assoc_t
{
384 } ssldecrypt_assoc_t
;
386 gint
ssl_get_keyex_alg(gint cipher
);
388 gboolean
ssldecrypt_uat_fld_ip_chk_cb(void*, const char*, unsigned, const void*, const void*, const char** err
);
389 gboolean
ssldecrypt_uat_fld_port_chk_cb(void*, const char*, unsigned, const void*, const void*, const char** err
);
390 gboolean
ssldecrypt_uat_fld_protocol_chk_cb(void*, const char*, unsigned, const void*, const void*, const char** err
);
391 gboolean
ssldecrypt_uat_fld_fileopen_chk_cb(void*, const char*, unsigned, const void*, const void*, const char** err
);
392 gboolean
ssldecrypt_uat_fld_password_chk_cb(void*, const char*, unsigned, const void*, const void*, const char** err
);
394 /** Initialize decryption engine/ssl layer. To be called once per execution */
398 /** Initialize an ssl session struct
399 @param ssl pointer to ssl session struct to be initialized */
401 ssl_session_init(SslDecryptSession
* ssl
);
403 /** Set server address and port */
405 ssl_set_server(SslDecryptSession
* ssl
, address
*addr
, port_type ptype
, guint32 port
);
407 /** set the data and len for the stringInfo buffer. buf should be big enough to
408 * contain the provided data
409 @param buf the buffer to update
410 @param src the data source
411 @param len the source data len */
413 ssl_data_set(StringInfo
* buf
, const guchar
* src
, guint len
);
416 ssl_cipher_setiv(SSL_CIPHER_CTX
*cipher
, guchar
* iv
, gint iv_len
);
418 /** Load an RSA private key from specified file
419 @param fp the file that contain the key data
420 @return a pointer to the loaded key on success, or NULL */
421 extern Ssl_private_key_t
*
422 ssl_load_key(FILE* fp
);
424 /** Deallocate the memory used for specified key
425 @param key pointer to the key to be freed */
427 ssl_free_key(Ssl_private_key_t
* key
);
429 /* Find private key in associations */
431 ssl_find_private_key(SslDecryptSession
*ssl_session
, GHashTable
*key_hash
, GTree
* associations
, packet_info
*pinfo
);
433 /** Search for the specified cipher suite id
434 @param num the id of the cipher suite to be searched
435 @param cs pointer to the cipher suite struct to be filled
436 @return 0 if the cipher suite is found, -1 elsewhere */
438 ssl_find_cipher(int num
,SslCipherSuite
* cs
);
440 /** Expand the pre_master_secret to generate all the session information
441 * (master secret, session keys, ivs)
442 @param ssl_session the store for all the session data
443 @return 0 on success */
445 ssl_generate_keyring_material(SslDecryptSession
*ssl_session
);
448 ssl_change_cipher(SslDecryptSession
*ssl_session
, gboolean server
);
450 /** Try to find the pre-master secret for the given encrypted pre-master secret
451 from a log of secrets.
452 @param ssl_session the store for the decrypted pre_master_secret
453 @param ssl_keylog_filename a file that contains a log of secrets (may be NULL)
454 @param encrypted_pre_master the rsa encrypted pre_master_secret (may be NULL)
455 @return 0 on success */
457 ssl_keylog_lookup(SslDecryptSession
* ssl_session
,
458 const gchar
* ssl_keylog_filename
,
459 StringInfo
* encrypted_pre_master
);
461 /** Try to decrypt in place the encrypted pre_master_secret
462 @param ssl_session the store for the decrypted pre_master_secret
463 @param encrypted_pre_master the rsa encrypted pre_master_secret
464 @param pk the private key to be used for decryption
465 @return 0 on success */
467 ssl_decrypt_pre_master_secret(SslDecryptSession
*ssl_session
,
468 StringInfo
* encrypted_pre_master
, SSL_PRIVATE_KEY
*pk
);
470 /** Try to decrypt an ssl record
471 @param ssl ssl_session the store all the session data
472 @param decoder the stream decoder to be used
473 @param ct the content type of this ssl record
474 @param in a pointer to the ssl record to be decrypted
475 @param inl the record length
476 @param comp_str a pointer to the store the compression data
477 @param out_str a pointer to the store for the decrypted data
478 @param outl the decrypted data len
479 @return 0 on success */
481 ssl_decrypt_record(SslDecryptSession
* ssl
,SslDecoder
* decoder
, gint ct
,
482 const guchar
* in
, guint inl
, StringInfo
* comp_str
, StringInfo
* out_str
, guint
* outl
);
485 /* Common part bitween SSL and DTLS dissectors */
486 /* Hash Functions for TLS/DTLS sessions table and private keys table */
488 ssl_equal (gconstpointer v
, gconstpointer v2
);
491 ssl_hash (gconstpointer v
);
494 ssl_private_key_equal (gconstpointer v
, gconstpointer v2
);
497 ssl_private_key_hash (gconstpointer v
);
499 /* private key table entries have a scope 'larger' then packet capture,
500 * so we can't relay on se_alloc** function */
502 ssl_private_key_free(gpointer id
, gpointer key
, gpointer dummy _U_
);
504 /* handling of association between tls/dtls ports and clear text protocol */
506 ssl_association_add(GTree
* associations
, dissector_handle_t handle
, guint port
, const gchar
*protocol
, gboolean tcp
, gboolean from_key_list
);
509 ssl_association_remove(GTree
* associations
, SslAssociation
*assoc
);
512 ssl_association_cmp(gconstpointer a
, gconstpointer b
);
514 extern SslAssociation
*
515 ssl_association_find(GTree
* associations
, guint port
, gboolean tcp
);
518 ssl_assoc_from_key_list(gpointer key _U_
, gpointer data
, gpointer user_data
);
521 ssl_packet_from_server(SslDecryptSession
* ssl
, GTree
* associations
, packet_info
*pinfo
);
523 /* add to packet data a copy of the specified real data */
525 ssl_add_record_info(gint proto
, packet_info
*pinfo
, guchar
* data
, gint data_len
, gint record_id
);
527 /* search in packet data for the specified id; return a newly created tvb for the associated data */
529 ssl_get_record_info(tvbuff_t
*parent_tvb
, gint proto
, packet_info
*pinfo
, gint record_id
);
532 ssl_add_data_info(gint proto
, packet_info
*pinfo
, guchar
* data
, gint data_len
, gint key
, SslFlow
*flow
);
535 ssl_get_data_info(int proto
, packet_info
*pinfo
, gint key
);
537 /* initialize/reset per capture state data (ssl sessions cache) */
539 ssl_common_init(GHashTable
**session_hash
, StringInfo
*decrypted_data
, StringInfo
*compressed_data
);
541 /* parse ssl related preferences (private keys and ports association strings) */
543 ssl_parse_key_list(const ssldecrypt_assoc_t
* uats
, GHashTable
*key_hash
, GTree
* associations
, dissector_handle_t handle
, gboolean tcp
);
545 /* store master secret into session data cache */
547 ssl_save_session(SslDecryptSession
* ssl
, GHashTable
*session_hash
);
550 ssl_restore_session(SslDecryptSession
* ssl
, GHashTable
*session_hash
);
553 ssl_is_valid_content_type(guint8 type
);
555 #ifdef SSL_DECRYPT_DEBUG
557 ssl_debug_printf(const gchar
* fmt
,...) G_GNUC_PRINTF(1,2);
559 ssl_print_data(const gchar
* name
, const guchar
* data
, size_t len
);
561 ssl_print_string(const gchar
* name
, const StringInfo
* data
);
563 ssl_set_debug(const gchar
* name
);
565 ssl_debug_flush(void);
568 /* No debug: nullify debug operation*/
569 static inline void G_GNUC_PRINTF(1,2)
570 ssl_debug_printf(const gchar
* fmt _U_
,...)
573 #define ssl_print_data(a, b, c)
574 #define ssl_print_string(a, b)
575 #define ssl_set_debug(name)
576 #define ssl_debug_flush()
578 #endif /* SSL_DECRYPT_DEBUG */
580 #endif /* SSL_UTILS_H */
583 * Editor modelines - http://www.wireshark.org/tools/modelines.html
588 * indent-tabs-mode: nil
591 * vi: set shiftwidth=4 tabstop=8 expandtab:
592 * :indentSize=4:tabSize=8:noTabs=true: