Skip to content

Commit

Permalink
Added initial support for max fragment size extension. (#25)
Browse files Browse the repository at this point in the history
Refactored the code to support more SSL extensions in the future.
  • Loading branch information
slaff authored and igrr committed Nov 21, 2016
1 parent aa87239 commit cf4c0bb
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 26 deletions.
20 changes: 18 additions & 2 deletions ssl/ssl.h
Expand Up @@ -225,6 +225,22 @@ EXP_FUNC SSL_CTX * STDCALL ssl_ctx_new(uint32_t options, int num_sessions);
*/
EXP_FUNC void STDCALL ssl_ctx_free(SSL_CTX *ssl_ctx);

/**
* @brief Allocates new SSL extensions structure and returns pointer to it
*
* @return ssl_ext Pointer to SSL_EXTENSIONS structure
*
*/
EXP_FUNC SSL_EXTENSIONS * STDCALL ssl_ext_new();

/**
* @brief Frees SSL extensions structure
*
* @param ssl_ext [in] Pointer to SSL_EXTENSION structure
*
*/
EXP_FUNC void STDCALL ssl_ext_free(SSL_EXTENSIONS *ssl_ext);

/**
* @brief (server only) Establish a new SSL connection to an SSL client.
*
Expand All @@ -251,11 +267,11 @@ EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd);
* can be null if no session resumption is being used or required. This option
* is not used in skeleton mode.
* @param sess_id_size The size of the session id (max 32)
* @param host_name If non-zero, host name to be sent to server for SNI support
* @param ssl_ext pointer to a structure with the activated SSL extensions and their values
* @return An SSL object reference. Use ssl_handshake_status() to check
* if a handshake succeeded.
*/
EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size, const char* host_name);
EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size, SSL_EXTENSIONS* ssl_ext);

/**
* @brief Free any used resources on this connection.
Expand Down
34 changes: 31 additions & 3 deletions ssl/tls1.c
Expand Up @@ -139,6 +139,35 @@ void DISPLAY_BYTES(SSL *ssl, const char *format,
const uint8_t *data, int size, ...) {}
#endif

/**
* Allocates new SSL extensions structure and returns pointer to it
*
*/
EXP_FUNC SSL_EXTENSIONS * STDCALL ssl_ext_new()
{
SSL_EXTENSIONS *ssl_ext = (SSL_EXTENSIONS *)malloc(sizeof(SSL_EXTENSIONS));
ssl_ext->max_fragment_size = 0;
ssl_ext->host_name = NULL;

return ssl_ext;
}

/**
* Allocates new SSL extensions structure and returns pointer to it
*
*/
EXP_FUNC void STDCALL ssl_ext_free(SSL_EXTENSIONS *ssl_ext)
{
if(ssl_ext == NULL ) {
return;
}

if(ssl_ext->host_name != NULL) {
free(ssl_ext->host_name);
}
free(ssl_ext);
}

/**
* Establish a new client/server context.
*/
Expand Down Expand Up @@ -257,7 +286,8 @@ EXP_FUNC void STDCALL ssl_free(SSL *ssl)
disposable_free(ssl);
certificate_free(ssl);
free(ssl->bm_all_data);
free(ssl->host_name);
ssl_ext_free(ssl->extensions);
ssl->extensions = NULL;
free(ssl);
}

Expand Down Expand Up @@ -631,8 +661,6 @@ SSL *ssl_new(SSL_CTX *ssl_ctx, int client_fd)
ssl->encrypt_ctx = malloc(sizeof(AES_CTX));
ssl->decrypt_ctx = malloc(sizeof(AES_CTX));

ssl->host_name = NULL;

SSL_CTX_UNLOCK(ssl_ctx->mutex);
return ssl;
}
Expand Down
8 changes: 7 additions & 1 deletion ssl/tls1.h
Expand Up @@ -120,6 +120,7 @@ enum
enum
{
SSL_EXT_SERVER_NAME = 0,
SSL_EXT_MAX_FRAGMENT_SIZE,
SSL_EXT_SIG_ALG = 0x0d,
};

