summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2012-10-07 10:33:55 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2012-10-07 10:37:44 +0200
commit531bac41a0ee19158f0722937d0c9efafbc3bb14 (patch)
treec768f0c17ae335479b628d0c644742da63fb0f44
parent5afff3b04637ee2d0fa29bf783428e7fc43ea722 (diff)
downloadgnutls-531bac41a0ee19158f0722937d0c9efafbc3bb14.tar.gz
Added functions to export structures in an allocated buffer.
-rw-r--r--NEWS15
-rw-r--r--doc/cha-cert-auth2.texi4
-rw-r--r--doc/cha-tokens.texi2
-rw-r--r--doc/invoke-gnutls-cli.texi19
-rw-r--r--lib/gnutls_dh_primes.c116
-rw-r--r--lib/gnutls_pubkey.c67
-rw-r--r--lib/includes/gnutls/abstract.h4
-rw-r--r--lib/includes/gnutls/gnutls.h.in3
-rw-r--r--lib/includes/gnutls/openpgp.h8
-rw-r--r--lib/includes/gnutls/pkcs11.h3
-rw-r--r--lib/includes/gnutls/pkcs12.h3
-rw-r--r--lib/includes/gnutls/x509.h23
-rw-r--r--lib/libgnutls.map13
-rw-r--r--lib/openpgp/openpgp_int.h6
-rw-r--r--lib/openpgp/pgp.c55
-rw-r--r--lib/openpgp/privkey.c25
-rw-r--r--lib/pkcs11.c32
-rw-r--r--lib/x509/common.c117
-rw-r--r--lib/x509/common.h14
-rw-r--r--lib/x509/crl.c59
-rw-r--r--lib/x509/crq.c32
-rw-r--r--lib/x509/dn.c32
-rw-r--r--lib/x509/pkcs12.c31
-rw-r--r--lib/x509/pkcs7.c26
-rw-r--r--lib/x509/privkey.c59
-rw-r--r--lib/x509/privkey_pkcs8.c89
-rw-r--r--lib/x509/x509.c30
-rw-r--r--libdane/dane.c18
28 files changed, 719 insertions, 186 deletions
diff --git a/NEWS b/NEWS
index caafbbd6c5..a7f8d3f8a0 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,8 @@ certificate status extension in verification.
** libgnutls: Fixed the receipt of session tickets during session resumption.
Reported by danblack at http://savannah.gnu.org/support/?108146
+** libgnutls: Added functions to export structures in an allocated buffer.
+
** libgnutls: Added gnutls_ocsp_resp_check_crt() to check whether the OCSP
response corresponds to the given certificate.
@@ -25,6 +27,19 @@ gnutls_certificate_set_ocsp_status_request_file: Added
gnutls_ocsp_status_request_enable_client: Added
gnutls_ocsp_status_request_get: Added
gnutls_ocsp_resp_check_crt: Added
+gnutls_dh_params_export2_pkcs3: Added
+gnutls_pubkey_export2: Added
+gnutls_x509_crt_export2: Added
+gnutls_x509_dn_export2: Added
+gnutls_x509_crl_export2: Added
+gnutls_pkcs7_export2: Added
+gnutls_x509_privkey_export2: Added
+gnutls_x509_privkey_export2_pkcs8: Added
+gnutls_x509_crq_export2: Added
+gnutls_openpgp_crt_export2: Added
+gnutls_openpgp_privkey_export2: Added
+gnutls_pkcs11_obj_export2: Added
+gnutls_pkcs12_export2: Added
dane_query_init: Added
dane_query_deinit: Added
dane_query_resolve_tlsa: Added
diff --git a/doc/cha-cert-auth2.texi b/doc/cha-cert-auth2.texi
index e375050a3c..6ce6d7a3b5 100644
--- a/doc/cha-cert-auth2.texi
+++ b/doc/cha-cert-auth2.texi
@@ -99,7 +99,7 @@ Optional CRL structure extensions.
The basic CRL structure functions follow.
-@showfuncC{gnutls_x509_crl_init,gnutls_x509_crl_import,gnutls_x509_crl_export}
+@showfuncD{gnutls_x509_crl_init,gnutls_x509_crl_import,gnutls_x509_crl_export,gnutls_x509_crl_export}
@subheading Reading a CRL
@@ -322,7 +322,7 @@ enumeration. Note however, that GnuTLS only supports the PKCS #5 PBES2
encryption scheme. Keys encrypted with the obsolete PBES1 scheme cannot
be decrypted.
-@showfuncB{gnutls_x509_privkey_import_pkcs8,gnutls_x509_privkey_export_pkcs8}
+@showfuncC{gnutls_x509_privkey_import_pkcs8,gnutls_x509_privkey_export_pkcs8,gnutls_x509_privkey_export2_pkcs8}
@showenumdesc{gnutls_pkcs_encrypt_flags_t,Encryption flags}
diff --git a/doc/cha-tokens.texi b/doc/cha-tokens.texi
index 936cf6dd3c..b290ff52c7 100644
--- a/doc/cha-tokens.texi
+++ b/doc/cha-tokens.texi
@@ -71,7 +71,7 @@ sequence.
@showfuncC{gnutls_pubkey_import_url,gnutls_pubkey_import_privkey,gnutls_pubkey_import}
-@showfuncdesc{gnutls_pubkey_export}
+@showfuncB{gnutls_pubkey_export,gnutls_pubkey_export2}
An important function is @funcref{gnutls_pubkey_import_url} which will import
public keys from URLs that identify objects stored in tokens (see @ref{Smart cards and HSMs} and @ref{Trusted Platform Module}).
diff --git a/doc/invoke-gnutls-cli.texi b/doc/invoke-gnutls-cli.texi
index 91f597097b..ade332a005 100644
--- a/doc/invoke-gnutls-cli.texi
+++ b/doc/invoke-gnutls-cli.texi
@@ -7,7 +7,7 @@
#
# DO NOT EDIT THIS FILE (invoke-gnutls-cli.texi)
#
-# It has been AutoGen-ed October 6, 2012 at 03:27:13 AM by AutoGen 5.16
+# It has been AutoGen-ed October 7, 2012 at 10:36:28 AM by AutoGen 5.16
# From the definitions ../src/cli-args.def
# and the template file agtexi-cmd.tpl
@end ignore
@@ -47,6 +47,9 @@ USAGE: gnutls-cli [ -<flag> [<val>] | --<name>[@{=| @}<val>] ]... [hostname]
- disabled as --no-tofu
--dane Enable DANE certificate verification (DNSSEC)
- disabled as --no-dane
+ --ca-verification Disable CA certificate verification
+ - disabled as --no-ca-verification
+ - enabled by default
--ocsp Enable OCSP certificate verification
- disabled as --no-ocsp
-r, --resume Establish a session and resume
@@ -133,6 +136,20 @@ This is the ``enable dane certificate verification (dnssec)'' option.
This option will, in addition to certificate authentication using
the trusted CAs, verify the server certificates using on the DANE information
available via DNSSEC.
+@anchor{gnutls-cli ca-verification}
+@subheading ca-verification option
+@cindex gnutls-cli-ca-verification
+
+This is the ``disable ca certificate verification'' option.
+
+@noindent
+This option has some usage constraints. It:
+@itemize @bullet
+@item
+is enabled by default.
+@end itemize
+
+This option will disable CA certificate verification. It is to be used with the --dane or --tofu options.
@anchor{gnutls-cli ocsp}
@subheading ocsp option
@cindex gnutls-cli-ocsp
diff --git a/lib/gnutls_dh_primes.c b/lib/gnutls_dh_primes.c
index caa9fe893a..4eb16388ef 100644
--- a/lib/gnutls_dh_primes.c
+++ b/lib/gnutls_dh_primes.c
@@ -27,6 +27,7 @@
#include <gnutls_global.h>
#include <gnutls_dh.h>
#include <gnutls_pk.h>
+#include <x509/common.h>
#include <gnutls/crypto.h>
#include "x509/x509_int.h"
#include "debug.h"
@@ -341,8 +342,56 @@ gnutls_dh_params_export_pkcs3 (gnutls_dh_params_t params,
unsigned char *params_data,
size_t * params_data_size)
{
+gnutls_datum_t out;
+int ret;
+
+ ret = gnutls_dh_params_export2_pkcs3( params, format, &out);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ if (*params_data_size < (unsigned) out.size+1)
+ {
+ gnutls_assert ();
+ gnutls_free (out.data);
+ *params_data_size = out.size + 1;
+ return GNUTLS_E_SHORT_MEMORY_BUFFER;
+ }
+
+ *params_data_size = out.size;
+ if (params_data)
+ {
+ memcpy( params_data, out.data, out.size);
+ params_data[out.size] = 0;
+ }
+
+ gnutls_free(out.data);
+
+ return 0;
+}
+
+/**
+ * gnutls_dh_params_export2_pkcs3:
+ * @params: Holds the DH parameters
+ * @format: the format of output params. One of PEM or DER.
+ * @out: will contain a PKCS3 DHParams structure PEM or DER encoded
+ *
+ * This function will export the given dh parameters to a PKCS3
+ * DHParams structure. This is the format generated by "openssl dhparam" tool.
+ * The data in @out will be allocated using gnutls_malloc().
+ *
+ * If the structure is PEM encoded, it will have a header
+ * of "BEGIN DH PARAMETERS".
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
+ * otherwise a negative error code is returned.
+ **/
+int
+gnutls_dh_params_export2_pkcs3 (gnutls_dh_params_t params,
+ gnutls_x509_crt_fmt_t format,
+ gnutls_datum_t * out)
+{
ASN1_TYPE c2;
- int result, _params_data_size;
+ int result;
size_t g_size, p_size;
uint8_t *p_data, *g_data;
uint8_t *all_data;
@@ -395,6 +444,7 @@ gnutls_dh_params_export_pkcs3 (gnutls_dh_params_t params,
if (result < 0)
{
gnutls_assert ();
+ gnutls_free (all_data);
asn1_delete_structure (&c2);
return _gnutls_asn2err (result);
}
@@ -415,78 +465,34 @@ gnutls_dh_params_export_pkcs3 (gnutls_dh_params_t params,
if (format == GNUTLS_X509_FMT_DER)
{
- if (params_data == NULL)
- *params_data_size = 0;
+ result = _gnutls_x509_der_encode(c2, "", out, 0);
- _params_data_size = *params_data_size;
- result =
- asn1_der_coding (c2, "", params_data, &_params_data_size, NULL);
- *params_data_size = _params_data_size;
asn1_delete_structure (&c2);
- if (result != ASN1_SUCCESS)
- {
- gnutls_assert ();
- if (result == ASN1_MEM_ERROR)
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
-
- return _gnutls_asn2err (result);
- }
+ if (result < 0)
+ return gnutls_assert_val (result);
}
else
{ /* PEM */
- uint8_t *tmp;
- gnutls_datum_t out;
- int len;
+ gnutls_datum_t t;
- len = 0;
- asn1_der_coding (c2, "", NULL, &len, NULL);
-
- tmp = gnutls_malloc (len);
- if (tmp == NULL)
- {
- gnutls_assert ();
- asn1_delete_structure (&c2);
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- if ((result =
- asn1_der_coding (c2, "", tmp, &len, NULL)) != ASN1_SUCCESS)
- {
- gnutls_assert ();
- gnutls_free (tmp);
- asn1_delete_structure (&c2);
- return _gnutls_asn2err (result);
- }
+ result = _gnutls_x509_der_encode(c2, "", &t, 0);
asn1_delete_structure (&c2);
- result = _gnutls_fbase64_encode ("DH PARAMETERS", tmp, len, &out);
+ if (result < 0)
+ return gnutls_assert_val (result);
+
+ result = _gnutls_fbase64_encode("DH PARAMETERS", t.data, t.size, out);
- gnutls_free (tmp);
+ gnutls_free (t.data);
if (result < 0)
{
gnutls_assert ();
return result;
}
-
- if ((unsigned) out.size > *params_data_size)
- {
- gnutls_assert ();
- gnutls_free (out.data);
- *params_data_size = out.size + 1;
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
- }
-
- *params_data_size = out.size;
-
- if (params_data)
- memcpy (params_data, out.data, out.size);
-
- gnutls_free (out.data);
-
}
return 0;
diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c
index c145562826..21bea55ed9 100644
--- a/lib/gnutls_pubkey.c
+++ b/lib/gnutls_pubkey.c
@@ -540,7 +540,74 @@ cleanup:
asn1_delete_structure (&spk);
return result;
+}
+
+/**
+ * gnutls_pubkey_export2:
+ * @key: Holds the certificate
+ * @format: the format of output params. One of PEM or DER.
+ * @out: will contain a certificate PEM or DER encoded
+ *
+ * This function will export the public key to DER or PEM format.
+ * The contents of the exported data is the SubjectPublicKeyInfo
+ * X.509 structure.
+ *
+ * The output buffer will be allocated using gnutls_malloc().
+ *
+ * If the structure is PEM encoded, it will have a header
+ * of "BEGIN CERTIFICATE".
+ *
+ * Returns: In case of failure a negative error code will be
+ * returned, and 0 on success.
+ *
+ * Since: 3.1.3
+ **/
+int
+gnutls_pubkey_export2 (gnutls_pubkey_t key,
+ gnutls_x509_crt_fmt_t format,
+ gnutls_datum_t * out)
+{
+ int result;
+ ASN1_TYPE spk = ASN1_TYPE_EMPTY;
+
+ if (key == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ if ((result = asn1_create_element
+ (_gnutls_get_pkix (), "PKIX1.SubjectPublicKeyInfo", &spk))
+ != ASN1_SUCCESS)
+ {
+ gnutls_assert ();
+ return _gnutls_asn2err (result);
+ }
+ result =
+ _gnutls_x509_encode_and_copy_PKI_params (spk, "",
+ key->pk_algorithm,
+ &key->params);
+ if (result < 0)
+ {
+ gnutls_assert ();
+ goto cleanup;
+ }
+
+ result = _gnutls_x509_export_int_named2 (spk, "",
+ format, PK_PEM_HEADER, out);
+ if (result < 0)
+ {
+ gnutls_assert ();
+ goto cleanup;
+ }
+
+ result = 0;
+
+cleanup:
+ asn1_delete_structure (&spk);
+
+ return result;
}
/**
diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h
index 245af8795e..b96d6305e8 100644
--- a/lib/includes/gnutls/abstract.h
+++ b/lib/includes/gnutls/abstract.h
@@ -108,6 +108,10 @@ int gnutls_pubkey_export (gnutls_pubkey_t key,
gnutls_x509_crt_fmt_t format,
void *output_data, size_t * output_data_size);
+int gnutls_pubkey_export2 (gnutls_pubkey_t key,
+ gnutls_x509_crt_fmt_t format,
+ gnutls_datum_t * out);
+
int gnutls_pubkey_get_key_id (gnutls_pubkey_t key, unsigned int flags,
unsigned char *output_data,
size_t * output_data_size);
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index e7de530f2a..51e594e65c 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -1291,6 +1291,9 @@ gnutls_ecc_curve_t gnutls_ecc_curve_get(gnutls_session_t session);
gnutls_x509_crt_fmt_t format,
unsigned char *params_data,
size_t * params_data_size);
+ int gnutls_dh_params_export2_pkcs3 (gnutls_dh_params_t params,
+ gnutls_x509_crt_fmt_t format,
+ gnutls_datum_t *out);
int gnutls_dh_params_export_raw (gnutls_dh_params_t params,
gnutls_datum_t * prime,
gnutls_datum_t * generator,
diff --git a/lib/includes/gnutls/openpgp.h b/lib/includes/gnutls/openpgp.h
index 1d4e0cd591..bed810168b 100644
--- a/lib/includes/gnutls/openpgp.h
+++ b/lib/includes/gnutls/openpgp.h
@@ -68,6 +68,9 @@ extern "C"
gnutls_openpgp_crt_fmt_t format,
void *output_data,
size_t * output_data_size);
+ int gnutls_openpgp_crt_export2 (gnutls_openpgp_crt_t key,
+ gnutls_openpgp_crt_fmt_t format,
+ gnutls_datum_t * out);
int gnutls_openpgp_crt_print (gnutls_openpgp_crt_t cert,
gnutls_certificate_print_formats_t format,
@@ -241,6 +244,11 @@ extern "C"
unsigned int flags,
void *output_data,
size_t * output_data_size);
+ int gnutls_openpgp_privkey_export2 (gnutls_openpgp_privkey_t key,
+ gnutls_openpgp_crt_fmt_t format,
+ const char *password,
+ unsigned int flags,
+ gnutls_datum_t * out);
int
gnutls_openpgp_privkey_set_preferred_key_id (gnutls_openpgp_privkey_t key,
diff --git a/lib/includes/gnutls/pkcs11.h b/lib/includes/gnutls/pkcs11.h
index 84af6f2ba1..0e486cea06 100644
--- a/lib/includes/gnutls/pkcs11.h
+++ b/lib/includes/gnutls/pkcs11.h
@@ -120,7 +120,8 @@ void gnutls_pkcs11_obj_deinit (gnutls_pkcs11_obj_t obj);
int gnutls_pkcs11_obj_export (gnutls_pkcs11_obj_t obj,
void *output_data, size_t * output_data_size);
-
+int gnutls_pkcs11_obj_export2 (gnutls_pkcs11_obj_t obj,
+ gnutls_datum_t *out);
int gnutls_pkcs11_copy_x509_crt (const char *token_url, gnutls_x509_crt_t crt,
const char *label, unsigned int flags
diff --git a/lib/includes/gnutls/pkcs12.h b/lib/includes/gnutls/pkcs12.h
index 09b75e935e..02f6351c17 100644
--- a/lib/includes/gnutls/pkcs12.h
+++ b/lib/includes/gnutls/pkcs12.h
@@ -46,6 +46,9 @@ extern "C"
int gnutls_pkcs12_export (gnutls_pkcs12_t pkcs12,
gnutls_x509_crt_fmt_t format,
void *output_data, size_t * output_data_size);
+ int gnutls_pkcs12_export2 (gnutls_pkcs12_t pkcs12,
+ gnutls_x509_crt_fmt_t format,
+ gnutls_datum_t *out);
int gnutls_pkcs12_get_bag (gnutls_pkcs12_t pkcs12,
int indx, gnutls_pkcs12_bag_t bag);
diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h
index 94e01a4729..7845f22ed0 100644
--- a/lib/includes/gnutls/x509.h
+++ b/lib/includes/gnutls/x509.h
@@ -123,6 +123,9 @@ extern "C"
int gnutls_x509_crt_export (gnutls_x509_crt_t cert,
gnutls_x509_crt_fmt_t format,
void *output_data, size_t * output_data_size);
+ int gnutls_x509_crt_export2 (gnutls_x509_crt_t cert,
+ gnutls_x509_crt_fmt_t format,
+ gnutls_datum_t* out);
int gnutls_x509_crt_get_private_key_usage_period (gnutls_x509_crt_t cert, time_t* activation, time_t* expiration,
unsigned int *critical);
@@ -463,6 +466,9 @@ extern "C"
int gnutls_x509_dn_export (gnutls_x509_dn_t dn,
gnutls_x509_crt_fmt_t format, void *output_data,
size_t * output_data_size);
+ int gnutls_x509_dn_export2 (gnutls_x509_dn_t dn,
+ gnutls_x509_crt_fmt_t format,
+ gnutls_datum_t * out);
void gnutls_x509_dn_deinit (gnutls_x509_dn_t dn);
@@ -478,6 +484,9 @@ extern "C"
int gnutls_x509_crl_export (gnutls_x509_crl_t crl,
gnutls_x509_crt_fmt_t format,
void *output_data, size_t * output_data_size);
+ int gnutls_x509_crl_export2 (gnutls_x509_crl_t crl,
+ gnutls_x509_crt_fmt_t format,
+ gnutls_datum_t *out);
int
gnutls_x509_crl_get_raw_issuer_dn (gnutls_x509_crl_t crl,
@@ -580,6 +589,9 @@ extern "C"
int gnutls_pkcs7_export (gnutls_pkcs7_t pkcs7,
gnutls_x509_crt_fmt_t format,
void *output_data, size_t * output_data_size);
+ int gnutls_pkcs7_export2 (gnutls_pkcs7_t pkcs7,
+ gnutls_x509_crt_fmt_t format,
+ gnutls_datum_t *out);
int gnutls_pkcs7_get_crt_count (gnutls_pkcs7_t pkcs7);
int gnutls_pkcs7_get_crt_raw (gnutls_pkcs7_t pkcs7, int indx,
@@ -803,12 +815,20 @@ extern "C"
gnutls_x509_crt_fmt_t format,
void *output_data,
size_t * output_data_size);
+ int gnutls_x509_privkey_export2 (gnutls_x509_privkey_t key,
+ gnutls_x509_crt_fmt_t format,
+ gnutls_datum_t * out);
int gnutls_x509_privkey_export_pkcs8 (gnutls_x509_privkey_t key,
gnutls_x509_crt_fmt_t format,
const char *password,
unsigned int flags,
void *output_data,
size_t * output_data_size);
+ int gnutls_x509_privkey_export2_pkcs8 (gnutls_x509_privkey_t key,
+ gnutls_x509_crt_fmt_t format,
+ const char *password,
+ unsigned int flags,
+ gnutls_datum_t * out);
int gnutls_x509_privkey_export_rsa_raw2 (gnutls_x509_privkey_t key,
gnutls_datum_t * m,
gnutls_datum_t * e,
@@ -887,6 +907,9 @@ extern "C"
int gnutls_x509_crq_export (gnutls_x509_crq_t crq,
gnutls_x509_crt_fmt_t format,
void *output_data, size_t * output_data_size);
+ int gnutls_x509_crq_export2 (gnutls_x509_crq_t crq,
+ gnutls_x509_crt_fmt_t format,
+ gnutls_datum_t * out);
int gnutls_x509_crt_set_crq (gnutls_x509_crt_t crt, gnutls_x509_crq_t crq);
int gnutls_x509_crt_set_crq_extensions (gnutls_x509_crt_t crt,
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 9cfe3d3177..578e159f17 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -841,6 +841,19 @@ GNUTLS_3_1_0 {
gnutls_certificate_set_ocsp_status_request_file;
gnutls_ocsp_status_request_enable_client;
gnutls_ocsp_status_request_get;
+ gnutls_dh_params_export2_pkcs3;
+ gnutls_pubkey_export2;
+ gnutls_x509_crt_export2;
+ gnutls_x509_dn_export2;
+ gnutls_x509_crl_export2;
+ gnutls_pkcs7_export2;
+ gnutls_x509_privkey_export2;
+ gnutls_x509_privkey_export2_pkcs8;
+ gnutls_x509_crq_export2;
+ gnutls_openpgp_crt_export2;
+ gnutls_openpgp_privkey_export2;
+ gnutls_pkcs11_obj_export2;
+ gnutls_pkcs12_export2;
} GNUTLS_3_0_0;
GNUTLS_PRIVATE {
diff --git a/lib/openpgp/openpgp_int.h b/lib/openpgp/openpgp_int.h
index 9f6b3a5212..a144793cf8 100644
--- a/lib/openpgp/openpgp_int.h
+++ b/lib/openpgp/openpgp_int.h
@@ -63,7 +63,11 @@ int _gnutls_map_cdk_rc (int rc);
int _gnutls_openpgp_export (cdk_kbnode_t node,
gnutls_openpgp_crt_fmt_t format,
void *output_data, size_t * output_data_size,
- int private);
+ int priv);
+
+int _gnutls_openpgp_export2 (cdk_kbnode_t node,
+ gnutls_openpgp_crt_fmt_t format,
+ gnutls_datum_t* out, int priv);
cdk_packet_t _gnutls_get_valid_subkey (cdk_kbnode_t knode, int key_type);
diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c
index dc6cadcad1..78ef7882b8 100644
--- a/lib/openpgp/pgp.c
+++ b/lib/openpgp/pgp.c
@@ -119,13 +119,39 @@ gnutls_openpgp_crt_import (gnutls_openpgp_crt_t key,
return 0;
}
+int _gnutls_openpgp_export2 (cdk_kbnode_t node,
+ gnutls_openpgp_crt_fmt_t format,
+ gnutls_datum_t* out, int priv)
+{
+int ret;
+size_t size = 0;
+
+ ret = _gnutls_openpgp_export(node, format, NULL, &size, priv);
+ if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
+ {
+ out->data = gnutls_malloc(size);
+
+ ret = _gnutls_openpgp_export(node, format, out->data, &size, priv);
+ if (ret < 0)
+ {
+ gnutls_free(out->data);
+ return gnutls_assert_val(ret);
+ }
+ out->size = size;
+ }
+ else if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ return 0;
+}
+
/* internal version of export
*/
int
_gnutls_openpgp_export (cdk_kbnode_t node,
gnutls_openpgp_crt_fmt_t format,
void *output_data,
- size_t * output_data_size, int private)
+ size_t * output_data_size, int priv)
{
size_t input_data_size = *output_data_size;
size_t calc_size;
@@ -141,7 +167,7 @@ _gnutls_openpgp_export (cdk_kbnode_t node,
/* If the caller uses output_data == NULL then return what he expects.
*/
- if (!output_data)
+ if (!output_data && format != GNUTLS_OPENPGP_FMT_BASE64)
{
gnutls_assert ();
return GNUTLS_E_SHORT_MEMORY_BUFFER;
@@ -156,7 +182,7 @@ _gnutls_openpgp_export (cdk_kbnode_t node,
buffer is large enough. */
rc = cdk_armor_encode_buffer (in, *output_data_size,
NULL, 0, &calc_size,
- private ? CDK_ARMOR_SECKEY :
+ priv ? CDK_ARMOR_SECKEY :
CDK_ARMOR_PUBKEY);
if (rc || calc_size > input_data_size)
{
@@ -168,7 +194,7 @@ _gnutls_openpgp_export (cdk_kbnode_t node,
rc = cdk_armor_encode_buffer (in, *output_data_size,
output_data, input_data_size, &calc_size,
- private ? CDK_ARMOR_SECKEY :
+ priv ? CDK_ARMOR_SECKEY :
CDK_ARMOR_PUBKEY);
gnutls_free (in);
*output_data_size = calc_size;
@@ -189,7 +215,7 @@ _gnutls_openpgp_export (cdk_kbnode_t node,
* gnutls_openpgp_crt_export:
* @key: Holds the key.
* @format: One of gnutls_openpgp_crt_fmt_t elements.
- * @output_data: will contain the key base64 encoded or raw
+ * @output_data: will contain the raw or base64 encoded key
* @output_data_size: holds the size of output_data (and will
* be replaced by the actual size of parameters)
*
@@ -209,6 +235,25 @@ gnutls_openpgp_crt_export (gnutls_openpgp_crt_t key,
}
/**
+ * gnutls_openpgp_crt_export2:
+ * @key: Holds the key.
+ * @format: One of gnutls_openpgp_crt_fmt_t elements.
+ * @out: will contain the raw or base64 encoded key
+ *
+ * This function will convert the given key to RAW or Base64 format.
+ * The output buffer is allocated using gnutls_malloc().
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
+ **/
+int
+gnutls_openpgp_crt_export2 (gnutls_openpgp_crt_t key,
+ gnutls_openpgp_crt_fmt_t format,
+ gnutls_datum_t *out)
+{
+ return _gnutls_openpgp_export2 (key->knode, format, out, 0);
+}
+
+/**
* gnutls_openpgp_crt_get_fingerprint:
* @key: the raw data that contains the OpenPGP public key.
* @fpr: the buffer to save the fingerprint, must hold at least 20 bytes.
diff --git a/lib/openpgp/privkey.c b/lib/openpgp/privkey.c
index bd04b21969..461aa9d0e6 100644
--- a/lib/openpgp/privkey.c
+++ b/lib/openpgp/privkey.c
@@ -230,6 +230,31 @@ gnutls_openpgp_privkey_export (gnutls_openpgp_privkey_t key,
output_data_size, 1);
}
+/**
+ * gnutls_openpgp_privkey_export2:
+ * @key: Holds the key.
+ * @format: One of gnutls_openpgp_crt_fmt_t elements.
+ * @password: the password that will be used to encrypt the key. (unused for now)
+ * @flags: (0) for future compatibility
+ * @out: will contain the raw or based64 encoded key
+ *
+ * This function will convert the given key to RAW or Base64 format.
+ * The output buffer is allocated using gnutls_malloc().
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
+ *
+ * Since: 3.1
+ **/
+int
+gnutls_openpgp_privkey_export2 (gnutls_openpgp_privkey_t key,
+ gnutls_openpgp_crt_fmt_t format,
+ const char *password, unsigned int flags,
+ gnutls_datum_t *out)
+{
+ /* FIXME for now we do not export encrypted keys */
+ return _gnutls_openpgp_export2 (key->knode, format, out, 1);
+}
+
/**
* gnutls_openpgp_privkey_get_pk_algorithm:
diff --git a/lib/pkcs11.c b/lib/pkcs11.c
index 48dcd035ed..0357c7ad5d 100644
--- a/lib/pkcs11.c
+++ b/lib/pkcs11.c
@@ -832,6 +832,38 @@ gnutls_pkcs11_obj_export (gnutls_pkcs11_obj_t obj,
return 0;
}
+/**
+ * gnutls_pkcs11_obj_export2:
+ * @obj: Holds the object
+ * @out: will contain a certificate PEM or DER encoded
+ *
+ * This function will export the PKCS11 object data. It is normal for
+ * data to be inaccesible and in that case %GNUTLS_E_INVALID_REQUEST
+ * will be returned.
+ *
+ * The output buffer is allocated using gnutls_malloc().
+ *
+ * If the structure is PEM encoded, it will have a header
+ * of "BEGIN CERTIFICATE".
+ *
+ * Returns: In case of failure a negative error code will be
+ * returned, and %GNUTLS_E_SUCCESS (0) on success.
+ *
+ * Since: 3.1
+ **/
+int
+gnutls_pkcs11_obj_export2 (gnutls_pkcs11_obj_t obj,
+ gnutls_datum_t *out)
+{
+ if (obj == NULL || obj->raw.data == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ return _gnutls_set_datum(out, obj->raw.data, obj->raw.size);
+}
+
int
pkcs11_find_object (struct pkcs11_session_info* sinfo,
struct pin_info_st * pin_info,
diff --git a/lib/x509/common.c b/lib/x509/common.c
index fd4b815f38..d577f8ae4a 100644
--- a/lib/x509/common.c
+++ b/lib/x509/common.c
@@ -776,91 +776,78 @@ _gnutls_x509_export_int_named (ASN1_TYPE asn1_data, const char *name,
unsigned char *output_data,
size_t * output_data_size)
{
- int result, len;
+ int ret;
+ gnutls_datum_t out;
+ size_t size;
- if (format == GNUTLS_X509_FMT_DER)
+ ret = _gnutls_x509_export_int_named2 (asn1_data, name,
+ format, pem_header, &out);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ if (format == GNUTLS_X509_FMT_PEM)
+ size = out.size+1;
+ else
+ size = out.size;
+
+ if (*output_data_size < size)
{
+ *output_data_size = size;
+ ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
+ goto cleanup;
+ }
- if (output_data == NULL)
- *output_data_size = 0;
+ *output_data_size = (size_t)out.size;
+ if (output_data)
+ {
+ memcpy (output_data, out.data, (size_t)out.size);
+ if (format == GNUTLS_X509_FMT_PEM)
+ output_data[out.size] = 0;
+ }
- len = *output_data_size;
+ ret = 0;
- if ((result =
- asn1_der_coding (asn1_data, name, output_data, &len,
- NULL)) != ASN1_SUCCESS)
- {
- *output_data_size = (size_t)len;
- if (result == ASN1_MEM_ERROR)
- {
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
- }
- gnutls_assert ();
- return _gnutls_asn2err (result);
- }
+cleanup:
+ gnutls_free (out.data);
- *output_data_size = (size_t)len;
+ return ret;
+}
+/* A generic export function. Will export the given ASN.1 encoded data
+ * to PEM or DER raw data.
+ */
+int
+_gnutls_x509_export_int_named2 (ASN1_TYPE asn1_data, const char *name,
+ gnutls_x509_crt_fmt_t format,
+ const char *pem_header,
+ gnutls_datum_t *out)
+{
+ int ret;
+
+ if (format == GNUTLS_X509_FMT_DER)
+ {
+ ret = _gnutls_x509_der_encode(asn1_data, name, out, 0);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
}
else
{ /* PEM */
- gnutls_datum_t out;
gnutls_datum_t tmp;
- result = _gnutls_x509_der_encode (asn1_data, name, &tmp, 0);
- if (result < 0)
- {
- gnutls_assert ();
- return result;
- }
-
- result = _gnutls_fbase64_encode (pem_header, tmp.data, tmp.size, &out);
+ ret = _gnutls_x509_der_encode (asn1_data, name, &tmp, 0);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ ret = _gnutls_fbase64_encode (pem_header, tmp.data, tmp.size, out);
_gnutls_free_datum (&tmp);
- if (result < 0)
- {
- gnutls_assert ();
- return result;
- }
-
- if ((size_t) out.size > *output_data_size)
- {
- gnutls_assert ();
- gnutls_free (out.data);
- *output_data_size = (size_t)out.size+1;
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
- }
-
- *output_data_size = (size_t)out.size;
-
- if (output_data)
- {
- memcpy (output_data, out.data, (size_t)out.size);
-
- /* do not include the null character into output size.
- */
- *output_data_size = (size_t)result - 1;
- }
- gnutls_free (out.data);
-
+ if (ret < 0)
+ return gnutls_assert_val(ret);
}
return 0;
}
-int
-_gnutls_x509_export_int (ASN1_TYPE asn1_data,
- gnutls_x509_crt_fmt_t format,
- const char *pem_header,
- unsigned char *output_data,
- size_t * output_data_size)
-{
- return _gnutls_x509_export_int_named (asn1_data, "",
- format, pem_header, output_data,
- output_data_size);
-}
-
/* Decodes an octet string. Leave string_type null for a normal
* octet string. Otherwise put something like BMPString, PrintableString
* etc.
diff --git a/lib/x509/common.h b/lib/x509/common.h
index e48e0f88e5..1ee919435b 100644
--- a/lib/x509/common.h
+++ b/lib/x509/common.h
@@ -95,11 +95,8 @@ int _gnutls_x509_der_encode_and_copy (ASN1_TYPE src, const char *src_name,
int _gnutls_x509_der_encode (ASN1_TYPE src, const char *src_name,
gnutls_datum_t * res, int str);
-int _gnutls_x509_export_int (ASN1_TYPE asn1_data,
- gnutls_x509_crt_fmt_t format,
- const char *pem_header,
- unsigned char *output_data,
- size_t * output_data_size);
+#define _gnutls_x509_export_int(asn1, format, header, out, out_size) \
+ _gnutls_x509_export_int_named(asn1, "", format, header, out, out_size)
int _gnutls_x509_export_int_named (ASN1_TYPE asn1_data, const char *name,
gnutls_x509_crt_fmt_t format,
@@ -107,6 +104,13 @@ int _gnutls_x509_export_int_named (ASN1_TYPE asn1_data, const char *name,
unsigned char *output_data,
size_t * output_data_size);
+#define _gnutls_x509_export_int2(asn1, format, header, out) \
+ _gnutls_x509_export_int_named2(asn1, "", format, header, out)
+int _gnutls_x509_export_int_named2 (ASN1_TYPE asn1_data, const char *name,
+ gnutls_x509_crt_fmt_t format,
+ const char *pem_header,
+ gnutls_datum_t * out);
+
int _gnutls_x509_read_value (ASN1_TYPE c, const char *root,
gnutls_datum_t * ret, int str);
int _gnutls_x509_write_value (ASN1_TYPE c, const char *root,
diff --git a/lib/x509/crl.c b/lib/x509/crl.c
index b0e1fd82e5..2565e9c3a7 100644
--- a/lib/x509/crl.c
+++ b/lib/x509/crl.c
@@ -637,6 +637,37 @@ gnutls_x509_crl_export (gnutls_x509_crl_t crl,
output_data, output_data_size);
}
+/**
+ * gnutls_x509_crl_export2:
+ * @crl: Holds the revocation list
+ * @format: the format of output params. One of PEM or DER.
+ * @out: will contain a private key PEM or DER encoded
+ *
+ * This function will export the revocation list to DER or PEM format.
+ *
+ * The output buffer is allocated using gnutls_malloc().
+ *
+ * If the structure is PEM encoded, it will have a header
+ * of "BEGIN X509 CRL".
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value. and a negative error code on failure.
+ *
+ * Since 3.1
+ **/
+int
+gnutls_x509_crl_export2 (gnutls_x509_crl_t crl,
+ gnutls_x509_crt_fmt_t format, gnutls_datum_t *out)
+{
+ if (crl == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ return _gnutls_x509_export_int2 (crl->crl, format, PEM_CRL, out);
+}
+
/*-
* _gnutls_x509_crl_cpy - This function copies a gnutls_x509_crl_t structure
* @dest: The structure where to copy
@@ -651,37 +682,15 @@ int
_gnutls_x509_crl_cpy (gnutls_x509_crl_t dest, gnutls_x509_crl_t src)
{
int ret;
- size_t der_size;
- uint8_t *der;
gnutls_datum_t tmp;
- ret = gnutls_x509_crl_export (src, GNUTLS_X509_FMT_DER, NULL, &der_size);
- if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
- {
- gnutls_assert ();
- return ret;
- }
-
- der = gnutls_malloc (der_size);
- if (der == NULL)
- {
- gnutls_assert ();
- return GNUTLS_E_MEMORY_ERROR;
- }
-
- ret = gnutls_x509_crl_export (src, GNUTLS_X509_FMT_DER, der, &der_size);
+ ret = gnutls_x509_crl_export2 (src, GNUTLS_X509_FMT_DER, &tmp);
if (ret < 0)
- {
- gnutls_assert ();
- gnutls_free (der);
- return ret;
- }
+ return gnutls_assert_val(ret);
- tmp.data = der;
- tmp.size = der_size;
ret = gnutls_x509_crl_import (dest, &tmp, GNUTLS_X509_FMT_DER);
- gnutls_free (der);
+ gnutls_free (tmp.data);
if (ret < 0)
{
diff --git a/lib/x509/crq.c b/lib/x509/crq.c
index c4dec27ae6..5651cb0e48 100644
--- a/lib/x509/crq.c
+++ b/lib/x509/crq.c
@@ -1156,6 +1156,38 @@ gnutls_x509_crq_export (gnutls_x509_crq_t crq,
}
/**
+ * gnutls_x509_crq_export2:
+ * @crq: should contain a #gnutls_x509_crq_t structure
+ * @format: the format of output params. One of PEM or DER.
+ * @out: will contain a certificate request PEM or DER encoded
+ *
+ * This function will export the certificate request to a PEM or DER
+ * encoded PKCS10 structure.
+ *
+ * The output buffer is allocated using gnutls_malloc().
+ *
+ * If the structure is PEM encoded, it will have a header of "BEGIN
+ * NEW CERTIFICATE REQUEST".
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value.
+ *
+ * Since 3.1
+ **/
+int
+gnutls_x509_crq_export2 (gnutls_x509_crq_t crq,
+ gnutls_x509_crt_fmt_t format, gnutls_datum_t *out)
+{
+ if (crq == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ return _gnutls_x509_export_int2 (crq->crq, format, PEM_CRQ, out);
+}
+
+/**
* gnutls_x509_crq_get_pk_algorithm:
* @crq: should contain a #gnutls_x509_crq_t structure
* @bits: if bits is non-%NULL it will hold the size of the parameters' in bits
diff --git a/lib/x509/dn.c b/lib/x509/dn.c
index 5152691d33..9c6096193d 100644
--- a/lib/x509/dn.c
+++ b/lib/x509/dn.c
@@ -1241,3 +1241,35 @@ gnutls_x509_dn_export (gnutls_x509_dn_t dn,
format, "NAME",
output_data, output_data_size);
}
+
+/**
+ * gnutls_x509_dn_export2:
+ * @dn: Holds the uint8_t DN object
+ * @format: the format of output params. One of PEM or DER.
+ * @out: will contain a DN PEM or DER encoded
+ *
+ * This function will export the DN to DER or PEM format.
+ *
+ * The output buffer is allocated using gnutls_malloc().
+ *
+ * If the structure is PEM encoded, it will have a header
+ * of "BEGIN NAME".
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value.
+ **/
+int
+gnutls_x509_dn_export2 (gnutls_x509_dn_t dn,
+ gnutls_x509_crt_fmt_t format, gnutls_datum_t *out)
+{
+ ASN1_TYPE asn1 = dn;
+
+ if (asn1 == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ return _gnutls_x509_export_int_named2 (asn1, "rdnSequence",
+ format, "NAME", out);
+}
diff --git a/lib/x509/pkcs12.c b/lib/x509/pkcs12.c
index d06fea4a85..380f3fc9b0 100644
--- a/lib/x509/pkcs12.c
+++ b/lib/x509/pkcs12.c
@@ -276,6 +276,37 @@ gnutls_pkcs12_export (gnutls_pkcs12_t pkcs12,
output_data, output_data_size);
}
+/**
+ * gnutls_pkcs12_export2:
+ * @pkcs12: Holds the pkcs12 structure
+ * @format: the format of output params. One of PEM or DER.
+ * @out: will contain a structure PEM or DER encoded
+ *
+ * This function will export the pkcs12 structure to DER or PEM format.
+ *
+ * The output buffer is allocated using gnutls_malloc().
+ *
+ * If the structure is PEM encoded, it will have a header
+ * of "BEGIN PKCS12".
+ *
+ * Returns: In case of failure a negative error code will be
+ * returned, and 0 on success.
+ *
+ * Since: 3.1
+ **/
+int
+gnutls_pkcs12_export2 (gnutls_pkcs12_t pkcs12,
+ gnutls_x509_crt_fmt_t format, gnutls_datum_t *out)
+{
+ if (pkcs12 == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ return _gnutls_x509_export_int2 (pkcs12->pkcs12, format, PEM_PKCS12, out);
+}
+
static int
oid2bag (const char *oid)
{
diff --git a/lib/x509/pkcs7.c b/lib/x509/pkcs7.c
index 16e4d3b28e..5149f5c3fe 100644
--- a/lib/x509/pkcs7.c
+++ b/lib/x509/pkcs7.c
@@ -432,6 +432,32 @@ gnutls_pkcs7_export (gnutls_pkcs7_t pkcs7,
output_data, output_data_size);
}
+/**
+ * gnutls_pkcs7_export2:
+ * @pkcs7: Holds the pkcs7 structure
+ * @format: the format of output params. One of PEM or DER.
+ * @out: will contain a structure PEM or DER encoded
+ *
+ * This function will export the pkcs7 structure to DER or PEM format.
+ *
+ * The output buffer is allocated using gnutls_malloc().
+ *
+ * If the structure is PEM encoded, it will have a header
+ * of "BEGIN PKCS7".
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value.
+ **/
+int
+gnutls_pkcs7_export2 (gnutls_pkcs7_t pkcs7,
+ gnutls_x509_crt_fmt_t format, gnutls_datum_t *out)
+{
+ if (pkcs7 == NULL)
+ return GNUTLS_E_INVALID_REQUEST;
+
+ return _gnutls_x509_export_int2 (pkcs7->pkcs7, format, PEM_PKCS7, out);
+}
+
/* Creates an empty signed data structure in the pkcs7
* structure and returns a handle to the signed data.
*/
diff --git a/lib/x509/privkey.c b/lib/x509/privkey.c
index b9039722a9..875d1f47e0 100644
--- a/lib/x509/privkey.c
+++ b/lib/x509/privkey.c
@@ -1016,6 +1016,18 @@ int ret;
return key->pk_algorithm;
}
+static const char* set_msg(gnutls_x509_privkey_t key)
+{
+ if (key->pk_algorithm == GNUTLS_PK_RSA)
+ return PEM_KEY_RSA;
+ else if (key->pk_algorithm == GNUTLS_PK_DSA)
+ return PEM_KEY_DSA;
+ else if (key->pk_algorithm == GNUTLS_PK_EC)
+ return PEM_KEY_ECC;
+ else
+ return "UNKNOWN";
+}
+
/**
* gnutls_x509_privkey_export:
* @key: Holds the key
@@ -1051,20 +1063,51 @@ gnutls_x509_privkey_export (gnutls_x509_privkey_t key,
return GNUTLS_E_INVALID_REQUEST;
}
- if (key->pk_algorithm == GNUTLS_PK_RSA)
- msg = PEM_KEY_RSA;
- else if (key->pk_algorithm == GNUTLS_PK_DSA)
- msg = PEM_KEY_DSA;
- else if (key->pk_algorithm == GNUTLS_PK_EC)
- msg = PEM_KEY_ECC;
- else
- msg = "UNKNOWN";
+ msg = set_msg(key);
return _gnutls_x509_export_int (key->key, format, msg,
output_data, output_data_size);
}
/**
+ * gnutls_x509_privkey_export2:
+ * @key: Holds the key
+ * @format: the format of output params. One of PEM or DER.
+ * @out: will contain a private key PEM or DER encoded
+ *
+ * This function will export the private key to a PKCS1 structure for
+ * RSA keys, or an integer sequence for DSA keys. The DSA keys are in
+ * the same format with the parameters used by openssl.
+ *
+ * The output buffer is allocated using gnutls_malloc().
+ *
+ * If the structure is PEM encoded, it will have a header
+ * of "BEGIN RSA PRIVATE KEY".
+ *
+ * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
+ * negative error value.
+ *
+ * Since 3.1
+ **/
+int
+gnutls_x509_privkey_export2 (gnutls_x509_privkey_t key,
+ gnutls_x509_crt_fmt_t format,
+ gnutls_datum_t * out)
+{
+ const char *msg;
+
+ if (key == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ msg = set_msg(key);
+
+ return _gnutls_x509_export_int2 (key->key, format, msg, out);
+}
+
+/**
* gnutls_x509_privkey_sec_param:
* @key: a key structure
*
diff --git a/lib/x509/privkey_pkcs8.c b/lib/x509/privkey_pkcs8.c
index 2ccb5f95dc..42d3c5112d 100644
--- a/lib/x509/privkey_pkcs8.c
+++ b/lib/x509/privkey_pkcs8.c
@@ -660,6 +660,95 @@ gnutls_x509_privkey_export_pkcs8 (gnutls_x509_privkey_t key,
return ret;
}
+/**
+ * gnutls_x509_privkey_export2_pkcs8:
+ * @key: Holds the key
+ * @format: the format of output params. One of PEM or DER.
+ * @password: the password that will be used to encrypt the key.
+ * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
+ * @out: will contain a private key PEM or DER encoded
+ *
+ * This function will export the private key to a PKCS8 structure.
+ * Both RSA and DSA keys can be exported. For DSA keys we use
+ * PKCS #11 definitions. If the flags do not specify the encryption
+ * cipher, then the default 3DES (PBES2) will be used.
+ *
+ * The @password can be either ASCII or UTF-8 in the default PBES2
+ * encryption schemas, or ASCII for the PKCS12 schemas.
+ *
+ * The output buffer is allocated using gnutls_malloc().
+ *
+ * If the structure is PEM encoded, it will have a header
+ * of "BEGIN ENCRYPTED PRIVATE KEY" or "BEGIN PRIVATE KEY" if
+ * encryption is not used.
+ *
+ * Returns: In case of failure a negative error code will be
+ * returned, and 0 on success.
+ *
+ * Since 3.1
+ **/
+int
+gnutls_x509_privkey_export2_pkcs8 (gnutls_x509_privkey_t key,
+ gnutls_x509_crt_fmt_t format,
+ const char *password,
+ unsigned int flags,
+ gnutls_datum_t *out)
+{
+ ASN1_TYPE pkcs8_asn, pkey_info;
+ int ret;
+ gnutls_datum_t tmp;
+ schema_id schema;
+
+ if (key == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ /* Get the private key info
+ * tmp holds the DER encoding.
+ */
+ ret = encode_to_private_key_info (key, &tmp, &pkey_info);
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
+ schema = _gnutls_pkcs_flags_to_schema (flags);
+
+ if (((flags & GNUTLS_PKCS_PLAIN) || password == NULL) && !(flags & GNUTLS_PKCS_NULL_PASSWORD))
+ {
+ _gnutls_free_datum (&tmp);
+
+ ret =
+ _gnutls_x509_export_int2 (pkey_info, format,
+ PEM_UNENCRYPTED_PKCS8, out);
+
+ asn1_delete_structure (&pkey_info);
+ }
+ else
+ {
+ asn1_delete_structure (&pkey_info); /* we don't need it */
+
+ ret = encode_to_pkcs8_key (schema, &tmp, password, &pkcs8_asn);
+ _gnutls_free_datum (&tmp);
+
+ if (ret < 0)
+ {
+ gnutls_assert ();
+ return ret;
+ }
+
+ ret =
+ _gnutls_x509_export_int2 (pkcs8_asn, format, PEM_PKCS8, out);
+
+ asn1_delete_structure (&pkcs8_asn);
+ }
+
+ return ret;
+}
+
/* Read the parameters cipher, IV, salt etc using the given
* schema ID.
diff --git a/lib/x509/x509.c b/lib/x509/x509.c
index 0e1430d189..308047fb07 100644
--- a/lib/x509/x509.c
+++ b/lib/x509/x509.c
@@ -2340,6 +2340,36 @@ gnutls_x509_crt_export (gnutls_x509_crt_t cert,
output_data, output_data_size);
}
+/**
+ * gnutls_x509_crt_export2:
+ * @cert: Holds the certificate
+ * @format: the format of output params. One of PEM or DER.
+ * @out: will contain a certificate PEM or DER encoded
+ *
+ * This function will export the certificate to DER or PEM format.
+ * The output buffer is allocated using gnutls_malloc().
+ *
+ * If the structure is PEM encoded, it will have a header
+ * of "BEGIN CERTIFICATE".
+ *
+ * Returns: In case of failure a negative error code will be
+ * returned, and 0 on success.
+ *
+ * Since: 3.1
+ **/
+int
+gnutls_x509_crt_export2 (gnutls_x509_crt_t cert,
+ gnutls_x509_crt_fmt_t format, gnutls_datum_t * out)
+{
+ if (cert == NULL)
+ {
+ gnutls_assert ();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ return _gnutls_x509_export_int2 (cert->cert, format, "CERTIFICATE", out);
+}
+
int
_gnutls_get_key_id (gnutls_pk_algorithm_t pk, gnutls_pk_params_st * params,
unsigned char *output_data,
diff --git a/libdane/dane.c b/libdane/dane.c
index 6f9a2db4cd..ebf362c498 100644
--- a/libdane/dane.c
+++ b/libdane/dane.c
@@ -306,7 +306,6 @@ static int crt_to_pubkey(const gnutls_datum_t *raw_crt, gnutls_datum_t * out)
gnutls_pubkey_t pub = NULL;
gnutls_x509_crt_t crt = NULL;
int ret;
-size_t size;
out->data = NULL;
@@ -332,27 +331,12 @@ size_t size;
goto cleanup;
}
- size = 0;
- ret = gnutls_pubkey_export(pub, GNUTLS_X509_FMT_DER, NULL, &size);
- if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) {
- ret = DANE_E_PUBKEY_ERROR;
- goto cleanup;
- }
-
- out->data = malloc(size);
- if (out->data == NULL) {
- ret = DANE_E_MEMORY_ERROR;
- goto cleanup;
- }
-
- ret = gnutls_pubkey_export(pub, GNUTLS_X509_FMT_DER, out->data, &size);
+ ret = gnutls_pubkey_export2(pub, GNUTLS_X509_FMT_DER, out);
if (ret < 0) {
ret = DANE_E_PUBKEY_ERROR;
goto cleanup;
}
- out->size = size;
-
ret = 0;
goto clean_certs;