Example #1
0
int
X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
{
	int ret = 0;
	BIO *in = NULL;
	int i, count = 0;
	X509_CRL *x = NULL;

	if (file == NULL)
		return (1);
	in = BIO_new(BIO_s_file_internal());

	if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) {
		X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_SYS_LIB);
		goto err;
	}

	if (type == X509_FILETYPE_PEM) {
		for (;;) {
			x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
			if (x == NULL) {
				if ((ERR_GET_REASON(ERR_peek_last_error()) ==
				    PEM_R_NO_START_LINE) && (count > 0)) {
					ERR_clear_error();
					break;
				} else {
					X509err(X509_F_X509_LOAD_CRL_FILE,
					    ERR_R_PEM_LIB);
					goto err;
				}
			}
			i = X509_STORE_add_crl(ctx->store_ctx, x);
			if (!i)
				goto err;
			count++;
			X509_CRL_free(x);
			x = NULL;
		}
		ret = count;
	} else if (type == X509_FILETYPE_ASN1) {
		x = d2i_X509_CRL_bio(in, NULL);
		if (x == NULL) {
			X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_ASN1_LIB);
			goto err;
		}
		i = X509_STORE_add_crl(ctx->store_ctx, x);
		if (!i)
			goto err;
		ret = i;
	} else {
		X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_BAD_X509_FILETYPE);
		goto err;
	}
err:
	if (x != NULL)
		X509_CRL_free(x);
	if (in != NULL)
		BIO_free(in);
	return (ret);
}
Example #2
0
static int
tls_sc_add_crl(lua_State *L) {

  tls_sc_t *ctx = getSC(L);
  X509_CRL *x509;
  BIO *bio;

  bio = _lua_load_bio(L, -1);
  if (!bio) {
    lua_pushboolean(L, 0);
    return 1;
  }

  x509 = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
  if (x509 == NULL) {
    BIO_free(bio);
    lua_pushboolean(L, 0);
    return 1;
  }

  X509_STORE_add_crl(ctx->ca_store, x509);
  X509_STORE_set_flags(ctx->ca_store,
                       X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);

  BIO_free(bio);
  X509_CRL_free(x509);

  lua_pushboolean(L, 1);
  return 1;
}
Example #3
0
int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
{
    STACK_OF(X509_INFO) *inf;
    X509_INFO *itmp;
    BIO *in;
    int i, count = 0;
    if (type != X509_FILETYPE_PEM)
        return X509_load_cert_file(ctx, file, type);
    in = BIO_new_file(file, "r");
    if (!in) {
        X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB);
        return 0;
    }
    inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
    BIO_free(in);
    if (!inf) {
        X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB);
        return 0;
    }
    for (i = 0; i < sk_X509_INFO_num(inf); i++) {
        itmp = sk_X509_INFO_value(inf, i);
        if (itmp->x509) {
            X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
            count++;
        }
        if (itmp->crl) {
            X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
            count++;
        }
    }
    sk_X509_INFO_pop_free(inf, X509_INFO_free);
    return count;
}
Example #4
0
static VALUE
ossl_x509store_add_crl(VALUE self, VALUE arg)
{
    X509_STORE *store;
    X509_CRL *crl;

    crl = GetX509CRLPtr(arg); /* NO NEED TO DUP */
    GetX509Store(self, store);
    if (X509_STORE_add_crl(store, crl) != 1){
        ossl_raise(eX509StoreError, NULL);
    }

    return self;
}
Example #5
0
/*
 * We will put into store X509 object from passed data in buffer only
 * when object name match passed. To compare both names we use our
 * method "ssh_X509_NAME_cmp"(it is more general).
 */
