Exemplo n.º 1
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;
}
Exemplo n.º 2
0
/**
 * gnutls_certificate_set_x509_crl:
 * @res: is a #gnutls_certificate_credentials_t type.
 * @crl_list: is a list of trusted CRLs. They should have been verified before.
 * @crl_list_size: holds the size of the crl_list
 *
 * This function adds the trusted CRLs in order to verify client or
 * server certificates.  In case of a client this is not required to
 * be called if the certificates are not verified using
 * gnutls_certificate_verify_peers2().  This function may be called
 * multiple times.
 *
 * Returns: number of CRLs processed, or a negative error code on error.
 *
 * Since: 2.4.0
 **/
int
gnutls_certificate_set_x509_crl(gnutls_certificate_credentials_t res,
				gnutls_x509_crl_t * crl_list,
				int crl_list_size)
{
	int ret, i, j;
	gnutls_x509_crl_t *new_crl = gnutls_malloc(crl_list_size * sizeof(gnutls_x509_crl_t));
	unsigned flags = GNUTLS_TL_USE_IN_TLS;

	if (res->flags & GNUTLS_CERTIFICATE_VERIFY_CRLS)
		flags |= GNUTLS_TL_VERIFY_CRL|GNUTLS_TL_FAIL_ON_INVALID_CRL;

	if (!new_crl)
		return GNUTLS_E_MEMORY_ERROR;

	for (i = 0; i < crl_list_size; i++) {
		ret = gnutls_x509_crl_init(&new_crl[i]);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}

		ret = _gnutls_x509_crl_cpy(new_crl[i], crl_list[i]);
		if (ret < 0) {
			gnutls_assert();
			goto cleanup;
		}
	}

	ret =
	    gnutls_x509_trust_list_add_crls(res->tlist, new_crl,
				    crl_list_size, flags, 0);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	free(new_crl);
	return ret;

      cleanup:
	for (j = 0; j < i; j++)
		gnutls_x509_crl_deinit(new_crl[j]);
	free(new_crl);

	return ret;
}
Exemplo n.º 3
0
/* This function will try to verify the peer's certificate chain, and
 * also check if the hostname matches.
 */