Expand Down Expand Up @@ -172,6 +173,11 @@ typedef struct
uint8_t key_block_generated;
} DISPOSABLE_CTX;

typedef struct {
char *host_name; /* Needed for the SNI support */
uint16_t max_fragment_size; /* Needed for the Max Fragment Size Extension. Allowed values: 2^9, 2^10 .. 2^14 */
} SSL_EXTENSIONS;

struct _SSL
{
uint32_t flag;
Expand Down Expand Up @@ -213,7 +219,7 @@ struct _SSL
uint8_t read_sequence[8]; /* 64 bit sequence number */
uint8_t write_sequence[8]; /* 64 bit sequence number */
uint8_t hmac_header[SSL_RECORD_SIZE]; /* rx hmac */
char *host_name; /* Needed for the SNI support */
SSL_EXTENSIONS *extensions; /* Contains the SSL (client) extensions */
};

typedef struct _SSL SSL;
Expand Down
52 changes: 32 additions & 20 deletions ssl/tls1_clnt.c
Expand Up @@ -64,7 +64,7 @@ static int send_cert_verify(SSL *ssl);
* Establish a new SSL connection to an SSL server.
*/
EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const
uint8_t *session_id, uint8_t sess_id_size, const char* host_name)
uint8_t *session_id, uint8_t sess_id_size, SSL_EXTENSIONS* ssl_ext)
{
SSL *ssl = ssl_new(ssl_ctx, client_fd);
ssl->version = SSL_PROTOCOL_VERSION_MAX; /* try top version first */
Expand All @@ -82,9 +82,7 @@ EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const
SET_SSL_FLAG(SSL_SESSION_RESUME); /* just flag for later */
}

if(host_name != NULL && strlen(host_name) > 0) {
ssl->host_name = (char *)strdup(host_name);
}
ssl->extensions = ssl_ext;

SET_SSL_FLAG(SSL_IS_CLIENT);
do_client_connect(ssl);
Expand Down Expand Up @@ -259,22 +257,36 @@ static int send_client_hello(SSL *ssl)
ext_len += sizeof(g_sig_alg);
}

/* send the host name if specified */
if (ssl->host_name != NULL) {
unsigned int host_len = strlen(ssl->host_name);

buf[offset++] = 0;
buf[offset++] = SSL_EXT_SERVER_NAME; /* server_name(0) (65535) */
buf[offset++] = 0;
buf[offset++] = host_len+5; /* server_name length */
buf[offset++] = 0;
buf[offset++] = host_len+3; /* server_list length */
buf[offset++] = 0; /* host_name(0) (255) */
buf[offset++] = 0;
buf[offset++] = host_len; /* host_name length */
strncpy((char*) &buf[offset], ssl->host_name, host_len);
offset += host_len;
ext_len += host_len + 9;
if (ssl->extensions != NULL) {
/* send the host name if specified */
if (ssl->extensions->host_name != NULL) {
unsigned int host_len = strlen(ssl->extensions->host_name);

buf[offset++] = 0;
buf[offset++] = SSL_EXT_SERVER_NAME; /* server_name(0) (65535) */
buf[offset++] = 0;
buf[offset++] = host_len + 5; /* server_name length */
buf[offset++] = 0;
buf[offset++] = host_len + 3; /* server_list length */
buf[offset++] = 0; /* host_name(0) (255) */
buf[offset++] = 0;
buf[offset++] = host_len; /* host_name length */
strncpy((char*) &buf[offset], ssl->extensions->host_name, host_len);
offset += host_len;
ext_len += host_len + 9;
}

if (ssl->extensions->max_fragment_size) {
buf[offset++] = 0;
buf[offset++] = SSL_EXT_MAX_FRAGMENT_SIZE;

buf[offset++] = 0; // size of data
buf[offset++] = 2;

buf[offset++] = (uint8_t)((ssl->extensions->max_fragment_size >> 8) & 0xff);
buf[offset++] = (uint8_t)(ssl->extensions->max_fragment_size & 0xff);
ext_len += 6;
}
}

if(ext_len > 0) {
Expand Down

0 comments on commit cf4c0bb

Please sign in to comment.