static int/*bool*/
ldaplookup_data2store(
	int         type,
	X509_NAME*  name,
	void*       buf,
	int         len,
	X509_STORE* store
) {
	int ok = 0;
	BIO *mbio;

	if (name == NULL) return(0);
	if (buf == NULL) return(0);
	if (len <= 0) return(0);
	if (store == NULL) return(0);

	mbio = BIO_new_mem_buf(buf, len);
	if (mbio == NULL) return(0);

	switch (type) {
	case X509_LU_X509: {
		X509 *x509 = d2i_X509_bio(mbio, NULL);
		if(x509 == NULL) goto exit;

		/*This is correct since lookup method is by subject*/
		if (ssh_X509_NAME_cmp(name, X509_get_subject_name(x509)) != 0) goto exit;

		ok = X509_STORE_add_cert(store, x509);
		} break;
	case X509_LU_CRL: {
		X509_CRL *crl = d2i_X509_CRL_bio(mbio, NULL);
		if(crl == NULL) goto exit;

		if (ssh_X509_NAME_cmp(name, X509_CRL_get_issuer(crl)) != 0) goto exit;

		ok = X509_STORE_add_crl(store, crl);
		} break;
	}

exit:
	if (mbio != NULL) BIO_free_all(mbio);
#ifdef TRACE_BY_LDAP
fprintf(stderr, "TRACE_BY_LDAP ldaplookup_data2store: ok=%d\n", ok);
#endif
	return(ok);
}
Example #6
0
/*
 * This function is used to load an X509_STORE using raw
 * data from a buffer.  The data is expected to be PEM
 * encoded.
 *
 * Returns the number of certs added to the store
 */
