/** * gnutls_pubkey_import_pkcs11: * @key: The public key * @obj: The parameters to be imported * @flags: should be zero * * Imports a public key from a pkcs11 key. This function will import * the given public key to the abstract #gnutls_pubkey_t type. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 2.12.0 **/ int gnutls_pubkey_import_pkcs11(gnutls_pubkey_t key, gnutls_pkcs11_obj_t obj, unsigned int flags) { int ret, type; type = gnutls_pkcs11_obj_get_type(obj); if (type != GNUTLS_PKCS11_OBJ_PUBKEY && type != GNUTLS_PKCS11_OBJ_X509_CRT) { gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } if (type == GNUTLS_PKCS11_OBJ_X509_CRT) { gnutls_x509_crt_t xcrt; ret = gnutls_x509_crt_init(&xcrt); if (ret < 0) { gnutls_assert() return ret; }
static gnutls_pubkey_t _load_pkcs11_pubkey(const char* url) { int ret; gnutls_pkcs11_obj_t obj; gnutls_x509_crt_t xcrt; gnutls_pubkey_t pubkey; unsigned int obj_flags = 0; ret = gnutls_pubkey_init (&pubkey); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } ret = gnutls_pkcs11_obj_init (&obj); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } ret = gnutls_pkcs11_obj_import_url (obj, url, obj_flags); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s: %s\n", __func__, __LINE__, gnutls_strerror (ret), url); exit (1); } switch (gnutls_pkcs11_obj_get_type (obj)) { case GNUTLS_PKCS11_OBJ_X509_CRT: ret = gnutls_x509_crt_init (&xcrt); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } ret = gnutls_x509_crt_import_pkcs11 (xcrt, obj); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } ret = gnutls_pubkey_import_x509 (pubkey, xcrt, 0); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } gnutls_x509_crt_deinit (xcrt); break; case GNUTLS_PKCS11_OBJ_PUBKEY: ret = gnutls_pubkey_import_pkcs11 (pubkey, obj, 0); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } break; default: { fprintf(stderr, "Unsupported PKCS #11 object\n"); exit (1); break; } } gnutls_pkcs11_obj_deinit (obj); return pubkey; }
/* lists certificates from a token */ void pkcs11_list (FILE * outfile, const char *url, int type, unsigned int login, unsigned int detailed, common_info_st * info) { gnutls_pkcs11_obj_t *crt_list; gnutls_x509_crt_t xcrt; unsigned int crt_list_size = 0; int ret; char *output; int i, attrs; unsigned int obj_flags = 0; if (login) obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; pkcs11_common (); if (url == NULL) url = "pkcs11:"; 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; } else if (type == PKCS11_TYPE_PRIVKEY) { attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY; } else { attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL; } /* give some initial value to avoid asking for the pkcs11 pin twice. */ crt_list_size = 128; crt_list = malloc (sizeof (*crt_list) * crt_list_size); if (crt_list == NULL) { fprintf (stderr, "Memory error\n"); exit (1); } ret = gnutls_pkcs11_obj_list_import_url (crt_list, &crt_list_size, url, attrs, obj_flags); if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { 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 (0); } if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { crt_list = realloc (crt_list, sizeof (*crt_list) * crt_list_size); if (crt_list == NULL) { fprintf (stderr, "Memory error\n"); exit (1); } ret = gnutls_pkcs11_obj_list_import_url (crt_list, &crt_list_size, url, attrs, obj_flags); if (ret < 0) { fprintf (stderr, "Error in crt_list_import: %s\n", gnutls_strerror (ret)); exit (1); } } for (i = 0; i < crt_list_size; i++) { char buf[128]; size_t size; 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); } fprintf (outfile, "Object %d:\n\tURL: %s\n", i, output); fprintf (outfile, "\tType: %s\n", gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_get_type (crt_list[i]))); 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); 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\n", buf); if (attrs == GNUTLS_PKCS11_OBJ_ATTR_ALL || attrs == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY) continue; ret = gnutls_x509_crt_init (&xcrt); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } ret = gnutls_x509_crt_import_pkcs11 (xcrt, crt_list[i]); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } #if 0 size = buffer_size; ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } fwrite (buffer, 1, size, outfile); fputs ("\n\n", outfile); #endif gnutls_x509_crt_deinit (xcrt); } return; }
/* 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; }
void pkcs11_export (FILE * outfile, const char *url, unsigned int login, common_info_st * info) { gnutls_pkcs11_obj_t crt; gnutls_x509_crt_t xcrt; gnutls_pubkey_t pubkey; int ret; size_t size; unsigned int obj_flags = 0; if (login) obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; pkcs11_common (); if (url == NULL) url = "pkcs11:"; ret = gnutls_pkcs11_obj_init (&crt); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } ret = gnutls_pkcs11_obj_import_url (crt, url, obj_flags); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } switch (gnutls_pkcs11_obj_get_type (crt)) { case GNUTLS_PKCS11_OBJ_X509_CRT: ret = gnutls_x509_crt_init (&xcrt); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } ret = gnutls_x509_crt_import_pkcs11 (xcrt, crt); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } size = buffer_size; ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } fwrite (buffer, 1, size, outfile); gnutls_x509_crt_deinit (xcrt); break; case GNUTLS_PKCS11_OBJ_PUBKEY: ret = gnutls_pubkey_init (&pubkey); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } ret = gnutls_pubkey_import_pkcs11 (pubkey, crt, 0); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } size = buffer_size; ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } fwrite (buffer, 1, size, outfile); gnutls_pubkey_deinit (pubkey); break; default: { gnutls_datum_t data, enc; size = buffer_size; ret = gnutls_pkcs11_obj_export (crt, buffer, &size); if (ret < 0) { break; } data.data = buffer; data.size = size; ret = gnutls_pem_base64_encode_alloc ("DATA", &data, &enc); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } fwrite (enc.data, 1, enc.size, outfile); gnutls_free (enc.data); break; } } fputs ("\n\n", outfile); gnutls_pkcs11_obj_deinit (crt); return; }