TIdCustomHTTPServer *Server = /*get you IndyServer Instance here*/;
TIdServerIOHandlerSSLOpenSSL *SSLHandler;
if (Server->IOHandler == NULL)
Server->IOHandler = SSLHandler = new TIdServerIOHandlerSSLOpenSSL();
else
SSLHandler = (TIdServerIOHandlerSSLOpenSSL*) Server->IOHandler;
SSLHandler->SSLOptions->RootCertFile = "";
SSLHandler->SSLOptions->CertFile = "path/to/cert.pem";
SSLHandler->SSLOptions->KeyFile = "path/to/cert.key";
SSLHandler->SSLOptions->Mode = Idsslopenssl::sslmServer;
SSLHandler->SSLOptions->VerifyDepth = 0;
SSLHandler->SSLOptions->SSLVersions = TIdSSLVersions();
SSLHandler->SSLOptions->SSLVersions << sslvTLSv1 << sslvTLSv1_1 << sslvTLSv1_2;
SSLHandler->SSLOptions->CipherList = "ALL:!LOW:!SSLv2:!aNULL:!aECDH:!eNULL:!EXP:!EXPORT:!DES:!RC4:!MD5:!PSK:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:@STRENGTH";
Server->OnQuerySSLPort = (TIdHTTPQuerySSLPortEvent)&IdQuerySSLPortHandler; // Callback to decide if we are on https port
// Adding the following list of headers in every response
//"X-Content-Type-Options:nosniff;X-Frame-Options:DENY;Strict-Transport-Security:max-age=31536000;\"Content-Security-Policy:style-src 'self' 'unsafe-inline'; img-src 'self' data:; default-src 'self';\";\"X-XSS-Protection:1; mode=block\""
// I read them in from config file, pass them through a TStringList('"', ';') with NameValueSeparator=':' and append them in every Response with ResponseInfo->CustomHeaders->Assign()
type
TIdSSLContextAccessor = class(TIdSSLContext);
function SSL_CTX_set_ecdh_auto(ctx: PSSL_CTX; m: TIdC_LONG): TIdC_LONG; inline;
const
SSL_CTRL_SET_ECDH_AUTO = 94;
begin
Result := SSL_CTX_ctrl(ctx, SSL_CTRL_SET_ECDH_AUTO, m, nil);
end;
procedure PatchSSLContext(const AContext: TIdSSLContext);
var
ctx: PSSL_CTX;
begin
ctx := TIdSSLContextAccessor(AContext).fContext;
// SSL_OP_CIPHER_SERVER_PREFERENCE:
// When choosing a cipher, use the server's preferences instead of the
// client preferences. When not set, the SSL server will always follow the
// clients preferences. When set, the SSL/TLS server will choose following
// its own preferences.
// SSL_OP_SINGLE_DH_USE:
// Always create a new key when using temporary/ephemeral DH parameters
// (see SSL_CTX_set_tmp_dh_callback). This option must be used to prevent
// small subgroup attacks, when the DH parameters were not generated using
// "strong" primes (e.g. when using DSA-parameters, see dhparam). If
// "strong" primes were used, it is not strictly necessary to generate a new
// DH key during each handshake but it is also recommended.
// SSL_OP_SINGLE_DH_USE should therefore be enabled whenever
// temporary/ephemeral DH parameters are used.
SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE or SSL_OP_SINGLE_DH_USE);
// SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION:
// Allow legacy insecure renegotiation between OpenSSL and unpatched clients or servers
SSL_CTX_clear_options(ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
SSL_CTX_set_ecdh_auto(ctx, 1);
end;