static int ossl_init_cert_store_from_raw (X509_STORE *store,
                                           unsigned char *raw, int size)
{
    STACK_OF(X509_INFO) * sk = NULL;
    X509_INFO *xi;
    BIO *in;
    int cert_cnt = 0;

    in = BIO_new_mem_buf(raw, size);
    if (in == NULL) {
        EST_LOG_ERR("Unable to open the raw CA cert buffer");
        return 0;
    }

    /* This loads from a file, a stack of x509/crl/pkey sets */
    sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
    if (sk == NULL) {
        EST_LOG_ERR("Unable to read PEM encoded certs from BIO");
        BIO_free(in);
        return 0;
    }
    BIO_free(in);

    /* scan over it and pull out the CRL's */
    while (sk_X509_INFO_num(sk)) {
        xi = sk_X509_INFO_shift(sk);
        if (xi->x509 != NULL) {
            EST_LOG_INFO("Adding cert to store (%s)", xi->x509->name);
            X509_STORE_add_cert(store, xi->x509);
	    cert_cnt++;
        }
        if (xi->crl != NULL) {
            EST_LOG_INFO("Adding CRL to store");
            X509_STORE_add_crl(store, xi->crl);
        }
        X509_INFO_free(xi);
    }

    if (sk != NULL) {
        sk_X509_INFO_pop_free(sk, X509_INFO_free);
    }
    return (cert_cnt);
}
Example #7
0
int
ssl_by_mem_ctrl(X509_LOOKUP *lu, int cmd, const char *buf,
    long type, char **ret)
{
	STACK_OF(X509_INFO)	*inf;
	const struct iovec	*iov;
	X509_INFO		*itmp;
	BIO			*in = NULL;
	int			 i, count = 0;

	iov = (const struct iovec *)buf;

	if (type != X509_FILETYPE_PEM)
		goto done;

	if ((in = BIO_new_mem_buf(iov->iov_base, iov->iov_len)) == NULL)
		goto done;

	if ((inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL)) == NULL)
		goto done;

	for (i = 0; i < sk_X509_INFO_num(inf); i++) {
		itmp = sk_X509_INFO_value(inf, i);
		if (itmp->x509) {
			X509_STORE_add_cert(lu->store_ctx, itmp->x509);
			count++;
		}
		if (itmp->crl) {
			X509_STORE_add_crl(lu->store_ctx, itmp->crl);
			count++;
		}
	}
	sk_X509_INFO_pop_free(inf, X509_INFO_free);

 done:
	if (!count)
		X509err(X509_F_X509_LOAD_CERT_CRL_FILE,ERR_R_PEM_LIB);

	if (in != NULL)
		BIO_free(in);
	return (count);
}
Example #8
0
static int X509_load_cert_crl_mem(X509_LOOKUP *ctx, const char *mem)
{
  STACK_OF(X509_INFO) *inf;
  X509_INFO *itmp;
  BIO *in;
  int i, count = 0;

  in = BIO_new(BIO_s_mem());
  if (!in) {
    printk("X509_load_cert_crl_mem: cannot allocate BIO\n");
    return 0;
  }

  BIO_write(in, mem, strlen(mem));

  inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
  BIO_free(in);

  if (!inf) {
    printk("X509_load_cert_crl_mem: cannot read X509_INFO\n");
    return 0;
  }

  for (i = 0; i < sk_X509_INFO_num(inf); i++) {
    itmp = sk_X509_INFO_value(inf, i);
    if (itmp->x509) {
      X509_STORE_add_cert(ctx->store_ctx, itmp->x509);
      count++;
    }
    else if (itmp->crl) {
      X509_STORE_add_crl(ctx->store_ctx, itmp->crl);
      count++;
    }
  }

  sk_X509_INFO_pop_free(inf, X509_INFO_free);

  return count;
}
Example #9
0
int SSL_CTX_load_verify_mem(SSL_CTX *ctx, void *data, int data_len)
{
	STACK_OF(X509_INFO) *stack = NULL;
	X509_INFO *info;
	int nstack, i, ret = 0, got = 0;
	BIO *bio;

	/* Read from memory */
	bio = BIO_new_mem_buf(data, data_len);
	if (!bio)
		goto failed;

	/* Parse X509_INFO records */
	stack = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
	if (!stack)
		goto failed;

	/* Loop over stack, add certs and revocation records to store */
	nstack = sk_X509_INFO_num(stack);
	for (i = 0; i < nstack; i++) {
		info = sk_X509_INFO_value(stack, i);
		if (info->x509 && !X509_STORE_add_cert(ctx->cert_store, info->x509))
			goto failed;
		if (info->crl && !X509_STORE_add_crl(ctx->cert_store, info->crl))
			goto failed;
		if (info->x509 || info->crl)
			got = 1;
	}
	ret = got;
failed:
	if (bio)
		BIO_free(bio);
	if (stack)
		sk_X509_INFO_pop_free(stack, X509_INFO_free);
	if (!ret)
		X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB);
	return ret;
}
Example #10
0
void openssl_x509_verify()
{
	FILE *fp;
	int uCert1Len;
	X509_CRL *Crl = NULL;
	X509_STORE_CTX *ctx = NULL;
	X509_STORE *rootCertStore = NULL;
	STACK_OF(X509) * caCertStack = NULL;
	X509 *usrCert1 = NULL, *usrCert2 = NULL, *rootCert = NULL;
	unsigned char tmp[MAX4_LEN];
	unsigned long uCert2Len, derCrlLen, derRootCertLen;
	const unsigned char *derCrl, *derRootCert, *uCert1, *uCert2;

	OpenSSL_add_all_algorithms();
	printf("\nX509_Verify info:\n");

	fp = fopen(RCERTF, "rb");
	derRootCertLen = fread(tmp, 1, 4096, fp);
	derRootCert = tmp;
	fclose(fp);
	rootCert = d2i_X509(NULL, &derRootCert, derRootCertLen);

	fp = fopen(CRLCRL, "rb");
	derCrlLen = fread(tmp, 1, 4096, fp);
	derCrl = tmp;
	fclose(fp);
	Crl = d2i_X509_CRL(NULL, &derCrl, derCrlLen);

	rootCertStore = X509_STORE_new();
	X509_STORE_add_cert(rootCertStore, rootCert);
	X509_STORE_set_flags(rootCertStore, X509_V_FLAG_CRL_CHECK);
	X509_STORE_add_crl(rootCertStore, Crl);
	ctx = X509_STORE_CTX_new();

	fp = fopen(U1CERTF, "rb");
	uCert1Len = fread(tmp, 1, 4096, fp);
	uCert1 = tmp;
	fclose(fp);
	usrCert1 = d2i_X509(NULL, &uCert1, uCert1Len);
	if (X509_STORE_CTX_init(ctx, rootCertStore, usrCert1, caCertStack) != 1) {
		perror("X509_STORE_CTX_init");
		return;
	}
	if (X509_verify_cert(ctx) != 1) {
		printf("user1.cer %s\n", X509_verify_cert_error_string(ctx->error));
		return;
	}

	fp = fopen(U2CERTF, "rb");
	uCert2Len = fread(tmp, 1, 4096, fp);
	uCert2 = tmp;
	fclose(fp);
	usrCert2 = d2i_X509(NULL, &uCert2, uCert2Len);
	if (X509_STORE_CTX_init(ctx, rootCertStore, usrCert2, caCertStack) != 1) {
		perror("X509_STORE_CTX_init");
		return;
	}
	if (X509_verify_cert(ctx) != 1) {
		printf("user2.cer %s\n", X509_verify_cert_error_string(ctx->error));
		return;
	}

	X509_free(usrCert1);
	X509_free(usrCert2);
	X509_free(rootCert);
	X509_STORE_CTX_cleanup(ctx);
	X509_STORE_CTX_free(ctx);
	X509_STORE_free(rootCertStore);

	return;
}
Example #11
0
int openconnect_open_https(struct openconnect_info *vpninfo)
{
	method_const SSL_METHOD *ssl3_method;
	SSL *https_ssl;
	BIO *https_bio;
	int ssl_sock;
	int err;

	if (vpninfo->https_ssl)
		return 0;

	if (vpninfo->peer_cert) {
		X509_free(vpninfo->peer_cert);
		vpninfo->peer_cert = NULL;
	}

	ssl_sock = connect_https_socket(vpninfo);
	if (ssl_sock < 0)
		return ssl_sock;

	ssl3_method = TLSv1_client_method();
	if (!vpninfo->https_ctx) {
		vpninfo->https_ctx = SSL_CTX_new(ssl3_method);

		/* Some servers (or their firewalls) really don't like seeing
		   extensions. */
#ifdef SSL_OP_NO_TICKET
		SSL_CTX_set_options(vpninfo->https_ctx, SSL_OP_NO_TICKET);
#endif

		if (vpninfo->cert) {
			err = load_certificate(vpninfo);
			if (err) {
				vpn_progress(vpninfo, PRG_ERR,
					     _("Loading certificate failed. Aborting.\n"));
				SSL_CTX_free(vpninfo->https_ctx);
				vpninfo->https_ctx = NULL;
				close(ssl_sock);
				return err;
			}
			check_certificate_expiry(vpninfo);
		}

		/* We just want to do:
		   SSL_CTX_set_purpose(vpninfo->https_ctx, X509_PURPOSE_ANY);
		   ... but it doesn't work with OpenSSL < 0.9.8k because of
		   problems with inheritance (fixed in v1.1.4.6 of
		   crypto/x509/x509_vpm.c) so we have to play silly buggers
		   instead. This trick doesn't work _either_ in < 0.9.7 but
		   I don't know of _any_ workaround which will, and can't
		   be bothered to find out either. */
#if OPENSSL_VERSION_NUMBER >= 0x00908000
		SSL_CTX_set_cert_verify_callback(vpninfo->https_ctx,
						 ssl_app_verify_callback, NULL);
#endif
		SSL_CTX_set_default_verify_paths(vpninfo->https_ctx);

#ifdef ANDROID_KEYSTORE
		if (vpninfo->cafile && !strncmp(vpninfo->cafile, "keystore:", 9)) {
			STACK_OF(X509_INFO) *stack;
			X509_STORE *store;
			X509_INFO *info;
			BIO *b = BIO_from_keystore(vpninfo, vpninfo->cafile);

			if (!b) {
				SSL_CTX_free(vpninfo->https_ctx);
				vpninfo->https_ctx = NULL;
				close(ssl_sock);
				return -EINVAL;
			}

			stack = PEM_X509_INFO_read_bio(b, NULL, NULL, NULL);
			BIO_free(b);

			if (!stack) {
				vpn_progress(vpninfo, PRG_ERR,
					     _("Failed to read certs from CA file '%s'\n"),
					     vpninfo->cafile);
				openconnect_report_ssl_errors(vpninfo);
				SSL_CTX_free(vpninfo->https_ctx);
				vpninfo->https_ctx = NULL;
				close(ssl_sock);
				return -ENOENT;
			}

			store = SSL_CTX_get_cert_store(vpninfo->https_ctx);

			while ((info = sk_X509_INFO_pop(stack))) {
				if (info->x509)
					X509_STORE_add_cert(store, info->x509);
				if (info->crl)
					X509_STORE_add_crl(store, info->crl);
				X509_INFO_free(info);
			}
			sk_X509_INFO_free(stack);
		} else
#endif
		if (vpninfo->cafile) {
			if (!SSL_CTX_load_verify_locations(vpninfo->https_ctx, vpninfo->cafile, NULL)) {
				vpn_progress(vpninfo, PRG_ERR,
					     _("Failed to open CA file '%s'\n"),
					     vpninfo->cafile);
				openconnect_report_ssl_errors(vpninfo);
				SSL_CTX_free(vpninfo->https_ctx);
				vpninfo->https_ctx = NULL;
				close(ssl_sock);
				return -EINVAL;
			}
		}

	}
	https_ssl = SSL_new(vpninfo->https_ctx);
	workaround_openssl_certchain_bug(vpninfo, https_ssl);

	https_bio = BIO_new_socket(ssl_sock, BIO_NOCLOSE);
	BIO_set_nbio(https_bio, 1);
	SSL_set_bio(https_ssl, https_bio, https_bio);

	vpn_progress(vpninfo, PRG_INFO, _("SSL negotiation with %s\n"),
		     vpninfo->hostname);

	while ((err = SSL_connect(https_ssl)) <= 0) {
		fd_set wr_set, rd_set;
		int maxfd = ssl_sock;

		FD_ZERO(&wr_set);
		FD_ZERO(&rd_set);

		err = SSL_get_error(https_ssl, err);
		if (err == SSL_ERROR_WANT_READ)
			FD_SET(ssl_sock, &rd_set);
		else if (err == SSL_ERROR_WANT_WRITE)
			FD_SET(ssl_sock, &wr_set);
		else {
			vpn_progress(vpninfo, PRG_ERR, _("SSL connection failure\n"));
			openconnect_report_ssl_errors(vpninfo);
			SSL_free(https_ssl);
			close(ssl_sock);
			return -EINVAL;
		}

		cmd_fd_set(vpninfo, &rd_set, &maxfd);
		select(maxfd + 1, &rd_set, &wr_set, NULL, NULL);
		if (is_cancel_pending(vpninfo, &rd_set)) {
			vpn_progress(vpninfo, PRG_ERR, _("SSL connection cancelled\n"));
			SSL_free(https_ssl);
			close(ssl_sock);
			return -EINVAL;
		}
	}

	if (verify_peer(vpninfo, https_ssl)) {
		SSL_free(https_ssl);
		close(ssl_sock);
		return -EINVAL;
	}

	vpninfo->ssl_fd = ssl_sock;
	vpninfo->https_ssl = https_ssl;

	/* Stash this now, because it might not be available later if the
	   server has disconnected. */
	vpninfo->peer_cert = SSL_get_peer_certificate(vpninfo->https_ssl);

	vpn_progress(vpninfo, PRG_INFO, _("Connected to HTTPS on %s\n"),
		     vpninfo->hostname);

	return 0;
}
Example #12
0
/* XXX share code with x509_read_from_dir() ?  */
int
x509_read_crls_from_dir(X509_STORE *ctx, char *name)
{
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
	FILE		*crlfp;
	X509_CRL	*crl;
	struct stat	sb;
	char		fullname[PATH_MAX];
	char		file[PATH_MAX];
	int		fd, off, size;

	if (strlen(name) >= sizeof fullname - 1) {
		log_print("x509_read_crls_from_dir: directory name too long");
		return 0;
	}
	LOG_DBG((LOG_CRYPTO, 40, "x509_read_crls_from_dir: reading CRLs "
	    "from %s", name));

	if (monitor_req_readdir(name) == -1) {
		LOG_DBG((LOG_CRYPTO, 10, "x509_read_crls_from_dir: opendir "
		    "(\"%s\") failed: %s", name, strerror(errno)));
		return 0;
	}
	strlcpy(fullname, name, sizeof fullname);
	off = strlen(fullname);
	size = sizeof fullname - off;

	while ((fd = monitor_readdir(file, sizeof file)) != -1) {
		LOG_DBG((LOG_CRYPTO, 60, "x509_read_crls_from_dir: reading "
		    "CRL %s", file));

		if (fstat(fd, &sb) == -1) {
			log_error("x509_read_crls_from_dir: fstat failed");
			close(fd);
			continue;
		}

		if (!S_ISREG(sb.st_mode)) {
			close(fd);
			continue;
		}

		if ((crlfp = fdopen(fd, "r")) == NULL) {
			log_error("x509_read_crls_from_dir: fdopen failed");
			close(fd);
			continue;
		}

		crl = PEM_read_X509_CRL(crlfp, NULL, NULL, NULL);

		fclose(crlfp);

		if (crl == NULL) {
			log_print("x509_read_crls_from_dir: "
			    "PEM_read_X509_CRL failed for %s",
			    file);
			continue;
		}
		if (!X509_STORE_add_crl(ctx, crl)) {
			LOG_DBG((LOG_CRYPTO, 50, "x509_read_crls_from_dir: "
			    "X509_STORE_add_crl failed for %s", file));
			continue;
		}
		/*
		 * XXX This is to make x509_cert_validate set this (and
		 * XXX another) flag when validating certificates. Currently,
		 * XXX OpenSSL defaults to reject an otherwise valid
		 * XXX certificate (chain) if these flags are set but there
		 * XXX are no CRLs to check. The current workaround is to only
		 * XXX set the flags if we actually loaded some CRL data.
		 */
		X509_STORE_set_flags(ctx, X509_V_FLAG_CRL_CHECK);
	}

#endif				/* OPENSSL_VERSION_NUMBER >= 0x00907000L */

	return 1;
}
Example #13
0
int
tls_configure_ssl_verify(struct tls *ctx, SSL_CTX *ssl_ctx, int verify)
{
	size_t ca_len = ctx->config->ca_len;
	char *ca_mem = ctx->config->ca_mem;
	char *crl_mem = ctx->config->crl_mem;
	size_t crl_len = ctx->config->crl_len;
	char *ca_free = NULL;
	STACK_OF(X509_INFO) *xis = NULL;
	X509_STORE *store;
	X509_INFO *xi;
	BIO *bio = NULL;
	int rv = -1;
	int i;

	SSL_CTX_set_verify(ssl_ctx, verify, NULL);
	SSL_CTX_set_cert_verify_callback(ssl_ctx, tls_ssl_cert_verify_cb, ctx);

	if (ctx->config->verify_depth >= 0)
		SSL_CTX_set_verify_depth(ssl_ctx, ctx->config->verify_depth);

	if (ctx->config->verify_cert == 0)
		goto done;

	/* If no CA has been specified, attempt to load the default. */
	if (ctx->config->ca_mem == NULL && ctx->config->ca_path == NULL) {
		if (tls_config_load_file(&ctx->error, "CA", _PATH_SSL_CA_FILE,
		    &ca_mem, &ca_len) != 0)
			goto err;
		ca_free = ca_mem;
	}

	if (ca_mem != NULL) {
		if (ca_len > INT_MAX) {
			tls_set_errorx(ctx, "ca too long");
			goto err;
		}
		if (SSL_CTX_load_verify_mem(ssl_ctx, ca_mem, ca_len) != 1) {
			tls_set_errorx(ctx, "ssl verify memory setup failure");
			goto err;
		}
	} else if (SSL_CTX_load_verify_locations(ssl_ctx, NULL,
	    ctx->config->ca_path) != 1) {
		tls_set_errorx(ctx, "ssl verify locations failure");
		goto err;
	}

	if (crl_mem != NULL) {
		if (crl_len > INT_MAX) {
			tls_set_errorx(ctx, "crl too long");
			goto err;
		}
		if ((bio = BIO_new_mem_buf(crl_mem, crl_len)) == NULL) {
			tls_set_errorx(ctx, "failed to create buffer");
			goto err;
		}
		if ((xis = PEM_X509_INFO_read_bio(bio, NULL, tls_password_cb,
		    NULL)) == NULL) {
			tls_set_errorx(ctx, "failed to parse crl");
			goto err;
		}
		store = SSL_CTX_get_cert_store(ssl_ctx);
		for (i = 0; i < sk_X509_INFO_num(xis); i++) {
			xi = sk_X509_INFO_value(xis, i);
			if (xi->crl == NULL)
				continue;
			if (!X509_STORE_add_crl(store, xi->crl)) {
				tls_set_error(ctx, "failed to add crl");
				goto err;
			}
			xi->crl = NULL;
		}
		X509_VERIFY_PARAM_set_flags(store->param,
		    X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
	}

 done:
	rv = 0;

 err:
	sk_X509_INFO_pop_free(xis, X509_INFO_free);
	BIO_free(bio);
	free(ca_free);

	return (rv);
}
Example #14
0
int main(int argc, char *argv[]) {
    X509 *cert;
    X509 *cacert;
    X509_CRL *crl;
    X509_STORE *store;
    X509_LOOKUP *lookup;
    X509_STORE_CTX *verify_ctx;
    STACK_OF(X509) *untrusted;
    STACK_OF(X509_CRL) *crls;
    FILE *fp;

    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    /* read the client certificate */
    if (!(fp = fopen(CLIENT_CERT, "r"))) {
        int_error("Error reading client certificate file");
    }
    if (!(cert = PEM_read_X509(fp, NULL, NULL, NULL))) {
        int_error("Error reading client certificate in file");
    }
    fclose(fp);

    /* read CA certificate */
    if (!(fp = fopen(CA_FILE, "r"))) {
        int_error("Error reading CA certificate file");
    }
    if (!(cacert = PEM_read_X509(fp, NULL, NULL, NULL))) {
        int_error("Error reading CA certificate in file");
    }
    fclose(fp);

    // Read CRL
    if (!(fp = fopen(CRL_FILE, "r"))) {
        int_error("Error opening CRL file");
    }
    if (!(crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL))) {
        int_error("Error reading CRL");
    }
    fclose(fp);
    
    /* create the cert store and set the verify callback */
    if (!(store = X509_STORE_new())) {
        int_error("Error creating X509_STORE_CTX object");
    }
    // Add CA cert to Store
    if (X509_STORE_add_cert(store, cacert) != 1) {
        int_error("Error adding CA certificate to certificate store");
    }
    // Add CRL to Store
    if (X509_STORE_add_crl(store, crl) != 1) {
        int_error("Error adding CRL to certificate store");
    }
    X509_STORE_set_verify_cb_func(store, verify_callback);
    /* set the flags of the store so that the CRLs are consulted */
    X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
    
    // Create an empty X509_Stack for untrusted
    if (!(untrusted = sk_X509_new_null())) {
        int_error("Error creating X509_Stack");
    }
    // Create a CRL_Stack 
    if (!(crls = sk_X509_CRL_new_null())) {
        int_error("Error creating X509_CRL");
    }
    // Add CRL to CRL_Stack
    if (sk_X509_CRL_push(crls, crl) != 1) {
        int_error("Error adding a CRL to the Stack of CRLs");
    }

    /* create a verification context and initialize it */
    if (!(verify_ctx = X509_STORE_CTX_new())) {
        int_error("Error creating X509_STORE_CTX object");
    }
    // We are explicitly adding an empty X509_Stack for untrusted
    if (X509_STORE_CTX_init(verify_ctx, store, cert, untrusted) != 1) {
        int_error("Error initializing verification context");
    }
    X509_STORE_CTX_set0_crls(verify_ctx, crls);
    /* verify the certificate */
    if (X509_verify_cert(verify_ctx) != 1) {
        int_error("Error verifying the certificate");
    }
    else {
        printf("Certificate verified correctly!\n");
    }
    return 0;
}
Example #15
0
static int op_capi_get_by_subject(X509_LOOKUP *_lu,int _type,X509_NAME *_name,
                                  X509_OBJECT *_ret) {
    HCERTSTORE h_store;
    if(_name==NULL)return 0;
    if(_name->bytes==NULL||_name->bytes->length<=0||_name->modified) {
        if(i2d_X509_NAME(_name,NULL)<0)return 0;
        OP_ASSERT(_name->bytes->length>0);
    }
    h_store=(HCERTSTORE)_lu->method_data;
    switch(_type) {
    case X509_LU_X509: {
        CERT_NAME_BLOB  find_para;
        PCCERT_CONTEXT  cert;
        X509           *x;
        int             ret;
        /*Although X509_NAME contains a canon_enc field, that "canonical" [1]
           encoding was just made up by OpenSSL.
          It doesn't correspond to any actual standard, and since it drops the
           initial sequence header, won't be recognized by the Crypto API.
          The assumption here is that CertFindCertificateInStore() will allow any
           appropriate variations in the encoding when it does its comparison.
          This is, however, emphatically not true under Wine, which just compares
           the encodings with memcmp().
          Most of the time things work anyway, though, and there isn't really
           anything we can do to make the situation better.

          [1] A "canonical form" is defined as the one where, if you locked 10
           mathematicians in a room and asked them to come up with a
           representation for something, it's the answer that 9 of them would
           give you back.
          I don't think OpenSSL's encoding qualifies.*/
        find_para.cbData=_name->bytes->length;
        find_para.pbData=(unsigned char *)_name->bytes->data;
        cert=CertFindCertificateInStore(h_store,X509_ASN_ENCODING,0,
                                        CERT_FIND_SUBJECT_NAME,&find_para,NULL);
        if(cert==NULL)return 0;
        x=d2i_X509(NULL,(const unsigned char **)&cert->pbCertEncoded,
                   cert->cbCertEncoded);
        CertFreeCertificateContext(cert);
        if(x==NULL)return 0;
        ret=X509_STORE_add_cert(_lu->store_ctx,x);
        X509_free(x);
        if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
    }
    break;
    case X509_LU_CRL: {
        CERT_INFO      cert_info;
        CERT_CONTEXT   find_para;
        PCCRL_CONTEXT  crl;
        X509_CRL      *x;
        int            ret;
        ret=op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
        if(ret>0)return ret;
        memset(&cert_info,0,sizeof(cert_info));
        cert_info.Issuer.cbData=_name->bytes->length;
        cert_info.Issuer.pbData=(unsigned char *)_name->bytes->data;
        memset(&find_para,0,sizeof(find_para));
        find_para.pCertInfo=&cert_info;
        crl=CertFindCRLInStore(h_store,0,0,CRL_FIND_ISSUED_BY,&find_para,NULL);
        if(crl==NULL)return 0;
        x=d2i_X509_CRL(NULL,(const unsigned char **)&crl->pbCrlEncoded,
                       crl->cbCrlEncoded);
        CertFreeCRLContext(crl);
        if(x==NULL)return 0;
        ret=X509_STORE_add_crl(_lu->store_ctx,x);
        X509_CRL_free(x);
        if(ret)return op_capi_retrieve_by_subject(_lu,_type,_name,_ret);
    }
    break;
    }
    return 0;
}
Example #16
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
    }
}
Example #17
0
		inline void store::add_certificate_revocation_list(certificate_revocation_list crl)
		{
			throw_error_if_not(X509_STORE_add_crl(raw(), crl.raw()) != 0);
		}
