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(); }
/* 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; }