static int run(struct fi_info *hints, char *node, char *port) { struct fi_info *info; int ret; uint64_t flags; flags = list_providers ? FI_PROV_ATTR_ONLY : 0; ret = fi_getinfo(FI_VERSION(FI_MAJOR_VERSION, FI_MINOR_VERSION), node, port, flags, hints, &info); if (ret) { fprintf(stderr, "fi_getinfo: %d\n", ret); return ret; } if (env) ret = print_vars(); else if (verbose) ret = print_long_info(info); else if (list_providers) ret = print_providers(info); else ret = print_short_info(info); fi_freeinfo(info); return ret; }
static int run(struct fi_info *hints, char *node, char *port) { struct fi_info *info; int ret; ret = fi_getinfo(FI_VERSION(FI_MAJOR_VERSION, FI_MINOR_VERSION), node, port, 0, hints, &info); if (ret) { fprintf(stderr, "fi_getinfo: %d\n", ret); return ret; } if (verbose) ret = print_long_info(info); else ret = print_short_info(info); fi_freeinfo(info); return ret; }
/* Export a certificate and its private key. */ void gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream) { gpg_error_t err = 0; KEYDB_HANDLE hd; KEYDB_SEARCH_DESC *desc = NULL; Base64Context b64writer = NULL; ksba_writer_t writer; ksba_cert_t cert = NULL; const unsigned char *image; size_t imagelen; char *keygrip = NULL; char *prompt; void *data; size_t datalen; hd = keydb_new (0); if (!hd) { log_error ("keydb_new failed\n"); goto leave; } desc = xtrycalloc (1, sizeof *desc); if (!desc) { log_error ("allocating memory for export failed: %s\n", gpg_strerror (out_of_core ())); goto leave; } err = classify_user_id (name, desc, 0); if (err) { log_error ("key '%s' not found: %s\n", name, gpg_strerror (err)); goto leave; } /* Lookup the certificate and make sure that it is unique. */ err = keydb_search (hd, desc, 1); if (!err) { err = keydb_get_cert (hd, &cert); if (err) { log_error ("keydb_get_cert failed: %s\n", gpg_strerror (err)); goto leave; } next_ambiguous: err = keydb_search (hd, desc, 1); if (!err) { ksba_cert_t cert2 = NULL; if (!keydb_get_cert (hd, &cert2)) { if (gpgsm_certs_identical_p (cert, cert2)) { ksba_cert_release (cert2); goto next_ambiguous; } ksba_cert_release (cert2); } err = gpg_error (GPG_ERR_AMBIGUOUS_NAME); } else if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF) err = 0; if (err) { log_error ("key '%s' not found: %s\n", name, gpg_strerror (err)); goto leave; } } keygrip = gpgsm_get_keygrip_hexstring (cert); if (!keygrip || gpgsm_agent_havekey (ctrl, keygrip)) { /* Note, that the !keygrip case indicates a bad certificate. */ err = gpg_error (GPG_ERR_NO_SECKEY); log_error ("can't export key '%s': %s\n", name, gpg_strerror (err)); goto leave; } image = ksba_cert_get_image (cert, &imagelen); if (!image) { log_error ("ksba_cert_get_image failed\n"); goto leave; } if (ctrl->create_pem) { print_short_info (cert, stream); es_putc ('\n', stream); } if (opt.p12_charset && ctrl->create_pem) { es_fprintf (stream, "The passphrase is %s encoded.\n\n", opt.p12_charset); } ctrl->pem_name = "PKCS12"; err = gpgsm_create_writer (&b64writer, ctrl, stream, &writer); if (err) { log_error ("can't create writer: %s\n", gpg_strerror (err)); goto leave; } prompt = gpgsm_format_keydesc (cert); err = export_p12 (ctrl, image, imagelen, prompt, keygrip, &data, &datalen); xfree (prompt); if (err) goto leave; err = ksba_writer_write (writer, data, datalen); xfree (data); if (err) { log_error ("write failed: %s\n", gpg_strerror (err)); goto leave; } if (ctrl->create_pem) { /* We want one certificate per PEM block */ err = gpgsm_finish_writer (b64writer); if (err) { log_error ("write failed: %s\n", gpg_strerror (err)); goto leave; } gpgsm_destroy_writer (b64writer); b64writer = NULL; } ksba_cert_release (cert); cert = NULL; leave: gpgsm_destroy_writer (b64writer); ksba_cert_release (cert); xfree (desc); keydb_release (hd); }
/* Export all certificates or just those given in NAMES. The output is written to STREAM. */ void gpgsm_export (ctrl_t ctrl, strlist_t names, estream_t stream) { KEYDB_HANDLE hd = NULL; KEYDB_SEARCH_DESC *desc = NULL; int ndesc; Base64Context b64writer = NULL; ksba_writer_t writer; strlist_t sl; ksba_cert_t cert = NULL; int rc=0; int count = 0; int i; duptable_t *dtable; dtable = create_duptable (); if (!dtable) { log_error ("creating duplicates table failed: %s\n", strerror (errno)); goto leave; } hd = keydb_new (0); if (!hd) { log_error ("keydb_new failed\n"); goto leave; } if (!names) ndesc = 1; else { for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) ; } desc = xtrycalloc (ndesc, sizeof *desc); if (!ndesc) { log_error ("allocating memory for export failed: %s\n", gpg_strerror (out_of_core ())); goto leave; } if (!names) desc[0].mode = KEYDB_SEARCH_MODE_FIRST; else { for (ndesc=0, sl=names; sl; sl = sl->next) { rc = classify_user_id (sl->d, desc+ndesc, 0); if (rc) { log_error ("key '%s' not found: %s\n", sl->d, gpg_strerror (rc)); rc = 0; } else ndesc++; } } /* If all specifications are done by fingerprint or keygrip, we switch to ephemeral mode so that _all_ currently available and matching certificates are exported. */ if (names && ndesc) { for (i=0; (i < ndesc && (desc[i].mode == KEYDB_SEARCH_MODE_FPR || desc[i].mode == KEYDB_SEARCH_MODE_FPR20 || desc[i].mode == KEYDB_SEARCH_MODE_FPR16 || desc[i].mode == KEYDB_SEARCH_MODE_KEYGRIP)); i++) ; if (i == ndesc) keydb_set_ephemeral (hd, 1); } while (!(rc = keydb_search (hd, desc, ndesc))) { unsigned char fpr[20]; int exists; if (!names) desc[0].mode = KEYDB_SEARCH_MODE_NEXT; rc = keydb_get_cert (hd, &cert); if (rc) { log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc)); goto leave; } gpgsm_get_fingerprint (cert, 0, fpr, NULL); rc = insert_duptable (dtable, fpr, &exists); if (rc) { log_error ("inserting into duplicates table failed: %s\n", gpg_strerror (rc)); goto leave; } if (!exists && count && !ctrl->create_pem) { log_info ("exporting more than one certificate " "is not possible in binary mode\n"); log_info ("ignoring other certificates\n"); break; } if (!exists) { const unsigned char *image; size_t imagelen; image = ksba_cert_get_image (cert, &imagelen); if (!image) { log_error ("ksba_cert_get_image failed\n"); goto leave; } if (ctrl->create_pem) { if (count) es_putc ('\n', stream); print_short_info (cert, stream); es_putc ('\n', stream); } count++; if (!b64writer) { ctrl->pem_name = "CERTIFICATE"; rc = gpgsm_create_writer (&b64writer, ctrl, stream, &writer); if (rc) { log_error ("can't create writer: %s\n", gpg_strerror (rc)); goto leave; } } rc = ksba_writer_write (writer, image, imagelen); if (rc) { log_error ("write error: %s\n", gpg_strerror (rc)); goto leave; } if (ctrl->create_pem) { /* We want one certificate per PEM block */ rc = gpgsm_finish_writer (b64writer); if (rc) { log_error ("write failed: %s\n", gpg_strerror (rc)); goto leave; } gpgsm_destroy_writer (b64writer); b64writer = NULL; } } ksba_cert_release (cert); cert = NULL; } if (rc && rc != -1) log_error ("keydb_search failed: %s\n", gpg_strerror (rc)); else if (b64writer) { rc = gpgsm_finish_writer (b64writer); if (rc) { log_error ("write failed: %s\n", gpg_strerror (rc)); goto leave; } } leave: gpgsm_destroy_writer (b64writer); ksba_cert_release (cert); xfree (desc); keydb_release (hd); destroy_duptable (dtable); }