[gnutls-devel] [PATCH 5/9] Add functions to export X.509 and OpenPGP private keys from the abstract type

Armin Burgmeier armin at arbur.net
Wed Sep 17 23:33:40 CEST 2014


Signed-off-by: Armin Burgmeier <armin at arbur.net>
---
 lib/gnutls_privkey.c           | 126 +++++++++++++++++++++++++++++++++++++++++
 lib/includes/gnutls/abstract.h |   5 ++
 lib/libgnutls.map              |   2 +
 3 files changed, 133 insertions(+)

diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c
index 647777e..6249155 100644
--- a/lib/gnutls_privkey.c
+++ b/lib/gnutls_privkey.c
@@ -416,6 +416,51 @@ int gnutls_privkey_import_pkcs11_url(gnutls_privkey_t key, const char *url)
 	return ret;
 }
 
+/* This is currently disabled because there is no routine to copy a
+ * PKCS#11 private key. */
+#if 0
+/**
+ * gnutls_privkey_export_pkcs11:
+ * @pkey: The private key
+ * @key: Location for the key to be exported.
+ *
+ * Converts the given abstract private key to a #gnutls_pkcs11_privkey_t
+ * structure. The key must be of type %GNUTLS_PRIVKEY_PKCS11. The key
+ * returned in @key must be deinitialized with
+ * gnutls_pkcs11_privkey_deinit().
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ *
+ * Since: 3.4.0
+ */
+int
+gnutls_privkey_export_pkcs11(gnutls_privkey_t pkey,
+                             gnutls_pkcs11_privkey_t *key)
+{
+	int ret;
+
+	if (pkey->type != GNUTLS_PRIVKEY_PKCS11) {
+		gnutls_assert();
+		return GNUTLS_E_INVALID_REQUEST;
+	}
+
+	ret = gnutls_pkcs11_privkey_init(key);
+	if (ret < 0)
+		return gnutls_assert_val(ret);
+
+	ret = _gnutls_pkcs11_privkey_cpy(*key, pkey->key.openpgp); /* TODO */
+	if (ret < 0) {
+		gnutls_pkcs11_privkey_deinit(*key);
+		*key = NULL;
+
+		return gnutls_assert_val(ret);
+	}
+
+	return 0;
+}
+#endif
+
 #endif				/* ENABLE_PKCS11 */
 
 /**
@@ -563,6 +608,46 @@ gnutls_privkey_import_x509(gnutls_privkey_t pkey,
 }
 
 /**
+ * gnutls_privkey_export_x509:
+ * @pkey: The private key
+ * @key: Location for the key to be exported.
+ *
+ * Converts the given abstract private key to a #gnutls_x509_privkey_t
+ * structure. The key must be of type %GNUTLS_PRIVKEY_X509. The key returned
+ * in @key must be deinitialized with gnutls_x509_privkey_deinit().
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ *
+ * Since: 3.4.0
+ */
+int
+gnutls_privkey_export_x509(gnutls_privkey_t pkey,
+                           gnutls_x509_privkey_t *key)
+{
+	int ret;
+
+	if (pkey->type != GNUTLS_PRIVKEY_X509) {
+		gnutls_assert();
+		return GNUTLS_E_INVALID_REQUEST;
+	}
+
+	ret = gnutls_x509_privkey_init(key);
+	if (ret < 0)
+		return gnutls_assert_val(ret);
+
+	ret = gnutls_x509_privkey_cpy(*key, pkey->key.x509);
+	if (ret < 0) {
+		gnutls_x509_privkey_deinit(*key);
+		*key = NULL;
+
+		return gnutls_assert_val(ret);
+	}
+
+	return 0;
+}
+
+/**
  * gnutls_privkey_generate:
  * @pkey: The private key
  * @algo: is one of the algorithms in #gnutls_pk_algorithm_t.
@@ -736,6 +821,47 @@ int gnutls_privkey_import_openpgp_raw(gnutls_privkey_t pkey,
 
 	return ret;
 }
+
+/**
+ * gnutls_privkey_export_openpgp:
+ * @pkey: The private key
+ * @key: Location for the key to be exported.
+ *
+ * Converts the given abstract private key to a #gnutls_openpgp_privkey_t
+ * structure. The key must be of type %GNUTLS_PRIVKEY_OPENPGP. The key
+ * returned in @key must be deinitialized with
+ * gnutls_openpgp_privkey_deinit().
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ *   negative error value.
+ *
+ * Since: 3.4.0
+ */
+int
+gnutls_privkey_export_openpgp(gnutls_privkey_t pkey,
+                              gnutls_openpgp_privkey_t *key)
+{
+	int ret;
+
+	if (pkey->type != GNUTLS_PRIVKEY_OPENPGP) {
+		gnutls_assert();
+		return GNUTLS_E_INVALID_REQUEST;
+	}
+
+	ret = gnutls_openpgp_privkey_init(key);
+	if (ret < 0)
+		return gnutls_assert_val(ret);
+
+	ret = _gnutls_openpgp_privkey_cpy(*key, pkey->key.openpgp);
+	if (ret < 0) {
+		gnutls_openpgp_privkey_deinit(*key);
+		*key = NULL;
+
+		return gnutls_assert_val(ret);
+	}
+
+	return 0;
+}
 #endif
 
 /**
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index 835fdb7..8ec1321 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -284,6 +284,11 @@ int gnutls_privkey_import_openpgp(gnutls_privkey_t pkey,
 				  gnutls_openpgp_privkey_t key,
 				  unsigned int flags);
 
+int gnutls_privkey_export_x509(gnutls_privkey_t pkey,
+                               gnutls_x509_privkey_t * key);
+int gnutls_privkey_export_openpgp(gnutls_privkey_t pkey,
+                                  gnutls_openpgp_privkey_t * key);
+
 int gnutls_privkey_import_openpgp_raw(gnutls_privkey_t pkey,
 				      const gnutls_datum_t * data,
 				      gnutls_openpgp_crt_fmt_t
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index b1121d0..27b12ba 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -925,6 +925,8 @@ GNUTLS_3_1_0 {
 	gnutls_x509_crl_get_raw_issuer_dn;
 	gnutls_certificate_get_crt_raw;
 	gnutls_privkey_generate;
+	gnutls_privkey_export_x509;
+	gnutls_privkey_export_openpgp;
 	gnutls_fips140_mode_enabled;
 	gnutls_record_check_corked;
 	gnutls_pkcs11_crt_is_known;
-- 
2.1.0




More information about the Gnutls-devel mailing list