client-hello.c (2686B)
- #include "debug.h" /* debug_printf */
- #include "tls-parameters-4.h" /* ciphers */
- #include <err.h>
- #include <errno.h> // errno
- #include <netdb.h> // getaddrinfo()
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h> /* arc4random_buf() */
- #include <string.h> /* memset(), strlcpy(), strlcat() */
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <unistd.h> /* close() */
- static int SSL_TLS_versions[] = {
- 0x0200, /* 2.0: SSLv2 */
- 0x0300, /* 3.0: SSLv3 */
- 0x0301, /* 3.1: TLSv1.0 */
- 0x0302, /* 3.2: TLSv1.1 */
- 0x0303, /* 3.3: TLSv1.2 */
- };
- static void usage(char *command)
- {
- printf("Usage: %s <host> [port]\n", command);
- printf("Default port: 443\n");
- exit(0);
- }
- int main(int argc, char *argv[])
- {
- size_t send_result;
- char *handshake, *tls_packet, *client_hello;
- char *s_port = "1337", random_bytes[32];
- if(argc < 2 || argc > 3) usage(argv[0]);
- /* START network connection, copied from manpages of getaddrinfo(3) from OpenBSD and GNU */
- struct addrinfo hints, *result, *rp;
- int error = 0;
- int save_errno = errno;
- int s = 0;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = 0;
- hints.ai_protocol = 0;
- error = getaddrinfo(argv[1], s_port, &hints, &result);
- if(error != 0) errx(1, "getaddrinfo: %s", gai_strerror(error));
- for(rp = result; rp != NULL; rp = rp->ai_next)
- {
- s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
- if(connect(s, rp->ai_addr, rp->ai_addrlen) != -1)
- {
- break;
- }
- else
- {
- save_errno = errno;
- }
- close(s);
- }
- if((s == -1) | (rp == NULL))
- {
- perror(strerror(save_errno));
- exit(EXIT_FAILURE);
- }
- freeaddrinfo(result);
- /* DONE network connection */
- arc4random_buf(random_bytes, sizeof(random_bytes));
- tls_packet = (uint16_t)'\x01'; /* client hello: 0x01 */
- strlcpy(client_hello, (uint32_t)0x0303, 4); /* SSL version max */
- strlcat(client_hello, (const char *)&random_bytes, 32);
- strlcat(tls_packet, (const char *)sizeof(client_hello), 3);
- strlcat(tls_packet, client_hello, sizeof(client_hello));
- strlcat(tls_packet, '\x00', 2); /* Session ID lenght */
- strlcat(tls_packet, sizeof(ciphers), 2);
- strlcat(tls_packet, &ciphers, sizeof(ciphers));
- strlcat(tls_packet, '\x01', 1); /* Compression Method */
- strlcat(tls_packet, '\x00', 1); /* Compression Methods */
- strlcat(tls_packet, "\x00\x00", 2); /* Extension Lenght */
- handshake = '\x16';
- strlcat(&handshake, 0x0200, 2); /* SSL version min */
- strlcat(&handshake, sizeof(tls_packet), 2);
- strlcat(&handshake, tls_packet, sizeof(tls_packet));
- write(s, handshake, sizeof(handshake));
- close(s);
- return 0;
- }