Postfix3.3.1
tls_certkey.c
[詳解]
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 Certification Authority certificates */
83 
84 int 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 
92 #define CA_PATH_FMT "%s%s%s"
93 #define CA_PATH_ARGS(var, nextvar) \
94  var ? #var "=\"" : "", \
95  var ? var : "", \
96  var ? (nextvar ? "\", " : "\"") : ""
97 
98  if (CAfile || CApath) {
99  if (!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) {
100  msg_info("cannot load Certification Authority data, "
101  CA_PATH_FMT CA_PATH_FMT ": disabling TLS support",
102  CA_PATH_ARGS(CAfile, CApath),
103  CA_PATH_ARGS(CApath, 0));
104  tls_print_errors();
105  return (-1);
106  }
107  if (var_tls_append_def_CA && !SSL_CTX_set_default_verify_paths(ctx)) {
108  msg_info("cannot set default OpenSSL certificate verification "
109  "paths: disabling TLS support");
110  tls_print_errors();
111  return (-1);
112  }
113  }
114  return (0);
115 }
116 
117 /* set_cert_stuff - specify certificate and key information */
118 
119 static int set_cert_stuff(SSL_CTX *ctx, const char *cert_type,
120  const char *cert_file,
121  const char *key_file)
122 {
123 
124  /*
125  * We need both the private key (in key_file) and the public key
126  * certificate (in cert_file). Both may specify the same file.
127  *
128  * Code adapted from OpenSSL apps/s_cb.c.
129  */
130  ERR_clear_error();
131  if (SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) {
132  msg_warn("cannot get %s certificate from file \"%s\": "
133  "disabling TLS support", cert_type, cert_file);
134  tls_print_errors();
135  return (0);
136  }
137  if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) {
138  msg_warn("cannot get %s private key from file \"%s\": "
139  "disabling TLS support", cert_type, key_file);
140  tls_print_errors();
141  return (0);
142  }
143 
144  /*
145  * Sanity check.
146  */
147  if (!SSL_CTX_check_private_key(ctx)) {
148  msg_warn("%s private key in %s does not match public key in %s: "
149  "disabling TLS support", cert_type, key_file, cert_file);
150  return (0);
151  }
152  return (1);
153 }
154 
155 /* tls_set_my_certificate_key_info - load client or server certificates/keys */
156 
157 int tls_set_my_certificate_key_info(SSL_CTX *ctx,
158  const char *cert_file,
159  const char *key_file,
160  const char *dcert_file,
161  const char *dkey_file,
162  const char *eccert_file,
163  const char *eckey_file)
164 {
165 
166  /*
167  * Lack of certificates is fine so long as we are prepared to use
168  * anonymous ciphers.
169  */
170  if (*cert_file && !set_cert_stuff(ctx, "RSA", cert_file, key_file))
171  return (-1); /* logged */
172  if (*dcert_file && !set_cert_stuff(ctx, "DSA", dcert_file, dkey_file))
173  return (-1); /* logged */
174 #if OPENSSL_VERSION_NUMBER >= 0x1000000fL && !defined(OPENSSL_NO_ECDH)
175  if (*eccert_file && !set_cert_stuff(ctx, "ECDSA", eccert_file, eckey_file))
176  return (-1); /* logged */
177 #else
178  if (*eccert_file)
179  msg_warn("ECDSA not supported. Ignoring ECDSA certificate file \"%s\"",
180  eccert_file);
181 #endif
182  return (0);
183 }
184 
185 #endif
void msg_warn(const char *fmt,...)
Definition: msg.c:215
bool var_tls_append_def_CA
void msg_info(const char *fmt,...)
Definition: msg.c:199