summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--lib/abstract_int.h7
-rw-r--r--lib/auth/cert.c28
-rw-r--r--lib/gnutls_pubkey.c32
-rw-r--r--lib/includes/gnutls/abstract.h12
-rw-r--r--lib/includes/gnutls/openpgp.h3
-rw-r--r--lib/openpgp/gnutls_openpgp.c2
7 files changed, 72 insertions, 15 deletions
diff --git a/NEWS b/NEWS
index 4fdec1d070..4cd5d34f8f 100644
--- a/NEWS
+++ b/NEWS
@@ -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,