예제 #1
0
파일: tls_o.c 프로젝트: cptaffe/openldap
static STACK_OF(X509_NAME) *
tlso_ca_list( char * bundle, char * dir )
{
	STACK_OF(X509_NAME) *ca_list = NULL;

	if ( bundle ) {
		ca_list = SSL_load_client_CA_file( bundle );
	}
#if defined(HAVE_DIRENT_H) || defined(dirent)
	if ( dir ) {
		int freeit = 0;

		if ( !ca_list ) {
			ca_list = sk_X509_NAME_new_null();
			freeit = 1;
		}
		if ( !SSL_add_dir_cert_subjects_to_stack( ca_list, dir ) &&
			freeit ) {
			sk_X509_NAME_free( ca_list );
			ca_list = NULL;
		}
	}
#endif
	return ca_list;
}
예제 #2
0
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);
}
예제 #3
0
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;
}
예제 #4
0
/* 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;
}