void doit(void)
{
	int ret;
	const char *lib;
	gnutls_privkey_t key;
	gnutls_pkcs11_obj_t obj;
	gnutls_datum_t sig = {NULL, 0}, data;
	unsigned flags = 0;

	lib = getenv("P11MOCKLIB1");
	if (lib == NULL)
		lib = P11LIB;

	{
		void *dl;
		unsigned int *pflags;

		dl = dlopen(lib, RTLD_NOW);
		if (dl == NULL) {
			fail("could not dlopen %s\n", lib);
			exit(1);
		}

		pflags = dlsym(dl, "pkcs11_mock_flags");
		if (pflags == NULL) {
			fail("could find pkcs11_mock_flags\n");
			exit(1);
		}

		*pflags = MOCK_FLAG_ALWAYS_AUTH;
	}

	data.data = (void*)"\x38\x17\x0c\x08\xcb\x45\x8f\xd4\x87\x9c\x34\xb6\xf6\x08\x29\x4c\x50\x31\x2b\xbb";
	data.size = 20;

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

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

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

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

	ret = gnutls_pkcs11_obj_init(&obj);
	assert(ret>=0);

	gnutls_pkcs11_obj_set_pin_function(obj, pin_func, NULL);

	ret = gnutls_pkcs11_obj_import_url(obj, "pkcs11:object=test;type=private", GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
	assert(ret>=0);

	ret = gnutls_pkcs11_obj_get_flags(obj, &flags);
	assert(ret>=0);

	if (!(flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH)) {
		fail("key object doesn't have the always authenticate flag\n");
	}
	gnutls_pkcs11_obj_deinit(obj);


	ret = gnutls_privkey_init(&key);
	assert(ret>=0);

	gnutls_privkey_set_pin_function(key, pin_func, NULL);

	ret = gnutls_privkey_import_url(key, "pkcs11:object=test", GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	pin_called = 0;

	ret = gnutls_privkey_sign_hash(key, GNUTLS_DIG_SHA1, 0, &data, &sig);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	if (pin_called == 0) {
		fail("PIN function wasn't called!\n");
	}
	pin_called = 0;

	gnutls_free(sig.data);

	/* call again - should re-authenticate */
	ret = gnutls_privkey_sign_hash(key, GNUTLS_DIG_SHA1, 0, &data, &sig);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	if (pin_called == 0) {
		fail("PIN function wasn't called twice!\n");
	}
	pin_called = 0;

	gnutls_free(sig.data);

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

	gnutls_privkey_deinit(key);
	gnutls_pkcs11_deinit();
	gnutls_global_deinit();
}
Exemple #2
0
/* lists certificates from a token
 */
void
pkcs11_list(FILE * outfile, const char *url, int type, unsigned int flags,
	    unsigned int detailed, common_info_st * info)
{
	gnutls_pkcs11_obj_t *crt_list;
	unsigned int crt_list_size = 0, i, j;
	int ret, otype;
	char *output, *str;
	int attrs, print_exts = 0;
	gnutls_x509_ext_st *exts;
	unsigned exts_size;
	unsigned int obj_flags = flags;

	pkcs11_common(info);

	FIX(url, outfile, detailed, info);

	gnutls_pkcs11_token_get_flags(url, &flags);
	if (flags & GNUTLS_PKCS11_TOKEN_TRUSTED)
		print_exts = 1;

	if (type == PKCS11_TYPE_TRUSTED) {
		attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED;
	} else if (type == PKCS11_TYPE_PK) {
		attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY;
	} else if (type == PKCS11_TYPE_CRT_ALL) {
		attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL;
		if (print_exts != 0) print_exts++;
	} else if (type == PKCS11_TYPE_PRIVKEY) {
		attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY;
	} else if (type == PKCS11_TYPE_INFO) {
		attrs = GNUTLS_PKCS11_OBJ_ATTR_MATCH;
	} else {
		attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL;
	}

	/* give some initial value to avoid asking for the pkcs11 pin twice.
	 */
	ret =
	    gnutls_pkcs11_obj_list_import_url2(&crt_list, &crt_list_size,
					       url, attrs, obj_flags);
	if (ret < 0) {
		fprintf(stderr, "Error in crt_list_import (1): %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	if (crt_list_size == 0) {
		fprintf(stderr, "No matching objects found\n");
		exit(2);
	}

	for (i = 0; i < crt_list_size; i++) {
		char buf[128];
		size_t size;
		unsigned int oflags;

		ret =
		    gnutls_pkcs11_obj_export_url(crt_list[i], detailed,
						 &output);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}

		if (info->only_urls) {
			fprintf(outfile, "%s\n", output);
			gnutls_free(output);
			continue;
		} else {
			fprintf(outfile, "Object %d:\n\tURL: %s\n", i, output);
			gnutls_free(output);
		}

		otype = gnutls_pkcs11_obj_get_type(crt_list[i]);
		fprintf(outfile, "\tType: %s\n",
			gnutls_pkcs11_type_get_name(otype));

		size = sizeof(buf);
		ret =
		    gnutls_pkcs11_obj_get_info(crt_list[i],
					       GNUTLS_PKCS11_OBJ_LABEL,
					       buf, &size);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}
		fprintf(outfile, "\tLabel: %s\n", buf);

		oflags = 0;
		ret = gnutls_pkcs11_obj_get_flags(crt_list[i], &oflags);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}
		str = gnutls_pkcs11_obj_flags_get_str(oflags);
		if (str != NULL) {
			fprintf(outfile, "\tFlags: %s\n", str);
			gnutls_free(str);
		}

		size = sizeof(buf);
		ret =
		    gnutls_pkcs11_obj_get_info(crt_list[i],
					       GNUTLS_PKCS11_OBJ_ID_HEX,
					       buf, &size);
		if (ret < 0) {
			fprintf(stderr, "Error in %s:%d: %s\n", __func__,
				__LINE__, gnutls_strerror(ret));
			exit(1);
		}
		fprintf(outfile, "\tID: %s\n", buf);

		if (otype == GNUTLS_PKCS11_OBJ_X509_CRT && print_exts > 0) {
			ret = gnutls_pkcs11_obj_get_exts(crt_list[i], &exts, &exts_size, 0);
			if (ret >= 0 && exts_size > 0) {
				gnutls_datum_t txt;

				if (print_exts > 1) {
					fprintf(outfile, "\tAttached extensions:\n");
					ret = gnutls_x509_ext_print(exts, exts_size, 0, &txt);
					if (ret >= 0) {
						fprintf(outfile, "%s", (char*)txt.data);
						gnutls_free(txt.data);
					}
				} else {
					fprintf(outfile, "\tAttached extensions:");
					for (j=0;j<exts_size;j++) {
						fprintf(outfile, "%s%s", exts[j].oid, (j!=exts_size-1)?",":" ");
					}
				}
				for (j=0;j<exts_size;j++) {
					gnutls_x509_ext_deinit(&exts[j]);
				}
				gnutls_free(exts);
				fprintf(outfile, "\n");
			}
		}

		fprintf(outfile, "\n");
	}

	UNFIX;
	return;
}