Пример #1
0
void
Certificate::unpack(Blob::const_iterator& begin, Blob::const_iterator& end)
{
    if (cert) {
        gnutls_x509_crt_deinit(cert);
        cert = nullptr;
    }
    gnutls_x509_crt_t* cert_list;
    unsigned cert_num;
    const gnutls_datum_t crt_dt {(uint8_t*)&(*begin), (unsigned)(end-begin)};
    int err = gnutls_x509_crt_list_import2(&cert_list, &cert_num, &crt_dt, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
    if (err != GNUTLS_E_SUCCESS)
        err = gnutls_x509_crt_list_import2(&cert_list, &cert_num, &crt_dt, GNUTLS_X509_FMT_DER, GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
    if (err != GNUTLS_E_SUCCESS || cert_num == 0) {
        cert = nullptr;
        throw CryptoException(std::string("Could not read certificate - ") + gnutls_strerror(err));
    }

    cert = cert_list[0];
    Certificate* crt = this;
    size_t i = 1;
    while (crt and i < cert_num) {
        crt->issuer = std::make_shared<Certificate>(cert_list[i++]);
        crt = crt->issuer.get();
    }
    gnutls_free(cert_list);
}
Пример #2
0
/**
 * gnutls_x509_trust_list_remove_trust_mem:
 * @list: The structure of the list
 * @cas: A buffer containing a list of CAs (optional)
 * @type: The format of the certificates
 *
 * This function will add the given certificate authorities
 * to the trusted list. 
 *
 * Returns: The number of added elements is returned.
 *
 * Since: 3.1.10
 **/
int
gnutls_x509_trust_list_remove_trust_mem(gnutls_x509_trust_list_t list,
                                     const gnutls_datum_t * cas, 
                                     gnutls_x509_crt_fmt_t type)
{
  int ret;
  gnutls_x509_crt_t *x509_ca_list = NULL;
  unsigned int x509_ncas;
  unsigned int r = 0, i;
  
  if (cas != NULL && cas->data != NULL)
    {
      ret = gnutls_x509_crt_list_import2( &x509_ca_list, &x509_ncas, cas, type, 0);
      if (ret < 0)
        return gnutls_assert_val(ret);

      ret = gnutls_x509_trust_list_remove_cas(list, x509_ca_list, x509_ncas);
      
      for (i=0;i<x509_ncas;i++)
        gnutls_x509_crt_deinit(x509_ca_list[i]);
      gnutls_free(x509_ca_list);

      if (ret < 0)
        return gnutls_assert_val(ret);
      else
        r += ret;
    }

  return r;
}
Пример #3
0
/**
 * gnutls_x509_trust_list_add_trust_mem:
 * @list: The list
 * @cas: A buffer containing a list of CAs (optional)
 * @crls: A buffer containing a list of CRLs (optional)
 * @type: The format of the certificates
 * @tl_flags: flags from %gnutls_trust_list_flags_t
 * @tl_vflags: gnutls_certificate_verify_flags if flags specifies GNUTLS_TL_VERIFY_CRL
 *
 * This function will add the given certificate authorities
 * to the trusted list. 
 *
 * Returns: The number of added elements is returned.
 *
 * Since: 3.1
 **/
int
gnutls_x509_trust_list_add_trust_mem(gnutls_x509_trust_list_t list,
				     const gnutls_datum_t * cas,
				     const gnutls_datum_t * crls,
				     gnutls_x509_crt_fmt_t type,
				     unsigned int tl_flags,
				     unsigned int tl_vflags)
{
	int ret;
	gnutls_x509_crt_t *x509_ca_list = NULL;
	gnutls_x509_crl_t *x509_crl_list = NULL;
	unsigned int x509_ncas, x509_ncrls;
	unsigned int r = 0;

	if (cas != NULL && cas->data != NULL) {
		ret =
		    gnutls_x509_crt_list_import2(&x509_ca_list, &x509_ncas,
						 cas, type, 0);
		if (ret < 0)
			return gnutls_assert_val(ret);

		ret =
		    gnutls_x509_trust_list_add_cas(list, x509_ca_list,
						   x509_ncas, tl_flags);
		gnutls_free(x509_ca_list);

		if (ret < 0)
			return gnutls_assert_val(ret);
		else
			r += ret;
	}

	if (crls != NULL && crls->data != NULL) {
		ret =
		    gnutls_x509_crl_list_import2(&x509_crl_list,
						 &x509_ncrls, crls, type,
						 0);
		if (ret < 0)
			return gnutls_assert_val(ret);

		ret =
		    gnutls_x509_trust_list_add_crls(list, x509_crl_list,
						    x509_ncrls, tl_flags|GNUTLS_TL_NO_DUPLICATES,
						    tl_vflags);
		gnutls_free(x509_crl_list);

		if (ret < 0)
			return gnutls_assert_val(ret);
		else
			r += ret;
	}

	return r;
}
Пример #4
0
/* Loads a certificate list
 */
gnutls_x509_crt_t *load_cert_list(int mand, size_t * crt_size,
				  common_info_st * info)
{
	FILE *fd;
	static gnutls_x509_crt_t *crt;
	int ret;
	gnutls_datum_t dat;
	unsigned size;
	unsigned int crt_max;

	*crt_size = 0;
	if (info->verbose)
		fprintf(stderr, "Loading certificate list...\n");

	if (info->cert == NULL) {
		if (mand) {
			fprintf(stderr, "missing --load-certificate\n");
			exit(1);
		} else
			return NULL;
	}

	fd = fopen(info->cert, "r");
	if (fd == NULL) {
		fprintf(stderr, "Could not open %s\n", info->cert);
		exit(1);
	}

	fix_lbuffer(file_size(fd));

	size = fread(lbuffer, 1, lbuffer_size - 1, fd);
	lbuffer[size] = 0;

	fclose(fd);

	dat.data = (void *) lbuffer;
	dat.size = size;

	ret = gnutls_x509_crt_list_import2(&crt, &crt_max, &dat, GNUTLS_X509_FMT_PEM, 0);
	if (ret < 0) {
		fprintf(stderr, "Error loading certificates: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	*crt_size = crt_max;

	if (info->verbose)
		fprintf(stderr, "Loaded %d certificates.\n",
			(int) crt_max);

	return crt;
}
Пример #5
0
static int import_key(gnutls_certificate_credentials_t xcred, const gnutls_datum_t *skey, const gnutls_datum_t *cert)
{
	gnutls_x509_privkey_t key;
	gnutls_x509_crt_t *crt_list;
	unsigned crt_list_size, idx, i;
	gnutls_datum_t tcert;
	int ret;

	assert(gnutls_x509_privkey_init(&key)>=0);

	ret = gnutls_x509_crt_list_import2(&crt_list, &crt_list_size, cert, GNUTLS_X509_FMT_PEM, 0);
	if (ret < 0) {
		fail("error in gnutls_x509_crt_list_import2: %s\n", gnutls_strerror(ret));
	}

	ret = gnutls_x509_privkey_import(key, skey, GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fail("error in key import: %s\n", gnutls_strerror(ret));
	}

	ret = gnutls_certificate_set_x509_key(xcred, crt_list,
				crt_list_size, key);
	if (ret < 0) {
		success("error in gnutls_certificate_set_x509_key: %s\n", gnutls_strerror(ret));
		idx = ret;
		goto cleanup;
	}

	/* return index */
	idx = ret;

	/* verify whether the stored certificate match the ones we have */
	for (i=0;i<MIN(2, crt_list_size);i++) {
		ret = gnutls_certificate_get_crt_raw(xcred, idx, i, &tcert);
		if (ret < 0) {
			fail("error in %d: cert: %d: %s\n", __LINE__, i, gnutls_strerror(ret));
			exit(1);
		}

		compare(&tcert, cert->data+i);
	}

 cleanup:
	gnutls_x509_privkey_deinit(key);
	for (i=0;i<crt_list_size;i++) {
		gnutls_x509_crt_deinit(crt_list[i]);
	}
	gnutls_free(crt_list);

	return idx;
}
Пример #6
0
static
void test_success2(const char *name, const char *prio)
{
	int ret;
	/* Server stuff. */
	gnutls_certificate_credentials_t serverx509cred;
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t clientx509cred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN;
	gnutls_x509_crt_t *crts;
	unsigned int crts_size;
	unsigned i;
	gnutls_x509_privkey_t pkey;
	unsigned status;

	success("testing cert verification success2 for %s\n", name);

	to_server_len = 0;
	to_client_len = 0;

	ret = gnutls_x509_crt_list_import2(&crts, &crts_size, &server_cert, GNUTLS_X509_FMT_PEM,
			GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_x509_privkey_init(&pkey);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_x509_privkey_import(pkey, &server_key,
					GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	/* Init server */
	gnutls_certificate_allocate_credentials(&serverx509cred);
	gnutls_certificate_set_x509_key(serverx509cred, crts, crts_size, pkey);
	gnutls_x509_privkey_deinit(pkey);
	for (i=0;i<crts_size;i++)
		gnutls_x509_crt_deinit(crts[i]);
	gnutls_free(crts);

	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				serverx509cred);
	assert(gnutls_priority_set_direct(server,
				   prio,
				   NULL)>=0);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);
	gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);

	/* Init client */
	/* Init client */
	ret = gnutls_certificate_allocate_credentials(&clientx509cred);
	if (ret < 0)
		exit(1);

	ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		exit(1);

	ret = gnutls_certificate_set_x509_key_mem(clientx509cred,
						  &cli_cert, &cli_key,
						  GNUTLS_X509_FMT_PEM);

	ret = gnutls_init(&client, GNUTLS_CLIENT);
	if (ret < 0)
		exit(1);

	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				clientx509cred);
	if (ret < 0)
		exit(1);

	assert(gnutls_priority_set_direct(client, prio, NULL)>=0);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	gnutls_session_set_verify_cert(client, "localhost", 0);

	HANDSHAKE(client, server);

	status = gnutls_session_get_verify_cert_status(client);

	if (status != 0) {
		fail("%s: should have accepted: %u!\n", __func__, status);
		exit(1);
	}

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);
}
Пример #7
0
static
void test_failure(const char *name, const char *prio)
{
	int ret;
	/* Server stuff. */
	gnutls_certificate_credentials_t serverx509cred;
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t clientx509cred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN;
	gnutls_x509_crt_t *crts;
	unsigned int crts_size;
	unsigned i;
	gnutls_typed_vdata_st vdata[2];
	gnutls_x509_privkey_t pkey;
	unsigned status;

	success("testing cert verification failure for %s\n", name);

	to_server_len = 0;
	to_client_len = 0;

	ret = gnutls_x509_crt_list_import2(&crts, &crts_size, &server_cert, GNUTLS_X509_FMT_PEM,
			GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_x509_privkey_init(&pkey);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_x509_privkey_import(pkey, &server_key,
					GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	/* Init server */
	gnutls_certificate_allocate_credentials(&serverx509cred);
	gnutls_certificate_set_x509_key(serverx509cred, crts, crts_size, pkey);
	gnutls_x509_privkey_deinit(pkey);
	for (i=0;i<crts_size;i++)
		gnutls_x509_crt_deinit(crts[i]);
	gnutls_free(crts);

	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				serverx509cred);
	assert(gnutls_priority_set_direct(server,
				   prio,
				   NULL) >= 0);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);
	gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);

	/* Init client */
	/* Init client */
	ret = gnutls_certificate_allocate_credentials(&clientx509cred);
	if (ret < 0)
		exit(1);

	ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		exit(1);

	ret = gnutls_certificate_set_x509_key_mem(clientx509cred,
						  &cli_cert, &cli_key,
						  GNUTLS_X509_FMT_PEM);

	ret = gnutls_init(&client, GNUTLS_CLIENT);
	if (ret < 0)
		exit(1);

	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				clientx509cred);
	if (ret < 0)
		exit(1);

	assert(gnutls_priority_set_direct(client, prio, NULL) >= 0);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	memset(vdata, 0, sizeof(vdata));

	/* check with wrong hostname */
	vdata[0].type = GNUTLS_DT_DNS_HOSTNAME;
	vdata[0].data = (void*)"localhost1";

	vdata[1].type = GNUTLS_DT_KEY_PURPOSE_OID;
	vdata[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER;

	gnutls_session_set_verify_cert2(client, vdata, 2, 0);

	HANDSHAKE_EXPECT(client, server, GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR, GNUTLS_E_AGAIN);

	status = gnutls_session_get_verify_cert_status(client);

	if (status == 0) {
		fail("should not have accepted!\n");
		exit(1);
	}

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);
}
Пример #8
0
static void dane_check(const char *host, const char *proto,
		       unsigned int port, common_info_st * cinfo)
{
#ifdef HAVE_DANE
	dane_state_t s;
	dane_query_t q;
	int ret, retcode = 1;
	unsigned entries;
	unsigned int flags = DANE_F_IGNORE_LOCAL_RESOLVER, i;
	unsigned int usage, type, match;
	gnutls_datum_t data, file;
	size_t size;
	unsigned del = 0;
	unsigned vflags = DANE_VFLAG_FAIL_IF_NOT_CHECKED;
	const char *cstr;
	char *str;
	gnutls_x509_crt_t *clist = NULL;
	unsigned int clist_size = 0;
	gnutls_datum_t certs[MAX_CLIST_SIZE];

	if (ENABLED_OPT(LOCAL_DNS))
		flags = 0;

	if (HAVE_OPT(INSECURE))
		flags |= DANE_F_INSECURE;

	if (HAVE_OPT(CHECK_EE))
		vflags |= DANE_VFLAG_ONLY_CHECK_EE_USAGE;

	if (HAVE_OPT(CHECK_CA))
		vflags |= DANE_VFLAG_ONLY_CHECK_CA_USAGE;

	if (!cinfo->cert) {
		const char *app_proto = NULL;
		if (HAVE_OPT(APP_PROTO))
			app_proto = OPT_ARG(APP_PROTO);

		cinfo->cert = obtain_cert(host, proto, port, app_proto, HAVE_OPT(QUIET));
		del = 1;
	}

	if (!HAVE_OPT(QUIET))
		fprintf(stderr, "Querying DNS for %s (%s:%d)...\n", host, proto, port);
	ret = dane_state_init(&s, flags);
	if (ret < 0) {
		fprintf(stderr, "dane_state_init: %s\n",
			dane_strerror(ret));
		retcode = 1;
		goto error;
	}

	if (HAVE_OPT(DLV)) {
		ret = dane_state_set_dlv_file(s, OPT_ARG(DLV));
		if (ret < 0) {
			fprintf(stderr, "dane_state_set_dlv_file: %s\n",
				dane_strerror(ret));
			retcode = 1;
			goto error;
		}
	}

	ret = dane_query_tlsa(s, &q, host, proto, port);
	if (ret < 0) {
		fprintf(stderr, "dane_query_tlsa: %s\n",
			dane_strerror(ret));
		retcode = 1;
		goto error;
	}

	if (ENABLED_OPT(PRINT_RAW)) {
		gnutls_datum_t t;
		char **dane_data;
		int *dane_data_len;
		int secure;
		int bogus;

		ret = dane_query_to_raw_tlsa(q, &entries, &dane_data,
			&dane_data_len, &secure, &bogus);
		if (ret < 0) {
			fprintf(stderr, "dane_query_to_raw_tlsa: %s\n",
				dane_strerror(ret));
			retcode = 1;
			goto error;
		}

		for (i=0;i<entries;i++) {
			size_t str_size;
			t.data = (void*)dane_data[i];
			t.size = dane_data_len[i];

			str_size = t.size * 2 + 1;
			str = gnutls_malloc(str_size);

			ret = gnutls_hex_encode(&t, str, &str_size);
			if (ret < 0) {
				fprintf(stderr, "gnutls_hex_encode: %s\n",
					dane_strerror(ret));
				retcode = 1;
				goto error;
			}
			fprintf(outfile, "[%u]: %s\n", i, str);
			gnutls_free(str);
		}
		fprintf(outfile, "\n");
	}

	if (cinfo->cert) {
		ret = gnutls_load_file(cinfo->cert, &file);
		if (ret < 0) {
			fprintf(stderr, "gnutls_load_file: %s\n",
				gnutls_strerror(ret));
			retcode = 1;
			goto error;
		}

		ret =
		    gnutls_x509_crt_list_import2(&clist,
						 &clist_size,
						 &file,
						 cinfo->
						 incert_format, 0);
		if (ret < 0) {
			fprintf(stderr,
				"gnutls_x509_crt_list_import2: %s\n",
				gnutls_strerror(ret));
			retcode = 1;
			goto error;
		}

		if (clist_size > 0) {
			for (i = 0; i < MIN(MAX_CLIST_SIZE,clist_size); i++) {
				ret =
				    gnutls_x509_crt_export2(clist
							    [i],
							    GNUTLS_X509_FMT_DER,
							    &certs
							    [i]);
				if (ret < 0) {
					fprintf(stderr,
						"gnutls_x509_crt_export2: %s\n",
						gnutls_strerror
						(ret));
					retcode = 1;
					goto error;
				}
			}
		}
	}

	entries = dane_query_entries(q);
	for (i = 0; i < entries; i++) {
		ret = dane_query_data(q, i, &usage, &type, &match, &data);
		if (ret < 0) {
			fprintf(stderr, "dane_query_data: %s\n",
				dane_strerror(ret));
			retcode = 1;
			goto error;
		}

		size = lbuffer_size;
		ret = gnutls_hex_encode(&data, (void *) lbuffer, &size);
		if (ret < 0) {
			fprintf(stderr, "gnutls_hex_encode: %s\n",
				dane_strerror(ret));
			retcode = 1;
			goto error;
		}

		if (entries > 1 && !HAVE_OPT(QUIET))
			fprintf(outfile, "\n==== Entry %d ====\n", i + 1);

		fprintf(outfile,
			"_%u._%s.%s. IN TLSA ( %.2x %.2x %.2x %s )\n",
			port, proto, host, usage, type, match, lbuffer);

		if (!HAVE_OPT(QUIET)) {
			cstr = dane_cert_usage_name(usage);
			if (cstr == NULL) cstr= "Unknown";
			fprintf(outfile, "Certificate usage: %s (%.2x)\n", cstr, usage);

			cstr = dane_cert_type_name(type);
			if (cstr == NULL) cstr= "Unknown";
			fprintf(outfile, "Certificate type:  %s (%.2x)\n", cstr, type);

			cstr = dane_match_type_name(match);
			if (cstr == NULL) cstr= "Unknown";
			fprintf(outfile, "Contents:          %s (%.2x)\n", cstr, match);
			fprintf(outfile, "Data:              %s\n", lbuffer);
		}

		/* Verify the DANE data */
		if (cinfo->cert) {
			unsigned int status;
			gnutls_datum_t out;

			ret =
			    dane_verify_crt(s, certs, clist_size,
					    GNUTLS_CRT_X509, host,
					    proto, port, 0, vflags,
					    &status);
			if (ret < 0) {
				fprintf(stderr,
					"dane_verify_crt: %s\n",
					dane_strerror(ret));
				retcode = 1;
				goto error;
			}

			ret =
			    dane_verification_status_print(status,
							   &out,
							   0);
			if (ret < 0) {
				fprintf(stderr,
					"dane_verification_status_print: %s\n",
					dane_strerror(ret));
				retcode = 1;
				goto error;
			}

			if (!HAVE_OPT(QUIET))
				fprintf(outfile, "\nVerification: %s\n", out.data);
			gnutls_free(out.data);

			/* if there is at least one correct accept */
			if (status == 0)
				retcode = 0;
		} else {
			fprintf(stderr,
				"\nCertificate could not be obtained. You can explicitly load the certificate using --load-certificate.\n");
		}
	}

	if (clist_size > 0) {
		for (i = 0; i < clist_size; i++) {
			gnutls_free(certs[i].data);
			gnutls_x509_crt_deinit(clist[i]);
		}
		gnutls_free(clist);
	}



	dane_query_deinit(q);
	dane_state_deinit(s);

 error:
	if (del != 0 && cinfo->cert) {
		remove(cinfo->cert);
	}

	exit(retcode);
#else
	fprintf(stderr,
		"This functionality is disabled (GnuTLS was not compiled with support for DANE).\n");
	return;
#endif
}
Пример #9
0
static int
server_cert_callback(gnutls_session_t session,
		     const struct gnutls_cert_retr_st *info,
		     gnutls_pcert_st **pcert,
		     unsigned int *pcert_length,
		     gnutls_ocsp_data_st **ocsp,
		     unsigned int *ocsp_length,
		     gnutls_privkey_t *pkey,
		     unsigned int *flags)
{
	int ret;
	gnutls_pcert_st *p;
	gnutls_privkey_t lkey;
	gnutls_x509_crt_t *certs;
	unsigned certs_size, i;

	if (server_pkey == NULL) {
		p = gnutls_malloc(2 * sizeof(*p));
		if (p == NULL)
			return -1;

		ocspdata[0].response.data = (void*)OCSP_DATA;
		ocspdata[0].response.size = OCSP_SIZE;
		ocspdata[0].exptime = 0;

		ocspdata[1].response.data = (void*)OCSP_DATA;
		ocspdata[1].response.size = OCSP_SIZE;
		ocspdata[1].exptime = 0;

		ret = gnutls_x509_crt_list_import2(&certs, &certs_size,
						   &server_ca3_localhost_cert_chain,
						   GNUTLS_X509_FMT_PEM, 0);
		if (ret < 0)
			return -1;
		ret = gnutls_pcert_import_x509_list(p, certs, &certs_size, 0);
		if (ret < 0)
			return -1;
		for (i = 0; i < certs_size; i++)
			gnutls_x509_crt_deinit(certs[i]);
		gnutls_free(certs);

		ret = gnutls_privkey_init(&lkey);
		if (ret < 0)
			return -1;

		ret =
		    gnutls_privkey_import_x509_raw(lkey, &server_ca3_key,
						   GNUTLS_X509_FMT_PEM, NULL,
						   0);
		if (ret < 0)
			return -1;

		server_pcert = p;
		server_pkey = lkey;

		*pcert = p;
		*pcert_length = 2;
		*pkey = lkey;
		*ocsp = ocspdata;
		*ocsp_length = 2;
	} else {
		*pcert = server_pcert;
		*pcert_length = 2;
		*pkey = server_pkey;
		*ocsp = ocspdata;
		*ocsp_length = 2;
	}

	return 0;
}
Пример #10
0
void doit(void)
{
	int exit_code = EXIT_SUCCESS;
	int ret;
	/* Server stuff. */
	gnutls_certificate_credentials_t serverx509cred;
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t clientx509cred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN;
	gnutls_x509_crt_t *crts;
	unsigned int crts_size;
	unsigned i;
	gnutls_x509_privkey_t pkey;

	/* General init. */
	global_init();
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(2);

	ret = gnutls_x509_crt_list_import2(&crts, &crts_size, &server_cert, GNUTLS_X509_FMT_PEM,
			GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_x509_privkey_init(&pkey);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_x509_privkey_import(pkey, &server_key,
				       GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	/* Init server */
	gnutls_certificate_allocate_credentials(&serverx509cred);
	gnutls_certificate_set_x509_key(serverx509cred, crts, crts_size, pkey);
	gnutls_x509_privkey_deinit(pkey);
	for (i=0;i<crts_size;i++)
		gnutls_x509_crt_deinit(crts[i]);
	gnutls_free(crts);

	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
			       serverx509cred);
	gnutls_priority_set_direct(server,
				   "NORMAL:-CIPHER-ALL:+AES-128-GCM",
				   NULL);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);
	gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);

	/* Init client */
	/* Init client */
	ret = gnutls_certificate_allocate_credentials(&clientx509cred);
	if (ret < 0)
		exit(1);

	ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		exit(1);

	gnutls_certificate_set_retrieve_function2(clientx509cred, cert_callback);

	ret = gnutls_init(&client, GNUTLS_CLIENT);
	if (ret < 0)
		exit(1);

	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
			       clientx509cred);
	if (ret < 0)
		exit(1);

	gnutls_priority_set_direct(client, "NORMAL", NULL);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	HANDSHAKE(client, server);

	if (gnutls_certificate_get_ours(client) == NULL) {
		fail("client certificate was not sent!\n");
		exit(1);
	}

	/* check gnutls_certificate_get_ours() - server side */
	{
		const gnutls_datum_t *mcert;
		gnutls_datum_t scert;
		gnutls_x509_crt_t crt;

		mcert = gnutls_certificate_get_ours(server);
		if (mcert == NULL) {
			fail("gnutls_certificate_get_ours(): failed\n");
			exit(1);
		}

		gnutls_x509_crt_init(&crt);
		ret = gnutls_x509_crt_import(crt, &server_cert, GNUTLS_X509_FMT_PEM);
		if (ret < 0) {
			fail("gnutls_x509_crt_import: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		ret = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_DER, &scert);
		if (ret < 0) {
			fail("gnutls_x509_crt_export2: %s\n", gnutls_strerror(ret));
			exit(1);
		}
		gnutls_x509_crt_deinit(crt);

		if (scert.size != mcert->size || memcmp(scert.data, mcert->data, mcert->size) != 0) {
			fail("gnutls_certificate_get_ours output doesn't match cert\n");
			exit(1);
		}
		gnutls_free(scert.data);
	}

	/* check gnutls_certificate_get_ours() - client side */
	{
		const gnutls_datum_t *mcert;
		gnutls_datum_t ccert;
		gnutls_x509_crt_t crt;

		mcert = gnutls_certificate_get_ours(client);
		if (mcert == NULL) {
			fail("gnutls_certificate_get_ours(): failed\n");
			exit(1);
		}

		gnutls_x509_crt_init(&crt);
		ret = gnutls_x509_crt_import(crt, &cli_cert, GNUTLS_X509_FMT_PEM);
		if (ret < 0) {
			fail("gnutls_x509_crt_import: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		ret = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_DER, &ccert);
		if (ret < 0) {
			fail("gnutls_x509_crt_export2: %s\n", gnutls_strerror(ret));
			exit(1);
		}
		gnutls_x509_crt_deinit(crt);

		if (ccert.size != mcert->size || memcmp(ccert.data, mcert->data, mcert->size) != 0) {
			fail("gnutls_certificate_get_ours output doesn't match cert\n");
			exit(1);
		}
		gnutls_free(ccert.data);
	}

	/* check the number of certificates received */
	{
		unsigned cert_list_size = 0;
		gnutls_typed_vdata_st data[2];
		unsigned status;

		memset(data, 0, sizeof(data));

		/* check with wrong hostname */
		data[0].type = GNUTLS_DT_DNS_HOSTNAME;
		data[0].data = (void*)"localhost1";

		data[1].type = GNUTLS_DT_KEY_PURPOSE_OID;
		data[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER;

		gnutls_certificate_get_peers(client, &cert_list_size);
		if (cert_list_size < 2) {
			fprintf(stderr, "received a certificate list of %d!\n", cert_list_size);
			exit(1);
		}

		ret = gnutls_certificate_verify_peers(client, data, 2, &status);
		if (ret < 0) {
			fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status == 0) {
			fprintf(stderr, "should not have accepted!\n");
			exit(1);
		}

		/* check with wrong purpose */
		data[0].type = GNUTLS_DT_DNS_HOSTNAME;
		data[0].data = (void*)"localhost";

		data[1].type = GNUTLS_DT_KEY_PURPOSE_OID;
		data[1].data = (void*)GNUTLS_KP_TLS_WWW_CLIENT;

		gnutls_certificate_get_peers(client, &cert_list_size);
		if (cert_list_size < 2) {
			fprintf(stderr, "received a certificate list of %d!\n", cert_list_size);
			exit(1);
		}

		ret = gnutls_certificate_verify_peers(client, data, 2, &status);
		if (ret < 0) {
			fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status == 0) {
			fprintf(stderr, "should not have accepted!\n");
			exit(1);
		}

		/* check with correct purpose */
		data[0].type = GNUTLS_DT_DNS_HOSTNAME;
		data[0].data = (void*)"localhost";

		data[1].type = GNUTLS_DT_KEY_PURPOSE_OID;
		data[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER;

		ret = gnutls_certificate_verify_peers(client, data, 2, &status);
		if (ret < 0) {
			fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status != 0) {
			fprintf(stderr, "could not verify certificate: %.4x\n", status);
			exit(1);
		}
	}

	if (gnutls_certificate_client_get_request_status(client) == 0) {
		fail("gnutls_certificate_client_get_request_status - 2 failed\n");
		exit(1);
	}

	gnutls_bye(client, GNUTLS_SHUT_RDWR);
	gnutls_bye(server, GNUTLS_SHUT_RDWR);

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);

	gnutls_global_deinit();

	if (debug > 0) {
		if (exit_code == 0)
			puts("Self-test successful");
		else
			puts("Self-test failed");
	}
}
Пример #11
0
static int _verify_response(gnutls_datum_t * data, gnutls_datum_t * nonce,
	gnutls_x509_crt_t signer)
{
	gnutls_ocsp_resp_t resp;
	int ret;
	size_t size;
	gnutls_x509_crt_t *x509_ca_list = NULL;
	gnutls_x509_trust_list_t list;
	unsigned int x509_ncas = 0;
	unsigned verify;
	gnutls_datum_t dat;

	ret = gnutls_ocsp_resp_init(&resp);
	if (ret < 0) {
		fprintf(stderr, "ocsp_resp_init: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_ocsp_resp_import(resp, data);
	if (ret < 0) {
		fprintf(stderr, "importing response: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	if (nonce) {
	        gnutls_datum_t rnonce;

		ret = gnutls_ocsp_resp_get_nonce(resp, NULL, &rnonce);
		if (ret < 0) {
			fprintf(stderr, "could not read response's nonce: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		if (rnonce.size != nonce->size || memcmp(nonce->data, rnonce.data,
			nonce->size) != 0) {
			fprintf(stderr, "nonce in the response doesn't match\n");
			exit(1);
		}

	        gnutls_free(rnonce.data);
	}

	if (HAVE_OPT(LOAD_TRUST)) {
		dat.data =
		    (void *) read_binary_file(OPT_ARG(LOAD_TRUST), &size);
		if (dat.data == NULL) {
			fprintf(stderr, "reading --load-trust: %s\n",
				OPT_ARG(LOAD_TRUST));
			exit(1);
		}
		dat.size = size;

		ret = gnutls_x509_trust_list_init(&list, 0);
		if (ret < 0) {
			fprintf(stderr, "gnutls_x509_trust_list_init: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		ret =
		    gnutls_x509_crt_list_import2(&x509_ca_list, &x509_ncas,
						 &dat, GNUTLS_X509_FMT_PEM,
						 0);
		if (ret < 0 || x509_ncas < 1) {
			fprintf(stderr, "error parsing CAs: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		if (HAVE_OPT(VERBOSE)) {
			unsigned int i;
			printf("Trust anchors:\n");
			for (i = 0; i < x509_ncas; i++) {
				gnutls_datum_t out;

				ret =
				    gnutls_x509_crt_print(x509_ca_list[i],
							  GNUTLS_CRT_PRINT_ONELINE,
							  &out);
				if (ret < 0) {
					fprintf(stderr,
						"gnutls_x509_crt_print: %s\n",
						gnutls_strerror(ret));
					exit(1);
				}

				printf("%d: %.*s\n", i, out.size,
				       out.data);
				gnutls_free(out.data);
			}
			printf("\n");
		}

		ret =
		    gnutls_x509_trust_list_add_cas(list, x509_ca_list,
						   x509_ncas, 0);
		if (ret < 0) {
			fprintf(stderr, "gnutls_x509_trust_add_cas: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		if (HAVE_OPT(VERBOSE))
			fprintf(stdout, "Loaded %d trust anchors\n",
				x509_ncas);

		ret = gnutls_ocsp_resp_verify(resp, list, &verify, 0);
		if (ret < 0) {
			fprintf(stderr, "gnutls_ocsp_resp_verify: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}
	} else if (signer) {
		if (HAVE_OPT(VERBOSE)) {
			gnutls_datum_t out;

			ret =
			    gnutls_x509_crt_print(signer,
						  GNUTLS_CRT_PRINT_ONELINE,
						  &out);
			if (ret < 0) {
				fprintf(stderr,
					"gnutls_x509_crt_print: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}

			printf("Signer: %.*s\n", out.size, out.data);
			gnutls_free(out.data);
			printf("\n");
		}

		ret =
		    gnutls_ocsp_resp_verify_direct(resp, signer, &verify,
						   0);
		if (ret < 0) {
			fprintf(stderr,
				"gnutls_ocsp_resp_verify_direct: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}
	} else {
		fprintf(stderr, "missing --load-trust or --load-signer\n");
		exit(1);
	}

	printf("Verifying OCSP Response: ");
	print_ocsp_verify_res(verify);
	printf(".\n");

	gnutls_ocsp_resp_deinit(resp);

	return verify;
}
void doit(void)
{
	int ret;
	gnutls_datum_t data;
	gnutls_x509_crt_t *crts;
	unsigned int crts_size, i;
	gnutls_x509_trust_list_t tl;
	unsigned int status, flags = GNUTLS_VERIFY_ALLOW_UNSORTED_CHAIN;
	unsigned int not_flags = GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN;

	/* this must be called once in the program
	 */
	global_init();

	gnutls_global_set_time_function(mytime);
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(6);

	/* test for gnutls_certificate_get_issuer() */
	gnutls_x509_trust_list_init(&tl, 0);

	ret =
	    gnutls_x509_trust_list_add_trust_mem(tl, &ca, NULL,
						 GNUTLS_X509_FMT_PEM, 0,
						 0);
	if (ret < 0) {
		fail("gnutls_x509_trust_list_add_trust_mem\n");
		exit(1);
	}

	/* Chain 1 */
	data.data = (void *) chain1;
	data.size = sizeof(chain1);
	ret =
	    gnutls_x509_crt_list_import2(&crts, &crts_size, &data,
					 GNUTLS_X509_FMT_PEM, 0);
	if (ret < 0) {
		fail("gnutls_x509_crt_list_import2: %s\n",
		     gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_x509_trust_list_verify_crt(tl, crts, crts_size, flags,
					      &status, NULL);
	if (ret < 0 || status != 0) {
		fail("gnutls_x509_trust_list_verify_crt - 1\n");
		exit(1);
	}

	for (i = 0; i < crts_size; i++)
		gnutls_x509_crt_deinit(crts[i]);
	gnutls_free(crts);

	/* Chain 2 */
	data.data = (void *) chain2;
	data.size = sizeof(chain2);

	/* verify whether the GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED flag is
	 * considered by gnutls_x509_crt_list_import2() */
	ret =
		gnutls_x509_crt_list_import2(&crts, &crts_size, &data,
					 GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
	if (ret != GNUTLS_E_CERTIFICATE_LIST_UNSORTED) {
		fail("gnutls_x509_crt_list_import2 with flag GNUTLS_E_CERTIFICATE_LIST_UNSORTED on unsorted chain didn't fail: %s\n",  gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_x509_crt_list_import2(&crts, &crts_size, &data,
					 GNUTLS_X509_FMT_PEM, 0);
	if (ret < 0) {
		fail("gnutls_x509_crt_list_import2: %s\n",
		     gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_x509_trust_list_verify_crt(tl, crts, crts_size, flags,
					      &status, NULL);
	if (ret < 0 || status != 0) {
		fail("gnutls_x509_trust_list_verify_crt - 2\n");
		exit(1);
	}

	for (i = 0; i < crts_size; i++)
		gnutls_x509_crt_deinit(crts[i]);
	gnutls_free(crts);

	/* Chain 3 */
	data.data = (void *) chain3;
	data.size = sizeof(chain3);
	ret =
	    gnutls_x509_crt_list_import2(&crts, &crts_size, &data,
					 GNUTLS_X509_FMT_PEM, 0);
	if (ret < 0) {
		fail("gnutls_x509_crt_list_import2: %s\n",
		     gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_x509_trust_list_verify_crt(tl, crts, crts_size, flags,
					      &status, NULL);
	if (ret < 0 || status != 0) {
		fail("gnutls_x509_trust_list_verify_crt - 3\n");
		exit(1);
	}

	for (i = 0; i < crts_size; i++)
		gnutls_x509_crt_deinit(crts[i]);
	gnutls_free(crts);

	/* Chain 4 */
	data.data = (void *) chain4;
	data.size = sizeof(chain4);
	ret =
	    gnutls_x509_crt_list_import2(&crts, &crts_size, &data,
					 GNUTLS_X509_FMT_PEM, 0);
	if (ret < 0) {
		fail("gnutls_x509_crt_list_import2: %s\n",
		     gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_x509_trust_list_verify_crt(tl, crts, crts_size, flags,
					      &status, NULL);
	if (ret < 0 || status != 0) {
		fail("gnutls_x509_trust_list_verify_crt - 4\n");
		exit(1);
	}

	for (i = 0; i < crts_size; i++)
		gnutls_x509_crt_deinit(crts[i]);
	gnutls_free(crts);

	/* Check if an unsorted list would fail if the unsorted flag is not given */
	data.data = (void *) chain2;
	data.size = sizeof(chain2);
	ret =
	    gnutls_x509_crt_list_import2(&crts, &crts_size, &data,
					 GNUTLS_X509_FMT_PEM, 0);
	if (ret < 0) {
		fail("gnutls_x509_crt_list_import2: %s\n",
		     gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_x509_trust_list_verify_crt(tl, crts, crts_size,
					      not_flags, &status, NULL);
	if (ret < 0 || status == 0) {
		fail("gnutls_x509_trust_list_verify_crt - 5\n");
		exit(1);
	}

	for (i = 0; i < crts_size; i++)
		gnutls_x509_crt_deinit(crts[i]);
	gnutls_free(crts);

	gnutls_x509_trust_list_deinit(tl, 1);

	gnutls_global_deinit();

	if (debug)
		success("success");
}
Пример #13
0
static int
_verify_response (gnutls_datum_t *data)
{
  gnutls_ocsp_resp_t resp;
  int ret;
  size_t size;
  gnutls_x509_crt_t *x509_ca_list = NULL;
  unsigned int x509_ncas = 0;
  gnutls_x509_trust_list_t list;
  gnutls_x509_crt_t signer;
  unsigned verify;
  gnutls_datum_t dat;

  ret = gnutls_ocsp_resp_init (&resp);
  if (ret < 0)
    error (EXIT_FAILURE, 0, "ocsp_resp_init: %s", gnutls_strerror (ret));

  ret = gnutls_ocsp_resp_import (resp, data);
  if (ret < 0)
    error (EXIT_FAILURE, 0, "importing response: %s", gnutls_strerror (ret));

  if (HAVE_OPT(LOAD_TRUST))
    {
      dat.data = (void*)read_binary_file (OPT_ARG(LOAD_TRUST), &size);
      if (dat.data == NULL)
	error (EXIT_FAILURE, errno, "reading --load-trust: %s", OPT_ARG(LOAD_TRUST));
      dat.size = size;

      ret = gnutls_x509_trust_list_init (&list, 0);
      if (ret < 0)
	error (EXIT_FAILURE, 0, "gnutls_x509_trust_list_init: %s",
	       gnutls_strerror (ret));

      ret = gnutls_x509_crt_list_import2 (&x509_ca_list, &x509_ncas, &dat,
					  GNUTLS_X509_FMT_PEM, 0);
      if (ret < 0 || x509_ncas < 1)
	error (EXIT_FAILURE, 0, "error parsing CAs: %s",
	       gnutls_strerror (ret));

      if (HAVE_OPT(VERBOSE))
	{
	  unsigned int i;
	  printf ("Trust anchors:\n");
	  for (i = 0; i < x509_ncas; i++)
	    {
	      gnutls_datum_t out;

	      ret = gnutls_x509_crt_print (x509_ca_list[i],
					   GNUTLS_CRT_PRINT_ONELINE, &out);
	      if (ret < 0)
		error (EXIT_FAILURE, 0, "gnutls_x509_crt_print: %s",
		       gnutls_strerror (ret));

	      printf ("%d: %.*s\n", i, out.size, out.data);
	      gnutls_free (out.data);
	    }
          printf("\n");
	}

      ret = gnutls_x509_trust_list_add_cas (list, x509_ca_list, x509_ncas, 0);
      if (ret < 0)
	error (EXIT_FAILURE, 0, "gnutls_x509_trust_add_cas: %s",
	       gnutls_strerror (ret));

      if (HAVE_OPT(VERBOSE))
	fprintf (stdout, "Loaded %d trust anchors\n", x509_ncas);

      ret = gnutls_ocsp_resp_verify (resp, list, &verify, 0);
      if (ret < 0)
	error (EXIT_FAILURE, 0, "gnutls_ocsp_resp_verify: %s",
	       gnutls_strerror (ret));
    }
  else if (HAVE_OPT(LOAD_SIGNER))
    {
      ret = gnutls_x509_crt_init (&signer);
      if (ret < 0)
	error (EXIT_FAILURE, 0, "crt_init: %s", gnutls_strerror (ret));

      dat.data = (void*)read_binary_file (OPT_ARG(LOAD_SIGNER), &size);
      if (dat.data == NULL)
	error (EXIT_FAILURE, errno, "reading --load-signer: %s", OPT_ARG(LOAD_SIGNER));
      dat.size = size;

      ret = gnutls_x509_crt_import (signer, &dat, encoding);
      free (dat.data);
      if (ret < 0)
	error (EXIT_FAILURE, 0, "importing --load-signer: %s: %s",
	       OPT_ARG(LOAD_SIGNER), gnutls_strerror (ret));

      if (HAVE_OPT(VERBOSE))
	{
	  gnutls_datum_t out;

	  ret = gnutls_x509_crt_print (signer, GNUTLS_CRT_PRINT_ONELINE, &out);
	  if (ret < 0)
	    error (EXIT_FAILURE, 0, "gnutls_x509_crt_print: %s",
		   gnutls_strerror (ret));

	  printf ("Signer: %.*s\n", out.size, out.data);
	  gnutls_free (out.data);
          printf("\n");
	}

      ret = gnutls_ocsp_resp_verify_direct (resp, signer, &verify, 0);
      if (ret < 0)
	error (EXIT_FAILURE, 0, "gnutls_ocsp_resp_verify_direct: %s",
	       gnutls_strerror (ret));
    }
  else
    error (EXIT_FAILURE, 0, "missing --load-trust or --load-signer");

  printf ("Verifying OCSP Response: ");
  print_ocsp_verify_res (verify);
  printf (".\n");

  gnutls_ocsp_resp_deinit (resp);
  
  return verify;
}
Пример #14
0
static void dane_check(const char *host, const char *proto,
		       unsigned int port, common_info_st * cinfo)
{
#ifdef HAVE_DANE
	dane_state_t s;
	dane_query_t q;
	int ret, retcode = 0;
	unsigned entries;
	unsigned int flags = DANE_F_IGNORE_LOCAL_RESOLVER, i;
	unsigned int usage, type, match;
	gnutls_datum_t data, file;
	size_t size;
	unsigned vflags = DANE_VFLAG_FAIL_IF_NOT_CHECKED;

	if (ENABLED_OPT(LOCAL_DNS))
		flags = 0;

	if (HAVE_OPT(INSECURE))
		flags |= DANE_F_INSECURE;

	if (HAVE_OPT(CHECK_EE))
		vflags |= DANE_VFLAG_ONLY_CHECK_EE_USAGE;

	if (HAVE_OPT(CHECK_CA))
		vflags |= DANE_VFLAG_ONLY_CHECK_CA_USAGE;

	printf("Querying %s (%s:%d)...\n", host, proto, port);
	ret = dane_state_init(&s, flags);
	if (ret < 0) {
		fprintf(stderr, "dane_state_init: %s\n",
			dane_strerror(ret));
		exit(1);
	}

	if (HAVE_OPT(DLV)) {
		ret = dane_state_set_dlv_file(s, OPT_ARG(DLV));
		if (ret < 0) {
			fprintf(stderr, "dane_state_set_dlv_file: %s\n",
				dane_strerror(ret));
			exit(1);
		}
	}

	ret = dane_query_tlsa(s, &q, host, proto, port);
	if (ret < 0) {
		fprintf(stderr, "dane_query_tlsa: %s\n",
			dane_strerror(ret));
		exit(1);
	}

	entries = dane_query_entries(q);
	for (i = 0; i < entries; i++) {
		ret = dane_query_data(q, i, &usage, &type, &match, &data);
		if (ret < 0) {
			fprintf(stderr, "dane_query_data: %s\n",
				dane_strerror(ret));
			exit(1);
		}


		size = buffer_size;
		ret = gnutls_hex_encode(&data, (void *) buffer, &size);
		if (ret < 0) {
			fprintf(stderr, "gnutls_hex_encode: %s\n",
				dane_strerror(ret));
			exit(1);
		}

		if (entries > 1)
			printf("\nEntry %d:\n", i + 1);

		fprintf(outfile,
			"_%u._%s.%s. IN TLSA ( %.2x %.2x %.2x %s )\n",
			port, proto, host, usage, type, match, buffer);
		printf("Certificate usage: %s (%.2x)\n",
		       dane_cert_usage_name(usage), usage);
		printf("Certificate type:  %s (%.2x)\n",
		       dane_cert_type_name(type), type);
		printf("Contents:          %s (%.2x)\n",
		       dane_match_type_name(match), match);
		printf("Data:              %s\n", buffer);

		/* Verify the DANE data */
		if (cinfo->cert) {
			gnutls_x509_crt_t *clist;
			unsigned int clist_size, status;

			ret = gnutls_load_file(cinfo->cert, &file);
			if (ret < 0) {
				fprintf(stderr, "gnutls_load_file: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}

			ret =
			    gnutls_x509_crt_list_import2(&clist,
							 &clist_size,
							 &file,
							 cinfo->
							 incert_format, 0);
			if (ret < 0) {
				fprintf(stderr,
					"gnutls_x509_crt_list_import2: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}

			if (clist_size > 0) {
				gnutls_datum_t certs[clist_size];
				gnutls_datum_t out;
				unsigned int i;

				for (i = 0; i < clist_size; i++) {
					ret =
					    gnutls_x509_crt_export2(clist
								    [i],
								    GNUTLS_X509_FMT_DER,
								    &certs
								    [i]);
					if (ret < 0) {
						fprintf(stderr,
							"gnutls_x509_crt_export2: %s\n",
							gnutls_strerror
							(ret));
						exit(1);
					}
				}

				ret =
				    dane_verify_crt(s, certs, clist_size,
						    GNUTLS_CRT_X509, host,
						    proto, port, 0, vflags,
						    &status);
				if (ret < 0) {
					fprintf(stderr,
						"dane_verify_crt: %s\n",
						dane_strerror(ret));
					exit(1);
				}

				ret =
				    dane_verification_status_print(status,
								   &out,
								   0);
				if (ret < 0) {
					fprintf(stderr,
						"dane_verification_status_print: %s\n",
						dane_strerror(ret));
					exit(1);
				}

				printf("\nVerification: %s\n", out.data);
				gnutls_free(out.data);

				if (status != 0)
					retcode = 1;

				for (i = 0; i < clist_size; i++) {
					gnutls_free(certs[i].data);
					gnutls_x509_crt_deinit(clist[i]);
				}
				gnutls_free(clist);
			}
		} else {
			fprintf(stderr,
				"\nCertificate was not verified. Use --load-certificate.\n");
		}
	}


	dane_query_deinit(q);
	dane_state_deinit(s);

	exit(retcode);
#else
	fprintf(stderr,
		"This functionality was disabled (GnuTLS was not compiled with support for DANE).\n");
	return;
#endif
}