* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <ksba.h>
#include "keydb.h"
-#include "exechelp.h"
-#include "i18n.h"
-#include "sysutils.h"
+#include "../common/exechelp.h"
+#include "../common/i18n.h"
+#include "../common/sysutils.h"
#include "minip12.h"
/* A table to store a fingerprint as used in a duplicates table. We
static gpg_error_t export_p12 (ctrl_t ctrl,
const unsigned char *certimg, size_t certimglen,
const char *prompt, const char *keygrip,
+ int rawmode,
void **r_result, size_t *r_resultlen);
#error cannot handle a table larger than 16 bits or smaller than 8 bits
#elif DUPTABLE_BITS > 8
idx <<= (DUPTABLE_BITS - 8);
- idx |= (fpr[1] & ~(~0 << 4));
+ idx |= (fpr[1] & ~(~0U << 4));
#endif
for (t = table[idx]; t; t = t->next)
KEYDB_HANDLE hd = NULL;
KEYDB_SEARCH_DESC *desc = NULL;
int ndesc;
- Base64Context b64writer = NULL;
+ gnupg_ksba_io_t b64writer = NULL;
ksba_writer_t writer;
strlist_t sl;
ksba_cert_t cert = NULL;
goto leave;
}
- hd = keydb_new (0);
+ hd = keydb_new ();
if (!hd)
{
log_error ("keydb_new failed\n");
{
for (ndesc=0, sl=names; sl; sl = sl->next)
{
- rc = classify_user_id (sl->d, desc+ndesc);
+ rc = classify_user_id (sl->d, desc+ndesc, 0);
if (rc)
{
- log_error ("key `%s' not found: %s\n",
+ log_error ("key '%s' not found: %s\n",
sl->d, gpg_strerror (rc));
rc = 0;
}
keydb_set_ephemeral (hd, 1);
}
- while (!(rc = keydb_search (hd, desc, ndesc)))
+ while (!(rc = keydb_search (ctrl, hd, desc, ndesc)))
{
unsigned char fpr[20];
int exists;
if (!b64writer)
{
ctrl->pem_name = "CERTIFICATE";
- rc = gpgsm_create_writer (&b64writer, ctrl, stream, &writer);
+ rc = gnupg_ksba_create_writer
+ (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0)
+ | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 :0)),
+ ctrl->pem_name, stream, &writer);
if (rc)
{
log_error ("can't create writer: %s\n", gpg_strerror (rc));
if (ctrl->create_pem)
{
/* We want one certificate per PEM block */
- rc = gpgsm_finish_writer (b64writer);
+ rc = gnupg_ksba_finish_writer (b64writer);
if (rc)
{
log_error ("write failed: %s\n", gpg_strerror (rc));
goto leave;
}
- gpgsm_destroy_writer (b64writer);
+ gnupg_ksba_destroy_writer (b64writer);
b64writer = NULL;
}
}
log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
else if (b64writer)
{
- rc = gpgsm_finish_writer (b64writer);
+ rc = gnupg_ksba_finish_writer (b64writer);
if (rc)
{
log_error ("write failed: %s\n", gpg_strerror (rc));
}
leave:
- gpgsm_destroy_writer (b64writer);
+ gnupg_ksba_destroy_writer (b64writer);
ksba_cert_release (cert);
xfree (desc);
keydb_release (hd);
}
-/* Export a certificate and its private key. */
+/* Export a certificate and its private key. RAWMODE controls the
+ actual output:
+ 0 - Private key and certifciate in PKCS#12 format
+ 1 - Only unencrypted private key in PKCS#8 format
+ 2 - Only unencrypted private key in PKCS#1 format
+ */
void
-gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream)
+gpgsm_p12_export (ctrl_t ctrl, const char *name, estream_t stream, int rawmode)
{
gpg_error_t err = 0;
KEYDB_HANDLE hd;
KEYDB_SEARCH_DESC *desc = NULL;
- Base64Context b64writer = NULL;
+ gnupg_ksba_io_t b64writer = NULL;
ksba_writer_t writer;
ksba_cert_t cert = NULL;
const unsigned char *image;
void *data;
size_t datalen;
-
- hd = keydb_new (0);
+ hd = keydb_new ();
if (!hd)
{
log_error ("keydb_new failed\n");
goto leave;
}
- err = classify_user_id (name, desc);
+ err = classify_user_id (name, desc, 0);
if (err)
{
- log_error ("key `%s' not found: %s\n",
+ 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);
+ err = keydb_search (ctrl, hd, desc, 1);
if (!err)
{
err = keydb_get_cert (hd, &cert);
}
next_ambiguous:
- err = keydb_search (hd, desc, 1);
+ err = keydb_search (ctrl, hd, desc, 1);
if (!err)
{
ksba_cert_t cert2 = NULL;
err = 0;
if (err)
{
- log_error ("key `%s' not found: %s\n",
+ log_error ("key '%s' not found: %s\n",
name, gpg_strerror (err));
goto leave;
}
{
/* 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));
+ log_error ("can't export key '%s': %s\n", name, gpg_strerror (err));
goto leave;
}
es_putc ('\n', stream);
}
- if (opt.p12_charset && ctrl->create_pem)
+ if (opt.p12_charset && ctrl->create_pem && !rawmode)
{
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 (rawmode == 0)
+ ctrl->pem_name = "PKCS12";
+ else if (rawmode == 1)
+ ctrl->pem_name = "PRIVATE KEY";
+ else
+ ctrl->pem_name = "RSA PRIVATE KEY";
+ err = gnupg_ksba_create_writer
+ (&b64writer, ((ctrl->create_pem? GNUPG_KSBA_IO_PEM : 0)
+ | (ctrl->create_base64? GNUPG_KSBA_IO_BASE64 : 0)),
+ ctrl->pem_name, stream, &writer);
if (err)
{
log_error ("can't create writer: %s\n", gpg_strerror (err));
}
prompt = gpgsm_format_keydesc (cert);
- err = export_p12 (ctrl, image, imagelen, prompt, keygrip, &data, &datalen);
+ err = export_p12 (ctrl, image, imagelen, prompt, keygrip, rawmode,
+ &data, &datalen);
xfree (prompt);
if (err)
goto leave;
if (ctrl->create_pem)
{
/* We want one certificate per PEM block */
- err = gpgsm_finish_writer (b64writer);
+ err = gnupg_ksba_finish_writer (b64writer);
if (err)
{
log_error ("write failed: %s\n", gpg_strerror (err));
goto leave;
}
- gpgsm_destroy_writer (b64writer);
+ gnupg_ksba_destroy_writer (b64writer);
b64writer = NULL;
}
cert = NULL;
leave:
- gpgsm_destroy_writer (b64writer);
+ gnupg_ksba_destroy_writer (b64writer);
ksba_cert_release (cert);
xfree (desc);
keydb_release (hd);
xfree (p);
}
es_putc ('\n', stream);
+
+ p = gpgsm_get_keygrip_hexstring (cert);
+ if (p)
+ {
+ es_fprintf (stream, "Keygrip ..: %s\n", p);
+ xfree (p);
+ }
}
\f
-/* Parse a private key S-expression and retutn a malloced array with
- the RSA paramaters in pkcs#12 order. The caller needs to
+/* Parse a private key S-expression and return a malloced array with
+ the RSA parameters in pkcs#12 order. The caller needs to
deep-release this array. */
static gcry_mpi_t *
sexp_to_kparms (gcry_sexp_t sexp)
static gpg_error_t
export_p12 (ctrl_t ctrl, const unsigned char *certimg, size_t certimglen,
- const char *prompt, const char *keygrip,
+ const char *prompt, const char *keygrip, int rawmode,
void **r_result, size_t *r_resultlen)
{
gpg_error_t err = 0;
goto leave;
}
- err = gpgsm_agent_ask_passphrase
- (ctrl,
- i18n_utf8 ("Please enter the passphrase to protect the "
- "new PKCS#12 object."),
- 1, &passphrase);
- if (err)
- goto leave;
+ if (rawmode)
+ {
+ /* Export in raw mode, that is only the pkcs#1/#8 private key. */
+ result = p12_raw_build (kparms, rawmode, &resultlen);
+ if (!result)
+ err = gpg_error (GPG_ERR_GENERAL);
+ }
+ else
+ {
+ err = gpgsm_agent_ask_passphrase
+ (ctrl,
+ i18n_utf8 ("Please enter the passphrase to protect the "
+ "new PKCS#12 object."),
+ 1, &passphrase);
+ if (err)
+ goto leave;
- result = p12_build (kparms, certimg, certimglen, passphrase,
- opt.p12_charset, &resultlen);
- xfree (passphrase);
- passphrase = NULL;
- if (!result)
- err = gpg_error (GPG_ERR_GENERAL);
+ result = p12_build (kparms, certimg, certimglen, passphrase,
+ opt.p12_charset, &resultlen);
+ xfree (passphrase);
+ passphrase = NULL;
+ if (!result)
+ err = gpg_error (GPG_ERR_GENERAL);
+ }
leave:
xfree (key);