1 /**************************************************************************
2  **
3  ** sngrep - SIP Messages flow viewer
4  **
5  ** Copyright (C) 2013-2018 Ivan Alonso (Kaian)
6  ** Copyright (C) 2013-2018 Irontec SL. All rights reserved.
7  **
8  ** This program is free software: you can redistribute it and/or modify
9  ** it under the terms of the GNU General Public License as published by
10  ** the Free Software Foundation, either version 3 of the License, or
11  ** (at your option) any later version.
12  **
13  ** This program is distributed in the hope that it will be useful,
14  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  ** GNU General Public License for more details.
17  **
18  ** You should have received a copy of the GNU General Public License
19  ** along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  **
21  ** In addition, as a special exception, the copyright holders give
22  ** permission to link the code of portions of this program with the
23  ** OpenSSL library under certain conditions as described in each
24  ** individual source file, and distribute linked combinations
25  ** including the two.
26  ** You must obey the GNU General Public License in all respects
27  ** for all of the code used other than OpenSSL.  If you modify
28  ** file(s) with this exception, you may extend this exception to your
29  ** version of the file(s), but you are not obligated to do so.  If you
30  ** do not wish to do so, delete this exception statement from your
31  ** version.  If you delete this exception statement from all source
32  ** files in the program, then also delete it here.
33  **
34  ****************************************************************************/
35 /**
36  * @file capture_tls.h
37  * @author Ivan Alonso [aka Kaian] <kaian@irontec.com>
38  *
39  * @brief Functions to manage SIP TLS messages
40  *
41  * This file contains the functions and structures to manage the SIP messages
42  * that use TLS as transport.
43  *
44  */
45 
46 #ifndef __SNGREP_CAPTURE_TLS_
47 #define __SNGREP_CAPTURE_TLS_
48 
49 #include "config.h"
50 #include <openssl/ssl.h>
51 #include <openssl/tls1.h>
52 #include <openssl/err.h>
53 #include <openssl/evp.h>
54 #include <openssl/hmac.h>
55 #include <openssl/rsa.h>
56 #include "capture.h"
57 
58 //! Cast two bytes into decimal (Big Endian)
59 #define UINT16_INT(i) ((i.x[0] << 8) | i.x[1])
60 //! Cast three bytes into decimal (Big Endian)
61 #define UINT24_INT(i) ((i.x[0] << 16) | (i.x[1] << 8) | i.x[2])
62 
63 //The symbol SSL3_MT_NEWSESSION_TICKET appears to have been introduced at around
64 //openssl 0.9.8f, and the use of if breaks builds with older openssls
65 #if OPENSSL_VERSION_NUMBER < 0x00908070L
66 #define OLD_OPENSSL_VERSION 1
67 #endif
68 
69 /* LibreSSL declares OPENSSL_VERSION_NUMBER == 2.0 but does not include most
70  * changes from OpenSSL >= 1.1 (new functions, macros, deprecations, ...)
71  */
72 #if defined(LIBRESSL_VERSION_NUMBER)
73 #define MODSSL_USE_OPENSSL_PRE_1_1_API (1)
74 #else
75 #define MODSSL_USE_OPENSSL_PRE_1_1_API (OPENSSL_VERSION_NUMBER < 0x10100000L)
76 #endif
77 
78 //! Three bytes unsigned integer
79 typedef struct uint16 {
80     unsigned char x[2];
81 } uint16;
82 
83 //! Three bytes unsigned integer
84 typedef struct uint24 {
85     unsigned char x[3];
86 } uint24;
87 
88 //! One byte generic type
89 typedef unsigned char opaque;
90 
91 //! SSLConnections states
92 enum SSLConnectionState {
93     //! Initial SYN packet has been received from client
94     TCP_STATE_SYN = 0,
95     //! SYN/ACK packet has been sent from the server
96     TCP_STATE_SYN_ACK,
97     //! Client ACK'ed the connection
98     TCP_STATE_ACK,
99     //! Connection is up, now SSL handshake should start!
100     TCP_STATE_ESTABLISHED,
101     //! Connection about to end
102     TCP_STATE_FIN,
103     //! Connection closed
104     TCP_STATE_CLOSED
105 };
106 
107 //! SSL Encoders algo
108 enum SSLCipherEncoders {
109     ENC_AES         = 1,
110     ENC_AES256      = 2
111 };
112 
113 //! SSL Digests algo
114 enum SSLCIpherDigest {
115     DIG_SHA1        = 1,
116     DIG_SHA256      = 2,
117     DIG_SHA384      = 3
118 };
119 
120 //! SSL Decode mode
121 enum SSLCipherMode {
122     MODE_CBC,
123     MODE_GCM
124 };
125 
126 //! ContentType values as defined in RFC5246
127 enum ContentType {
128     change_cipher_spec = SSL3_RT_CHANGE_CIPHER_SPEC,
129     alert = SSL3_RT_ALERT,
130     handshake = SSL3_RT_HANDSHAKE,
131     application_data = SSL3_RT_APPLICATION_DATA
132 };
133 
134 //! HanshakeType values as defined in RFC5246
135 enum HandshakeType {
136     hello_request = SSL3_MT_HELLO_REQUEST,
137     client_hello = SSL3_MT_CLIENT_HELLO,
138     server_hello = SSL3_MT_SERVER_HELLO,
139     certificate = SSL3_MT_CERTIFICATE,
140     certificate_request = SSL3_MT_CERTIFICATE_REQUEST,
141     server_hello_done = SSL3_MT_SERVER_DONE,
142     certificate_verify = SSL3_MT_CERTIFICATE_VERIFY,
143     client_key_exchange = SSL3_MT_CLIENT_KEY_EXCHANGE,
144 #ifndef OLD_OPENSSL_VERSION
145     new_session_ticket = SSL3_MT_NEWSESSION_TICKET,
146 #endif
147     finished = SSL3_MT_FINISHED
148 };
149 
150 //! ProtocolVersion header as defined in RFC5246
151 struct ProtocolVersion {
152     uint8_t major;
153     uint8_t minor;
154 };
155 
156 //! TLSPlaintext record structure
157 struct TLSPlaintext {
158     uint8_t type;
159     struct ProtocolVersion version;
160     uint16 length;
161 };
162 
163 //! Hanshake record structure
164 struct Handshake {
165     uint8_t type;
166     uint24 length;
167 };
168 
169 //! Handshake random structure
170 struct Random {
171     uint8_t gmt_unix_time[4];
172     uint8_t random_bytes[28];
173 };
174 
175 struct CipherSuite {
176     uint8_t cs1;
177     uint8_t cs2;
178 };
179 
180 struct CipherData {
181     int num;
182     int enc;
183     int ivblock;
184     int bits;
185     int digest;
186     int diglen;
187     int mode;
188 };
189 
190 struct ClientHelloSSLv2 {
191     struct ProtocolVersion client_version;
192     uint16 cipherlist_len;
193     uint16 sessionid_len;
194     uint16 random_len;
195     // CipherSuite cipher_suite;
196     // struct Random random;
197 };
198 
199 //! ClientHello type in Handshake records
200 struct ClientHello {
201     struct ProtocolVersion client_version;
202     struct Random random;
203 //    uint8_t session_id_length;
204 // CipherSuite cipher_suite;
205 // Extension extensions;
206 };
207 
208 //! ServerHello type in Handshake records
209 struct ServerHello {
210     struct ProtocolVersion server_version;
211     struct Random random;
212     uint8_t session_id_length;
213 // SessionID session_id;
214 // CipherSuite cipher_suite;
215 // CompressionMethod compression_method;
216 };
217 
218 struct MasterSecret {
219     uint8_t random[48];
220 };
221 
222 struct PreMasterSecret {
223     struct ProtocolVersion client_version;
224     uint8_t random[46];
225 };
226 
227 struct EncryptedPreMasterSecret {
228     uint8_t pre_master_secret[128];
229 };
230 
231 //! ClientKeyExchange type in Handshake records
232 struct ClientKeyExchange {
233     uint16 length;
234     struct EncryptedPreMasterSecret exchange_keys;
235 };
236 
237 /**
238  * Structure to store all information from a TLS
239  * connection. This is also used as linked list
240  * node.
241  */
242 struct SSLConnection {
243     //! Connection status
244     enum SSLConnectionState state;
245     //! Current packet direction
246     int direction;
247     //! Data is encrypted flag
248     int encrypted;
249     //! TLS version
250     int version;
251 
252     //! Client IP address
253     struct in_addr client_addr;
254     //! Server IP address
255     struct in_addr server_addr;
256     //! Client port
257     uint16_t client_port;
258     //! Server port
259     uint16_t server_port;
260 
261     SSL *ssl;
262     SSL_CTX *ssl_ctx;
263     EVP_PKEY *server_private_key;
264     const EVP_CIPHER *ciph;
265     struct Random client_random;
266     struct Random server_random;
267     struct CipherSuite cipher_suite;
268     struct CipherData cipher_data;
269     struct PreMasterSecret pre_master_secret;
270     struct MasterSecret master_secret;
271 
272     struct tls_data {
273         uint8_t *client_write_MAC_key;
274         uint8_t *server_write_MAC_key;
275         uint8_t *client_write_key;
276         uint8_t *server_write_key;
277         uint8_t *client_write_IV;
278         uint8_t *server_write_IV;
279     } key_material;
280 
281     EVP_CIPHER_CTX *client_cipher_ctx;
282     EVP_CIPHER_CTX *server_cipher_ctx;
283 
284     struct SSLConnection *next;
285 };
286 
287 /**
288  * @brief P_hash expansion function as defined in RFC5246
289  *
290  * This function will expand Secret and Seed into output using digest
291  * hash function. The amount of data generated will be determined by output
292  * length (dlen).
293  *
294  * @param digest Digest name to get the hash function
295  * @param dest Destination of hash function result. Memory must be already allocated
296  * @param dlen Destination length in bytes
297  * @param secret Input for the hash function
298  * @param sslen Secret length in bytes
299  * @param seed Input for the hash function
300  * @param slen Seed length in bytes
301  * @return Output bytes
302  */
303 int
304 P_hash(const char *digest, unsigned char *dest, int dlen, unsigned char *secret, int sslen,
305        unsigned char *seed, int slen);
306 
307 /**
308  * @brief Pseudorandom Function as defined in RFC2246
309  *
310  * This function will generate MasterSecret and KeyMaterial data from PreMasterSecret and Seed
311  *
312  * @param dest Destination of PRF function result. Memory must be already allocated
313  * @param dlen Destination length in bytes
314  * @param pre_master_secret PreMasterSecret decrypted from ClientKeyExchange Handhsake record
315  * @param pslen PreMasterSecret length in bytes
316  * @param label Fixed ASCII string
317  * @param seed Concatenation of Random data from Hello Handshake records
318  * @param slen Seed length in bytes
319  * @return destination length in bytes
320  */
321 int
322 PRF(struct SSLConnection *conn, unsigned char *dest, int dlen, unsigned char *pre_master_secret,
323     int plen, unsigned char *label, unsigned char *seed, int slen);
324 
325 /**
326  * @brief Create a new SSLConnection
327  *
328  * This will allocate enough memory to store all connection data
329  * from a detected SSL connection. This will also add this structure to
330  * the connections linked list.
331  *
332  * @param caddr Client address
333  * @param cport Client port
334  * @param saddr Server address
335  * @param sport Server port
336  * @return a pointer to a new allocated SSLConnection structure
337  */
338 struct SSLConnection *
339 tls_connection_create(struct in_addr caddr, uint16_t cport, struct in_addr saddr, uint16_t sport);
340 
341 /**
342  * @brief Destroys an existing SSLConnection
343  *
344  * This will free all allocated memory of SSLConnection also removing
345  * the connection from connections list.
346  *
347  * @param conn Existing connection pointer
348  */
349 void
350 tls_connection_destroy(struct SSLConnection *conn);
351 
352 /**
353  * @brief Check if given keyfile is valid
354  *
355  * This can be used to check if a file contains valid RSA data
356  *
357  * @param keyfile Absolute path the keyfile
358  * @return 1 if file contains RSA private info, 0 otherwise
359  */
360 int
361 tls_check_keyfile(const char *keyfile);
362 
363 /**
364  * @brief Determines packet direction
365  *
366  * Determine if the given address is from client or server.
367  *
368  * @param conn Existing connection pointer
369  * @param addr Client or server address
370  * @param port Client or server port
371  * @return 0 if address belongs to client, 1 to server or -1 otherwise
372  */
373 int
374 tls_connection_dir(struct SSLConnection *conn, struct in_addr addr, uint16_t port);
375 
376 /**
377  * @brief Find a connection
378  *
379  * Try to find connection data for a given address and port.
380  * This address:port convination can be the client or server one.
381  *
382  * @param addr Client or server address
383  * @param port Client or server port
384  * @return an existing Connection pointer or NULL if not found
385  */
386 struct SSLConnection*
387 tls_connection_find(struct in_addr src, uint16_t sport, struct in_addr dst, uint16_t dport);
388 
389 /**
390  * @brief Process a TCP segment to check TLS data
391  *
392  * Check if a TCP segment contains TLS data. In case a TLS record is found
393  * process it and return decrypted data if case of application_data record.
394  *
395  * @param tcp Pointer to tcp header of the packet
396  * @param out Pointer to the output char array. Memory must be already allocated
397  * @param out Number of bytes returned by this function
398  * @return 0 in all cases
399  */
400 int
401 tls_process_segment(packet_t *packet, struct tcphdr *tcp);
402 
403 /**
404  * @brief Process TLS record data
405  *
406  * Process a TLS record
407  *  - If the record type is Handshake process it in tls_process_record_handshake
408  *  - If the record type is Application Data process it in tls_process_record_data
409  *
410  * @param conn Existing connection pointer
411  * @param payload Packet peyload
412  * @param len Payload length
413  * @param out pointer to store decryted data
414  * @param outl decrypted data length
415  * @return Decrypted data length
416  */
417 int
418 tls_process_record(struct SSLConnection *conn, const uint8_t *payload, const int len, uint8_t **out,
419                    uint32_t *outl);
420 
421 /**
422  * @brief Check if this Record looks like SSLv2
423  *
424  * Some devices send the initial ClientHello in a SSLv2 record for compatibility
425  * with only SSLv2 protocol.
426  *
427  * We will only parse SSLv2 Client hello fragments that have TLSv1/SSLv3 content
428  * so this does not make us SSLv2 compatible ;-p
429  * @param conn Existing connection pointer
430  * @param payload Packet peyload
431  * @param len Payload length
432  * @return 1 if payload seems a SSLv2 record, 0 otherwise
433  */
434 int
435 tls_record_handshake_is_ssl2(struct SSLConnection *conn, const uint8_t *payload,
436                    const int len);
437 /**
438  * @brief Process TLS Handshake SSLv2 record types
439  *
440  * Process all types of Handshake records to store and compute all required
441  * data to decrypt application data packets
442  *
443  * @param conn Existing connection pointer
444  * @param fragment Handshake record data
445  * @param len Decimal length of the fragment
446  * @return 0 on valid record processed, 1 otherwise
447  */
448 int
449 tls_process_record_ssl2(struct SSLConnection *conn, const uint8_t *payload,
450                    const int len, uint8_t **out, uint32_t *outl);
451 
452 /**
453  * @brief Process TLS Handshake record types
454  *
455  * Process all types of Handshake records to store and compute all required
456  * data to decrypt application data packets
457  *
458  * @param conn Existing connection pointer
459  * @param fragment Handshake record data
460  * @param len Decimal length of the fragment
461  * @return 0 on valid record processed, 1 otherwise
462  */
463 int
464 tls_process_record_handshake(struct SSLConnection *conn, const opaque *fragment, const int len);
465 
466 /**
467  * @brief Process TLS ApplicationData record types
468  *
469  * Process application data record, trying to decrypt it with connection
470  * information
471  *
472  * @param conn Existing connection pointer
473  * @param fragment Application record data
474  * @param len record length in bytes
475  * @param out pointer to store decryted data
476  * @param outl decrypted data length
477  * @return decoded data length
478  */
479 int
480 tls_process_record_data(struct SSLConnection *conn, const opaque *fragment, const int len,
481                         uint8_t **out, uint32_t *outl);
482 
483 
484 /**
485  * @brief Get the cipher data from the given connection
486  *
487  * Load cipher pointer depending on the selected cipher in
488  * Handshake messages.
489  *
490  * This function can be used to test is a cipher decrypting is supported
491  * @param conn Existing connection pointer
492  * @return 0 on valid cipher, 1 otherwise
493  */
494 int
495 tls_connection_load_cipher(struct SSLConnection *conn);
496 
497 #endif
498