int _gnutls_openpgp_count_key_names (gnutls_openpgp_key_t key) { cdk_kbnode_t p, ctx = NULL; cdk_packet_t pkt; int nuids = 0; if (key == NULL) { gnutls_assert (); return 0; } while ((p = cdk_kbnode_walk (key->knode, &ctx, 0))) { pkt = cdk_kbnode_get_packet (p); if (pkt->pkttype == CDK_PKT_USER_ID) nuids++; } return nuids; }
/** * gnutls_openpgp_privkey_get_subkey_count: * @key: is an OpenPGP key * * This function will return the number of subkeys present in the * given OpenPGP certificate. * * Returns: the number of subkeys, or a negative error code on error. * * Since: 2.4.0 **/ int gnutls_openpgp_privkey_get_subkey_count(gnutls_openpgp_privkey_t key) { cdk_kbnode_t p, ctx; cdk_packet_t pkt; int subkeys; if (key == NULL) { gnutls_assert(); return 0; } ctx = NULL; subkeys = 0; while ((p = cdk_kbnode_walk(key->knode, &ctx, 0))) { pkt = cdk_kbnode_get_packet(p); if (pkt->pkttype == CDK_PKT_SECRET_SUBKEY) subkeys++; } return subkeys; }
/** * gnutls_openpgp_key_to_xml - Return a certificate as a XML fragment * @cert: the certificate which holds the whole OpenPGP key. * @xmlkey: he datum struct to store the XML result. * @ext: extension mode (1/0), 1 means include key signatures and key data. * * This function will return the all OpenPGP key information encapsulated as * a XML string. **/ int gnutls_openpgp_key_to_xml (gnutls_openpgp_key_t key, gnutls_datum_t * xmlkey, int ext) { cdk_kbnode_t node, ctx = NULL; cdk_packet_t pkt; char name[MAX_CN]; size_t name_len; const char *s; int idx = 0, rc = 0; gnutls_string string_xml_key; if (!key || !xmlkey) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } _gnutls_string_init (&string_xml_key, malloc, realloc, free); memset (xmlkey, 0, sizeof *xmlkey); s = "<?xml version=\"1.0\"?>\n\n"; _gnutls_string_append_str (&string_xml_key, s); s = "<gnutls:openpgp:key version=\"1.0\">\n"; _gnutls_string_append_str (&string_xml_key, s); s = " <OPENPGPKEY>\n"; _gnutls_string_append_str (&string_xml_key, s); idx = 1; while ((node = cdk_kbnode_walk (key->knode, &ctx, 0))) { pkt = cdk_kbnode_get_packet (node); switch (pkt->pkttype) { case CDK_PKT_PUBLIC_KEY: rc = xml_add_key (&string_xml_key, ext, pkt->pkt.public_key, 0); break; case CDK_PKT_PUBLIC_SUBKEY: rc = xml_add_key (&string_xml_key, ext, pkt->pkt.public_key, 1); break; case CDK_PKT_USER_ID: name_len = sizeof (name); gnutls_openpgp_key_get_name (key, idx, name, &name_len); rc = xml_add_userid (&string_xml_key, ext, name, pkt->pkt.user_id); idx++; break; case CDK_PKT_SIGNATURE: rc = xml_add_sig (&string_xml_key, ext, pkt->pkt.signature); break; default: break; } } if (!rc) { s = " </OPENPGPKEY>\n"; _gnutls_string_append_str (&string_xml_key, s); } s = "</gnutls:openpgp:key>\n"; _gnutls_string_append_str (&string_xml_key, s); _gnutls_string_append_data (&string_xml_key, "\n\0", 2); *xmlkey = _gnutls_string2datum (&string_xml_key); xmlkey->size--; return rc; }
/** * gnutls_openpgp_key_get_name - Extracts the userID * @key: the structure that contains the OpenPGP public key. * @idx: the index of the ID to extract * @buf: a pointer to a structure to hold the name * @sizeof_buf: holds the size of 'buf' * * Extracts the userID from the parsed OpenPGP key. * * Returns 0 on success, and GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE * if the index of the ID does not exist. * **/ int gnutls_openpgp_key_get_name (gnutls_openpgp_key_t key, int idx, char *buf, size_t * sizeof_buf) { cdk_kbnode_t ctx = NULL, p; cdk_packet_t pkt = NULL; cdk_pkt_userid_t uid = NULL; int pos = 0; size_t size = 0; int rc = 0; if (!key || !buf) { gnutls_assert (); return GNUTLS_E_INVALID_REQUEST; } if (idx < 0 || idx > _gnutls_openpgp_count_key_names (key)) { return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; } if (!idx) pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_USER_ID); else { pos = 0; while ((p = cdk_kbnode_walk (key->knode, &ctx, 0))) { pkt = cdk_kbnode_get_packet (p); if (pkt->pkttype == CDK_PKT_USER_ID && ++pos == idx) break; } } if (!pkt) { rc = GNUTLS_E_INTERNAL_ERROR; goto leave; } uid = pkt->pkt.user_id; if (uid->len >= *sizeof_buf) { gnutls_assert (); *sizeof_buf = uid->len + 1; rc = GNUTLS_E_SHORT_MEMORY_BUFFER; goto leave; } size = uid->len < *sizeof_buf ? uid->len : *sizeof_buf - 1; memcpy (buf, uid->name, size); buf[size] = '\0'; /* make sure it's a string */ if (uid->is_revoked) { rc = GNUTLS_E_OPENPGP_UID_REVOKED; goto leave; } leave: return rc; }