struct tls_config * tls_config_new(void) { struct tls_config *config; if ((config = calloc(1, sizeof(*config))) == NULL) return (NULL); /* * Default configuration. */ if (tls_config_set_ca_file(config, _PATH_SSL_CA_FILE) != 0) goto err; if (tls_config_set_dheparams(config, "none") != 0) goto err; if (tls_config_set_ecdhecurve(config, "auto") != 0) goto err; if (tls_config_set_ciphers(config, "secure") != 0) goto err; tls_config_set_protocols(config, TLS_PROTOCOLS_DEFAULT); tls_config_set_verify_depth(config, 6); tls_config_verify(config); return (config); err: tls_config_free(config); return (NULL); }
static const char *create_worker(struct Worker **w_p, bool is_server, ...) { va_list ap; const char *k, *v; int klen; struct Worker *w; int err; const char *mem = NULL; void *fdata; size_t flen; const char *errmsg = NULL; *w_p = NULL; w = calloc(1, sizeof *w); if (!w) return "calloc"; w->wstate = HANDSHAKE; w->is_server = is_server; w->config = tls_config_new(); if (!w->config) return "tls_config_new failed"; if (is_server) { w->base = tls_server(); if (!w->base) return "tls_server failed"; } else { w->ctx = tls_client(); if (!w->ctx) return "tls_client failed"; } va_start(ap, is_server); while (1) { k = va_arg(ap, char *); if (!k) break; v = strchr(k, '='); if (!v) { errmsg = k; break; } v++; klen = v - k; err = 0; if (!strncmp(k, "mem=", klen)) { mem = v; } else if (!strncmp(k, "ca=", klen)) { if (mem) { fdata = load_file(v, &flen); if (!fdata) { errmsg = strerror(errno); break; } err = tls_config_set_ca_mem(w->config, fdata, flen); free(fdata); } else { err = tls_config_set_ca_file(w->config, v); } } else if (!strncmp(k, "cert=", klen)) { if (mem) { fdata = load_file(v, &flen); if (!fdata) { errmsg = strerror(errno); break; } err = tls_config_set_cert_mem(w->config, fdata, flen); free(fdata); } else { err = tls_config_set_cert_file(w->config, v); } } else if (!strncmp(k, "key=", klen)) { if (mem) { fdata = load_file(v, &flen); if (!fdata) { errmsg = strerror(errno); break; } err = tls_config_set_key_mem(w->config, fdata, flen); free(fdata); } else { err = tls_config_set_key_file(w->config, v); } } else if (!strncmp(k, "show=", klen)) { w->show = v; } else if (!strncmp(k, "ciphers=", klen)) { err = tls_config_set_ciphers(w->config, v); } else if (!strncmp(k, "host=", klen)) { w->hostname = v; } else if (!strncmp(k, "noverifycert=", klen)) { tls_config_insecure_noverifycert(w->config); } else if (!strncmp(k, "noverifyname=", klen)) { tls_config_insecure_noverifyname(w->config); } else if (!strncmp(k, "verify=", klen)) { tls_config_verify(w->config); } else if (!strncmp(k, "dheparams=", klen)) { err = tls_config_set_dheparams(w->config, v); } else if (!strncmp(k, "ecdhecurve=", klen)) { err = tls_config_set_ecdhecurve(w->config, v); } else if (!strncmp(k, "protocols=", klen)) { uint32_t protos; err = tls_config_parse_protocols(&protos, v); tls_config_set_protocols(w->config, protos); } else if (!strncmp(k, "peer-sha1=", klen)) { w->peer_fingerprint_sha1 = v; } else if (!strncmp(k, "peer-sha256=", klen)) { w->peer_fingerprint_sha256 = v; } else if (!strncmp(k, "verify-client=", klen)) { tls_config_verify_client(w->config); } else if (!strncmp(k, "verify-client-optional=", klen)) { tls_config_verify_client_optional(w->config); } else if (!strncmp(k, "aggressive-close=", klen)) { w->aggressive_close = 1; } else { errmsg = k; break; } if (err < 0) { errmsg = k; break; } } va_end(ap); if (errmsg) return errmsg; if (is_server) { if (tls_configure(w->base, w->config) < 0) return tls_error(w->base); } else { if (tls_configure(w->ctx, w->config) < 0) return tls_error(w->ctx); } *w_p = w; return "OK"; }