Example #18
0
static int load_crl(SSL_CTX * ctx, char *crl_directory, int crl_check_all)
{
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
	DIR *d;
	struct dirent *dir;
	int crl_added = 0;
	LM_DBG("Loading CRL from directory\n");

	/*Get X509 store from SSL context*/
	X509_STORE *store = SSL_CTX_get_cert_store(ctx);
	if(!store) {
		LM_ERR("Unable to get X509 store from ssl context\n");
		return -1;
	}

	/*Parse directory*/
	d = opendir(crl_directory);
	if(!d) {
		LM_ERR("Unable to open crl directory '%s'\n", crl_directory);
		return -1;
	}

	while ((dir = readdir(d)) != NULL) {
		/*Skip if not regular file*/
		if (dir->d_type != DT_REG)
			continue;

		/*Create filename*/
		char* filename = (char*) pkg_malloc(sizeof(char)*(strlen(crl_directory)+strlen(dir->d_name)+2));
		if (!filename) {
			LM_ERR("Unable to allocate crl filename\n");
			closedir(d);
			return -1;
		}
		strcpy(filename,crl_directory);
		if(filename[strlen(filename)-1] != '/')
			strcat(filename,"/");
		strcat(filename,dir->d_name);

		/*Get CRL content*/
		FILE *fp = fopen(filename,"r");
		pkg_free(filename);
		if(!fp)
			continue;

		X509_CRL *crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL);
		fclose(fp);
		if(!crl)
			continue;

		/*Add CRL to X509 store*/
		if (X509_STORE_add_crl(store, crl) == 1)
			crl_added++;
		else
			LM_ERR("Unable to add crl to ssl context\n");

		X509_CRL_free(crl);
	}
	closedir(d);

	if (!crl_added) {
		LM_ERR("No suitable CRL files found in directory %s\n", crl_directory);
		return -1;
	}

	/*Enable CRL checking*/
	X509_VERIFY_PARAM *param;
	param = X509_VERIFY_PARAM_new();

	int flags =  X509_V_FLAG_CRL_CHECK;
	if(crl_check_all)
		flags |= X509_V_FLAG_CRL_CHECK_ALL;

	X509_VERIFY_PARAM_set_flags(param, flags);

	SSL_CTX_set1_param(ctx, param);
	X509_VERIFY_PARAM_free(param);

	return 0;
#else
	static int already_warned = 0;
	if (!already_warned) {
		LM_WARN("CRL not supported in %s\n", OPENSSL_VERSION_TEXT);
		already_warned = 1;
	}
	return 0;
#endif
}
Example #19
0
extern "C" int32_t CryptoNative_X509StoreAddCrl(X509_STORE* ctx, X509_CRL* x)
{
    return X509_STORE_add_crl(ctx, x);
}