/* * Attach the EAP-TLS module. */ static int eaptls_attach(CONF_SECTION *cs, void **instance) { EAP_TLS_CONF *conf; eap_tls_t *inst; /* Store all these values in the data structure for later references */ inst = (eap_tls_t *)malloc(sizeof(*inst)); if (!inst) { radlog(L_ERR, "rlm_eap_tls: out of memory"); return -1; } memset(inst, 0, sizeof(*inst)); /* * Parse the config file & get all the configured values */ conf = (EAP_TLS_CONF *)malloc(sizeof(*conf)); if (conf == NULL) { radlog(L_ERR, "rlm_eap_tls: out of memory"); return -1; } memset(conf, 0, sizeof(*conf)); inst->conf = conf; if (cf_section_parse(cs, conf, module_config) < 0) { eaptls_detach(inst); return -1; } /* * Initialize TLS */ inst->ctx = init_tls_ctx(conf); if (inst->ctx == NULL) { eaptls_detach(inst); return -1; } if (load_dh_params(inst->ctx, conf->dh_file) < 0) { eaptls_detach(inst); return -1; } if (generate_eph_rsa_key(inst->ctx) < 0) { eaptls_detach(inst); return -1; } *instance = inst; return 0; }
/* * Attach the EAP-TLS module. */ static int eaptls_attach(CONF_SECTION *cs, void **instance) { EAP_TLS_CONF *conf; eap_tls_t *inst; /* Store all these values in the data structure for later references */ inst = (eap_tls_t *)malloc(sizeof(*inst)); if (!inst) { radlog(L_ERR, "rlm_eap_tls: out of memory"); return -1; } memset(inst, 0, sizeof(*inst)); /* * Parse the config file & get all the configured values */ conf = (EAP_TLS_CONF *)malloc(sizeof(*conf)); if (conf == NULL) { free(inst); radlog(L_ERR, "rlm_eap_tls: out of memory"); return -1; } memset(conf, 0, sizeof(*conf)); inst->conf = conf; if (cf_section_parse(cs, conf, module_config) < 0) { eaptls_detach(inst); return -1; } /* * The EAP RFC's say 1020, but we're less picky. */ if (conf->fragment_size < 100) { radlog(L_ERR, "rlm_eap_tls: Fragment size is too small."); eaptls_detach(inst); return -1; } /* * The maximum size for a RADIUS packet is 4096, * minus the header (20), Message-Authenticator (18), * and State (18), etc. results in about 4000 bytes of data * that can be devoted *solely* to EAP. */ if (conf->fragment_size > 4000) { radlog(L_ERR, "rlm_eap_tls: Fragment size is too large."); eaptls_detach(inst); return -1; } /* * Account for the EAP header (4), and the EAP-TLS header * (6), as per Section 4.2 of RFC 2716. What's left is * the maximum amount of data we read from a TLS buffer. */ conf->fragment_size -= 10; /* * This magic makes the administrators life HUGELY easier * on initial deployments. * * If the server starts up in debugging mode, AND the * bootstrap command is configured, AND it exists, AND * there is no server certificate */ if (conf->make_cert_command && (debug_flag >= 2)) { struct stat buf; if ((stat(conf->make_cert_command, &buf) == 0) && (stat(conf->certificate_file, &buf) < 0) && (errno == ENOENT) && (radius_exec_program(conf->make_cert_command, NULL, 1, NULL, 0, NULL, NULL, 0) != 0)) { eaptls_detach(inst); return -1; } } /* * Initialize TLS */ inst->ctx = init_tls_ctx(conf); if (inst->ctx == NULL) { eaptls_detach(inst); return -1; } #ifdef HAVE_OPENSSL_OCSP_H /* * Initialize OCSP Revocation Store */ if (conf->ocsp_enable) { inst->store = init_revocation_store(conf); if (inst->store == NULL) { eaptls_detach(inst); return -1; } } #endif HAVE_OPENSSL_OCSP_H if (load_dh_params(inst->ctx, conf->dh_file) < 0) { eaptls_detach(inst); return -1; } if (generate_eph_rsa_key(inst->ctx) < 0) { eaptls_detach(inst); return -1; } if (conf->verify_tmp_dir) { if (chmod(conf->verify_tmp_dir, S_IRWXU) < 0) { radlog(L_ERR, "rlm_eap_tls: Failed changing permissions on %s: %s", conf->verify_tmp_dir, strerror(errno)); eaptls_detach(inst); return -1; } } if (conf->verify_client_cert_cmd && !conf->verify_tmp_dir) { radlog(L_ERR, "rlm_eap_tls: You MUST set the verify directory in order to use verify_client_cmd"); eaptls_detach(inst); return -1; } *instance = inst; return 0; }
SSL_CTX * tls_init(srv_t * srv) { char path[_POSIX_PATH_MAX]; SSL_CTX *ctx; int r; char errorstr[1024]; unsigned long e; SSL_library_init(); SSL_load_error_strings(); /* basic set up */ OpenSSL_add_ssl_algorithms(); /* * Create a TLS context */ if (!(ctx = SSL_CTX_new(SSLv23_method()))) { LOG(SPOCP_ERR) traceLog(LOG_ERR,"Error allocation SSL_CTX"); return 0; } LOG(SPOCP_DEBUG) traceLog(LOG_DEBUG,"Do we have enough randomness ??"); if (!RAND_status()) { /* * load entropy from files */ add_entropy(srv->SslEntropyFile); add_entropy(RAND_file_name(path, sizeof(path))); /* * load entropy from egd sockets */ #ifdef HAVE_RAND_EGD add_entropy(getenv("EGDSOCKET")); snprintf(path, sizeof(path), "%s/.entropy", NONULL(Homedir)); add_entropy(path); add_entropy("/tmp/entropy"); #endif /* * shuffle $RANDFILE (or ~/.rnd if unset) */ RAND_write_file(RAND_file_name(path, sizeof(path))); if (!RAND_status()) { LOG(SPOCP_ERR) traceLog(LOG_ERR, "Failed to find enough entropy on your system"); return 0; } } /* * Initialize with DH parameters if supplied */ if (srv->dhFile) { if (init_dh(ctx, (unsigned char *) srv->dhFile) == FALSE) { LOG(SPOCP_ERR) traceLog(LOG_ERR,"Error initializing DH"); SSL_CTX_free(ctx); return 0; } else LOG(SPOCP_ERR) traceLog(LOG_ERR,"Initializing DH OK"); } /* * and a RSA key too */ if (generate_eph_rsa_key(ctx, 512) == FALSE) { LOG(SPOCP_ERR) traceLog(LOG_ERR,"Error initializing RSA key"); SSL_CTX_free(ctx); return 0; } else LOG(SPOCP_ERR) traceLog(LOG_ERR,"Initializing RSA key OK"); /* * Set up certificates and keys */ if (srv->certificateFile != NULL) { LOG(SPOCP_INFO) traceLog(LOG_INFO,"Reading Certificate File"); if (!SSL_CTX_use_certificate_chain_file (ctx, srv->certificateFile)) { LOG(SPOCP_ERR) traceLog(LOG_ERR,"Error in SSL_CTX_use_certificate_file"); SSL_CTX_free(ctx); return 0; } } if (srv->privateKey != NULL) { if (srv->passwd) { SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) srv-> passwd); SSL_CTX_set_default_passwd_cb(ctx, password_cb); } LOG(SPOCP_INFO) traceLog(LOG_INFO,"Reading Private Key File"); r = SSL_CTX_use_PrivateKey_file(ctx, srv->privateKey, SSL_FILETYPE_PEM); if (r == 0) { e = ERR_get_error(); ERR_error_string_n(e, errorstr, 1024); LOG(SPOCP_ERR) traceLog(LOG_ERR,"Error in SSL_CTX_use_PrivateKey_file"); LOG(SPOCP_ERR) traceLog(LOG_ERR,"%s", errorstr); SSL_CTX_free(ctx); return 0; } } if (srv->caList != NULL) { LOG(SPOCP_INFO) traceLog(LOG_INFO,"Reading Trusted CAs File"); if (!SSL_CTX_load_verify_locations(ctx, srv->caList, 0)) { LOG(SPOCP_ERR) traceLog(LOG_ERR,"Error in SSL_CTX_load_verify_locations"); SSL_CTX_free(ctx); return 0; } } if (srv->clientcert == NONE) SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback_ok); else { int i = SSL_VERIFY_PEER; if (srv->clientcert == HARD) i |= SSL_VERIFY_CLIENT_ONCE; SSL_CTX_set_verify(ctx, i, verify_callback); } SSL_CTX_set_verify_depth(ctx, srv->sslverifydepth); SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2); if (SSL_CTX_set_cipher_list(ctx, CIPHER_LIST) != 1) { LOG(SPOCP_ERR) traceLog(LOG_ERR,"No valid ciphers in cipherlist"); SSL_CTX_free(ctx); return 0; } LOG(SPOCP_DEBUG) traceLog(LOG_DEBUG,"Initialised TLS"); return ctx; }