summaryrefslogtreecommitdiffstats
path: root/openssl.c
diff options
context:
space:
mode:
authorSimon Rettberg2015-04-28 15:54:45 +0200
committerSimon Rettberg2015-04-28 15:54:45 +0200
commitd611cc597822049b1bd091b6bf2f136e07ae53cf (patch)
tree6a31137cda1d6727123e668268d891d429b53c9d /openssl.c
parent"Support" feature query (done by sssd) (diff)
downloadldadp-d611cc597822049b1bd091b6bf2f136e07ae53cf.tar.gz
ldadp-d611cc597822049b1bd091b6bf2f136e07ae53cf.tar.xz
ldadp-d611cc597822049b1bd091b6bf2f136e07ae53cf.zip
SSL support when talking to ADS
Diffstat (limited to 'openssl.c')
-rw-r--r--openssl.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/openssl.c b/openssl.c
index 32c7bca..c8e4142 100644
--- a/openssl.c
+++ b/openssl.c
@@ -2,6 +2,7 @@
#include "helper.h"
static BOOL initDone = FALSE;
+static const EVP_MD *sha1 = NULL;
void ssl_printErrors(char *bailMsg)
{
@@ -19,6 +20,8 @@ BOOL ssl_init()
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
+ sha1 = EVP_get_digestbyname("sha1");
+ if (sha1 == NULL) ssl_printErrors("Could not load SHA-1 digest\n");
return TRUE;
}
@@ -29,13 +32,26 @@ SSL_CTX* ssl_newServerCtx(char *certfile, char *keyfile)
SSL_CTX *ctx = SSL_CTX_new(m);
if (ctx == NULL) ssl_printErrors("newServerCtx: ctx is NULL");
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, keyfile, SSL_FILETYPE_PEM);
if (!SSL_CTX_check_private_key(ctx)) ssl_printErrors("Could not load cert/private key");
+ SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
return ctx;
}
-SSL *ssl_startAccept(int clientFd, SSL_CTX *ctx)
+SSL_CTX* ssl_newClientCtx()
+{
+ const SSL_METHOD *m = SSLv23_client_method();
+ if (m == NULL) ssl_printErrors("newClientCtx: method is NULL");
+ SSL_CTX *ctx = SSL_CTX_new(m);
+ if (ctx == NULL) ssl_printErrors("newClientCtx: ctx is NULL");
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
+ SSL_CTX_set_mode(ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
+ return ctx;
+}
+
+SSL *ssl_new(int clientFd, SSL_CTX *ctx)
{
SSL *ssl = SSL_new(ctx);
if (ssl == NULL) {
@@ -47,7 +63,6 @@ SSL *ssl_startAccept(int clientFd, SSL_CTX *ctx)
SSL_free(ssl);
return NULL;
}
- SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
return ssl;
}
@@ -66,3 +81,45 @@ BOOL ssl_acceptClient(epoll_client_t *client)
return FALSE;
}
+BOOL ssl_connectServer(epoll_server_t *server)
+{
+ if (server->sslConnected) return TRUE;
+ int ret = SSL_connect(server->ssl);
+ if (ret == 1) {
+ if (!ssl_checkCertificateHash(server)) {
+ printf("Warning: Fingerprint of %s doesn't match value given in config, refusing to talk to server!\n", server->serverData->addr);
+ return FALSE;
+ }
+ server->sslConnected = TRUE;
+ return TRUE;
+ }
+ if (ret < 0) {
+ int err = SSL_get_error(server->ssl, ret);
+ if (SSL_BLOCKED(err)) return TRUE;
+ }
+ return FALSE;
+}
+
+BOOL ssl_checkCertificateHash(epoll_server_t *server)
+{
+ if (server->ssl == NULL) {
+ printf("Bug: Asked to check certificate of non-SSL connection\n");
+ return FALSE;
+ }
+ for (int i = 0; i < FINGERPRINTLEN; ++i) {
+ if (server->serverData->fingerprint[i] != 0) {
+ unsigned char md[EVP_MAX_MD_SIZE];
+ unsigned int n = 20;
+ X509 *cert = SSL_get_peer_certificate(server->ssl);
+ if (cert == NULL) {
+ printf("Warning: Server %s has no certificate!\n", server->serverData->addr);
+ return FALSE;
+ }
+ X509_free(cert);
+ X509_digest(cert, sha1, md, &n);
+ return n == 20 && memcmp(md, server->serverData->fingerprint, n) == 0;
+ }
+ }
+ return TRUE;
+}
+