diff options
Diffstat (limited to 'lib/openpgp/pgp.c')
-rw-r--r-- | lib/openpgp/pgp.c | 2143 |
1 files changed, 1044 insertions, 1099 deletions
diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c index 38cab4f417..0c714e8e4c 100644 --- a/lib/openpgp/pgp.c +++ b/lib/openpgp/pgp.c @@ -40,14 +40,13 @@ * * Returns: %GNUTLS_E_SUCCESS on success, or an error code. **/ -int -gnutls_openpgp_crt_init (gnutls_openpgp_crt_t * key) +int gnutls_openpgp_crt_init(gnutls_openpgp_crt_t * key) { - *key = gnutls_calloc (1, sizeof (gnutls_openpgp_crt_int)); + *key = gnutls_calloc(1, sizeof(gnutls_openpgp_crt_int)); - if (*key) - return 0; /* success */ - return GNUTLS_E_MEMORY_ERROR; + if (*key) + return 0; /* success */ + return GNUTLS_E_MEMORY_ERROR; } /** @@ -56,19 +55,17 @@ gnutls_openpgp_crt_init (gnutls_openpgp_crt_t * key) * * This function will deinitialize a key structure. **/ -void -gnutls_openpgp_crt_deinit (gnutls_openpgp_crt_t key) +void gnutls_openpgp_crt_deinit(gnutls_openpgp_crt_t key) { - if (!key) - return; + if (!key) + return; - if (key->knode) - { - cdk_kbnode_release (key->knode); - key->knode = NULL; - } + if (key->knode) { + cdk_kbnode_release(key->knode); + key->knode = NULL; + } - gnutls_free (key); + gnutls_free(key); } /** @@ -84,130 +81,125 @@ gnutls_openpgp_crt_deinit (gnutls_openpgp_crt_t 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) +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); - 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; + 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); + 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 _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; + 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) +_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); - memcpy (in, output_data, *output_data_size); - - /* 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; + 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); + memcpy(in, output_data, *output_data_size); + + /* 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; } @@ -226,12 +218,12 @@ _gnutls_openpgp_export (cdk_kbnode_t node, * 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) +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); + return _gnutls_openpgp_export(key->knode, format, output_data, + output_data_size, 0); } /** @@ -248,11 +240,11 @@ gnutls_openpgp_crt_export (gnutls_openpgp_crt_t key, * Since: 3.1.3 **/ int -gnutls_openpgp_crt_export2 (gnutls_openpgp_crt_t key, - gnutls_openpgp_crt_fmt_t format, - gnutls_datum_t *out) +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); + return _gnutls_openpgp_export2(key->knode, format, out, 0); } /** @@ -267,58 +259,54 @@ gnutls_openpgp_crt_export2 (gnutls_openpgp_crt_t key, * 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) +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; + cdk_packet_t pkt; + cdk_pkt_pubkey_t pk = NULL; - if (!fpr || !fprlen) - { - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } + if (!fpr || !fprlen) { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } - *fprlen = 0; + *fprlen = 0; - pkt = cdk_kbnode_find_packet (key->knode, CDK_PKT_PUBLIC_KEY); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; + 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; + 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); + /* 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; + return 0; } -static int -_gnutls_openpgp_count_key_names (gnutls_openpgp_crt_t key) +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; + 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; } @@ -338,60 +326,54 @@ _gnutls_openpgp_count_key_names (gnutls_openpgp_crt_t key) * error code. **/ int -gnutls_openpgp_crt_get_name (gnutls_openpgp_crt_t key, - int idx, char *buf, size_t * sizeof_buf) +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; + 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; } /** @@ -410,42 +392,42 @@ gnutls_openpgp_crt_get_name (gnutls_openpgp_crt_t key, * 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) +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; + 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; } @@ -457,22 +439,21 @@ gnutls_openpgp_crt_get_pk_algorithm (gnutls_openpgp_crt_t 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) +int gnutls_openpgp_crt_get_version(gnutls_openpgp_crt_t key) { - cdk_packet_t pkt; - int version; + cdk_packet_t pkt; + int version; - if (!key) - return -1; + 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; + pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); + if (pkt) + version = pkt->pkt.public_key->version; + else + version = 0; - return version; + return version; } @@ -484,22 +465,21 @@ gnutls_openpgp_crt_get_version (gnutls_openpgp_crt_t key) * * Returns: the timestamp when the OpenPGP key was created. **/ -time_t -gnutls_openpgp_crt_get_creation_time (gnutls_openpgp_crt_t key) +time_t gnutls_openpgp_crt_get_creation_time(gnutls_openpgp_crt_t key) { - cdk_packet_t pkt; - time_t timestamp; + cdk_packet_t pkt; + time_t timestamp; - if (!key) - return (time_t) - 1; + 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; + pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); + if (pkt) + timestamp = pkt->pkt.public_key->timestamp; + else + timestamp = 0; - return timestamp; + return timestamp; } @@ -512,22 +492,21 @@ gnutls_openpgp_crt_get_creation_time (gnutls_openpgp_crt_t key) * * Returns: the time when the OpenPGP key expires. **/ -time_t -gnutls_openpgp_crt_get_expiration_time (gnutls_openpgp_crt_t key) +time_t gnutls_openpgp_crt_get_expiration_time(gnutls_openpgp_crt_t key) { - cdk_packet_t pkt; - time_t expiredate; + cdk_packet_t pkt; + time_t expiredate; - if (!key) - return (time_t) - 1; + 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; + pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY); + if (pkt) + expiredate = pkt->pkt.public_key->expiredate; + else + expiredate = 0; - return expiredate; + return expiredate; } /** @@ -542,27 +521,26 @@ gnutls_openpgp_crt_get_expiration_time (gnutls_openpgp_crt_t key) * Since: 2.4.0 **/ int -gnutls_openpgp_crt_get_key_id (gnutls_openpgp_crt_t key, - gnutls_openpgp_keyid_t keyid) +gnutls_openpgp_crt_get_key_id(gnutls_openpgp_crt_t key, + gnutls_openpgp_keyid_t keyid) { - cdk_packet_t pkt; - uint32_t kid[2]; + cdk_packet_t pkt; + uint32_t kid[2]; - if (!key || !keyid) - { - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } + 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; + 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); + cdk_pk_get_keyid(pkt->pkt.public_key, kid); + _gnutls_write_uint32(kid[0], keyid); + _gnutls_write_uint32(kid[1], keyid + 4); - return 0; + return 0; } /** @@ -576,24 +554,22 @@ gnutls_openpgp_crt_get_key_id (gnutls_openpgp_crt_t key, * * Since: 2.4.0 **/ -int -gnutls_openpgp_crt_get_revoked_status (gnutls_openpgp_crt_t key) +int gnutls_openpgp_crt_get_revoked_status(gnutls_openpgp_crt_t key) { - cdk_packet_t pkt; + cdk_packet_t pkt; - if (!key) - { - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } + 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; + 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; + if (pkt->pkt.public_key->is_revoked != 0) + return 1; + return 0; } /** @@ -608,52 +584,52 @@ gnutls_openpgp_crt_get_revoked_status (gnutls_openpgp_crt_t key) * 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) +gnutls_openpgp_crt_check_hostname(gnutls_openpgp_crt_t key, + const char *hostname) { - 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, 0)) - return 1; - } - } - - /* not found a matching name */ - return 0; + 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, 0)) + return 1; + } + } + + /* not found a matching name */ + return 0; } -unsigned int -_gnutls_get_pgp_key_usage (unsigned int cdk_usage) +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; + 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; } /** @@ -668,24 +644,24 @@ _gnutls_get_pgp_key_usage (unsigned int cdk_usage) * 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) +gnutls_openpgp_crt_get_key_usage(gnutls_openpgp_crt_t key, + unsigned int *key_usage) { - cdk_packet_t pkt; + cdk_packet_t pkt; - if (!key) - { - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } + 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; + 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); + *key_usage = + _gnutls_get_pgp_key_usage(pkt->pkt.public_key->pubkey_usage); - return 0; + return 0; } /** @@ -699,55 +675,51 @@ gnutls_openpgp_crt_get_key_usage (gnutls_openpgp_crt_t key, * * Since: 2.4.0 **/ -int -gnutls_openpgp_crt_get_subkey_count (gnutls_openpgp_crt_t key) +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; + 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) +_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; + 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. @@ -756,41 +728,39 @@ _get_public_subkey (gnutls_openpgp_crt_t key, unsigned int indx) * pkt->pkt.public_key; */ cdk_packet_t -_gnutls_openpgp_find_key (cdk_kbnode_t knode, uint32_t keyid[2], - unsigned int priv) +_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; + 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 @@ -799,41 +769,42 @@ _gnutls_openpgp_find_key (cdk_kbnode_t knode, uint32_t keyid[2], * pkt->pkt.public_key; */ int -_gnutls_openpgp_find_subkey_idx (cdk_kbnode_t knode, uint32_t keyid[2], - unsigned int priv) +_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; + 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; } /** @@ -849,27 +820,26 @@ _gnutls_openpgp_find_subkey_idx (cdk_kbnode_t knode, uint32_t keyid[2], * Since: 2.4.0 **/ int -gnutls_openpgp_crt_get_subkey_revoked_status (gnutls_openpgp_crt_t key, - unsigned int idx) +gnutls_openpgp_crt_get_subkey_revoked_status(gnutls_openpgp_crt_t key, + unsigned int idx) { - cdk_packet_t pkt; + cdk_packet_t pkt; - if (!key) - { - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } + if (!key) { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_revoked_status(key); + 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; + 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; + if (pkt->pkt.public_key->is_revoked != 0) + return 1; + return 0; } /** @@ -891,33 +861,33 @@ gnutls_openpgp_crt_get_subkey_revoked_status (gnutls_openpgp_crt_t key, * 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) +gnutls_openpgp_crt_get_subkey_pk_algorithm(gnutls_openpgp_crt_t key, + unsigned int idx, + unsigned int *bits) { - cdk_packet_t pkt; - int algo; + cdk_packet_t pkt; + int algo; - if (!key) - { - gnutls_assert (); - return GNUTLS_PK_UNKNOWN; - } + if (!key) { + gnutls_assert(); + return GNUTLS_PK_UNKNOWN; + } - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_pk_algorithm(key, bits); + if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) + return gnutls_openpgp_crt_get_pk_algorithm(key, bits); - pkt = _get_public_subkey (key, idx); + 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); - } + 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; + return algo; } /** @@ -932,25 +902,25 @@ gnutls_openpgp_crt_get_subkey_pk_algorithm (gnutls_openpgp_crt_t key, * Since: 2.4.0 **/ time_t -gnutls_openpgp_crt_get_subkey_creation_time (gnutls_openpgp_crt_t key, - unsigned int idx) +gnutls_openpgp_crt_get_subkey_creation_time(gnutls_openpgp_crt_t key, + unsigned int idx) { - cdk_packet_t pkt; - time_t timestamp; + cdk_packet_t pkt; + time_t timestamp; - if (!key) - return (time_t) - 1; + if (!key) + return (time_t) - 1; - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_creation_time(key); + 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; + pkt = _get_public_subkey(key, idx); + if (pkt) + timestamp = pkt->pkt.public_key->timestamp; + else + timestamp = 0; - return timestamp; + return timestamp; } @@ -967,25 +937,25 @@ gnutls_openpgp_crt_get_subkey_creation_time (gnutls_openpgp_crt_t key, * Since: 2.4.0 **/ time_t -gnutls_openpgp_crt_get_subkey_expiration_time (gnutls_openpgp_crt_t key, - unsigned int idx) +gnutls_openpgp_crt_get_subkey_expiration_time(gnutls_openpgp_crt_t key, + unsigned int idx) { - cdk_packet_t pkt; - time_t expiredate; + cdk_packet_t pkt; + time_t expiredate; - if (!key) - return (time_t) - 1; + if (!key) + return (time_t) - 1; - if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) - return gnutls_openpgp_crt_get_expiration_time(key); + 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; + pkt = _get_public_subkey(key, idx); + if (pkt) + expiredate = pkt->pkt.public_key->expiredate; + else + expiredate = 0; - return expiredate; + return expiredate; } /** @@ -999,31 +969,30 @@ gnutls_openpgp_crt_get_subkey_expiration_time (gnutls_openpgp_crt_t key, * 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) +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; + 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; } /** @@ -1041,37 +1010,37 @@ gnutls_openpgp_crt_get_subkey_id (gnutls_openpgp_crt_t key, * Since: 2.4.0 **/ int -gnutls_openpgp_crt_get_subkey_fingerprint (gnutls_openpgp_crt_t key, - unsigned int idx, - void *fpr, size_t * fprlen) +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; + cdk_packet_t pkt; + cdk_pkt_pubkey_t pk = NULL; + + if (!fpr || !fprlen) { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } - 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); + if (idx == GNUTLS_OPENPGP_MASTER_KEYID_IDX) + return gnutls_openpgp_crt_get_fingerprint(key, fpr, + fprlen); - *fprlen = 0; + *fprlen = 0; - pkt = _get_public_subkey (key, idx); - if (!pkt) - return GNUTLS_E_OPENPGP_GETKEY_FAILED; + pkt = _get_public_subkey(key, idx); + if (!pkt) + return GNUTLS_E_OPENPGP_GETKEY_FAILED; - pk = pkt->pkt.public_key; - *fprlen = 20; + 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); + /* 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; + return 0; } /** @@ -1086,34 +1055,32 @@ gnutls_openpgp_crt_get_subkey_fingerprint (gnutls_openpgp_crt_t key, * Since: 2.4.0 **/ int -gnutls_openpgp_crt_get_subkey_idx (gnutls_openpgp_crt_t key, - const gnutls_openpgp_keyid_t keyid) +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; + 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; } /** @@ -1133,326 +1100,310 @@ gnutls_openpgp_crt_get_subkey_idx (gnutls_openpgp_crt_t key, * Since: 2.4.0 */ int -gnutls_openpgp_crt_get_subkey_usage (gnutls_openpgp_crt_t key, - unsigned int idx, - unsigned int *key_usage) +gnutls_openpgp_crt_get_subkey_usage(gnutls_openpgp_crt_t key, + unsigned int idx, + unsigned int *key_usage) { - cdk_packet_t pkt; + cdk_packet_t pkt; - if (!key) - { - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } + 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); + 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; + 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); + *key_usage = + _gnutls_get_pgp_key_usage(pkt->pkt.public_key->pubkey_usage); - return 0; + return 0; } int -_gnutls_read_pgp_mpi (cdk_packet_t pkt, unsigned int priv, size_t idx, - bigint_t * m) +_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_scan (m, buf, buf_size); - gnutls_free (buf); - - if (err < 0) - { - gnutls_assert (); - return err; - } - - return 0; + 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_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) +_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; + 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) +_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; + 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) +_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; + 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; } @@ -1471,20 +1422,19 @@ cleanup: * 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) +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; + 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; - } + 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); + return _get_pk_rsa_raw(crt, keyid, m, e); } /** @@ -1504,21 +1454,20 @@ gnutls_openpgp_crt_get_pk_rsa_raw (gnutls_openpgp_crt_t crt, * 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) +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; + 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; - } + 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); + return _get_pk_dsa_raw(crt, keyid, p, q, g, y); } /** @@ -1537,25 +1486,24 @@ gnutls_openpgp_crt_get_pk_dsa_raw (gnutls_openpgp_crt_t crt, * 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) +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; + 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); + 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; - } + 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); + return _get_pk_rsa_raw(crt, keyid, m, e); } /** @@ -1576,27 +1524,26 @@ gnutls_openpgp_crt_get_subkey_pk_rsa_raw (gnutls_openpgp_crt_t crt, * 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) +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; + 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); + 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; - } + 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); + return _get_pk_dsa_raw(crt, keyid, p, q, g, y); } /** @@ -1610,21 +1557,22 @@ gnutls_openpgp_crt_get_subkey_pk_dsa_raw (gnutls_openpgp_crt_t crt, * 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) +gnutls_openpgp_crt_get_preferred_key_id(gnutls_openpgp_crt_t key, + gnutls_openpgp_keyid_t keyid) { - if (!key->preferred_set) - return gnutls_assert_val(GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR); + if (!key->preferred_set) + return + gnutls_assert_val + (GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR); - if (!key || !keyid) - { - gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } + if (!key || !keyid) { + gnutls_assert(); + return GNUTLS_E_INVALID_REQUEST; + } - memcpy (keyid, key->preferred_keyid, GNUTLS_OPENPGP_KEYID_SIZE); + memcpy(keyid, key->preferred_keyid, GNUTLS_OPENPGP_KEYID_SIZE); - return 0; + return 0; } /** @@ -1642,44 +1590,42 @@ gnutls_openpgp_crt_get_preferred_key_id (gnutls_openpgp_crt_t key, * 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) +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; + 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; } /** @@ -1696,67 +1642,66 @@ gnutls_openpgp_crt_set_preferred_key_id (gnutls_openpgp_crt_t key, * 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) +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; + 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; } |