commit
02838e530f
3 changed files with 114 additions and 33 deletions
|
@ -88,7 +88,7 @@
|
||||||
static int httpPromoteToSSL(struct HttpConnection *http, const char *buf,
|
static int httpPromoteToSSL(struct HttpConnection *http, const char *buf,
|
||||||
int len) {
|
int len) {
|
||||||
if (http->ssl->enabled && !http->sslHndl) {
|
if (http->ssl->enabled && !http->sslHndl) {
|
||||||
debug("Switching to SSL (replaying %d+%d bytes)",
|
debug("SSL: switching to SSL (replaying %d+%d bytes)",
|
||||||
http->partialLength, len);
|
http->partialLength, len);
|
||||||
if (http->partial && len > 0) {
|
if (http->partial && len > 0) {
|
||||||
check(http->partial = realloc(http->partial,
|
check(http->partial = realloc(http->partial,
|
||||||
|
@ -102,6 +102,8 @@ static int httpPromoteToSSL(struct HttpConnection *http, const char *buf,
|
||||||
http->partial ? http->partialLength : len);
|
http->partial ? http->partialLength : len);
|
||||||
if (http->sslHndl) {
|
if (http->sslHndl) {
|
||||||
check(!rc);
|
check(!rc);
|
||||||
|
// Reset renegotiations count for connections promoted to SSL.
|
||||||
|
http->ssl->renegotiationCount = 0;
|
||||||
SSL_set_app_data(http->sslHndl, http);
|
SSL_set_app_data(http->sslHndl, http);
|
||||||
}
|
}
|
||||||
free(http->partial);
|
free(http->partial);
|
||||||
|
@ -138,6 +140,13 @@ static ssize_t httpRead(struct HttpConnection *http, char *buf, ssize_t len) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dcheck(!ERR_peek_error());
|
dcheck(!ERR_peek_error());
|
||||||
|
|
||||||
|
// Shutdown SSL connection, if client initiated renegotiation.
|
||||||
|
if (http->ssl->renegotiationCount > 1) {
|
||||||
|
debug("SSL: connection shutdown due to client initiated renegotiation!");
|
||||||
|
rc = 0;
|
||||||
|
errno = EINVAL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
rc = NOINTR(read(http->fd, buf, len));
|
rc = NOINTR(read(http->fd, buf, len));
|
||||||
}
|
}
|
||||||
|
|
107
libhttp/ssl.c
107
libhttp/ssl.c
|
@ -102,15 +102,20 @@ BIO * (*BIO_new)(BIO_METHOD *);
|
||||||
BIO * (*BIO_new_socket)(int, int);
|
BIO * (*BIO_new_socket)(int, int);
|
||||||
BIO * (*BIO_pop)(BIO *);
|
BIO * (*BIO_pop)(BIO *);
|
||||||
BIO * (*BIO_push)(BIO *, BIO *);
|
BIO * (*BIO_push)(BIO *, BIO *);
|
||||||
|
#if defined(HAVE_OPENSSL_EC)
|
||||||
|
void (*EC_KEY_free)(EC_KEY *);
|
||||||
|
EC_KEY * (*EC_KEY_new_by_curve_name)(int);
|
||||||
|
#endif
|
||||||
void (*ERR_clear_error)(void);
|
void (*ERR_clear_error)(void);
|
||||||
void (*ERR_clear_error)(void);
|
|
||||||
unsigned long (*ERR_peek_error)(void);
|
|
||||||
unsigned long (*ERR_peek_error)(void);
|
unsigned long (*ERR_peek_error)(void);
|
||||||
long (*SSL_CTX_callback_ctrl)(SSL_CTX *, int, void (*)(void));
|
long (*SSL_CTX_callback_ctrl)(SSL_CTX *, int, void (*)(void));
|
||||||
int (*SSL_CTX_check_private_key)(const SSL_CTX *);
|
int (*SSL_CTX_check_private_key)(const SSL_CTX *);
|
||||||
long (*SSL_CTX_ctrl)(SSL_CTX *, int, long, void *);
|
long (*SSL_CTX_ctrl)(SSL_CTX *, int, long, void *);
|
||||||
void (*SSL_CTX_free)(SSL_CTX *);
|
void (*SSL_CTX_free)(SSL_CTX *);
|
||||||
SSL_CTX * (*SSL_CTX_new)(SSL_METHOD *);
|
SSL_CTX * (*SSL_CTX_new)(SSL_METHOD *);
|
||||||
|
int (*SSL_CTX_set_cipher_list)(SSL_CTX *, const char *);
|
||||||
|
void (*SSL_CTX_set_info_callback)(SSL_CTX *,
|
||||||
|
void (*)(const SSL *, int, int));
|
||||||
int (*SSL_CTX_use_PrivateKey_file)(SSL_CTX *, const char *, int);
|
int (*SSL_CTX_use_PrivateKey_file)(SSL_CTX *, const char *, int);
|
||||||
int (*SSL_CTX_use_PrivateKey_ASN1)(int, SSL_CTX *,
|
int (*SSL_CTX_use_PrivateKey_ASN1)(int, SSL_CTX *,
|
||||||
const unsigned char *, long);
|
const unsigned char *, long);
|
||||||
|
@ -136,7 +141,6 @@ int (*SSL_write)(SSL *, const void *, int);
|
||||||
SSL_METHOD * (*SSLv23_server_method)(void);
|
SSL_METHOD * (*SSLv23_server_method)(void);
|
||||||
X509 * (*d2i_X509)(X509 **px, const unsigned char **in, int len);
|
X509 * (*d2i_X509)(X509 **px, const unsigned char **in, int len);
|
||||||
void (*X509_free)(X509 *a);
|
void (*X509_free)(X509 *a);
|
||||||
int (*x_SSL_CTX_set_cipher_list)(SSL_CTX *ctx, const char *str);
|
|
||||||
void (*x_sk_zero)(void *st);
|
void (*x_sk_zero)(void *st);
|
||||||
void * (*x_SSL_COMP_get_compression_methods)(void);
|
void * (*x_SSL_COMP_get_compression_methods)(void);
|
||||||
#endif
|
#endif
|
||||||
|
@ -166,6 +170,7 @@ void initSSL(struct SSLSupport *ssl) {
|
||||||
ssl->sslContext = NULL;
|
ssl->sslContext = NULL;
|
||||||
ssl->sniCertificatePattern = NULL;
|
ssl->sniCertificatePattern = NULL;
|
||||||
ssl->generateMissing = 0;
|
ssl->generateMissing = 0;
|
||||||
|
ssl->renegotiationCount = 0;
|
||||||
initTrie(&ssl->sniContexts, sslDestroyCachedContext, ssl);
|
initTrie(&ssl->sniContexts, sslDestroyCachedContext, ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,11 +285,17 @@ static void loadSSL(void) {
|
||||||
{ { &ERR_clear_error }, "ERR_clear_error" },
|
{ { &ERR_clear_error }, "ERR_clear_error" },
|
||||||
{ { &ERR_peek_error }, "ERR_peek_error" },
|
{ { &ERR_peek_error }, "ERR_peek_error" },
|
||||||
{ { &ERR_peek_error }, "ERR_peek_error" },
|
{ { &ERR_peek_error }, "ERR_peek_error" },
|
||||||
|
#ifdef HAVE_OPENSSL_EC
|
||||||
|
{ { &EC_KEY_free }, "EC_KEY_free" },
|
||||||
|
{ { &EC_KEY_new_by_curve_name }, "EC_KEY_new_by_curve_name" },
|
||||||
|
#endif
|
||||||
{ { &SSL_CTX_callback_ctrl }, "SSL_CTX_callback_ctrl" },
|
{ { &SSL_CTX_callback_ctrl }, "SSL_CTX_callback_ctrl" },
|
||||||
{ { &SSL_CTX_check_private_key }, "SSL_CTX_check_private_key" },
|
{ { &SSL_CTX_check_private_key }, "SSL_CTX_check_private_key" },
|
||||||
{ { &SSL_CTX_ctrl }, "SSL_CTX_ctrl" },
|
{ { &SSL_CTX_ctrl }, "SSL_CTX_ctrl" },
|
||||||
{ { &SSL_CTX_free }, "SSL_CTX_free" },
|
{ { &SSL_CTX_free }, "SSL_CTX_free" },
|
||||||
{ { &SSL_CTX_new }, "SSL_CTX_new" },
|
{ { &SSL_CTX_new }, "SSL_CTX_new" },
|
||||||
|
{ { &SSL_CTX_set_cipher_list }, "SSL_CTX_set_cipher_list" },
|
||||||
|
{ { &SSL_CTX_set_info_callback }, "SSL_CTX_set_info_callback" },
|
||||||
{ { &SSL_CTX_use_PrivateKey_file }, "SSL_CTX_use_PrivateKey_file" },
|
{ { &SSL_CTX_use_PrivateKey_file }, "SSL_CTX_use_PrivateKey_file" },
|
||||||
{ { &SSL_CTX_use_PrivateKey_ASN1 }, "SSL_CTX_use_PrivateKey_ASN1" },
|
{ { &SSL_CTX_use_PrivateKey_ASN1 }, "SSL_CTX_use_PrivateKey_ASN1" },
|
||||||
{ { &SSL_CTX_use_certificate_file },"SSL_CTX_use_certificate_file"},
|
{ { &SSL_CTX_use_certificate_file },"SSL_CTX_use_certificate_file"},
|
||||||
|
@ -312,12 +323,11 @@ static void loadSSL(void) {
|
||||||
{ { &SSLv23_server_method }, "SSLv23_server_method" },
|
{ { &SSLv23_server_method }, "SSLv23_server_method" },
|
||||||
{ { &d2i_X509 }, "d2i_X509" },
|
{ { &d2i_X509 }, "d2i_X509" },
|
||||||
{ { &X509_free }, "X509_free" },
|
{ { &X509_free }, "X509_free" },
|
||||||
{ { &x_SSL_CTX_set_cipher_list }, "SSL_CTX_set_cipher_list" },
|
|
||||||
{ { &x_sk_zero }, "sk_zero" }
|
{ { &x_sk_zero }, "sk_zero" }
|
||||||
};
|
};
|
||||||
for (unsigned i = 0; i < sizeof(symbols)/sizeof(symbols[0]); i++) {
|
for (unsigned i = 0; i < sizeof(symbols)/sizeof(symbols[0]); i++) {
|
||||||
if (!(*symbols[i].var = loadSymbol(path_libssl, symbols[i].fn))) {
|
if (!(*symbols[i].var = loadSymbol(path_libssl, symbols[i].fn))) {
|
||||||
debug("Failed to load SSL support. Could not find \"%s\"",
|
debug("SSL: failed to load SSL support. Could not find \"%s\"",
|
||||||
symbols[i].fn);
|
symbols[i].fn);
|
||||||
for (unsigned j = 0; j < sizeof(symbols)/sizeof(symbols[0]); j++) {
|
for (unsigned j = 0; j < sizeof(symbols)/sizeof(symbols[0]); j++) {
|
||||||
*symbols[j].var = NULL;
|
*symbols[j].var = NULL;
|
||||||
|
@ -329,9 +339,10 @@ static void loadSSL(void) {
|
||||||
x_SSL_COMP_get_compression_methods = loadSymbol(path_libssl, "SSL_COMP_get_compression_methods");
|
x_SSL_COMP_get_compression_methods = loadSymbol(path_libssl, "SSL_COMP_get_compression_methods");
|
||||||
// ends
|
// ends
|
||||||
|
|
||||||
|
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
dcheck(!ERR_peek_error());
|
dcheck(!ERR_peek_error());
|
||||||
debug("Loaded SSL suppport");
|
debug("SSL: loaded SSL suppport");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -368,12 +379,12 @@ int serverSupportsSSL(void) {
|
||||||
#if defined(HAVE_OPENSSL)
|
#if defined(HAVE_OPENSSL)
|
||||||
static void sslGenerateCertificate(const char *certificate,
|
static void sslGenerateCertificate(const char *certificate,
|
||||||
const char *serverName) {
|
const char *serverName) {
|
||||||
debug("Auto-generating missing certificate \"%s\" for \"%s\"",
|
debug("SSL: auto-generating missing certificate \"%s\" for \"%s\"",
|
||||||
certificate, serverName);
|
certificate, serverName);
|
||||||
|
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
warn("Failed to generate self-signed certificate \"%s\"", certificate);
|
warn("SSL: failed to generate self-signed certificate \"%s\"", certificate);
|
||||||
} else if (pid == 0) {
|
} else if (pid == 0) {
|
||||||
int fd = NOINTR(open("/dev/null", O_RDONLY));
|
int fd = NOINTR(open("/dev/null", O_RDONLY));
|
||||||
check(fd != -1);
|
check(fd != -1);
|
||||||
|
@ -390,14 +401,14 @@ static void sslGenerateCertificate(const char *certificate,
|
||||||
if (execlp("openssl", "openssl", "req", "-x509", "-nodes", "-days", "7300",
|
if (execlp("openssl", "openssl", "req", "-x509", "-nodes", "-days", "7300",
|
||||||
"-newkey", "rsa:2048", "-keyout", certificate, "-out", certificate,
|
"-newkey", "rsa:2048", "-keyout", certificate, "-out", certificate,
|
||||||
"-subj", subject, (char *)NULL) < 0) {
|
"-subj", subject, (char *)NULL) < 0) {
|
||||||
warn("Failed to generate self-signed certificate \"%s\"", certificate);
|
warn("SSL: failed to generate self-signed certificate \"%s\"", certificate);
|
||||||
free(subject);
|
free(subject);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int status;
|
int status;
|
||||||
check(NOINTR(waitpid(pid, &status, 0)) == pid);
|
check(NOINTR(waitpid(pid, &status, 0)) == pid);
|
||||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||||
warn("Failed to generate self-signed certificate \"%s\"", certificate);
|
warn("SSL: failed to generate self-signed certificate \"%s\"", certificate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -595,29 +606,73 @@ static int sslSetCertificateFromFile(SSL_CTX *context,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sslInfoCallback(const SSL *sslHndl, int type, int val) {
|
||||||
|
// Count the number of renegotiations for each SSL session.
|
||||||
|
if (type & SSL_CB_HANDSHAKE_START) {
|
||||||
|
struct HttpConnection *http =
|
||||||
|
(struct HttpConnection *) SSL_get_app_data(sslHndl);
|
||||||
|
http->ssl->renegotiationCount += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static SSL_CTX *sslMakeContext(void) {
|
static SSL_CTX *sslMakeContext(void) {
|
||||||
|
|
||||||
SSL_CTX *context;
|
SSL_CTX *context;
|
||||||
check(context = SSL_CTX_new(SSLv23_server_method()));
|
check(context = SSL_CTX_new(SSLv23_server_method()));
|
||||||
SSL_CTX_set_options(context, SSL_OP_ALL);
|
|
||||||
SSL_CTX_set_options(context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
|
long options = SSL_OP_ALL;
|
||||||
|
options |= SSL_OP_NO_SSLv2;
|
||||||
|
options |= SSL_OP_NO_SSLv3;
|
||||||
|
options |= SSL_OP_SINGLE_DH_USE;
|
||||||
|
|
||||||
#ifdef SSL_OP_NO_COMPRESSION
|
#ifdef SSL_OP_NO_COMPRESSION
|
||||||
SSL_CTX_set_options(context, SSL_OP_NO_COMPRESSION);
|
options |= SSL_OP_NO_COMPRESSION;
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_DLOPEN)
|
|
||||||
|
#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
|
||||||
|
options |= SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set default SSL options.
|
||||||
|
SSL_CTX_set_options(context, options);
|
||||||
|
|
||||||
|
// Workaround for SSL_OP_NO_COMPRESSION with older OpenSSL versions.
|
||||||
|
#ifdef HAVE_DLOPEN
|
||||||
if (SSL_COMP_get_compression_methods) {
|
if (SSL_COMP_get_compression_methods) {
|
||||||
sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
|
sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
|
||||||
}
|
}
|
||||||
#elif OPENSSL_VERSION_NUMBER >= 0x00908000L
|
#elif OPENSSL_VERSION_NUMBER >= 0x00908000L
|
||||||
sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
|
sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
|
||||||
#endif
|
#endif
|
||||||
SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
|
|
||||||
#ifdef SSL_OP_SINGLE_ECDH_USE
|
// For Perfect Forward Secrecy (PFS) support we need to enable some additional
|
||||||
|
// SSL options, provide eliptic curve key object for handshake and add chipers
|
||||||
|
// suits with ECDHE handshake on top of the ciper list.
|
||||||
|
#ifdef HAVE_OPENSSL_EC
|
||||||
SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
|
SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
|
||||||
|
SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE);
|
||||||
|
|
||||||
|
EC_KEY *ecKey;
|
||||||
|
check(ecKey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
|
||||||
|
SSL_CTX_set_tmp_ecdh(context, ecKey);
|
||||||
|
EC_KEY_free(ecKey);
|
||||||
|
|
||||||
|
debug("SSL: support for PFS enabled...");
|
||||||
#endif
|
#endif
|
||||||
#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
|
|
||||||
SSL_CTX_set_options(context, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
|
check(SSL_CTX_set_cipher_list(context,
|
||||||
#endif
|
"ECDHE-RSA-AES256-GCM-SHA384:"
|
||||||
check(SSL_CTX_set_cipher_list(context, "HIGH:MEDIUM:!aNULL:!MD5"));
|
"ECDHE-RSA-AES128-GCM-SHA256:"
|
||||||
|
"ECDHE-RSA-AES256-SHA384:"
|
||||||
|
"ECDHE-RSA-AES128-SHA256:"
|
||||||
|
"ECDHE-RSA-AES256-SHA:"
|
||||||
|
"ECDHE-RSA-AES128-SHA:"
|
||||||
|
"ECDHE-RSA-DES-CBC3-SHA:"
|
||||||
|
"HIGH:MEDIUM:!RC4:!aNULL:!MD5"));
|
||||||
|
|
||||||
|
SSL_CTX_set_info_callback(context, sslInfoCallback);
|
||||||
|
|
||||||
|
debug("SSL: server context succesfully initialized...");
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -634,7 +689,7 @@ static int sslSNICallback(SSL *sslHndl, int *al ATTR_UNUSED,
|
||||||
}
|
}
|
||||||
struct HttpConnection *http =
|
struct HttpConnection *http =
|
||||||
(struct HttpConnection *)SSL_get_app_data(sslHndl);
|
(struct HttpConnection *)SSL_get_app_data(sslHndl);
|
||||||
debug("Received SNI callback for virtual host \"%s\" from \"%s:%d\"",
|
debug("SSL: received SNI callback for virtual host \"%s\" from \"%s:%d\"",
|
||||||
name, httpGetPeerName(http), httpGetPort(http));
|
name, httpGetPeerName(http), httpGetPort(http));
|
||||||
char *serverName;
|
char *serverName;
|
||||||
check(serverName = malloc(strlen(name)+2));
|
check(serverName = malloc(strlen(name)+2));
|
||||||
|
@ -671,7 +726,7 @@ static int sslSNICallback(SSL *sslHndl, int *al ATTR_UNUSED,
|
||||||
// the default certificate, instead.
|
// the default certificate, instead.
|
||||||
sslSetCertificateFromFile(context, certificate);
|
sslSetCertificateFromFile(context, certificate);
|
||||||
} else {
|
} else {
|
||||||
warn("Could not find matching certificate \"%s\" for \"%s\"",
|
warn("SSL: could not find matching certificate \"%s\" for \"%s\"",
|
||||||
certificate, serverName + 1);
|
certificate, serverName + 1);
|
||||||
SSL_CTX_free(context);
|
SSL_CTX_free(context);
|
||||||
context = ssl->sslContext;
|
context = ssl->sslContext;
|
||||||
|
@ -748,7 +803,7 @@ void sslSetCertificate(struct SSLSupport *ssl, const char *filename,
|
||||||
sslGenerateCertificate(defaultCertificate, he->h_name);
|
sslGenerateCertificate(defaultCertificate, he->h_name);
|
||||||
} else {
|
} else {
|
||||||
if (h_err) {
|
if (h_err) {
|
||||||
warn("Error getting host information: \"%s\".", hstrerror(h_err));
|
warn("SSL: error getting host information: \"%s\".", hstrerror(h_err));
|
||||||
}
|
}
|
||||||
sslGenerateCertificate(defaultCertificate, hostname);
|
sslGenerateCertificate(defaultCertificate, hostname);
|
||||||
}
|
}
|
||||||
|
@ -757,7 +812,7 @@ void sslSetCertificate(struct SSLSupport *ssl, const char *filename,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sslSetCertificateFromFile(ssl->sslContext, defaultCertificate) < 0) {
|
if (sslSetCertificateFromFile(ssl->sslContext, defaultCertificate) < 0) {
|
||||||
fatal("Cannot read valid certificate from \"%s\". "
|
fatal("SSL: cannot read valid certificate from \"%s\". "
|
||||||
"Check file permissions and file format.", defaultCertificate);
|
"Check file permissions and file format.", defaultCertificate);
|
||||||
}
|
}
|
||||||
valid_certificate:
|
valid_certificate:
|
||||||
|
@ -823,7 +878,7 @@ void sslSetCertificateFd(struct SSLSupport *ssl, int fd) {
|
||||||
ssl->sslContext = sslMakeContext();
|
ssl->sslContext = sslMakeContext();
|
||||||
char *filename = sslFdToFilename(fd);
|
char *filename = sslFdToFilename(fd);
|
||||||
if (!sslSetCertificateFromFd(ssl->sslContext, fd)) {
|
if (!sslSetCertificateFromFd(ssl->sslContext, fd)) {
|
||||||
fatal("Cannot read valid certificate from %s. Check file format.",
|
fatal("SSL: cannot read valid certificate from %s. Check file format.",
|
||||||
filename);
|
filename);
|
||||||
}
|
}
|
||||||
free(filename);
|
free(filename);
|
||||||
|
@ -996,7 +1051,7 @@ void sslFreeHndl(SSL **sslHndl) {
|
||||||
// We do not know, how to fix this situation. Something must have
|
// We do not know, how to fix this situation. Something must have
|
||||||
// changed in the OpenSSL internals. Either, this is a new bug, or
|
// changed in the OpenSSL internals. Either, this is a new bug, or
|
||||||
// somebody fixed the code in a way that we did not anticipate.
|
// somebody fixed the code in a way that we did not anticipate.
|
||||||
fatal("Unexpected corruption of OpenSSL data structures");
|
fatal("SSL: unexpected corruption of OpenSSL data structures");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SSL_free(*sslHndl);
|
SSL_free(*sslHndl);
|
||||||
|
|
|
@ -61,6 +61,7 @@
|
||||||
#undef HAVE_OPENSSL
|
#undef HAVE_OPENSSL
|
||||||
typedef struct BIO BIO;
|
typedef struct BIO BIO;
|
||||||
typedef struct BIO_METHOD BIO_METHOD;
|
typedef struct BIO_METHOD BIO_METHOD;
|
||||||
|
typedef struct EC_KEY EC_KEY;
|
||||||
typedef struct SSL SSL;
|
typedef struct SSL SSL;
|
||||||
typedef struct SSL_CTX SSL_CTX;
|
typedef struct SSL_CTX SSL_CTX;
|
||||||
typedef struct SSL_METHOD SSL_METHOD;
|
typedef struct SSL_METHOD SSL_METHOD;
|
||||||
|
@ -69,6 +70,12 @@ typedef struct X509 X509;
|
||||||
#define SSL_ERROR_WANT_WRITE 3
|
#define SSL_ERROR_WANT_WRITE 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// EC support was added to OpenSSL in 0.9.8, but it can be disabled in some
|
||||||
|
// distributions.
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL && !defined(OPENSSL_NO_EC)
|
||||||
|
# define HAVE_OPENSSL_EC
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_DLOPEN)
|
#if defined(HAVE_DLOPEN)
|
||||||
extern long (*x_BIO_ctrl)(BIO *, int, long, void *);
|
extern long (*x_BIO_ctrl)(BIO *, int, long, void *);
|
||||||
extern BIO_METHOD *(*x_BIO_f_buffer)(void);
|
extern BIO_METHOD *(*x_BIO_f_buffer)(void);
|
||||||
|
@ -77,15 +84,20 @@ extern BIO *(*x_BIO_new)(BIO_METHOD *);
|
||||||
extern BIO *(*x_BIO_new_socket)(int, int);
|
extern BIO *(*x_BIO_new_socket)(int, int);
|
||||||
extern BIO *(*x_BIO_pop)(BIO *);
|
extern BIO *(*x_BIO_pop)(BIO *);
|
||||||
extern BIO *(*x_BIO_push)(BIO *, BIO *);
|
extern BIO *(*x_BIO_push)(BIO *, BIO *);
|
||||||
|
#if defined(HAVE_OPENSSL_EC)
|
||||||
|
extern void (*x_EC_KEY_free)(EC_KEY *);
|
||||||
|
extern EC_KEY *(*x_EC_KEY_new_by_curve_name)(int);
|
||||||
|
#endif
|
||||||
extern void (*x_ERR_clear_error)(void);
|
extern void (*x_ERR_clear_error)(void);
|
||||||
extern void (*x_ERR_clear_error)(void);
|
|
||||||
extern unsigned long (*x_ERR_peek_error)(void);
|
|
||||||
extern unsigned long (*x_ERR_peek_error)(void);
|
extern unsigned long (*x_ERR_peek_error)(void);
|
||||||
extern long (*x_SSL_CTX_callback_ctrl)(SSL_CTX *, int, void (*)(void));
|
extern long (*x_SSL_CTX_callback_ctrl)(SSL_CTX *, int, void (*)(void));
|
||||||
extern int (*x_SSL_CTX_check_private_key)(const SSL_CTX *);
|
extern int (*x_SSL_CTX_check_private_key)(const SSL_CTX *);
|
||||||
extern long (*x_SSL_CTX_ctrl)(SSL_CTX *, int, long, void *);
|
extern long (*x_SSL_CTX_ctrl)(SSL_CTX *, int, long, void *);
|
||||||
extern void (*x_SSL_CTX_free)(SSL_CTX *);
|
extern void (*x_SSL_CTX_free)(SSL_CTX *);
|
||||||
extern SSL_CTX*(*x_SSL_CTX_new)(SSL_METHOD *);
|
extern SSL_CTX*(*x_SSL_CTX_new)(SSL_METHOD *);
|
||||||
|
extern int (*x_SSL_CTX_set_cipher_list)(SSL_CTX *, const char *);
|
||||||
|
extern void (*x_SSL_CTX_set_info_callback)(SSL_CTX *,
|
||||||
|
void (*)(const SSL *, int, int));
|
||||||
extern int (*x_SSL_CTX_use_PrivateKey_file)(SSL_CTX *, const char *, int);
|
extern int (*x_SSL_CTX_use_PrivateKey_file)(SSL_CTX *, const char *, int);
|
||||||
extern int (*x_SSL_CTX_use_PrivateKey_ASN1)(int, SSL_CTX *,
|
extern int (*x_SSL_CTX_use_PrivateKey_ASN1)(int, SSL_CTX *,
|
||||||
const unsigned char *, long);
|
const unsigned char *, long);
|
||||||
|
@ -111,7 +123,6 @@ extern int (*x_SSL_write)(SSL *, const void *, int);
|
||||||
extern SSL_METHOD *(*x_SSLv23_server_method)(void);
|
extern SSL_METHOD *(*x_SSLv23_server_method)(void);
|
||||||
extern X509 * (*x_d2i_X509)(X509 **px, const unsigned char **in, int len);
|
extern X509 * (*x_d2i_X509)(X509 **px, const unsigned char **in, int len);
|
||||||
extern void (*x_X509_free)(X509 *a);
|
extern void (*x_X509_free)(X509 *a);
|
||||||
extern int (*x_SSL_CTX_set_cipher_list)(SSL_CTX *ctx, const char *str);
|
|
||||||
extern void (*x_sk_zero)(void *st);
|
extern void (*x_sk_zero)(void *st);
|
||||||
extern void *(*x_SSL_COMP_get_compression_methods)(void);
|
extern void *(*x_SSL_COMP_get_compression_methods)(void);
|
||||||
|
|
||||||
|
@ -122,15 +133,17 @@ extern void *(*x_SSL_COMP_get_compression_methods)(void);
|
||||||
#define BIO_new_socket x_BIO_new_socket
|
#define BIO_new_socket x_BIO_new_socket
|
||||||
#define BIO_pop x_BIO_pop
|
#define BIO_pop x_BIO_pop
|
||||||
#define BIO_push x_BIO_push
|
#define BIO_push x_BIO_push
|
||||||
|
#define EC_KEY_free x_EC_KEY_free
|
||||||
|
#define EC_KEY_new_by_curve_name x_EC_KEY_new_by_curve_name
|
||||||
#define ERR_clear_error x_ERR_clear_error
|
#define ERR_clear_error x_ERR_clear_error
|
||||||
#define ERR_clear_error x_ERR_clear_error
|
|
||||||
#define ERR_peek_error x_ERR_peek_error
|
|
||||||
#define ERR_peek_error x_ERR_peek_error
|
#define ERR_peek_error x_ERR_peek_error
|
||||||
#define SSL_CTX_callback_ctrl x_SSL_CTX_callback_ctrl
|
#define SSL_CTX_callback_ctrl x_SSL_CTX_callback_ctrl
|
||||||
#define SSL_CTX_check_private_key x_SSL_CTX_check_private_key
|
#define SSL_CTX_check_private_key x_SSL_CTX_check_private_key
|
||||||
#define SSL_CTX_ctrl x_SSL_CTX_ctrl
|
#define SSL_CTX_ctrl x_SSL_CTX_ctrl
|
||||||
#define SSL_CTX_free x_SSL_CTX_free
|
#define SSL_CTX_free x_SSL_CTX_free
|
||||||
#define SSL_CTX_new x_SSL_CTX_new
|
#define SSL_CTX_new x_SSL_CTX_new
|
||||||
|
#define SSL_CTX_set_cipher_list x_SSL_CTX_set_cipher_list
|
||||||
|
#define SSL_CTX_set_info_callback x_SSL_CTX_set_info_callback
|
||||||
#define SSL_CTX_use_PrivateKey_file x_SSL_CTX_use_PrivateKey_file
|
#define SSL_CTX_use_PrivateKey_file x_SSL_CTX_use_PrivateKey_file
|
||||||
#define SSL_CTX_use_PrivateKey_ASN1 x_SSL_CTX_use_PrivateKey_ASN1
|
#define SSL_CTX_use_PrivateKey_ASN1 x_SSL_CTX_use_PrivateKey_ASN1
|
||||||
#define SSL_CTX_use_certificate_file x_SSL_CTX_use_certificate_file
|
#define SSL_CTX_use_certificate_file x_SSL_CTX_use_certificate_file
|
||||||
|
@ -154,13 +167,13 @@ extern void *(*x_SSL_COMP_get_compression_methods)(void);
|
||||||
#define SSLv23_server_method x_SSLv23_server_method
|
#define SSLv23_server_method x_SSLv23_server_method
|
||||||
#define d2i_X509 x_d2i_X509
|
#define d2i_X509 x_d2i_X509
|
||||||
#define X509_free x_X509_free
|
#define X509_free x_X509_free
|
||||||
#define SSL_CTX_set_cipher_list x_SSL_CTX_set_cipher_list
|
|
||||||
#define sk_zero x_sk_zero
|
#define sk_zero x_sk_zero
|
||||||
#define SSL_COMP_get_compression_methods x_SSL_COMP_get_compression_methods
|
#define SSL_COMP_get_compression_methods x_SSL_COMP_get_compression_methods
|
||||||
|
|
||||||
#undef BIO_set_buffer_read_data
|
#undef BIO_set_buffer_read_data
|
||||||
#undef SSL_CTX_set_tlsext_servername_arg
|
#undef SSL_CTX_set_tlsext_servername_arg
|
||||||
#undef SSL_CTX_set_tlsext_servername_callback
|
#undef SSL_CTX_set_tlsext_servername_callback
|
||||||
|
#undef SSL_CTX_set_tmp_ecdh
|
||||||
#undef SSL_get_app_data
|
#undef SSL_get_app_data
|
||||||
#undef SSL_set_app_data
|
#undef SSL_set_app_data
|
||||||
#undef SSL_set_mode
|
#undef SSL_set_mode
|
||||||
|
@ -175,6 +188,9 @@ extern void *(*x_SSL_COMP_get_compression_methods)(void);
|
||||||
(x_SSL_CTX_callback_ctrl(ctx, \
|
(x_SSL_CTX_callback_ctrl(ctx, \
|
||||||
SSL_CTRL_SET_TLSEXT_SERVERNAME_CB, \
|
SSL_CTRL_SET_TLSEXT_SERVERNAME_CB, \
|
||||||
(void (*)(void))cb))
|
(void (*)(void))cb))
|
||||||
|
#define SSL_CTX_set_tmp_ecdh(ctx, ecdh) \
|
||||||
|
(x_SSL_CTX_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH, \
|
||||||
|
0, (char *)ecdh))
|
||||||
#define SSL_get_app_data(s) (x_SSL_get_ex_data(s, 0))
|
#define SSL_get_app_data(s) (x_SSL_get_ex_data(s, 0))
|
||||||
#define SSL_set_app_data(s, arg) (x_SSL_set_ex_data(s, 0, (char *)arg))
|
#define SSL_set_app_data(s, arg) (x_SSL_set_ex_data(s, 0, (char *)arg))
|
||||||
#define SSL_set_mode(ssl, op) (x_SSL_ctrl((ssl), SSL_CTRL_MODE, (op), NULL))
|
#define SSL_set_mode(ssl, op) (x_SSL_ctrl((ssl), SSL_CTRL_MODE, (op), NULL))
|
||||||
|
@ -185,6 +201,7 @@ struct SSLSupport {
|
||||||
SSL_CTX *sslContext;
|
SSL_CTX *sslContext;
|
||||||
char *sniCertificatePattern;
|
char *sniCertificatePattern;
|
||||||
int generateMissing;
|
int generateMissing;
|
||||||
|
int renegotiationCount;
|
||||||
struct Trie sniContexts;
|
struct Trie sniContexts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue