From abd7fa6e1d3e955bea3f339d5e402496b71cd7a2 Mon Sep 17 00:00:00 2001 From: Nikos Date: Fri, 25 Jan 2008 23:47:13 +0200 Subject: updates in openpgp keyring handling. --- lib/gnutls_openpgp.c | 8 +++- lib/openpgp/extras.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 116 insertions(+), 6 deletions(-) diff --git a/lib/gnutls_openpgp.c b/lib/gnutls_openpgp.c index cd7c074f8f..7968eab4c9 100644 --- a/lib/gnutls_openpgp.c +++ b/lib/gnutls_openpgp.c @@ -298,6 +298,7 @@ gnutls_openpgp_get_key (gnutls_datum_t * key, void *desc; size_t len; int rc = 0; + cdk_keydb_search_t st; if (!key || !keyring || by == KEY_ATTR_NONE) { @@ -320,9 +321,12 @@ gnutls_openpgp_get_key (gnutls_datum_t * key, } else desc = pattern; - rc = cdk_keydb_search_start (keyring->db, by, desc); + rc = cdk_keydb_search_start (&st, keyring->db, by, desc); if (!rc) - rc = cdk_keydb_search (keyring->db, &knode); + rc = cdk_keydb_search (st, keyring->db, &knode); + + cdk_keydb_search_release( st); + if (rc) { rc = _gnutls_map_cdk_rc (rc); diff --git a/lib/openpgp/extras.c b/lib/openpgp/extras.c index 2ce4ce256d..d9a28f3c3c 100644 --- a/lib/openpgp/extras.c +++ b/lib/openpgp/extras.c @@ -19,16 +19,16 @@ * along with this program. If not, see . */ -/* Functions on OpenPGP keyring parsing +/* Functions on keyring parsing */ #include #include #include #include +#include #include #include -#include /* Keyring stuff. */ @@ -37,7 +37,7 @@ * gnutls_openpgp_keyring_init - This function initializes a gnutls_openpgp_keyring_t structure * @keyring: The structure to be initialized * - * This function will initialize an OpenPGP keyring structure. + * This function will initialize an keyring structure. * * Returns 0 on success. * @@ -116,7 +116,7 @@ gnutls_openpgp_keyring_check_id (gnutls_openpgp_keyring_t ring, } /** - * gnutls_openpgp_keyring_import - Import a raw- or Base64-encoded OpenPGP keyring + * gnutls_openpgp_keyring_import - Import a raw- or Base64-encoded keyring * @keyring: The structure to store the parsed key. * @data: The RAW or BASE64 encoded keyring. * @format: One of #gnutls_openpgp_keyring_fmt elements. @@ -170,3 +170,109 @@ gnutls_openpgp_keyring_import (gnutls_openpgp_keyring_t keyring, return _gnutls_map_cdk_rc (err); } +#define knode_is_pkey(node) \ + cdk_kbnode_find_packet (node, CDK_PKT_PUBLIC_KEY)!=NULL + +/** + * gnutls_openpgp_keyring_get_crt_count - This function returns the number of certificates + * @ring: is an OpenPGP key ring + * + * This function will return the number of OpenPGP certificates present in the given + * keyring. + * + * Returns then number of subkeys or a negative value on error. + * + **/ +int +gnutls_openpgp_keyring_get_crt_count (gnutls_openpgp_keyring_t ring) +{ + cdk_kbnode_t knode; + cdk_error_t err; + cdk_keydb_search_t st; + int ret = 0; + + err = cdk_keydb_search_start( &st, ring->db, CDK_DBSEARCH_NEXT, NULL); + if (err != CDK_Success) + { + gnutls_assert(); + return _gnutls_map_cdk_rc(err); + } + + do { + err = cdk_keydb_search( st, ring->db, &knode); + if (err != CDK_Error_No_Key && err != CDK_Success) + { + gnutls_assert(); + cdk_keydb_search_release(st); + return _gnutls_map_cdk_rc(err); + } + + if (knode_is_pkey( knode)) + ret++; + + cdk_kbnode_release(knode); + + } while( err != CDK_Error_No_Key); + + cdk_keydb_search_release(st); + return ret; +} + +/** + * gnutls_openpgp_keyring_get_crt - This function will export an openpgp certificate from a keyring + * @key: Holds the key. + * @idx: the index of the certificate to export + * @crt: An uninitialized &gnutls_openpgp_crt_t structure + * + * This function will extract an OpenPGP certificate from the given keyring. + * If the index given is out of range GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be + * returned. The returned structure needs to be deinited. + * + * Returns 0 on success. + * + **/ +int +gnutls_openpgp_keyring_get_crt (gnutls_openpgp_keyring_t ring, unsigned int idx, + gnutls_openpgp_crt_t* cert) +{ + cdk_kbnode_t knode; + cdk_error_t err; + int ret = 0; + cdk_keydb_search_t st; + + err = cdk_keydb_search_start( &st, ring->db, CDK_DBSEARCH_NEXT, NULL); + if (err != CDK_Success) + { + gnutls_assert(); + return _gnutls_map_cdk_rc(err); + } + + do { + err = cdk_keydb_search( st, ring->db, &knode); + if (err != CDK_EOF && err != CDK_Success) + { + gnutls_assert(); + cdk_keydb_search_release(st); + return _gnutls_map_cdk_rc(err); + } + + if (idx == ret) + { + ret = gnutls_openpgp_crt_init( cert); + if (ret == 0) + (*cert)->knode = knode; + cdk_keydb_search_release(st); + return ret; + } + + if (knode_is_pkey( knode)) + ret++; + + cdk_kbnode_release(knode); + + } while( err != CDK_EOF); + + cdk_keydb_search_release(st); + return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; +} + -- cgit v1.2.1