diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-06-16 08:50:32 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-06-16 15:31:43 +0200 |
commit | 4ad76785ef2feec7af64f3821edd8eb67de88762 (patch) | |
tree | b2ad5e723822fb447de94a27f06360a990d014e4 /lib/openpgp/pgp.c | |
parent | 7df03e9c6995f2ecfdf3ed0023dbf35e015f33e2 (diff) | |
download | gnutls-4ad76785ef2feec7af64f3821edd8eb67de88762.tar.gz |
Removed support for openpgp certificates and keys
Resolves #178
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'lib/openpgp/pgp.c')
-rw-r--r-- | lib/openpgp/pgp.c | 1780 |
1 files changed, 0 insertions, 1780 deletions
diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c deleted file mode 100644 index 03a507d4c4..0000000000 --- a/lib/openpgp/pgp.c +++ /dev/null @@ -1,1780 +0,0 @@ -/* - * Copyright (C) 2002-2012 Free Software Foundation, Inc. - * - * Author: Timo Schulz, Nikos Mavrogiannopoulos - * - * This file is part of GnuTLS. - * - * The GnuTLS is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/> - * - */ - -/* Functions on OpenPGP key parsing - */ - -#include "gnutls_int.h" -#include <datum.h> -#include <global.h> -#include "errors.h" -#include <openpgp_int.h> -#include <str.h> -#include <num.h> -#include <x509/common.h> - -/** - * gnutls_openpgp_crt_init: - * @key: A pointer to the type to be initialized - * - * This function will initialize an OpenPGP key structure. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int gnutls_openpgp_crt_init(gnutls_openpgp_crt_t * key) -{ - *key = gnutls_calloc(1, sizeof(gnutls_openpgp_crt_int)); - - if (*key) - return 0; /* success */ - return GNUTLS_E_MEMORY_ERROR; -} - -/** - * gnutls_openpgp_crt_deinit: - * @key: A pointer to the type to be initialized - * - * This function will deinitialize a key structure. - **/ -void gnutls_openpgp_crt_deinit(gnutls_openpgp_crt_t key) -{ - if (!key) - return; - - if (key->knode) { - cdk_kbnode_release(key->knode); - key->knode = NULL; - } - - gnutls_free(key); -} - -/** - * gnutls_openpgp_crt_import: - * @key: The structure to store the parsed key. - * @data: The RAW or BASE64 encoded key. - * @format: One of gnutls_openpgp_crt_fmt_t elements. - * - * This function will convert the given RAW or Base64 encoded key to - * the native #gnutls_openpgp_crt_t format. The output will be stored - * in 'key'. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int -gnutls_openpgp_crt_import(gnutls_openpgp_crt_t key, - const gnutls_datum_t * data, - gnutls_openpgp_crt_fmt_t format) -{ - cdk_packet_t pkt; - int rc, armor; - - if (data->data == NULL || data->size == 0) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - if (format == GNUTLS_OPENPGP_FMT_RAW) - armor = 0; - else - armor = 1; - - rc = cdk_kbnode_read_from_mem(&key->knode, armor, data->data, - data->size, 1); - if (rc) { - rc = _gnutls_map_cdk_rc(rc); - gnutls_assert(); - return rc; - } - - /* Test if the import was successful. */ - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (pkt == NULL) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - 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 priv) -{ - size_t input_data_size = *output_data_size; - size_t calc_size; - int rc; - - rc = cdk_kbnode_write_to_mem(node, output_data, output_data_size); - if (rc) { - rc = _gnutls_map_cdk_rc(rc); - gnutls_assert(); - return rc; - } - - /* If the caller uses output_data == NULL then return what he expects. - */ - if (!output_data && format != GNUTLS_OPENPGP_FMT_BASE64) { - gnutls_assert(); - return GNUTLS_E_SHORT_MEMORY_BUFFER; - } - - if (format == GNUTLS_OPENPGP_FMT_BASE64) { - unsigned char *in = gnutls_calloc(1, *output_data_size); - if (in == NULL) - return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); - - rc = cdk_kbnode_write_to_mem(node, in, output_data_size); - if (rc) { - gnutls_free(in); - rc = _gnutls_map_cdk_rc(rc); - gnutls_assert(); - return rc; - } - - /* Calculate the size of the encoded data and check if the provided - buffer is large enough. */ - rc = cdk_armor_encode_buffer(in, *output_data_size, - NULL, 0, &calc_size, - priv ? CDK_ARMOR_SECKEY : - CDK_ARMOR_PUBKEY); - if (rc || calc_size > input_data_size) { - gnutls_free(in); - *output_data_size = calc_size; - gnutls_assert(); - return GNUTLS_E_SHORT_MEMORY_BUFFER; - } - - rc = cdk_armor_encode_buffer(in, *output_data_size, - output_data, input_data_size, - &calc_size, - priv ? CDK_ARMOR_SECKEY : - CDK_ARMOR_PUBKEY); - gnutls_free(in); - *output_data_size = calc_size; - - if (rc) { - rc = _gnutls_map_cdk_rc(rc); - gnutls_assert(); - return rc; - } - } - - return 0; - -} - -/** - * gnutls_openpgp_crt_export: - * @key: Holds the key. - * @format: One of gnutls_openpgp_crt_fmt_t elements. - * @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) - * - * This function will convert the given key to RAW or Base64 format. - * If the buffer provided is not long enough to hold the output, then - * %GNUTLS_E_SHORT_MEMORY_BUFFER will be returned. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int -gnutls_openpgp_crt_export(gnutls_openpgp_crt_t key, - gnutls_openpgp_crt_fmt_t format, - void *output_data, size_t * output_data_size) -{ - return _gnutls_openpgp_export(key->knode, format, output_data, - 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. - * - * Since: 3.1.3 - **/ -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. - * @fprlen: the integer to save the length of the fingerprint. - * - * Get key fingerprint. Depending on the algorithm, the fingerprint - * can be 16 or 20 bytes. - * - * Returns: On success, 0 is returned. Otherwise, an error code. - **/ -int -gnutls_openpgp_crt_get_fingerprint(gnutls_openpgp_crt_t key, - void *fpr, size_t * fprlen) -{ - cdk_packet_t pkt; - cdk_pkt_pubkey_t pk = NULL; - - if (!fpr || !fprlen) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - *fprlen = 0; - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - pk = pkt->pkt.public_key; - *fprlen = 20; - - /* FIXME: Check if the draft allows old PGP keys. */ - if (is_RSA(pk->pubkey_algo) && pk->version < 4) - *fprlen = 16; - cdk_pk_get_fingerprint(pk, fpr); - - return 0; -} - -static int _gnutls_openpgp_count_key_names(gnutls_openpgp_crt_t key) -{ - cdk_kbnode_t p, ctx; - cdk_packet_t pkt; - int nuids; - - if (key == NULL) { - gnutls_assert(); - return 0; - } - - ctx = NULL; - nuids = 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_crt_get_name: - * @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, may be %NULL - * to only get the @sizeof_buf. - * @sizeof_buf: holds the maximum size of @buf, on return hold the - * actual/required size of @buf. - * - * Extracts the userID from the parsed OpenPGP key. - * - * Returns: %GNUTLS_E_SUCCESS on success, and if the index of the ID - * does not exist %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE, or an - * error code. - **/ -int -gnutls_openpgp_crt_get_name(gnutls_openpgp_crt_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; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (idx < 0 || idx >= _gnutls_openpgp_count_key_names(key)) - return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; - - pos = 0; - while ((p = cdk_kbnode_walk(key->knode, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - if (pkt->pkttype == CDK_PKT_USER_ID) { - if (pos == idx) - break; - pos++; - } - } - - if (!pkt) { - gnutls_assert(); - return GNUTLS_E_INTERNAL_ERROR; - } - - uid = pkt->pkt.user_id; - if (uid->len >= *sizeof_buf) { - gnutls_assert(); - *sizeof_buf = uid->len + 1; - return GNUTLS_E_SHORT_MEMORY_BUFFER; - } - - if (buf) { - memcpy(buf, uid->name, uid->len); - buf[uid->len] = '\0'; /* make sure it's a string */ - } - *sizeof_buf = uid->len + 1; - - if (uid->is_revoked) - return GNUTLS_E_OPENPGP_UID_REVOKED; - - return 0; -} - -/** - * gnutls_openpgp_crt_get_pk_algorithm: - * @key: is an OpenPGP key - * @bits: if bits is non null it will hold the size of the parameters' in bits - * - * This function will return the public key algorithm of an OpenPGP - * certificate. - * - * If bits is non null, it should have enough size to hold the parameters - * size in bits. For RSA the bits returned is the modulus. - * For DSA the bits returned are of the public exponent. - * - * Returns: a member of the #gnutls_pk_algorithm_t enumeration on - * success, or GNUTLS_PK_UNKNOWN on error. - **/ -gnutls_pk_algorithm_t -gnutls_openpgp_crt_get_pk_algorithm(gnutls_openpgp_crt_t key, - unsigned int *bits) -{ - cdk_packet_t pkt; - int algo = 0, ret; - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - - if (!key) { - gnutls_assert(); - return GNUTLS_PK_UNKNOWN; - } - - ret = gnutls_openpgp_crt_get_preferred_key_id(key, keyid); - if (ret == 0) { - int idx; - - idx = gnutls_openpgp_crt_get_subkey_idx(key, keyid); - if (idx != GNUTLS_OPENPGP_MASTER_KEYID_IDX) { - algo = - gnutls_openpgp_crt_get_subkey_pk_algorithm(key, - idx, - bits); - return algo; - } - } - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (pkt) { - if (bits) - *bits = cdk_pk_get_nbits(pkt->pkt.public_key); - algo = - _gnutls_openpgp_get_algo(pkt->pkt.public_key-> - pubkey_algo); - } - - return algo; -} - - -/** - * gnutls_openpgp_crt_get_version: - * @key: the structure that contains the OpenPGP public key. - * - * Extract the version of the OpenPGP key. - * - * Returns: the version number is returned, or a negative error code on errors. - **/ -int gnutls_openpgp_crt_get_version(gnutls_openpgp_crt_t key) -{ - cdk_packet_t pkt; - int version; - - if (!key) - return -1; - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (pkt) - version = pkt->pkt.public_key->version; - else - version = 0; - - return version; -} - - -/** - * gnutls_openpgp_crt_get_creation_time: - * @key: the structure that contains the OpenPGP public key. - * - * Get key creation time. - * - * Returns: the timestamp when the OpenPGP key was created. - **/ -time_t gnutls_openpgp_crt_get_creation_time(gnutls_openpgp_crt_t key) -{ - cdk_packet_t pkt; - time_t timestamp; - - if (!key) - return (time_t) - 1; - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (pkt) - timestamp = pkt->pkt.public_key->timestamp; - else - timestamp = 0; - - return timestamp; -} - - -/** - * gnutls_openpgp_crt_get_expiration_time: - * @key: the structure that contains the OpenPGP public key. - * - * Get key expiration time. A value of '0' means that the key doesn't - * expire at all. - * - * Returns: the time when the OpenPGP key expires. - **/ -time_t gnutls_openpgp_crt_get_expiration_time(gnutls_openpgp_crt_t key) -{ - cdk_packet_t pkt; - time_t expiredate; - - if (!key) - return (time_t) - 1; - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (pkt) - expiredate = pkt->pkt.public_key->expiredate; - else - expiredate = 0; - - return expiredate; -} - -/** - * gnutls_openpgp_crt_get_key_id: - * @key: the structure that contains the OpenPGP public key. - * @keyid: the buffer to save the keyid. - * - * Get key id string. - * - * Returns: the 64-bit keyID of the OpenPGP key. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_key_id(gnutls_openpgp_crt_t key, - gnutls_openpgp_keyid_t keyid) -{ - cdk_packet_t pkt; - uint32_t kid[2]; - - if (!key || !keyid) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - cdk_pk_get_keyid(pkt->pkt.public_key, kid); - _gnutls_write_uint32(kid[0], keyid); - _gnutls_write_uint32(kid[1], keyid + 4); - - return 0; -} - -/** - * gnutls_openpgp_crt_get_revoked_status: - * @key: the structure that contains the OpenPGP public key. - * - * Get revocation status of key. - * - * Returns: true (1) if the key has been revoked, or false (0) if it - * has not. - * - * Since: 2.4.0 - **/ -int gnutls_openpgp_crt_get_revoked_status(gnutls_openpgp_crt_t key) -{ - cdk_packet_t pkt; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - if (pkt->pkt.public_key->is_revoked != 0) - return 1; - return 0; -} - -/** - * gnutls_openpgp_crt_check_hostname: - * @key: should contain a #gnutls_openpgp_crt_t type - * @hostname: A null terminated string that contains a DNS name - * - * This function will check if the given key's owner matches the - * given hostname. This is a basic implementation of the matching - * described in RFC2818 (HTTPS), which takes into account wildcards. - * - * Returns: non-zero for a successful match, and zero on failure. - **/ -int -gnutls_openpgp_crt_check_hostname(gnutls_openpgp_crt_t key, - const char *hostname) -{ - return gnutls_openpgp_crt_check_hostname2(key, hostname, 0); -} - -/** - * gnutls_openpgp_crt_check_hostname2: - * @key: should contain a #gnutls_openpgp_crt_t type - * @hostname: A null terminated string that contains a DNS name - * @flags: gnutls_certificate_verify_flags - * - * This function will check if the given key's owner matches the - * given hostname. - * - * Unless, the flag %GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS is specified, - * wildcards are only considered if the domain name consists of three - * components or more, and the wildcard starts at the leftmost position. - * - * Returns: non-zero for a successful match, and zero on failure. - **/ -int -gnutls_openpgp_crt_check_hostname2(gnutls_openpgp_crt_t key, - const char *hostname, unsigned flags) -{ - char dnsname[MAX_CN]; - size_t dnsnamesize; - int ret = 0; - int i; - - /* Check through all included names. */ - for (i = 0; !(ret < 0); i++) { - dnsnamesize = sizeof(dnsname); - ret = - gnutls_openpgp_crt_get_name(key, i, dnsname, - &dnsnamesize); - - if (ret == 0) { - /* Length returned by gnutls_openpgp_crt_get_name includes - the terminating (0). */ - dnsnamesize--; - - if (_gnutls_hostname_compare - (dnsname, dnsnamesize, hostname, flags)) - return 1; - } - } - - /* not found a matching name */ - return 0; -} - -/** - * gnutls_openpgp_crt_check_email: - * @key: should contain a #gnutls_openpgp_crt_t type - * @email: A null terminated string that contains an RFC822 address (email) - * @flags: gnutls_certificate_verify_flags - * - * This function will check if the given key's owner matches the - * given email address. - * - * Returns: non-zero for a successful match, and zero on failure. - **/ -int -gnutls_openpgp_crt_check_email(gnutls_openpgp_crt_t key, - const char *email, unsigned flags) -{ - char rfc822name[MAX_CN]; - size_t rfc822name_size; - int ret = 0; - int i; - - /* Check through all included names. */ - for (i = 0; !(ret < 0); i++) { - rfc822name_size = sizeof(rfc822name); - ret = - gnutls_openpgp_crt_get_name(key, i, rfc822name, - &rfc822name_size); - - if (ret == 0) { - /* Length returned by gnutls_openpgp_crt_get_name includes - the terminating (0). */ - rfc822name_size--; - - if (_gnutls_hostname_compare - (rfc822name, rfc822name_size, email, GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS)) - return 1; - } - } - - /* not found a matching name */ - return 0; -} - -unsigned int _gnutls_get_pgp_key_usage(unsigned int cdk_usage) -{ - unsigned int usage = 0; - - if (cdk_usage & CDK_KEY_USG_CERT_SIGN) - usage |= GNUTLS_KEY_KEY_CERT_SIGN; - if (cdk_usage & CDK_KEY_USG_DATA_SIGN) - usage |= GNUTLS_KEY_DIGITAL_SIGNATURE; - if (cdk_usage & CDK_KEY_USG_COMM_ENCR) - usage |= GNUTLS_KEY_KEY_ENCIPHERMENT; - if (cdk_usage & CDK_KEY_USG_STORAGE_ENCR) - usage |= GNUTLS_KEY_DATA_ENCIPHERMENT; - if (cdk_usage & CDK_KEY_USG_AUTH) - usage |= GNUTLS_KEY_KEY_AGREEMENT; - - return usage; -} - -/** - * gnutls_openpgp_crt_get_key_usage: - * @key: should contain a gnutls_openpgp_crt_t type - * @key_usage: where the key usage bits will be stored - * - * This function will return certificate's key usage, by checking the - * key algorithm. The key usage value will ORed values of the: - * %GNUTLS_KEY_DIGITAL_SIGNATURE, %GNUTLS_KEY_KEY_ENCIPHERMENT. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - */ -int -gnutls_openpgp_crt_get_key_usage(gnutls_openpgp_crt_t key, - unsigned int *key_usage) -{ - cdk_packet_t pkt; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - *key_usage = - _gnutls_get_pgp_key_usage(pkt->pkt.public_key->pubkey_usage); - - return 0; -} - -/** - * gnutls_openpgp_crt_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_crt_get_subkey_count(gnutls_openpgp_crt_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_PUBLIC_SUBKEY) - subkeys++; - } - - return subkeys; -} - -/* returns the subkey with the given index */ -static cdk_packet_t -_get_public_subkey(gnutls_openpgp_crt_t key, unsigned int indx) -{ - cdk_kbnode_t p, ctx; - cdk_packet_t pkt; - unsigned int subkeys; - - if (key == NULL) { - gnutls_assert(); - return NULL; - } - - ctx = NULL; - subkeys = 0; - while ((p = cdk_kbnode_walk(key->knode, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - if (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY - && indx == subkeys++) - return pkt; - } - - return NULL; -} - -/* returns the key with the given keyid. It can be either key or subkey. - * depending on what requested: - * pkt->pkt.secret_key; - * pkt->pkt.public_key; - */ -cdk_packet_t -_gnutls_openpgp_find_key(cdk_kbnode_t knode, uint32_t keyid[2], - unsigned int priv) -{ - cdk_kbnode_t p, ctx; - cdk_packet_t pkt; - uint32_t local_keyid[2]; - - ctx = NULL; - while ((p = cdk_kbnode_walk(knode, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - - if ((priv == 0 - && (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY - || pkt->pkttype == CDK_PKT_PUBLIC_KEY)) - || (priv != 0 - && (pkt->pkttype == CDK_PKT_SECRET_SUBKEY - || pkt->pkttype == CDK_PKT_SECRET_KEY))) { - if (priv == 0) - cdk_pk_get_keyid(pkt->pkt.public_key, - local_keyid); - else - cdk_pk_get_keyid(pkt->pkt.secret_key->pk, - local_keyid); - - if (local_keyid[0] == keyid[0] - && local_keyid[1] == keyid[1]) { - return pkt; - } - } - } - - gnutls_assert(); - return NULL; -} - -/* returns the key with the given keyid - * depending on what requested: - * pkt->pkt.secret_key; - * pkt->pkt.public_key; - */ -int -_gnutls_openpgp_find_subkey_idx(cdk_kbnode_t knode, uint32_t keyid[2], - unsigned int priv) -{ - cdk_kbnode_t p, ctx; - cdk_packet_t pkt; - int i = 0; - uint32_t local_keyid[2]; - - _gnutls_hard_log("Looking keyid: %x.%x\n", keyid[0], keyid[1]); - - ctx = NULL; - while ((p = cdk_kbnode_walk(knode, &ctx, 0))) { - pkt = cdk_kbnode_get_packet(p); - - if ((priv == 0 && (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)) - || (priv != 0 - && (pkt->pkttype == CDK_PKT_SECRET_SUBKEY))) { - if (priv == 0) - cdk_pk_get_keyid(pkt->pkt.public_key, - local_keyid); - else - cdk_pk_get_keyid(pkt->pkt.secret_key->pk, - local_keyid); - - _gnutls_hard_log("Found keyid: %x.%x\n", - local_keyid[0], local_keyid[1]); - if (local_keyid[0] == keyid[0] - && local_keyid[1] == keyid[1]) { - return i; - } - i++; - } - } - - gnutls_assert(); - return GNUTLS_E_OPENPGP_SUBKEY_ERROR; -} - -/** - * gnutls_openpgp_crt_get_subkey_revoked_status: - * @key: the structure that contains the OpenPGP public key. - * @idx: is the subkey index - * - * Get subkey revocation status. A negative error code indicates an error. - * - * Returns: true (1) if the key has been revoked, or false (0) if it - * has not. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_subkey_revoked_status(gnutls_openpgp_crt_t key, - unsigned int idx) -{ - cdk_packet_t pkt; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_revoked_status(key); - - pkt = _get_public_subkey(key, idx); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - if (pkt->pkt.public_key->is_revoked != 0) - return 1; - return 0; -} - -/** - * gnutls_openpgp_crt_get_subkey_pk_algorithm: - * @key: is an OpenPGP key - * @idx: is the subkey index - * @bits: if bits is non null it will hold the size of the parameters' in bits - * - * This function will return the public key algorithm of a subkey of an OpenPGP - * certificate. - * - * If bits is non null, it should have enough size to hold the - * parameters size in bits. For RSA the bits returned is the modulus. - * For DSA the bits returned are of the public exponent. - * - * Returns: a member of the #gnutls_pk_algorithm_t enumeration on - * success, or GNUTLS_PK_UNKNOWN on error. - * - * Since: 2.4.0 - **/ -gnutls_pk_algorithm_t -gnutls_openpgp_crt_get_subkey_pk_algorithm(gnutls_openpgp_crt_t key, - unsigned int idx, - unsigned int *bits) -{ - cdk_packet_t pkt; - int algo; - - if (!key) { - gnutls_assert(); - return GNUTLS_PK_UNKNOWN; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_pk_algorithm(key, bits); - - pkt = _get_public_subkey(key, idx); - - algo = 0; - if (pkt) { - if (bits) - *bits = cdk_pk_get_nbits(pkt->pkt.public_key); - algo = - _gnutls_openpgp_get_algo(pkt->pkt.public_key-> - pubkey_algo); - } - - return algo; -} - -/** - * gnutls_openpgp_crt_get_subkey_creation_time: - * @key: the structure that contains the OpenPGP public key. - * @idx: the subkey index - * - * Get subkey creation time. - * - * Returns: the timestamp when the OpenPGP sub-key was created. - * - * Since: 2.4.0 - **/ -time_t -gnutls_openpgp_crt_get_subkey_creation_time(gnutls_openpgp_crt_t key, - unsigned int idx) -{ - cdk_packet_t pkt; - time_t timestamp; - - if (!key) - return (time_t) - 1; - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_creation_time(key); - - pkt = _get_public_subkey(key, idx); - if (pkt) - timestamp = pkt->pkt.public_key->timestamp; - else - timestamp = 0; - - return timestamp; -} - - -/** - * gnutls_openpgp_crt_get_subkey_expiration_time: - * @key: the structure that contains the OpenPGP public key. - * @idx: the subkey index - * - * Get subkey expiration time. A value of '0' means that the key - * doesn't expire at all. - * - * Returns: the time when the OpenPGP key expires. - * - * Since: 2.4.0 - **/ -time_t -gnutls_openpgp_crt_get_subkey_expiration_time(gnutls_openpgp_crt_t key, - unsigned int idx) -{ - cdk_packet_t pkt; - time_t expiredate; - - if (!key) - return (time_t) - 1; - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_expiration_time(key); - - pkt = _get_public_subkey(key, idx); - if (pkt) - expiredate = pkt->pkt.public_key->expiredate; - else - expiredate = 0; - - return expiredate; -} - -/** - * gnutls_openpgp_crt_get_subkey_id: - * @key: the structure that contains the OpenPGP public key. - * @idx: the subkey index - * @keyid: the buffer to save the keyid. - * - * Get the subkey's key-id. - * - * Returns: the 64-bit keyID of the OpenPGP key. - **/ -int -gnutls_openpgp_crt_get_subkey_id(gnutls_openpgp_crt_t key, - unsigned int idx, - gnutls_openpgp_keyid_t keyid) -{ - cdk_packet_t pkt; - uint32_t kid[2]; - - if (!key || !keyid) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_key_id(key, keyid); - - pkt = _get_public_subkey(key, idx); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - cdk_pk_get_keyid(pkt->pkt.public_key, kid); - _gnutls_write_uint32(kid[0], keyid); - _gnutls_write_uint32(kid[1], keyid + 4); - - return 0; -} - -/** - * gnutls_openpgp_crt_get_subkey_fingerprint: - * @key: the raw data that contains the OpenPGP public key. - * @idx: the subkey index - * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes. - * @fprlen: the integer to save the length of the fingerprint. - * - * Get key fingerprint of a subkey. Depending on the algorithm, the - * fingerprint can be 16 or 20 bytes. - * - * Returns: On success, 0 is returned. Otherwise, an error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_subkey_fingerprint(gnutls_openpgp_crt_t key, - unsigned int idx, - void *fpr, size_t * fprlen) -{ - cdk_packet_t pkt; - cdk_pkt_pubkey_t pk = NULL; - - if (!fpr || !fprlen) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_fingerprint(key, fpr, - fprlen); - - *fprlen = 0; - - pkt = _get_public_subkey(key, idx); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - - pk = pkt->pkt.public_key; - *fprlen = 20; - - /* FIXME: Check if the draft allows old PGP keys. */ - if (is_RSA(pk->pubkey_algo) && pk->version < 4) - *fprlen = 16; - cdk_pk_get_fingerprint(pk, fpr); - - return 0; -} - -/** - * gnutls_openpgp_crt_get_subkey_idx: - * @key: the structure that contains the OpenPGP public key. - * @keyid: the keyid. - * - * Get subkey's index. - * - * Returns: the index of the subkey or a negative error value. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_subkey_idx(gnutls_openpgp_crt_t key, - const gnutls_openpgp_keyid_t keyid) -{ - int ret; - uint32_t kid[2]; - uint8_t master_id[GNUTLS_OPENPGP_KEYID_SIZE]; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - ret = gnutls_openpgp_crt_get_key_id(key, master_id); - if (ret < 0) - return gnutls_assert_val(ret); - if (memcmp(master_id, keyid, GNUTLS_OPENPGP_KEYID_SIZE) == 0) - return GNUTLS_OPENPGP_MASTER_KEYID_IDX; - - KEYID_IMPORT(kid, keyid); - ret = _gnutls_openpgp_find_subkey_idx(key->knode, kid, 0); - - if (ret < 0) { - gnutls_assert(); - } - - return ret; -} - -/** - * gnutls_openpgp_crt_get_subkey_usage: - * @key: should contain a gnutls_openpgp_crt_t type - * @idx: the subkey index - * @key_usage: where the key usage bits will be stored - * - * This function will return certificate's key usage, by checking the - * key algorithm. The key usage value will ORed values of - * %GNUTLS_KEY_DIGITAL_SIGNATURE or %GNUTLS_KEY_KEY_ENCIPHERMENT. - * - * A negative error code may be returned in case of parsing error. - * - * Returns: key usage value. - * - * Since: 2.4.0 - */ -int -gnutls_openpgp_crt_get_subkey_usage(gnutls_openpgp_crt_t key, - unsigned int idx, - unsigned int *key_usage) -{ - cdk_packet_t pkt; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_key_usage(key, key_usage); - - pkt = _get_public_subkey(key, idx); - if (!pkt) - return GNUTLS_E_OPENPGP_SUBKEY_ERROR; - - *key_usage = - _gnutls_get_pgp_key_usage(pkt->pkt.public_key->pubkey_usage); - - return 0; -} - -int -_gnutls_read_pgp_mpi(cdk_packet_t pkt, unsigned int priv, size_t idx, - bigint_t * m) -{ - size_t buf_size = 512; - uint8_t *buf = gnutls_malloc(buf_size); - int err; - unsigned int max_pub_params = 0; - - if (priv != 0) - max_pub_params = - cdk_pk_get_npkey(pkt->pkt.secret_key->pk->pubkey_algo); - - if (buf == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - /* FIXME: Note that opencdk doesn't like the buf to be NULL. - */ - if (priv == 0) - err = - cdk_pk_get_mpi(pkt->pkt.public_key, idx, buf, buf_size, - &buf_size, NULL); - else { - if (idx < max_pub_params) - err = - cdk_pk_get_mpi(pkt->pkt.secret_key->pk, idx, - buf, buf_size, &buf_size, NULL); - else { - err = - cdk_sk_get_mpi(pkt->pkt.secret_key, - idx - max_pub_params, buf, - buf_size, &buf_size, NULL); - } - } - - if (err == CDK_Too_Short) { - buf = gnutls_realloc_fast(buf, buf_size); - if (buf == NULL) { - gnutls_assert(); - return GNUTLS_E_MEMORY_ERROR; - } - - if (priv == 0) - err = - cdk_pk_get_mpi(pkt->pkt.public_key, idx, buf, - buf_size, &buf_size, NULL); - else { - if (idx < max_pub_params) - err = - cdk_pk_get_mpi(pkt->pkt.secret_key->pk, - idx, buf, buf_size, - &buf_size, NULL); - else { - err = - cdk_sk_get_mpi(pkt->pkt.secret_key, - idx - max_pub_params, - buf, buf_size, - &buf_size, NULL); - } - } - } - - if (err != CDK_Success) { - gnutls_assert(); - gnutls_free(buf); - return _gnutls_map_cdk_rc(err); - } - - err = _gnutls_mpi_init_scan(m, buf, buf_size); - gnutls_free(buf); - - if (err < 0) { - gnutls_assert(); - return err; - } - - return 0; -} - - -/* Extracts DSA and RSA parameters from a certificate. - */ -int -_gnutls_openpgp_crt_get_mpis(gnutls_openpgp_crt_t cert, - uint32_t * keyid /* [2] */ , - gnutls_pk_params_st * params) -{ - int result, i; - int pk_algorithm, local_params; - cdk_packet_t pkt; - - if (keyid == NULL) - pkt = - cdk_kbnode_find_packet(cert->knode, - CDK_PKT_PUBLIC_KEY); - else - pkt = _gnutls_openpgp_find_key(cert->knode, keyid, 0); - - if (pkt == NULL) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - pk_algorithm = - _gnutls_openpgp_get_algo(pkt->pkt.public_key->pubkey_algo); - - switch (pk_algorithm) { - case GNUTLS_PK_RSA: - local_params = RSA_PUBLIC_PARAMS; - break; - case GNUTLS_PK_DSA: - local_params = DSA_PUBLIC_PARAMS; - break; - default: - gnutls_assert(); - return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; - } - - gnutls_pk_params_init(params); - - for (i = 0; i < local_params; i++) { - result = - _gnutls_read_pgp_mpi(pkt, 0, i, ¶ms->params[i]); - if (result < 0) { - gnutls_assert(); - goto error; - } - params->params_nr++; - } - - return 0; - - error: - gnutls_pk_params_release(params); - - return result; -} - -/* The internal version of export - */ -static int -_get_pk_rsa_raw(gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, - gnutls_datum_t * m, gnutls_datum_t * e) -{ - int pk_algorithm, ret; - cdk_packet_t pkt; - uint32_t kid32[2]; - gnutls_pk_params_st params; - - gnutls_pk_params_init(¶ms); - - if (crt == NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - KEYID_IMPORT(kid32, keyid); - - pkt = _gnutls_openpgp_find_key(crt->knode, kid32, 0); - if (pkt == NULL) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - pk_algorithm = - _gnutls_openpgp_get_algo(pkt->pkt.public_key->pubkey_algo); - - if (pk_algorithm != GNUTLS_PK_RSA) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - ret = _gnutls_openpgp_crt_get_mpis(crt, kid32, ¶ms); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - ret = _gnutls_mpi_dprint(params.params[0], m); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - ret = _gnutls_mpi_dprint(params.params[1], e); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(m); - goto cleanup; - } - - ret = 0; - - cleanup: - gnutls_pk_params_release(¶ms); - return ret; -} - -static int -_get_pk_dsa_raw(gnutls_openpgp_crt_t crt, gnutls_openpgp_keyid_t keyid, - gnutls_datum_t * p, gnutls_datum_t * q, - gnutls_datum_t * g, gnutls_datum_t * y) -{ - int pk_algorithm, ret; - cdk_packet_t pkt; - uint32_t kid32[2]; - gnutls_pk_params_st params; - - gnutls_pk_params_init(¶ms); - - if (crt == NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - KEYID_IMPORT(kid32, keyid); - - pkt = _gnutls_openpgp_find_key(crt->knode, kid32, 0); - if (pkt == NULL) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_GETKEY_FAILED; - } - - pk_algorithm = - _gnutls_openpgp_get_algo(pkt->pkt.public_key->pubkey_algo); - - if (pk_algorithm != GNUTLS_PK_DSA) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - ret = _gnutls_openpgp_crt_get_mpis(crt, kid32, ¶ms); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - /* P */ - ret = _gnutls_mpi_dprint(params.params[0], p); - if (ret < 0) { - gnutls_assert(); - goto cleanup; - } - - /* Q */ - ret = _gnutls_mpi_dprint(params.params[1], q); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(p); - goto cleanup; - } - - - /* G */ - ret = _gnutls_mpi_dprint(params.params[2], g); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(p); - _gnutls_free_datum(q); - goto cleanup; - } - - - /* Y */ - ret = _gnutls_mpi_dprint(params.params[3], y); - if (ret < 0) { - gnutls_assert(); - _gnutls_free_datum(p); - _gnutls_free_datum(g); - _gnutls_free_datum(q); - goto cleanup; - } - - ret = 0; - - cleanup: - gnutls_pk_params_release(¶ms); - return ret; -} - - -/** - * gnutls_openpgp_crt_get_pk_rsa_raw: - * @crt: Holds the certificate - * @m: will hold the modulus - * @e: will hold the public exponent - * - * This function will export the RSA public key's parameters found in - * the given structure. The new parameters will be allocated using - * gnutls_malloc() and will be stored in the appropriate datum. - * - * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_pk_rsa_raw(gnutls_openpgp_crt_t crt, - gnutls_datum_t * m, gnutls_datum_t * e) -{ - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int ret; - - ret = gnutls_openpgp_crt_get_key_id(crt, keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return _get_pk_rsa_raw(crt, keyid, m, e); -} - -/** - * gnutls_openpgp_crt_get_pk_dsa_raw: - * @crt: Holds the certificate - * @p: will hold the p - * @q: will hold the q - * @g: will hold the g - * @y: will hold the y - * - * This function will export the DSA public key's parameters found in - * the given certificate. The new parameters will be allocated using - * gnutls_malloc() and will be stored in the appropriate datum. - * - * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_pk_dsa_raw(gnutls_openpgp_crt_t crt, - gnutls_datum_t * p, gnutls_datum_t * q, - gnutls_datum_t * g, gnutls_datum_t * y) -{ - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int ret; - - ret = gnutls_openpgp_crt_get_key_id(crt, keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return _get_pk_dsa_raw(crt, keyid, p, q, g, y); -} - -/** - * gnutls_openpgp_crt_get_subkey_pk_rsa_raw: - * @crt: Holds the certificate - * @idx: Is the subkey index - * @m: will hold the modulus - * @e: will hold the public exponent - * - * This function will export the RSA public key's parameters found in - * the given structure. The new parameters will be allocated using - * gnutls_malloc() and will be stored in the appropriate datum. - * - * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_subkey_pk_rsa_raw(gnutls_openpgp_crt_t crt, - unsigned int idx, - gnutls_datum_t * m, - gnutls_datum_t * e) -{ - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int ret; - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_pk_rsa_raw(crt, m, e); - - ret = gnutls_openpgp_crt_get_subkey_id(crt, idx, keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return _get_pk_rsa_raw(crt, keyid, m, e); -} - -/** - * gnutls_openpgp_crt_get_subkey_pk_dsa_raw: - * @crt: Holds the certificate - * @idx: Is the subkey index - * @p: will hold the p - * @q: will hold the q - * @g: will hold the g - * @y: will hold the y - * - * This function will export the DSA public key's parameters found in - * the given certificate. The new parameters will be allocated using - * gnutls_malloc() and will be stored in the appropriate datum. - * - * Returns: %GNUTLS_E_SUCCESS on success, otherwise a negative error code. - * - * Since: 2.4.0 - **/ -int -gnutls_openpgp_crt_get_subkey_pk_dsa_raw(gnutls_openpgp_crt_t crt, - unsigned int idx, - gnutls_datum_t * p, - gnutls_datum_t * q, - gnutls_datum_t * g, - gnutls_datum_t * y) -{ - uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; - int ret; - - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_pk_dsa_raw(crt, p, q, g, y); - - ret = gnutls_openpgp_crt_get_subkey_id(crt, idx, keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - return _get_pk_dsa_raw(crt, keyid, p, q, g, y); -} - -/** - * gnutls_openpgp_crt_get_preferred_key_id: - * @key: the structure that contains the OpenPGP public key. - * @keyid: the struct to save the keyid. - * - * Get preferred key id. If it hasn't been set it returns - * %GNUTLS_E_INVALID_REQUEST. - * - * Returns: the 64-bit preferred keyID of the OpenPGP key. - **/ -int -gnutls_openpgp_crt_get_preferred_key_id(gnutls_openpgp_crt_t key, - gnutls_openpgp_keyid_t keyid) -{ - if (!key || !keyid) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (!key->preferred_set) - return - gnutls_assert_val - (GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR); - - memcpy(keyid, key->preferred_keyid, GNUTLS_OPENPGP_KEYID_SIZE); - - return 0; -} - -/** - * gnutls_openpgp_crt_set_preferred_key_id: - * @key: the structure that contains the OpenPGP public key. - * @keyid: the selected keyid - * - * This allows setting a preferred key id for the given certificate. - * This key will be used by functions that involve key handling. - * - * If the provided @keyid is %NULL then the master key is - * set as preferred. - * - * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, - * otherwise a negative error code is returned. - **/ -int -gnutls_openpgp_crt_set_preferred_key_id(gnutls_openpgp_crt_t key, - const gnutls_openpgp_keyid_t keyid) -{ - int ret; - - if (!key) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - - if (keyid == NULL) { /* set the master as preferred */ - uint8_t tmp[GNUTLS_OPENPGP_KEYID_SIZE]; - - ret = gnutls_openpgp_crt_get_key_id(key, tmp); - if (ret < 0) - return gnutls_assert_val(ret); - - key->preferred_set = 1; - memcpy(key->preferred_keyid, tmp, - GNUTLS_OPENPGP_KEYID_SIZE); - - return 0; - } - - /* check if the id is valid */ - ret = gnutls_openpgp_crt_get_subkey_idx(key, keyid); - if (ret < 0) { - _gnutls_debug_log("the requested subkey does not exist\n"); - gnutls_assert(); - return ret; - } - - key->preferred_set = 1; - memcpy(key->preferred_keyid, keyid, GNUTLS_OPENPGP_KEYID_SIZE); - - return 0; -} - -/** - * gnutls_openpgp_crt_get_auth_subkey: - * @crt: the structure that contains the OpenPGP public key. - * @keyid: the struct to save the keyid. - * @flag: Non-zero indicates that a valid subkey is always returned. - * - * Returns the 64-bit keyID of the first valid OpenPGP subkey marked - * for authentication. If flag is non-zero and no authentication - * subkey exists, then a valid subkey will be returned even if it is - * not marked for authentication. - * - * Returns: %GNUTLS_E_SUCCESS on success, or an error code. - **/ -int -gnutls_openpgp_crt_get_auth_subkey(gnutls_openpgp_crt_t crt, - gnutls_openpgp_keyid_t keyid, - unsigned int flag) -{ - int ret, subkeys, i; - unsigned int usage; - unsigned int keyid_init = 0; - - subkeys = gnutls_openpgp_crt_get_subkey_count(crt); - if (subkeys <= 0) { - gnutls_assert(); - return GNUTLS_E_OPENPGP_SUBKEY_ERROR; - } - - /* Try to find a subkey with the authentication flag set. - * if none exists use the last one found - */ - for (i = 0; i < subkeys; i++) { - ret = - gnutls_openpgp_crt_get_subkey_pk_algorithm(crt, i, - NULL); - if (ret == GNUTLS_PK_UNKNOWN) - continue; - - ret = gnutls_openpgp_crt_get_subkey_revoked_status(crt, i); - if (ret != 0) /* it is revoked. ignore it */ - continue; - - if (keyid_init == 0) { /* keep the first valid subkey */ - ret = - gnutls_openpgp_crt_get_subkey_id(crt, i, - keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - keyid_init = 1; - } - - ret = gnutls_openpgp_crt_get_subkey_usage(crt, i, &usage); - if (ret < 0) { - gnutls_assert(); - return ret; - } - - if (usage & GNUTLS_KEY_KEY_AGREEMENT) { - ret = - gnutls_openpgp_crt_get_subkey_id(crt, i, - keyid); - if (ret < 0) { - gnutls_assert(); - return ret; - } - return 0; - } - } - - if (flag && keyid_init) - return 0; - else - return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; -} |