static int cmd_ClientCAPath(SSL_CONF_CTX *cctx, const char *value) { if (cctx->canames == NULL) cctx->canames = sk_X509_NAME_new_null(); if (cctx->canames == NULL) return 0; return SSL_add_dir_cert_subjects_to_stack(cctx->canames, value); }
static int cmd_RequestCAFile(SSL_CONF_CTX *cctx, const char *value) { if (cctx->canames == NULL) cctx->canames = sk_X509_NAME_new_null(); if (cctx->canames == NULL) return 0; return SSL_add_file_cert_subjects_to_stack(cctx->canames, value); }
static STACK_OF(X509_NAME) * use_inline_load_client_CA_file (SSL_CTX *ctx, const char *ca_string) { BIO *in = NULL; X509 *x = NULL; X509_NAME *xn = NULL; STACK_OF(X509_NAME) *ret = NULL, *sk; sk=sk_X509_NAME_new(xname_cmp); in = BIO_new_mem_buf ((char *)ca_string, -1); if (!in) goto err; if ((sk == NULL) || (in == NULL)) goto err; for (;;) { if (PEM_read_bio_X509(in,&x,NULL,NULL) == NULL) break; if (ret == NULL) { ret = sk_X509_NAME_new_null(); if (ret == NULL) goto err; } if ((xn=X509_get_subject_name(x)) == NULL) goto err; /* check for duplicates */ xn=X509_NAME_dup(xn); if (xn == NULL) goto err; if (sk_X509_NAME_find(sk,xn) >= 0) X509_NAME_free(xn); else { sk_X509_NAME_push(sk,xn); sk_X509_NAME_push(ret,xn); } } if (0) { err: if (ret != NULL) sk_X509_NAME_pop_free(ret,X509_NAME_free); ret=NULL; } if (sk != NULL) sk_X509_NAME_free(sk); if (in != NULL) BIO_free(in); if (x != NULL) X509_free(x); if (ret != NULL) ERR_clear_error(); return(ret); }
static int tlsaddcacrl(SSL_CTX *ctx, struct tls *conf) { STACK_OF(X509_NAME) *calist; X509_STORE *x509_s; unsigned long error; if (!SSL_CTX_load_verify_locations(ctx, conf->cacertfile, conf->cacertpath)) { while ((error = ERR_get_error())) debug(DBG_ERR, "SSL: %s", ERR_error_string(error, NULL)); debug(DBG_ERR, "tlsaddcacrl: Error updating TLS context %s", conf->name); return 0; } calist = conf->cacertfile ? SSL_load_client_CA_file(conf->cacertfile) : NULL; if (!conf->cacertfile || calist) { if (conf->cacertpath) { if (!calist) calist = sk_X509_NAME_new_null(); if (!SSL_add_dir_cert_subjects_to_stack(calist, conf->cacertpath)) { sk_X509_NAME_free(calist); calist = NULL; } } } if (!calist) { while ((error = ERR_get_error())) debug(DBG_ERR, "SSL: %s", ERR_error_string(error, NULL)); debug(DBG_ERR, "tlsaddcacrl: Error adding CA subjects in TLS context %s", conf->name); return 0; } ERR_clear_error(); /* add_dir_cert_subj returns errors on success */ SSL_CTX_set_client_CA_list(ctx, calist); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb); SSL_CTX_set_verify_depth(ctx, MAX_CERT_DEPTH + 1); if (conf->crlcheck || conf->vpm) { x509_s = SSL_CTX_get_cert_store(ctx); if (conf->crlcheck) X509_STORE_set_flags(x509_s, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); if (conf->vpm) X509_STORE_set1_param(x509_s, conf->vpm); } debug(DBG_DBG, "tlsaddcacrl: updated TLS context %s", conf->name); return 1; }
/* Load CA certs from a file into a STACK. Note that it is somewhat misnamed; * it doesn't really have anything to do with clients (except that a common use * for a stack of CAs is to send it to the client). Actually, it doesn't have * much to do with CAs, either, since it will load any old cert. * * \param file the file containing one or more certs. * \return a ::STACK containing the certs. */ STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) { BIO *in; X509 *x = NULL; X509_NAME *xn = NULL; STACK_OF(X509_NAME) *ret = NULL, *sk; sk = sk_X509_NAME_new(xname_cmp); in = BIO_new(BIO_s_file()); if (sk == NULL || in == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } if (!BIO_read_filename(in, file)) { goto err; } for (;;) { if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) { break; } if (ret == NULL) { ret = sk_X509_NAME_new_null(); if (ret == NULL) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } xn = X509_get_subject_name(x); if (xn == NULL) { goto err; } /* check for duplicates */ xn = X509_NAME_dup(xn); if (xn == NULL) { goto err; } if (sk_X509_NAME_find(sk, NULL, xn)) { X509_NAME_free(xn); } else { sk_X509_NAME_push(sk, xn); sk_X509_NAME_push(ret, xn); } } if (0) { err: sk_X509_NAME_pop_free(ret, X509_NAME_free); ret = NULL; } sk_X509_NAME_free(sk); BIO_free(in); X509_free(x); if (ret != NULL) { ERR_clear_error(); } return ret; }
int ACE_SSL_Context::load_trusted_ca (const char* ca_file, const char* ca_dir, bool use_env_defaults) { this->check_context (); if (ca_file == 0 && use_env_defaults) { // Use the default environment settings. ca_file = ACE_OS::getenv (ACE_SSL_CERT_FILE_ENV); #ifdef ACE_DEFAULT_SSL_CERT_FILE if (ca_file == 0) ca_file = ACE_DEFAULT_SSL_CERT_FILE; #endif } if (ca_dir == 0 && use_env_defaults) { // Use the default environment settings. ca_dir = ACE_OS::getenv (ACE_SSL_CERT_DIR_ENV); #ifdef ACE_DEFAULT_SSL_CERT_DIR if (ca_dir == 0) ca_dir = ACE_DEFAULT_SSL_CERT_DIR; #endif } // NOTE: SSL_CTX_load_verify_locations() returns 0 on error. if (::SSL_CTX_load_verify_locations (this->context_, ca_file, ca_dir) <= 0) { if (ACE::debug ()) ACE_SSL_Context::report_error (); return -1; } ++this->have_ca_; // For TLS/SSL servers scan all certificates in ca_file and ca_dir and // list them as acceptable CAs when requesting a client certificate. if (mode_ == SSLv23 || mode_ == SSLv23_server || mode_ == TLSv1 || mode_ == TLSv1_server || mode_ == SSLv3 || mode_ == SSLv3_server || mode_ == SSLv2 || mode_ == SSLv2_server) { // Note: The STACK_OF(X509_NAME) pointer is a copy of the pointer in // the CTX; any changes to it by way of these function calls will // change the CTX directly. STACK_OF (X509_NAME) * cert_names = 0; cert_names = ::SSL_CTX_get_client_CA_list (this->context_); bool error = false; // Add CAs from both the file and dir, if specified. There should // already be a STACK_OF(X509_NAME) in the CTX, but if not, we create // one. if (ca_file) { if (cert_names == 0) { if ((cert_names = ::SSL_load_client_CA_file (ca_file)) != 0) ::SSL_CTX_set_client_CA_list (this->context_, cert_names); else error = true; } else { // Add new certificate names to the list. error = (0 == ::SSL_add_file_cert_subjects_to_stack (cert_names, ca_file)); } if (error) { if (ACE::debug ()) ACE_SSL_Context::report_error (); return -1; } } // SSL_add_dir_cert_subjects_to_stack is defined at 0.9.8a (but not // on OpenVMS or Mac Classic); it may be available earlier. Change // this comparison if so. #if defined (OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090801fL) # if !defined (OPENSSL_SYS_VMS) && !defined (OPENSSL_SYS_MACINTOSH_CLASSIC) # if !defined (OPENSSL_SYS_WIN32) || (OPENSSL_VERSION_NUMBER > 0x0090807fL) if (ca_dir != 0) { if (cert_names == 0) { if ((cert_names = sk_X509_NAME_new_null ()) == 0) { if (ACE::debug ()) ACE_SSL_Context::report_error (); return -1; } ::SSL_CTX_set_client_CA_list (this->context_, cert_names); } if (0 == ::SSL_add_dir_cert_subjects_to_stack (cert_names, ca_dir)) { if (ACE::debug ()) ACE_SSL_Context::report_error (); return -1; } } # endif /* !OPENSSL_SYS_WIN32 || OPENSSL_VERSION_NUMBER >= 0x0090807fL */ # endif /* !OPENSSL_SYS_VMS && !OPENSSL_SYS_MACINTOSH_CLASSIC */ #endif /* OPENSSL_VERSION_NUMBER >= 0.9.8a release */ } return 0; }