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