>From c4a8f333fc118ac454906e6ef056789b4069e4d2 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Sat, 27 Aug 2011 20:20:43 +0200 Subject: [PATCH] gnutls_certificate_set_x509_key() and gnutls_certificate_set_openpgp_key() operate as in gnutls 2.10.x and do not require to hold the structures. --- NEWS | 11 +++++++++ lib/gnutls_privkey.c | 39 +++++++++++++++++++++++++++++-- lib/gnutls_x509.c | 2 +- lib/includes/gnutls/abstract.h | 3 +- lib/openpgp/gnutls_openpgp.c | 3 +- lib/openpgp/gnutls_openpgp.h | 3 ++ lib/openpgp/privkey.c | 49 ++++++++++++++++++++++++++++++++++++++++ lib/x509/x509.c | 3 +- 8 files changed, 105 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 66a1151..cfa076b 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,17 @@ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. See the end for copying conditions. +* Version 2.12.10 (unreleased) + +** libgnutls: gnutls_certificate_set_x509_key() and +gnutls_certificate_set_openpgp_key() operate as in 2.10.x +and allow the release of the private key during the +lifetime of the certificate structure. + +** API and ABI modifications: +GNUTLS_PRIVKEY_IMPORT_COPY: new gnutls_privkey_import() flag + + * Version 2.12.9 (released 2011-08-21) ** libgnutls-extra: Replaced enumeration with unsigned diff --git a/lib/gnutls_privkey.c b/lib/gnutls_privkey.c index 499640e..f61524f 100644 --- a/lib/gnutls_privkey.c +++ b/lib/gnutls_privkey.c @@ -271,7 +271,7 @@ gnutls_privkey_deinit (gnutls_privkey_t key) { if (key == NULL) return; - if (key->flags & GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE) + if (key->flags & GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE || key->flags & GNUTLS_PRIVKEY_IMPORT_COPY) switch (key->type) { #ifdef ENABLE_OPENPGP @@ -331,6 +331,9 @@ int ret; return ret; } + if (flags & GNUTLS_PRIVKEY_IMPORT_COPY) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + pkey->key.pkcs11 = key; pkey->type = GNUTLS_PRIVKEY_PKCS11; pkey->pk_algorithm = gnutls_pkcs11_privkey_get_pk_algorithm (key, NULL); @@ -369,7 +372,22 @@ int ret; return ret; } - pkey->key.x509 = key; + if (flags & GNUTLS_PRIVKEY_IMPORT_COPY) + { + ret = gnutls_x509_privkey_init(&pkey->key.x509); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = gnutls_x509_privkey_cpy(pkey->key.x509, key); + if (ret < 0) + { + gnutls_x509_privkey_deinit(pkey->key.x509); + return gnutls_assert_val(ret); + } + } + else + pkey->key.x509 = key; + pkey->type = GNUTLS_PRIVKEY_X509; pkey->pk_algorithm = gnutls_x509_privkey_get_pk_algorithm (key); pkey->flags = flags; @@ -409,7 +427,22 @@ uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; return ret; } - pkey->key.openpgp = key; + if (flags & GNUTLS_PRIVKEY_IMPORT_COPY) + { + ret = gnutls_openpgp_privkey_init(&pkey->key.openpgp); + if (ret < 0) + return gnutls_assert_val(ret); + + ret = _gnutls_openpgp_privkey_cpy(pkey->key.openpgp, key); + if (ret < 0) + { + gnutls_openpgp_privkey_deinit(pkey->key.openpgp); + return gnutls_assert_val(ret); + } + } + else + pkey->key.openpgp = key; + pkey->type = GNUTLS_PRIVKEY_OPENPGP; ret = gnutls_openpgp_privkey_get_preferred_key_id (key, keyid); diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c index 9b74ef5..6f73c44 100644 --- a/lib/gnutls_x509.c +++ b/lib/gnutls_x509.c @@ -969,7 +969,7 @@ gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res, return ret; } - ret = gnutls_privkey_import_x509 (pkey, key, 0); + ret = gnutls_privkey_import_x509 (pkey, key, GNUTLS_PRIVKEY_IMPORT_COPY); if (ret < 0) { gnutls_assert (); diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h index 73266df..0e2c226 100644 --- a/lib/includes/gnutls/abstract.h +++ b/lib/includes/gnutls/abstract.h @@ -101,7 +101,8 @@ gnutls_privkey_get_preferred_hash_algorithm (gnutls_privkey_t key, gnutls_privkey_type_t gnutls_privkey_get_type (gnutls_privkey_t key); -#define GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE 1 +#define GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE (1<<0) +#define GNUTLS_PRIVKEY_IMPORT_COPY (1<<1) int gnutls_privkey_import_pkcs11 (gnutls_privkey_t pkey, gnutls_pkcs11_privkey_t key, unsigned int flags); diff --git a/lib/openpgp/gnutls_openpgp.c b/lib/openpgp/gnutls_openpgp.c index 5e13fd4..9cff120 100644 --- a/lib/openpgp/gnutls_openpgp.c +++ b/lib/openpgp/gnutls_openpgp.c @@ -152,7 +152,7 @@ gnutls_certificate_set_openpgp_key (gnutls_certificate_credentials_t res, ret = gnutls_privkey_import_openpgp (privkey, pkey, - GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); + GNUTLS_PRIVKEY_IMPORT_COPY); if (ret < 0) { gnutls_privkey_deinit (privkey); @@ -431,6 +431,7 @@ gnutls_certificate_set_openpgp_key_mem2 (gnutls_certificate_credentials_t res, ret = gnutls_certificate_set_openpgp_key (res, crt, pkey); gnutls_openpgp_crt_deinit (crt); + gnutls_openpgp_privkey_deinit (pkey); return ret; } diff --git a/lib/openpgp/gnutls_openpgp.h b/lib/openpgp/gnutls_openpgp.h index 7816fcd..b7add60 100644 --- a/lib/openpgp/gnutls_openpgp.h +++ b/lib/openpgp/gnutls_openpgp.h @@ -34,6 +34,9 @@ _gnutls_openpgp_raw_privkey_to_gkey (gnutls_privkey_t * pkey, const gnutls_datum_t * raw_key); int +_gnutls_openpgp_privkey_cpy (gnutls_openpgp_privkey_t dest, gnutls_openpgp_privkey_t src); + +int _gnutls_openpgp_request_key (gnutls_session_t, gnutls_datum_t * ret, const gnutls_certificate_credentials_t cred, diff --git a/lib/openpgp/privkey.c b/lib/openpgp/privkey.c index 0040922..61ae9aa 100644 --- a/lib/openpgp/privkey.c +++ b/lib/openpgp/privkey.c @@ -75,6 +75,55 @@ gnutls_openpgp_privkey_deinit (gnutls_openpgp_privkey_t key) gnutls_free (key); } +/*- + * _gnutls_openpgp_privkey_cpy - This function copies a gnutls_openpgp_privkey_t structure + * @dest: The structure where to copy + * @src: The structure to be copied + * + * This function will copy an X.509 certificate structure. + * + * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a + * negative error value. + -*/ +int +_gnutls_openpgp_privkey_cpy (gnutls_openpgp_privkey_t dest, gnutls_openpgp_privkey_t src) +{ + int ret; + size_t der_size=0; + opaque *der; + gnutls_datum_t tmp; + + ret = gnutls_openpgp_privkey_export (src, GNUTLS_OPENPGP_FMT_RAW, NULL, 0, NULL, &der_size); + if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER) + return gnutls_assert_val(ret); + + der = gnutls_malloc (der_size); + if (der == NULL) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + ret = gnutls_openpgp_privkey_export (src, GNUTLS_OPENPGP_FMT_RAW, NULL, 0, der, &der_size); + if (ret < 0) + { + gnutls_assert (); + gnutls_free (der); + return ret; + } + + tmp.data = der; + tmp.size = der_size; + ret = gnutls_openpgp_privkey_import (dest, &tmp, GNUTLS_OPENPGP_FMT_RAW, NULL, 0); + + gnutls_free (der); + + if (ret < 0) + return gnutls_assert_val(ret); + + memcpy(dest->preferred_keyid, src->preferred_keyid, GNUTLS_OPENPGP_KEYID_SIZE); + dest->preferred_set = src->preferred_set; + + return 0; +} + /** * gnutls_openpgp_privkey_sec_param: * @key: a key structure diff --git a/lib/x509/x509.c b/lib/x509/x509.c index 50a742e..8924ad6 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -84,7 +84,7 @@ int _gnutls_x509_crt_cpy (gnutls_x509_crt_t dest, gnutls_x509_crt_t src) { int ret; - size_t der_size; + size_t der_size = 0; opaque *der; gnutls_datum_t tmp; @@ -123,7 +123,6 @@ _gnutls_x509_crt_cpy (gnutls_x509_crt_t dest, gnutls_x509_crt_t src) } return 0; - } /** -- 1.7.5.4