void
verify_certificate_chain(const char *hostname,
                         const gnutls_datum_t * cert_chain,
                         int cert_chain_length)
{
        int i;
        gnutls_x509_trust_list_t tlist;
        gnutls_x509_crt_t *cert;

        unsigned int output;

        /* Initialize the trusted certificate list. This should be done
         * once on initialization. gnutls_x509_crt_list_import2() and
         * gnutls_x509_crl_list_import2() can be used to load them.
         */
        gnutls_x509_trust_list_init(&tlist, 0);

        gnutls_x509_trust_list_add_cas(tlist, ca_list, ca_list_size, 0);
        gnutls_x509_trust_list_add_crls(tlist, crl_list, crl_list_size,
                                        GNUTLS_TL_VERIFY_CRL, 0);

        cert = malloc(sizeof(*cert) * cert_chain_length);

        /* Import all the certificates in the chain to
         * native certificate format.
         */
        for (i = 0; i < cert_chain_length; i++) {
                gnutls_x509_crt_init(&cert[i]);
                gnutls_x509_crt_import(cert[i], &cert_chain[i],
                                       GNUTLS_X509_FMT_DER);
        }

        gnutls_x509_trust_list_verify_named_crt(tlist, cert[0], hostname,
                                                strlen(hostname),
                                                GNUTLS_VERIFY_DISABLE_CRL_CHECKS,
                                                &output,
                                                print_details_func);

        /* if this certificate is not explicitly trusted verify against CAs 
         */
        if (output != 0) {
                gnutls_x509_trust_list_verify_crt(tlist, cert,
                                                  cert_chain_length, 0,
                                                  &output,
                                                  print_details_func);
        }

        if (output & GNUTLS_CERT_INVALID) {
                fprintf(stderr, "Not trusted");

                if (output & GNUTLS_CERT_SIGNER_NOT_FOUND)
                        fprintf(stderr, ": no issuer was found");
                if (output & GNUTLS_CERT_SIGNER_NOT_CA)
                        fprintf(stderr, ": issuer is not a CA");
                if (output & GNUTLS_CERT_NOT_ACTIVATED)
                        fprintf(stderr, ": not yet activated\n");
                if (output & GNUTLS_CERT_EXPIRED)
                        fprintf(stderr, ": expired\n");

                fprintf(stderr, "\n");
        } else
                fprintf(stderr, "Trusted\n");

        /* Check if the name in the first certificate matches our destination!
         */
        if (!gnutls_x509_crt_check_hostname(cert[0], hostname)) {
                printf
                    ("The certificate's owner does not match hostname '%s'\n",
                     hostname);
        }

        gnutls_x509_trust_list_deinit(tlist, 1);

        return;
}
Exemplo n.º 4
0
void doit(void)
{
	int exit_val = 0;
	size_t i;
	int ret;
	gnutls_x509_trust_list_t tl;
	unsigned int verify_status;
	gnutls_x509_crl_t crl;
	gnutls_x509_crt_t ca;
	gnutls_datum_t tmp;

	/* The overloading of time() seems to work in linux (ELF?)
	 * systems only. Disable it on windows.
	 */
#ifdef _WIN32
	exit(77);
#endif

	ret = global_init();
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

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

	for (i = 0; crl_list[i].name; i++) {

		if (debug)
			printf("Chain '%s' (%d)...\n", crl_list[i].name,
				(int) i);

		if (debug > 2)
			printf("\tAdding CRL...");

		ret = gnutls_x509_crl_init(&crl);
		if (ret < 0) {
			fprintf(stderr,
				"gnutls_x509_crl_init[%d]: %s\n",
				(int) i,
				gnutls_strerror(ret));
			exit(1);
		}

		tmp.data = (unsigned char *) *crl_list[i].crl;
		tmp.size = strlen(*crl_list[i].crl);

		ret =
		    gnutls_x509_crl_import(crl, &tmp,
					   GNUTLS_X509_FMT_PEM);
		if (debug > 2)
		printf("done\n");
		if (ret < 0) {
			fprintf(stderr,
				"gnutls_x509_crl_import[%s]: %s\n",
				crl_list[i].name,
				gnutls_strerror(ret));
			exit(1);
		}

		gnutls_x509_crl_print(crl,
				      GNUTLS_CRT_PRINT_ONELINE,
				      &tmp);
		if (debug)
			printf("\tCRL: %.*s\n", 
				tmp.size, tmp.data);
		gnutls_free(tmp.data);

		if (debug > 2)
			printf("\tAdding CA certificate...");

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

		tmp.data = (unsigned char *) *crl_list[i].ca;
		tmp.size = strlen(*crl_list[i].ca);

		ret =
		    gnutls_x509_crt_import(ca, &tmp, GNUTLS_X509_FMT_PEM);
		if (ret < 0) {
			fprintf(stderr, "gnutls_x509_crt_import: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		if (debug > 2)
			printf("done\n");

		gnutls_x509_crt_print(ca, GNUTLS_CRT_PRINT_ONELINE, &tmp);
		if (debug)
			printf("\tCA Certificate: %.*s\n", tmp.size,
				tmp.data);
		gnutls_free(tmp.data);

		if (debug)
			printf("\tVerifying...");

		ret = gnutls_x509_crl_verify(crl, &ca, 1, crl_list[i].verify_flags,
						  &verify_status);
		if (ret < 0) {
			fprintf(stderr,
				"gnutls_x509_crt_list_verify[%d]: %s\n",
				(int) i, gnutls_strerror(ret));
			exit(1);
		}

		if (verify_status != crl_list[i].expected_verify_result) {
			gnutls_datum_t out1, out2;
			gnutls_certificate_verification_status_print
			    (verify_status, GNUTLS_CRT_X509, &out1, 0);
			gnutls_certificate_verification_status_print(crl_list
								     [i].
								     expected_verify_result,
								     GNUTLS_CRT_X509,
								     &out2,
								     0);
			fail("chain[%s]:\nverify_status: %d: %s\nexpected: %d: %s\n", crl_list[i].name, verify_status, out1.data, crl_list[i].expected_verify_result, out2.data);
			gnutls_free(out1.data);
			gnutls_free(out2.data);

			if (!debug)
				exit(1);
		} else if (debug)
			printf("done\n");

		gnutls_x509_trust_list_init(&tl, 0);

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

		/* make sure that the two functions don't diverge */
		ret = gnutls_x509_trust_list_add_crls(tl, &crl, 1, GNUTLS_TL_VERIFY_CRL, crl_list[i].verify_flags);
		if (crl_list[i].expected_verify_result == 0 && ret < 0) {
			fprintf(stderr,
				"gnutls_x509_trust_list_add_crls[%d]: %s\n",
				(int) i, gnutls_strerror(ret));
			exit(1);
		}
		if (crl_list[i].expected_verify_result != 0 && ret > 0) {
			fprintf(stderr,
				"gnutls_x509_trust_list_add_crls[%d]: succeeded when it shouldn't\n",
				(int) i);
			exit(1);
		}

		if (debug)
			printf("\tCleanup...");

		gnutls_x509_trust_list_deinit(tl, 0);
		gnutls_x509_crt_deinit(ca);
		gnutls_x509_crl_deinit(crl);

		if (debug)
			printf("done\n\n\n");
	}

	gnutls_global_deinit();

	if (debug)
		printf("Exit status...%d\n", exit_val);

	exit(exit_val);
}