1 /* Copyright (C) 2010 Trend Micro Inc.
4 * This program is a free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License (version 2) as published by the FSF - Free Software
9 * In addition, as a special exception, the copyright holders give
10 * permission to link the code of portions of this program with the
11 * OpenSSL library under certain conditions as described in each
12 * individual source file, and distribute linked combinations
15 * You must obey the GNU General Public License in all respects
16 * for all of the code used other than OpenSSL. If you modify
17 * file(s) with this exception, you may extend this exception to your
18 * version of the file(s), but you are not obligated to do so. If you
19 * do not wish to do so, delete this exception statement from your
20 * version. If you delete this exception statement from all source
21 * files in the program, then also delete it here.
25 #ifdef LIBOPENSSL_ENABLED
30 /* Global variables */
34 /* Create an SSL context. If certificate verification is requested
35 * then load the file containing the CA chain and verify the certificate
38 SSL_CTX *os_ssl_keys(int is_server, const char *os_dir, const char *ciphers, const char *cert, const char *key, const char *ca_cert)
42 if (!(ctx = get_ssl_context(ciphers))) {
46 /* If a CA certificate has been specified then load it and verify the peer */
48 debug1("%s: DEBUG: Peer verification requested.", ARGV0);
50 if (!load_ca_cert(ctx, ca_cert)) {
54 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback);
57 /* Loading a certificate and key is mandatory for the server and optional for clients */
59 char default_cert[PATH_MAX + 1];
60 char default_key[PATH_MAX + 1];
63 snprintf(default_cert, PATH_MAX + 1, "%s%s", os_dir, CERTFILE);
68 snprintf(default_key, PATH_MAX + 1, "%s%s", os_dir, KEYFILE);
72 if (!load_cert_and_key(ctx, cert, key)) {
76 debug1("%s: DEBUG: Returning CTX for server.", ARGV0);
79 if (!load_cert_and_key(ctx, cert, key)) {
84 debug1("%s: DEBUG: Returning CTX for client.", ARGV0);
94 return (SSL_CTX *)NULL;
97 SSL_CTX *get_ssl_context(const char *ciphers)
99 const SSL_METHOD *sslmeth = NULL;
103 SSL_load_error_strings();
104 OpenSSL_add_all_algorithms();
106 /* Create our context */
107 sslmeth = TLSv1_2_method();
108 if (!(ctx = SSL_CTX_new(sslmeth))) {
112 /* Explicitly set options and cipher list */
113 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
114 if (!(SSL_CTX_set_cipher_list(ctx, ciphers))) {
125 return (SSL_CTX *)NULL;
128 int load_cert_and_key(SSL_CTX *ctx, const char *cert, const char *key)
130 if (File_DateofChange(cert) <= 0) {
131 merror("%s: ERROR: Unable to read certificate file (not found): %s", ARGV0, cert);
135 if (!(SSL_CTX_use_certificate_chain_file(ctx, cert))) {
136 merror("%s: ERROR: Unable to read certificate file: %s", ARGV0, cert);
137 ERR_print_errors_fp(stderr);
141 if (!(SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM))) {
142 merror("%s: ERROR: Unable to read private key file: %s", ARGV0, key);
143 ERR_print_errors_fp(stderr);
147 if (!SSL_CTX_check_private_key(ctx)) {
148 merror("%s: ERROR: Unable to verify private key file", ARGV0);
149 ERR_print_errors_fp(stderr);
153 #if(OPENSSL_VERSION_NUMBER < 0x00905100L)
154 SSL_CTX_set_verify_depth(ctx, 1);
160 int load_ca_cert(SSL_CTX *ctx, const char *ca_cert)
163 merror("%s: ERROR: Verification requested but no CA certificate file specified", ARGV0);
167 if (SSL_CTX_load_verify_locations(ctx, ca_cert, NULL) != 1) {
168 merror("%s: ERROR: Unable to read CA certificate file \"%s\"", ARGV0, ca_cert);
175 /* No extra verification is done here. This function provides more
176 * information in the case that certificate verification fails
179 int verify_callback(int ok, X509_STORE_CTX *store)
184 X509 *cert = X509_STORE_CTX_get_current_cert(store);
185 int depth = X509_STORE_CTX_get_error_depth(store);
186 int err = X509_STORE_CTX_get_error(store);
188 merror("%s: ERROR: Problem with certificate at depth %i", ARGV0, depth);
190 X509_NAME_oneline(X509_get_issuer_name(cert), data, 256);
191 merror("%s: ERROR: issuer = %s", ARGV0, data);
193 X509_NAME_oneline(X509_get_subject_name(cert), data, 256);
194 merror("%s: ERROR: subject = %s", ARGV0, data);
196 merror("%s: ERROR: %i:%s", ARGV0, err, X509_verify_cert_error_string(err));
202 #endif /* LIBOPENSSL_ENABLED */