diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | lib/abstract_int.h | 7 | ||||
-rw-r--r-- | lib/auth/cert.c | 28 | ||||
-rw-r--r-- | lib/gnutls_pubkey.c | 32 | ||||
-rw-r--r-- | lib/includes/gnutls/abstract.h | 12 | ||||
-rw-r--r-- | lib/includes/gnutls/openpgp.h | 3 | ||||
-rw-r--r-- | lib/openpgp/gnutls_openpgp.c | 2 |
7 files changed, 72 insertions, 15 deletions
@@ -21,6 +21,9 @@ cards are present. ** libgnutls: Corrected issue in the (deprecated) external key signing interface, when used with TLS 1.2. Reported by Bjorn H. Christensen. +** libgnutls: Fixes in openpgp handshake with fingerprints. Reported by +Joke de Buhr. + ** libgnutls-dane: Updated DANE verification options. ** configure: Trust store file must be explicitly set or unset when diff --git a/lib/abstract_int.h b/lib/abstract_int.h index ae7af940c5..00141a222e 100644 --- a/lib/abstract_int.h +++ b/lib/abstract_int.h @@ -67,8 +67,13 @@ struct gnutls_pubkey_st */ gnutls_pk_params_st params; +#ifdef ENABLE_OPENPGP uint8_t openpgp_key_id[GNUTLS_OPENPGP_KEYID_SIZE]; - int openpgp_key_id_set; + unsigned int openpgp_key_id_set; + + uint8_t openpgp_key_fpr[GNUTLS_OPENPGP_V4_FINGERPRINT_SIZE]; + unsigned int openpgp_key_fpr_set:1; +#endif unsigned int key_usage; /* bits from GNUTLS_KEY_* */ diff --git a/lib/auth/cert.c b/lib/auth/cert.c index 77538eb4ec..0d57048063 100644 --- a/lib/auth/cert.c +++ b/lib/auth/cert.c @@ -935,7 +935,9 @@ _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, { int ret, packet_size; uint8_t type, fpr[20]; - size_t fpr_size; + uint8_t id[20]; + unsigned int subkey; + size_t fpr_size, id_size; gnutls_pcert_st *apr_cert_list; gnutls_privkey_t apr_pkey; int apr_cert_list_length; @@ -949,10 +951,21 @@ _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, return ret; } + if (apr_cert_list_length <= 0) + return _gnutls_gen_openpgp_certificate (session, data); + + id_size = sizeof (id); + ret = + gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, id, + &id_size, &subkey); + if (ret < 0) + return gnutls_assert_val (ret); + fpr_size = sizeof (fpr); ret = - gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, 0, fpr, - &fpr_size, NULL); + gnutls_pubkey_get_openpgp_key_id (apr_cert_list[0].pubkey, + GNUTLS_PUBKEY_GET_OPENPGP_FINGERPRINT, + fpr, &fpr_size, NULL); if (ret < 0) return gnutls_assert_val (ret); @@ -961,10 +974,7 @@ _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, /* Only v4 fingerprints are sent */ - if (apr_cert_list_length > 0) - packet_size += 20 + 1; - else /* empty certificate case */ - return _gnutls_gen_openpgp_certificate (session, data); + packet_size += 20 + 1; ret = _gnutls_buffer_append_prefix (data, 24, packet_size - 3); if (ret < 0) @@ -975,6 +985,10 @@ _gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, if (ret < 0) return gnutls_assert_val (ret); + ret = _gnutls_buffer_append_data_prefix (data, 8, id, id_size); + if (ret < 0) + return gnutls_assert_val (ret); + ret = _gnutls_buffer_append_data_prefix (data, 8, fpr, fpr_size); if (ret < 0) return gnutls_assert_val (ret); diff --git a/lib/gnutls_pubkey.c b/lib/gnutls_pubkey.c index d8e44afe7b..f11cc5e5e4 100644 --- a/lib/gnutls_pubkey.c +++ b/lib/gnutls_pubkey.c @@ -400,6 +400,13 @@ gnutls_pubkey_import_openpgp (gnutls_pubkey_t key, uint32_t kid32[2]; uint32_t *k; uint8_t keyid[GNUTLS_OPENPGP_KEYID_SIZE]; + size_t len; + + len = sizeof(key->openpgp_key_fpr); + ret = gnutls_openpgp_crt_get_fingerprint(crt, key->openpgp_key_fpr, &len); + if (ret < 0) + return gnutls_assert_val(ret); + key->openpgp_key_fpr_set = 1; ret = gnutls_openpgp_crt_get_preferred_key_id (crt, keyid); if (ret == GNUTLS_E_OPENPGP_PREFERRED_KEY_ERROR) @@ -453,16 +460,19 @@ gnutls_pubkey_import_openpgp (gnutls_pubkey_t key, /** * gnutls_pubkey_get_openpgp_key_id: * @key: Holds the public key - * @flags: should be 0 for now + * @flags: should be 0 or %GNUTLS_PUBKEY_GET_OPENPGP_FINGERPRINT * @output_data: will contain the key ID * @output_data_size: holds the size of output_data (and will be * replaced by the actual size of parameters) * @subkey: Will be non zero if the key ID corresponds to a subkey * - * This function returned the OpenPGP key ID of the corresponding key. + * This function returns the OpenPGP key ID of the corresponding key. * The key is a unique ID that depends on the public * key parameters. * + * If the flag %GNUTLS_PUBKEY_GET_OPENPGP_FINGERPRINT is specified + * this function returns the fingerprint of the master key. + * * If the buffer provided is not long enough to hold the output, then * *output_data_size is updated and %GNUTLS_E_SHORT_MEMORY_BUFFER will * be returned. The output is %GNUTLS_OPENPGP_KEYID_SIZE bytes long. @@ -484,6 +494,24 @@ gnutls_pubkey_get_openpgp_key_id (gnutls_pubkey_t key, unsigned int flags, return GNUTLS_E_INVALID_REQUEST; } + if (flags & GNUTLS_PUBKEY_GET_OPENPGP_FINGERPRINT) + { + if (*output_data_size < sizeof(key->openpgp_key_fpr)) + { + *output_data_size = sizeof(key->openpgp_key_fpr); + return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); + } + + if (key->openpgp_key_fpr_set == 0) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + if (output_data) + memcpy(output_data, key->openpgp_key_fpr, sizeof(key->openpgp_key_fpr)); + *output_data_size = sizeof(key->openpgp_key_fpr); + + return 0; + } + if (*output_data_size < sizeof(key->openpgp_key_id)) { *output_data_size = sizeof(key->openpgp_key_id); diff --git a/lib/includes/gnutls/abstract.h b/lib/includes/gnutls/abstract.h index 5bcc5aca53..6c121b3acc 100644 --- a/lib/includes/gnutls/abstract.h +++ b/lib/includes/gnutls/abstract.h @@ -36,6 +36,13 @@ extern "C" /* Public key operations */ +#define GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA 1 +/* The following flag disables call to PIN callbacks etc. + * Only works for TPM keys. + */ +#define GNUTLS_PUBKEY_DISABLE_CALLBACKS (1<<2) +#define GNUTLS_PUBKEY_GET_OPENPGP_FINGERPRINT (1<<3) + struct gnutls_pubkey_st; typedef struct gnutls_pubkey_st *gnutls_pubkey_t; @@ -175,11 +182,6 @@ int gnutls_x509_crt_set_pubkey (gnutls_x509_crt_t crt, gnutls_pubkey_t key); int gnutls_x509_crq_set_pubkey (gnutls_x509_crq_t crq, gnutls_pubkey_t key); -#define GNUTLS_PUBKEY_VERIFY_FLAG_TLS_RSA 1 -/* The following flag disables call to PIN callbacks etc. - * Only works for TPM keys. - */ -#define GNUTLS_PUBKEY_DISABLE_CALLBACKS (1<<2) int gnutls_pubkey_verify_hash2 (gnutls_pubkey_t key, gnutls_sign_algorithm_t algo, diff --git a/lib/includes/gnutls/openpgp.h b/lib/includes/gnutls/openpgp.h index bc6b3f13d4..e87e2d307f 100644 --- a/lib/includes/gnutls/openpgp.h +++ b/lib/includes/gnutls/openpgp.h @@ -52,6 +52,7 @@ extern "C" } gnutls_openpgp_crt_fmt_t; #define GNUTLS_OPENPGP_KEYID_SIZE 8 +#define GNUTLS_OPENPGP_V4_FINGERPRINT_SIZE 20 typedef unsigned char gnutls_openpgp_keyid_t[GNUTLS_OPENPGP_KEYID_SIZE]; /* gnutls_openpgp_cert_t should be defined in gnutls.h @@ -310,6 +311,8 @@ extern "C" * fingerprint instead of a full key. See also * gnutls_openpgp_set_recv_key_function(). * + * The variable @key must be allocated using gnutls_malloc(). + * * Returns: On success, %GNUTLS_E_SUCCESS (zero) is returned, * otherwise an error code is returned. */ diff --git a/lib/openpgp/gnutls_openpgp.c b/lib/openpgp/gnutls_openpgp.c index 6ca59e37a9..cbc0da7a98 100644 --- a/lib/openpgp/gnutls_openpgp.c +++ b/lib/openpgp/gnutls_openpgp.c @@ -686,6 +686,8 @@ error: * callback is only useful in server side, and will be used if the peer * sent a key fingerprint instead of a full key. * + * The retrieved key must be allocated using gnutls_malloc(). + * **/ void gnutls_openpgp_set_recv_key_function (gnutls_session_t session, |