1/*++ 2/* NAME 3/* tls_certkey 3 4/* SUMMARY 5/* public key certificate and private key loader 6/* SYNOPSIS 7/* #define TLS_INTERNAL 8/* #include <tls.h> 9/* 10/* int tls_set_ca_certificate_info(ctx, CAfile, CApath) 11/* SSL_CTX *ctx; 12/* const char *CAfile; 13/* const char *CApath; 14/* 15/* int tls_set_my_certificate_key_info(ctx, cert_file, key_file, 16/* dcert_file, dkey_file, 17/* eccert_file, eckey_file) 18/* SSL_CTX *ctx; 19/* const char *cert_file; 20/* const char *key_file; 21/* const char *dcert_file; 22/* const char *dkey_file; 23/* const char *eccert_file; 24/* const char *eckey_file; 25/* DESCRIPTION 26/* OpenSSL supports two options to specify CA certificates: 27/* either one file CAfile that contains all CA certificates, 28/* or a directory CApath with separate files for each 29/* individual CA, with symbolic links named after the hash 30/* values of the certificates. The second option is not 31/* convenient with a chrooted process. 32/* 33/* tls_set_ca_certificate_info() loads the CA certificate 34/* information for the specified TLS server or client context. 35/* The result is -1 on failure, 0 on success. 36/* 37/* tls_set_my_certificate_key_info() loads the public key 38/* certificates and private keys for the specified TLS server 39/* or client context. Up to 3 pairs of key pairs (RSA, DSA and 40/* ECDSA) may be specified; each certificate and key pair must 41/* match. The result is -1 on failure, 0 on success. 42/* LICENSE 43/* .ad 44/* .fi 45/* This software is free. You can do with it whatever you want. 46/* The original author kindly requests that you acknowledge 47/* the use of his software. 48/* AUTHOR(S) 49/* Originally written by: 50/* Lutz Jaenicke 51/* BTU Cottbus 52/* Allgemeine Elektrotechnik 53/* Universitaetsplatz 3-4 54/* D-03044 Cottbus, Germany 55/* 56/* Updated by: 57/* Wietse Venema 58/* IBM T.J. Watson Research 59/* P.O. Box 704 60/* Yorktown Heights, NY 10598, USA 61/*--*/ 62 63/* System library. */ 64 65#include <sys_defs.h> 66 67#ifdef USE_TLS 68 69/* Utility library. */ 70 71#include <msg.h> 72 73/* Global library. */ 74 75#include <mail_params.h> 76 77/* TLS library. */ 78 79#define TLS_INTERNAL 80#include <tls.h> 81 82/* tls_set_ca_certificate_info - load certificate authority certificates */ 83 84int tls_set_ca_certificate_info(SSL_CTX *ctx, const char *CAfile, 85 const char *CApath) 86{ 87 if (*CAfile == 0) 88 CAfile = 0; 89 if (*CApath == 0) 90 CApath = 0; 91 if (CAfile || CApath) { 92 if (!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) { 93 msg_info("cannot load Certificate Authority data: " 94 "disabling TLS support"); 95 tls_print_errors(); 96 return (-1); 97 } 98 if (var_tls_append_def_CA && !SSL_CTX_set_default_verify_paths(ctx)) { 99 msg_info("cannot set certificate verification paths: " 100 "disabling TLS support"); 101 tls_print_errors(); 102 return (-1); 103 } 104 } 105 return (0); 106} 107 108/* set_cert_stuff - specify certificate and key information */ 109 110static int set_cert_stuff(SSL_CTX *ctx, const char *cert_type, 111 const char *cert_file, 112 const char *key_file) 113{ 114 115 /* 116 * We need both the private key (in key_file) and the public key 117 * certificate (in cert_file). Both may specify the same file. 118 * 119 * Code adapted from OpenSSL apps/s_cb.c. 120 */ 121 ERR_clear_error(); 122 if (SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) { 123 msg_warn("cannot get %s certificate from file %s: " 124 "disabling TLS support", cert_type, cert_file); 125 tls_print_errors(); 126 return (0); 127 } 128 if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) { 129 msg_warn("cannot get %s private key from file %s: " 130 "disabling TLS support", cert_type, key_file); 131 tls_print_errors(); 132 return (0); 133 } 134 135 /* 136 * Sanity check. 137 */ 138 if (!SSL_CTX_check_private_key(ctx)) { 139 msg_warn("%s private key in %s does not match public key in %s: " 140 "disabling TLS support", cert_type, key_file, cert_file); 141 return (0); 142 } 143 return (1); 144} 145 146/* tls_set_my_certificate_key_info - load client or server certificates/keys */ 147 148int tls_set_my_certificate_key_info(SSL_CTX *ctx, 149 const char *cert_file, 150 const char *key_file, 151 const char *dcert_file, 152 const char *dkey_file, 153 const char *eccert_file, 154 const char *eckey_file) 155{ 156 157 /* 158 * Lack of certificates is fine so long as we are prepared to use 159 * anonymous ciphers. 160 */ 161 if (*cert_file && !set_cert_stuff(ctx, "RSA", cert_file, key_file)) 162 return (-1); /* logged */ 163 if (*dcert_file && !set_cert_stuff(ctx, "DSA", dcert_file, dkey_file)) 164 return (-1); /* logged */ 165#if OPENSSL_VERSION_NUMBER >= 0x1000000fL && !defined(OPENSSL_NO_ECDH) 166 if (*eccert_file && !set_cert_stuff(ctx, "ECDSA", eccert_file, eckey_file)) 167 return (-1); /* logged */ 168#else 169 if (*eccert_file) 170 msg_warn("ECDSA not supported. Ignoring ECDSA certificate file \"%s\"", 171 eccert_file); 172#endif 173 return (0); 174} 175 176#endif 177