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