00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "klone_conf.h"
00012 #include <sys/types.h>
00013 #include <sys/time.h>
00014 #include <unistd.h>
00015 #include <strings.h>
00016 #ifdef HAVE_LIBOPENSSL
00017 #include <openssl/ssl.h>
00018 #include <openssl/rand.h>
00019 #include <openssl/err.h>
00020 #include <u/libu.h>
00021 #include <klone/tls.h>
00022 #include <klone/utils.h>
00023 #include <klone/tlsprv.h>
00024
00025 static int tls_sid = 1;
00026 static int tls_inited = 0;
00027
00028
00029 static int tls_init (void);
00030 static int tls_context (SSL_CTX **);
00031 static int tls_load_creds (SSL_CTX *, tls_ctx_args_t *);
00032 static int tls_gendh_params (SSL_CTX *, const char *);
00033 static int tls_gen_eph_rsa (SSL_CTX *);
00034 static void tls_rand_seed (void);
00035 static int tls_sid_context (SSL_CTX *, int *);
00036 static DH *tls_load_dh_param (const char *);
00037 static int tls_no_passphrase_cb (char *, int, int, void *);
00038 static int tls_init_ctx_args (tls_ctx_args_t *);
00039 static int tls_set_ctx_vdepth (u_config_t *, tls_ctx_args_t *);
00040 static int tls_set_ctx_vmode (u_config_t *, tls_ctx_args_t *);
00041 static int tls_check_ctx (tls_ctx_args_t *);
00042 static void tls_free_ctx_args (tls_ctx_args_t *cargs);
00043
00044
00045
00046 int tls_load_ctx_args (u_config_t *cfg, tls_ctx_args_t **cargs)
00047 {
00048 dbg_return_if (!cfg || !cargs, ~0);
00049
00050 dbg_err_if (!(*cargs = u_zalloc(sizeof(tls_ctx_args_t))));
00051
00052 (void) tls_init_ctx_args(*cargs);
00053
00054 (*cargs)->cert = u_config_get_subkey_value(cfg, "cert_file");
00055 (*cargs)->key = u_config_get_subkey_value(cfg, "key_file");
00056 (*cargs)->certchain = u_config_get_subkey_value(cfg, "certchain_file");
00057 (*cargs)->ca = u_config_get_subkey_value(cfg, "ca_file");
00058 (*cargs)->dh = u_config_get_subkey_value(cfg, "dh_file");
00059 dbg_err_if (tls_set_ctx_vdepth(cfg, *cargs));
00060 dbg_err_if (tls_set_ctx_vmode(cfg, *cargs));
00061
00062
00063 dbg_err_if (tls_check_ctx(*cargs));
00064
00065 return 0;
00066
00067 err:
00068 if (*cargs)
00069 tls_free_ctx_args(*cargs);
00070 return ~0;
00071 }
00072
00073
00074
00075 SSL_CTX *tls_init_ctx (tls_ctx_args_t *cargs)
00076 {
00077 SSL_CTX *c = NULL;
00078
00079 dbg_return_if (!cargs, NULL);
00080
00081
00082 dbg_err_if (tls_init());
00083
00084
00085 dbg_err_if (tls_context(&c));
00086
00087
00088 SSL_CTX_set_default_passwd_cb(c, tls_no_passphrase_cb);
00089
00090
00091 dbg_err_if (tls_load_creds(c, cargs));
00092
00093
00094 dbg_err_if (tls_gen_eph_rsa(c));
00095
00096
00097 dbg_err_if (tls_gendh_params(c, cargs->dh));
00098
00099
00100 dbg_err_if (tls_sid_context(c, &tls_sid));
00101
00102 return c;
00103
00104 err:
00105 if (c)
00106 SSL_CTX_free(c);
00107 return NULL;
00108 }
00109
00110 static int tls_sid_context (SSL_CTX *c, int *sid)
00111 {
00112 if (!c || !sid)
00113 return ~0;
00114
00115
00116 (*sid)++;
00117 dbg_err_if (!SSL_CTX_set_session_id_context(c, (void *) sid, sizeof(*sid)));
00118
00119 return 0;
00120
00121 err:
00122 dbg("%s", tls_get_error());
00123
00124 return ~0;
00125 }
00126
00127 static int tls_context (SSL_CTX **c)
00128 {
00129 if (!c)
00130 return ~0;
00131
00132 dbg_err_if (!(*c = SSL_CTX_new(SSLv23_server_method())));
00133
00134 return 0;
00135
00136 err:
00137 dbg("%s", tls_get_error());
00138 *c = NULL;
00139
00140 return ~0;
00141 }
00142
00143
00144 char *tls_get_error (void)
00145 {
00146 unsigned long e;
00147
00148 e = ERR_get_error();
00149 return ERR_error_string(e, NULL);
00150 }
00151
00152 void tls_dbg_openssl_err (void)
00153 {
00154 enum { BUFSZ = 256 };
00155 unsigned long e;
00156 char buf[BUFSZ];
00157
00158 while ((e = ERR_get_error()))
00159 warn("%s", ERR_error_string(e, buf));
00160
00161 return;
00162 }
00163
00164
00165 static int tls_load_creds (SSL_CTX *c, tls_ctx_args_t *cargs)
00166 {
00167 dbg_return_if (!c || !cargs || !cargs->cert, ~0);
00168
00169 if (!cargs->key)
00170 cargs->key = cargs->cert;
00171
00172
00173 if (cargs->ca)
00174 dbg_err_if (tls_load_verify_locations(c, cargs->ca));
00175
00176
00177 if (cargs->ca && cargs->vmode != SSL_VERIFY_NONE)
00178 SSL_CTX_set_client_CA_list(c, tls_load_client_CA_file(cargs->ca));
00179
00180
00181 dbg_err_if (tls_use_certificate_file(c, cargs->cert,
00182 SSL_FILETYPE_PEM) <= 0);
00183
00184
00185 dbg_err_if (tls_use_PrivateKey_file(c, cargs->key, SSL_FILETYPE_PEM) <= 0);
00186
00187
00188 dbg_err_if (!SSL_CTX_check_private_key(c));
00189
00190
00191 if (cargs->certchain)
00192 dbg_err_if (tls_use_certificate_chain(c, cargs->certchain,
00193 0, NULL) < 0);
00194
00195
00196 SSL_CTX_set_verify(c, cargs->vmode, NULL);
00197 if (cargs->depth > 0)
00198 SSL_CTX_set_verify_depth(c, cargs->depth);
00199
00200 return 0;
00201
00202 err:
00203 dbg("%s", tls_get_error());
00204 return ~0;
00205 }
00206
00207 static int tls_init (void)
00208 {
00209 if (tls_inited)
00210 return 0;
00211
00212 SSL_load_error_strings();
00213 dbg_err_if (!SSL_library_init());
00214 tls_rand_seed();
00215 tls_inited++;
00216
00217 return 0;
00218
00219 err:
00220 dbg("%s", tls_get_error());
00221 return ~0;
00222 }
00223
00224 static void tls_rand_seed (void)
00225 {
00226 struct timeval tv;
00227 tls_rand_seed_t seed;
00228
00229 (void) gettimeofday(&tv, NULL);
00230
00231 seed.pid = getpid();
00232 seed.t1 = tv.tv_sec;
00233 seed.t2 = tv.tv_usec;
00234 seed.stack = (void *) &seed;
00235
00236 RAND_seed((const void *) &seed, sizeof seed);
00237 }
00238
00239
00240 static int tls_gen_eph_rsa(SSL_CTX *c)
00241 {
00242 RSA *eph_rsa = NULL;
00243
00244 dbg_return_if (!c, ~0);
00245
00246 dbg_err_if (!(eph_rsa = RSA_generate_key(512, RSA_F4, 0, NULL)));
00247 dbg_err_if (!SSL_CTX_set_tmp_rsa(c, eph_rsa));
00248 RSA_free(eph_rsa);
00249
00250 return 0;
00251
00252 err:
00253 dbg("%s", tls_get_error());
00254 if (eph_rsa)
00255 RSA_free(eph_rsa);
00256
00257 return ~0;
00258 }
00259
00260
00261 static int tls_gendh_params(SSL_CTX *c, const char *dhfile)
00262 {
00263 DH *eph_dh = NULL;
00264
00265 dbg_return_if (!c, ~0);
00266
00267 eph_dh = dhfile ? tls_load_dh_param(dhfile) : get_dh1024();
00268 dbg_err_if (!(eph_dh));
00269
00270 dbg_err_if (!SSL_CTX_set_tmp_dh(c, eph_dh));
00271
00272 #if 0
00273
00274
00275
00276 (void) SSL_CTX_set_options(c, SSL_OP_SINGLE_DH_USE); */
00277 #endif
00278
00279 return 0;
00280
00281 err:
00282 dbg("%s", tls_get_error());
00283 if (eph_dh)
00284 DH_free(eph_dh);
00285
00286 return ~0;
00287 }
00288
00289 static DH *tls_load_dh_param (const char *res_name)
00290 {
00291 DH *dh = NULL;
00292 BIO *bio = NULL;
00293
00294 dbg_return_if (!res_name, NULL);
00295
00296
00297
00298 dbg_return_if (!(bio = tls_get_file_bio(res_name)), NULL);
00299
00300 dbg_err_if (!(dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL)));
00301
00302 BIO_free(bio);
00303 return dh;
00304
00305 err:
00306 dbg("%s", tls_get_error());
00307 if (bio)
00308 BIO_free(bio);
00309
00310 return NULL;
00311 }
00312
00313 static int tls_no_passphrase_cb (char *buf, int num, int w, void *arg)
00314 {
00315
00316 buf = NULL;
00317 arg = NULL;
00318 num = w = 0;
00319
00320 return -1;
00321 }
00322
00323 static int tls_init_ctx_args (tls_ctx_args_t *cargs)
00324 {
00325 dbg_return_if (!cargs, ~0);
00326
00327 cargs->cert = NULL;
00328 cargs->key = NULL;
00329 cargs->ca = NULL;
00330 cargs->dh = NULL;
00331 cargs->depth = 1;
00332 cargs->vmode = SSL_VERIFY_NONE;
00333
00334 return 0;
00335 }
00336
00337 static int tls_set_ctx_vdepth (u_config_t *cfg, tls_ctx_args_t *cargs)
00338 {
00339 u_config_t *k;
00340
00341 dbg_return_if (!cfg || !cargs, ~0);
00342
00343 if (!u_config_get_subkey(cfg, "verify_depth", &k))
00344 {
00345 cargs->depth = atoi(u_config_get_value(k));
00346 }
00347
00348
00349
00350 return 0;
00351 }
00352
00353 static int tls_set_ctx_vmode (u_config_t *cfg, tls_ctx_args_t *cargs)
00354 {
00355 const char *v;
00356
00357 dbg_return_if (!cfg || !cargs, ~0);
00358
00359 if (!(v = u_config_get_subkey_value(cfg, "verify_mode")))
00360 return 0;
00361
00362 if (!strcasecmp(v, "no"))
00363 cargs->vmode = SSL_VERIFY_NONE;
00364 else if (!strcasecmp(v, "optional"))
00365 cargs->vmode = SSL_VERIFY_PEER;
00366 else if (!strcasecmp(v, "require"))
00367 cargs->vmode = SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
00368 else {
00369 dbg("unknown verification value:\'%s\'", v);
00370 return ~0;
00371 }
00372
00373 return 0;
00374 }
00375
00376 static int tls_check_ctx (tls_ctx_args_t *cargs)
00377 {
00378 dbg_return_if (!cargs, ~0);
00379
00380
00381 dbg_err_if (!cargs->cert || strlen(cargs->cert) == 0);
00382
00383
00384 dbg_if (!cargs->key);
00385
00386
00387 if (cargs->vmode & SSL_VERIFY_PEER)
00388 dbg_err_if (!cargs->ca);
00389
00390 return 0;
00391 err:
00392 return ~0;
00393 }
00394
00395
00396 static void tls_free_ctx_args (tls_ctx_args_t *cargs)
00397 {
00398 KLONE_FREE(cargs);
00399 return;
00400 }
00401 #endif