+int args_ssl_call(SSL_CTX *ctx, BIO *err, SSL_CONF_CTX *cctx,
+ STACK_OF(OPENSSL_STRING) *str, int no_ecdhe, int no_jpake)
+ {
+ int i;
+ SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
+ for (i = 0; i < sk_OPENSSL_STRING_num(str); i+= 2)
+ {
+ const char *param = sk_OPENSSL_STRING_value(str, i);
+ const char *value = sk_OPENSSL_STRING_value(str, i + 1);
+ /* If no_ecdhe or named curve already specified don't need
+ * a default.
+ */
+ if (!no_ecdhe && !strcmp(param, "-named_curve"))
+ no_ecdhe = 1;
+#ifndef OPENSSL_NO_JPAKE
+ if (!no_jpake && !strcmp(param, "-cipher"))
+ {
+ BIO_puts(err, "JPAKE sets cipher to PSK\n");
+ return 0;
+ }
+#endif
+ if (SSL_CONF_cmd(cctx, param, value) <= 0)
+ {
+ BIO_printf(err, "Error with command: \"%s %s\"\n",
+ param, value ? value : "");
+ ERR_print_errors(err);
+ return 0;
+ }
+ }
+ /* This is a special case to keep existing s_server functionality:
+ * if we don't have any curve specified *and* we haven't disabled
+ * ECDHE then use P-256.
+ */
+ if (!no_ecdhe)
+ {
+ if (SSL_CONF_cmd(cctx, "-named_curve", "P-256") <= 0)
+ {
+ BIO_puts(err, "Error setting EC curve\n");
+ ERR_print_errors(err);
+ return 0;
+ }
+ }
+#ifndef OPENSSL_NO_JPAKE
+ if (!no_jpake)
+ {
+ if (SSL_CONF_cmd(cctx, "-cipher", "PSK") <= 0)
+ {
+ BIO_puts(err, "Error setting cipher to PSK\n");
+ ERR_print_errors(err);
+ return 0;
+ }
+ }
+#endif
+ if (!SSL_CONF_CTX_finish(cctx))
+ {
+ BIO_puts(err, "Error finishing context\n");
+ ERR_print_errors(err);
+ return 0;
+ }
+ return 1;
+ }
+
+static int add_crls_store(X509_STORE *st, STACK_OF(X509_CRL) *crls)
+ {
+ X509_CRL *crl;
+ int i;
+ for (i = 0; i < sk_X509_CRL_num(crls); i++)
+ {
+ crl = sk_X509_CRL_value(crls, i);
+ X509_STORE_add_crl(st, crl);
+ }
+ return 1;
+ }
+
+int ssl_ctx_add_crls(SSL_CTX *ctx, STACK_OF(X509_CRL) *crls, int crl_download)
+ {
+ X509_STORE *st;
+ st = SSL_CTX_get_cert_store(ctx);
+ add_crls_store(st, crls);
+ if (crl_download)
+ store_setup_crl_download(st);
+ return 1;
+ }
+
+int ssl_load_stores(SSL_CTX *ctx,
+ const char *vfyCApath, const char *vfyCAfile,
+ const char *chCApath, const char *chCAfile,
+ STACK_OF(X509_CRL) *crls, int crl_download)
+ {
+ X509_STORE *vfy = NULL, *ch = NULL;
+ int rv = 0;
+ if (vfyCApath || vfyCAfile)
+ {
+ vfy = X509_STORE_new();
+ if (!X509_STORE_load_locations(vfy, vfyCAfile, vfyCApath))
+ goto err;
+ add_crls_store(vfy, crls);
+ SSL_CTX_set1_verify_cert_store(ctx, vfy);
+ if (crl_download)
+ store_setup_crl_download(vfy);
+ }
+ if (chCApath || chCAfile)
+ {
+ ch = X509_STORE_new();
+ if (!X509_STORE_load_locations(ch, chCAfile, chCApath))
+ goto err;
+ SSL_CTX_set1_chain_cert_store(ctx, ch);
+ }
+ rv = 1;
+ err:
+ if (vfy)
+ X509_STORE_free(vfy);
+ if (ch)
+ X509_STORE_free(ch);
+ return rv;
+ }