X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/d6453af2c864d0bd57785f5f808bc366d6f18970..184e88237dea64ce48076cdd0184612d057cbafd:/src/src/tls-openssl.c diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index 951e46c25..297b68b0d 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -1,10 +1,10 @@ -/* $Cambridge: exim/src/src/tls-openssl.c,v 1.2 2004/11/25 15:29:37 ph10 Exp $ */ +/* $Cambridge: exim/src/src/tls-openssl.c,v 1.9 2007/01/08 10:50:18 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2004 */ +/* Copyright (c) University of Cambridge 1995 - 2007 */ /* See the file NOTICE for conditions of use and distribution. */ /* This module provides the TLS (aka SSL) support for Exim using the OpenSSL @@ -182,9 +182,6 @@ else tls_peerdn = txt; } - -debug_printf("+++verify_callback_called=%d\n", verify_callback_called); - if (!verify_callback_called) tls_certificate_verified = TRUE; verify_callback_called = TRUE; @@ -293,8 +290,8 @@ Returns: OK/DEFER/FAIL */ static int -tls_init(host_item *host, uschar *dhparam, uschar *certificate, uschar *privatekey, - address_item *addr) +tls_init(host_item *host, uschar *dhparam, uschar *certificate, + uschar *privatekey, address_item *addr) { SSL_load_error_strings(); /* basic set up */ OpenSSL_add_ssl_algorithms(); @@ -389,7 +386,11 @@ if (certificate != NULL) !expand_check(privatekey, US"tls_privatekey", &expanded)) return DEFER; - if (expanded != NULL) + /* If expansion was forced to fail, key_expanded will be NULL. If the result + of the expansion is an empty string, ignore it also, and assume the private + key is in the same file as the certificate. */ + + if (expanded != NULL && *expanded != 0) { DEBUG(D_tls) debug_printf("tls_privatekey file %s\n", expanded); if (!SSL_CTX_use_PrivateKey_file(ctx, CS expanded, SSL_FILETYPE_PEM)) @@ -526,34 +527,51 @@ if (expcerts != NULL) #if OPENSSL_VERSION_NUMBER > 0x00907000L + /* This bit of code is now the version supplied by Lars Mainka. (I have + * merely reformatted it into the Exim code style.) + + * "From here I changed the code to add support for multiple crl's + * in pem format in one file or to support hashed directory entries in + * pem format instead of a file. This method now uses the library function + * X509_STORE_load_locations to add the CRL location to the SSL context. + * OpenSSL will then handle the verify against CA certs and CRLs by + * itself in the verify callback." */ + if (!expand_check(crl, US"tls_crl", &expcrl)) return DEFER; if (expcrl != NULL && *expcrl != 0) { - BIO *crl_bio; - X509_CRL *crl_x509; - X509_STORE *cvstore; - - cvstore = SSL_CTX_get_cert_store(ctx); /* cert validation store */ - - crl_bio = BIO_new(BIO_s_file_internal()); - if (crl_bio != NULL) + struct stat statbufcrl; + if (Ustat(expcrl, &statbufcrl) < 0) { - if (BIO_read_filename(crl_bio, expcrl)) + log_write(0, LOG_MAIN|LOG_PANIC, + "failed to stat %s for certificates revocation lists", expcrl); + return DEFER; + } + else + { + /* is it a file or directory? */ + uschar *file, *dir; + X509_STORE *cvstore = SSL_CTX_get_cert_store(ctx); + if ((statbufcrl.st_mode & S_IFMT) == S_IFDIR) { - crl_x509 = PEM_read_bio_X509_CRL(crl_bio, NULL, NULL, NULL); - BIO_free(crl_bio); - X509_STORE_add_crl(cvstore, crl_x509); - X509_CRL_free(crl_x509); - X509_STORE_set_flags(cvstore, - X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); + file = NULL; + dir = expcrl; + DEBUG(D_tls) debug_printf("SSL CRL value is a directory %s\n", dir); } else { - BIO_free(crl_bio); - return tls_error(US"BIO_read_filename", host); + file = expcrl; + dir = NULL; + DEBUG(D_tls) debug_printf("SSL CRL value is a file %s\n", file); } + if (X509_STORE_load_locations(cvstore, CS file, CS dir) == 0) + return tls_error(US"X509_STORE_load_locations", host); + + /* setting the flags to check against the complete crl chain */ + + X509_STORE_set_flags(cvstore, + X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); } - else return tls_error(US"BIO_new", host); } #endif /* OPENSSL_VERSION_NUMBER > 0x00907000L */ @@ -666,7 +684,8 @@ if (!tls_on_connect) /* Now negotiate the TLS session. We put our own timer on it, since it seems that the OpenSSL library doesn't. */ -SSL_set_fd(ssl, fileno(smtp_out)); +SSL_set_wfd(ssl, fileno(smtp_out)); +SSL_set_rfd(ssl, fileno(smtp_in)); SSL_set_accept_state(ssl); DEBUG(D_tls) debug_printf("Calling SSL_accept\n");