Ejemplo n.º 1
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);
}
Ejemplo n.º 2
0
int
mono_btls_ssl_ctx_set_client_ca_list (MonoBtlsSslCtx *ctx, int count, int *sizes, const void **data)
{
	STACK_OF(X509_NAME) *name_list;
	int i;

	name_list = sk_X509_NAME_new_null ();
	if (!name_list)
		return 0;

	for (i = 0; i < count; i++) {
		X509_NAME *name;
		const unsigned char *ptr = (const unsigned char*)data[i];

		name = d2i_X509_NAME (NULL, &ptr, sizes[i]);
		if (!name) {
			sk_X509_NAME_pop_free (name_list, X509_NAME_free);
			return 0;
		}
		sk_X509_NAME_push (name_list, name);
	}

	// Takes ownership of the list.
	SSL_CTX_set_client_CA_list (ctx->ctx, name_list);
	return 1;
}
Ejemplo n.º 3
0
static STACK_OF(X509_NAME) *
tlso_ca_list( char * bundle, char * dir, X509 *cert )
{
	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
	if ( cert ) {
		X509_NAME *xn = X509_get_subject_name( cert );
		xn = X509_NAME_dup( xn );
		if ( !ca_list )
			ca_list = sk_X509_NAME_new_null();
		if ( xn && ca_list )
			sk_X509_NAME_push( ca_list, xn );
	}
	return ca_list;
}
Ejemplo n.º 4
0
void
tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
    const char *ca_file_inline,
    const char *ca_path, bool tls_server
    )
{
  STACK_OF(X509_INFO) *info_stack = NULL;
  STACK_OF(X509_NAME) *cert_names = NULL;
  X509_LOOKUP *lookup = NULL;
  X509_STORE *store = NULL;
  X509_NAME *xn = NULL;
  BIO *in = NULL;
  int i, added = 0;

  ASSERT(NULL != ctx);

  store = SSL_CTX_get_cert_store(ctx->ctx);
  if (!store)
    msg(M_SSLERR, "Cannot get certificate store (SSL_CTX_get_cert_store)");

  /* Try to add certificates and CRLs from ca_file */
  if (ca_file)
    {
      if (!strcmp (ca_file, INLINE_FILE_TAG) && ca_file_inline)
        in = BIO_new_mem_buf ((char *)ca_file_inline, -1);
      else
        in = BIO_new_file (ca_file, "r");

      if (in)
        info_stack = PEM_X509_INFO_read_bio (in, NULL, NULL, NULL);

      if (info_stack)
        {
          for (i = 0; i < sk_X509_INFO_num (info_stack); i++)
            {
              X509_INFO *info = sk_X509_INFO_value (info_stack, i);
              if (info->crl)
                  X509_STORE_add_crl (store, info->crl);

              if (info->x509)
                {
                  X509_STORE_add_cert (store, info->x509);
                  added++;

                  if (!tls_server)
                    continue;

                  /* Use names of CAs as a client CA list */
                  if (cert_names == NULL)
                    {
                      cert_names = sk_X509_NAME_new (sk_x509_name_cmp);
                      if (!cert_names)
                        continue;
                    }

                  xn = X509_get_subject_name (info->x509);
                  if (!xn)
                    continue;

                  /* Don't add duplicate CA names */
                  if (sk_X509_NAME_find (cert_names, xn) == -1)
                    {
                      xn = X509_NAME_dup (xn);
                      if (!xn)
                        continue;
                      sk_X509_NAME_push (cert_names, xn);
                    }
                }
            }
          sk_X509_INFO_pop_free (info_stack, X509_INFO_free);
        }

      if (tls_server)
        SSL_CTX_set_client_CA_list (ctx->ctx, cert_names);

      if (!added || (tls_server && sk_X509_NAME_num (cert_names) != added))
        msg (M_SSLERR, "Cannot load CA certificate file %s", np(ca_file));
      if (in)
        BIO_free (in);
    }

  /* Set a store for certs (CA & CRL) with a lookup on the "capath" hash directory */
  if (ca_path)
    {
      lookup = X509_STORE_add_lookup (store, X509_LOOKUP_hash_dir ());
      if (lookup && X509_LOOKUP_add_dir (lookup, ca_path, X509_FILETYPE_PEM))
        msg(M_WARN, "WARNING: experimental option --capath %s", ca_path);
      else
        msg(M_SSLERR, "Cannot add lookup at --capath %s", ca_path);
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
      X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
#else
      msg(M_WARN, "WARNING: this version of OpenSSL cannot handle CRL files in capath");
#endif
    }
}
Ejemplo n.º 5
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;
}