119 lines
2.1 KiB
C
119 lines
2.1 KiB
C
|
/*
|
||
|
* ssl.c
|
||
|
* Copyright (C) 2019 Ilja Kartašov <ik@lowenware.com>
|
||
|
*
|
||
|
* Distributed under terms of the MIT license.
|
||
|
*/
|
||
|
|
||
|
#include <openssl/err.h>
|
||
|
#include "ssl.h"
|
||
|
|
||
|
|
||
|
#ifndef AISL_WITHOUT_SSL
|
||
|
|
||
|
static int
|
||
|
get_ssl_context( SSL * ssl, int * ptr, void * handle )
|
||
|
{
|
||
|
const char * server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
|
||
|
|
||
|
SSL_CTX * ctx = aisl_get_ssl_ctx( (aisl_t) handle, server_name );
|
||
|
|
||
|
if (ctx)
|
||
|
{
|
||
|
SSL_set_SSL_CTX(ssl, ctx);
|
||
|
}
|
||
|
|
||
|
return SSL_TLSEXT_ERR_OK;
|
||
|
}
|
||
|
|
||
|
/* -------------------------------------------------------------------------- */
|
||
|
|
||
|
static SSL_CTX *
|
||
|
create_ssl_context( aisl_t instance,
|
||
|
const char * key_file,
|
||
|
const char * crt_file )
|
||
|
{
|
||
|
const SSL_METHOD * method;
|
||
|
SSL_CTX * ctx;
|
||
|
|
||
|
method = SSLv23_server_method();
|
||
|
|
||
|
if ( !(ctx = SSL_CTX_new(method)) )
|
||
|
goto except;
|
||
|
|
||
|
SSL_CTX_set_ecdh_auto(ctx, 1);
|
||
|
|
||
|
SSL_CTX_set_tlsext_servername_callback( ctx, get_ssl_context );
|
||
|
SSL_CTX_set_tlsext_servername_arg( ctx, (void *) instance );
|
||
|
|
||
|
if (!(SSL_CTX_use_certificate_file(ctx, crt_file, SSL_FILETYPE_PEM) > 0))
|
||
|
goto release;
|
||
|
|
||
|
if (!(SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) > 0))
|
||
|
goto release;
|
||
|
|
||
|
goto finally;
|
||
|
|
||
|
release:
|
||
|
SSL_CTX_free(ctx);
|
||
|
ctx = NULL;
|
||
|
|
||
|
except:
|
||
|
aisl_set_error( instance, ERR_error_string(ERR_get_error(),NULL) );
|
||
|
|
||
|
finally:
|
||
|
return ctx;
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
crypter_free( crypter_t self )
|
||
|
{
|
||
|
if (self->srvName)
|
||
|
free(self->srvName);
|
||
|
|
||
|
if (self->keyFile)
|
||
|
{
|
||
|
free(self->keyFile);
|
||
|
SSL_CTX_free(self->sslCtx);
|
||
|
}
|
||
|
|
||
|
if (self->crtFile)
|
||
|
free(self->crtFile);
|
||
|
|
||
|
free(self);
|
||
|
}
|
||
|
|
||
|
|
||
|
static crypter_t
|
||
|
crypter_new( const char * server_name,
|
||
|
const char * key_file,
|
||
|
const char * crt_file )
|
||
|
{
|
||
|
crypter_t self;
|
||
|
|
||
|
if ( (self=calloc(1, sizeof(struct crypter))) != NULL )
|
||
|
{
|
||
|
if (!(self->srvName = str_copy( server_name ? server_name : "*" )))
|
||
|
goto release;
|
||
|
|
||
|
if ( key_file && !(self->keyFile = str_copy(key_file)))
|
||
|
goto release;
|
||
|
|
||
|
if ( crt_file && !(self->crtFile = str_copy(crt_file)))
|
||
|
goto release;
|
||
|
|
||
|
}
|
||
|
|
||
|
goto finally;
|
||
|
|
||
|
|
||
|
release:
|
||
|
crypter_free(self);
|
||
|
self = NULL;
|
||
|
|
||
|
finally:
|
||
|
return self;
|
||
|
}
|
||
|
|
||
|
#endif
|