]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added functions to export structures in an allocated buffer.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 7 Oct 2012 08:33:55 +0000 (10:33 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 7 Oct 2012 08:37:44 +0000 (10:37 +0200)
28 files changed:
NEWS
doc/cha-cert-auth2.texi
doc/cha-tokens.texi
doc/invoke-gnutls-cli.texi
lib/gnutls_dh_primes.c
lib/gnutls_pubkey.c
lib/includes/gnutls/abstract.h
lib/includes/gnutls/gnutls.h.in
lib/includes/gnutls/openpgp.h
lib/includes/gnutls/pkcs11.h
lib/includes/gnutls/pkcs12.h
lib/includes/gnutls/x509.h
lib/libgnutls.map
lib/openpgp/openpgp_int.h
lib/openpgp/pgp.c
lib/openpgp/privkey.c
lib/pkcs11.c
lib/x509/common.c
lib/x509/common.h
lib/x509/crl.c
lib/x509/crq.c
lib/x509/dn.c
lib/x509/pkcs12.c
lib/x509/pkcs7.c
lib/x509/privkey.c
lib/x509/privkey_pkcs8.c
lib/x509/x509.c
libdane/dane.c

diff --git a/NEWS b/NEWS
index caafbbd6c523ff05d997d937f2e82f4a44e0d6ab..a7f8d3f8a0a786b4b59886d13a233138e77f5492 100644 (file)
--- 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
index e375050a3c6b9571c4cdc3c145db9a3d16612e6b..6ce6d7a3b5d5cd0813775b689ac805a5ffbb4c8b 100644 (file)
@@ -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}
 
index 936cf6dd3c9bf7fa4d68e58c59a28ae8007629ee..b290ff52c75bad91fb20fbbadf3a3e77bf66c305 100644 (file)
@@ -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}).
index 91f597097bb54d251ba51192c240c993a977391e..ade332a00531a247306a334a449864ad592d9370 100644 (file)
@@ -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
index caa9fe893acc2c043be8c3ee9d99a527b231dd15..4eb16388ef4c23b2ce49db66fadf4d0bfb6b13e0 100644 (file)
@@ -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"
@@ -340,9 +341,57 @@ gnutls_dh_params_export_pkcs3 (gnutls_dh_params_t params,
                                gnutls_x509_crt_fmt_t format,
                                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;
index c1455628268f4a272fd59f1ab317b40fe745e865..21bea55ed96d4472cd3037c5059146293a78e2be 100644 (file)
@@ -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;
 }
 
 /**
index 245af8795ef263b3cc98720c2c48c59e2a0d618f..b96d6305e894b515ee3b9ac7747ec8c92fd05c8d 100644 (file)
@@ -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);
index e7de530f2a37c6773d4cfc53910a3d18fdfab210..51e594e65c7ae3a831b5ae791f3c4c29c3c6df7f 100644 (file)
@@ -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,
index 1d4e0cd5919f2cefae6c20e5fd5a54cd3041f41f..bed810168be1668225678743a92ccab83e38255a 100644 (file)
@@ -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,
index 84af6f2ba16c21d8a1666a13439c6c21e9a6fd47..0e486cea066f635c3b34a7344c01ec20b514b562 100644 (file)
@@ -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
index 09b75e935ec69c0d6ab01cce1808bfb4bdab1ed0..02f6351c174ca3201cc5d1ce4d726fe03fbe4f2f 100644 (file)
@@ -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);
index 94e01a4729b86d93354c517bd0e509d2ee67ad74..7845f22ed03aa54bb00dbb28a84356ef6f6d151e 100644 (file)
@@ -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,
index 9cfe3d317758ae43c633fa1c9063cb1ad53cfe9f..578e159f17bfc3d6f9794b431eb0403b0b4cd932 100644 (file)
@@ -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 {
index 9f6b3a5212691dec415c6dcb5f4c3d952e797a25..a144793cf8e6e537d572ca020fcda671a2f61e88 100644 (file)
@@ -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);
 
index dc6cadcad1fc6a95684da161cc73dc9f444cec1d..78ef7882b842670577e99d0cbe9f36a739074c08 100644 (file)
@@ -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)
  *
@@ -208,6 +234,25 @@ gnutls_openpgp_crt_export (gnutls_openpgp_crt_t key,
                                  output_data_size, 0);
 }
 
+/**
+ * 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.
index bd04b21969fc5e16122e6917696d79e1788acb05..461aa9d0e6136d27fc1ebe73578c02f00874a57a 100644 (file)
@@ -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:
index 48dcd035edcb60b9f61fc0564669278fef7afa54..0357c7ad5df3afd63526101ff4e3f2d204975fd8 100644 (file)
@@ -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,
index fd4b815f38b6cb2839ed883f7340a1f3af211bd8..d577f8ae4a902782763f586929f10a7c67012f3c 100644 (file)
@@ -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.
index e48e0f88e53d33fe0e338a169dc40842295c26be..1ee919435b3415bee0d8c2fe07b7ad37cecf0f67 100644 (file)
@@ -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,
index b0e1fd82e5d957c7190c1c1c32e58faf6f87661f..2565e9c3a7519dbabc4ca43facacdbea60b70b42 100644 (file)
@@ -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)
     {
index c4dec27ae6218883315443ac451089cb685661d0..5651cb0e485fc649892e8e4a00b071909c6ae4c6 100644 (file)
@@ -1155,6 +1155,38 @@ gnutls_x509_crq_export (gnutls_x509_crq_t crq,
                                   output_data, output_data_size);
 }
 
+/**
+ * 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
index 5152691d33b4319cac34c2d07bf797d227364c1b..9c6096193de9cf662b88cb827ac78bcf49f0f267 100644 (file)
@@ -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);
+}
index d06fea4a8511dcaf6ac9a39780a8bb40b8cb5a03..380f3fc9b01eb859dc93a5ef050165250268dff4 100644 (file)
@@ -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)
 {
index 16e4d3b28e32075991322fd3ff8ad07a2c39313f..5149f5c3fed2380890941a229a7a1b5054d8c45f 100644 (file)
@@ -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.
  */
index b9039722a9e0dd290ce23a9feb137d7dbe5b70e5..875d1f47e0152a4f93a9689cccc23db902589db8 100644 (file)
@@ -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,19 +1063,50 @@ 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
index 2ccb5f95dcf94b1df98cb2226baf00342c2b8790..42d3c5112dc1dc63d8171b21e1ae2e79cb24a63f 100644 (file)
@@ -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.
index 0e1430d1893df6a9d5fd38ef04bf50c25556c73c..308047fb073888e9a4f2c16dba2f276a73784f83 100644 (file)
@@ -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,
index 6f9a2db4cdba0933dd1e88ff2ab6674ea22cc200..ebf362c498ec15fed5d873c143a1ac04097077ee 100644 (file)
@@ -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;