From 730868e3af71e691aa9b26467e72977f0d69c66f Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Thu, 11 Oct 2012 22:37:25 +0200 Subject: [PATCH] Added (back) RFC5081 support in client mode. --- NEWS | 5 +++-- lib/auth/cert.c | 23 +++++++++++++++++++---- lib/gnutls_pcert.c | 11 ++++------- lib/openpgp/pgp.c | 17 +++++++++++++++++ lib/openpgp/privkey.c | 20 +++++++++++++++++++- 5 files changed, 62 insertions(+), 14 deletions(-) diff --git a/NEWS b/NEWS index b2fc91d3b..bee8f68f0 100644 --- a/NEWS +++ b/NEWS @@ -27,8 +27,9 @@ response corresponds to the given certificate. OCSP certificate status request extensions by default. The flag GNUTLS_NO_EXTENSIONS can be used to prevent that. -** libgnutls: Compatibility code with RFC5081 was removed. The OpenPGP -code now is RFC6091 compliant only. +** libgnutls: Several updates in the OpenPGP code. The generating code +is fully RFC6091 compliant and RFC5081 support is only supported in client +mode. ** libgnutls-dane: Added. It is a library to provide DANE with DNSSEC certificate verification. diff --git a/lib/auth/cert.c b/lib/auth/cert.c index 95bd6d06e..937d9a274 100644 --- a/lib/auth/cert.c +++ b/lib/auth/cert.c @@ -1180,6 +1180,7 @@ _gnutls_proc_openpgp_server_crt (gnutls_session_t session, int key_type; gnutls_pcert_st *peer_certificate_list = NULL; gnutls_datum_t tmp, akey = { NULL, 0 }; + unsigned int compat = 0; uint8_t subkey_id[GNUTLS_OPENPGP_KEYID_SIZE]; cred = (gnutls_certificate_credentials_t) @@ -1294,10 +1295,18 @@ _gnutls_proc_openpgp_server_crt (gnutls_session_t session, len = _gnutls_read_uint24 (p); p += 3; - if (len != 0) /* PGP_EMPTY_KEY */ - return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH); - else + if (len == 0) /* PGP_EMPTY_KEY */ return GNUTLS_E_NO_CERTIFICATE_FOUND; + /* Uncomment to remove compatibility with RFC5081. + else + return gnutls_assert_val(GNUTLS_E_UNEXPECTED_PACKET_LENGTH);*/ + + DECR_LEN (dsize, len); + + tmp.size = len; + tmp.data = p; + + compat = 1; } else { @@ -1320,13 +1329,19 @@ _gnutls_proc_openpgp_server_crt (gnutls_session_t session, gnutls_pcert_import_openpgp_raw (&peer_certificate_list[0], &tmp, GNUTLS_OPENPGP_FMT_RAW, - subkey_id, + (compat==0)?subkey_id:NULL, 0); if (ret < 0) { gnutls_assert (); goto cleanup; } + + if (compat != 0) + { + size_t t = sizeof(subkey_id); + gnutls_pubkey_get_openpgp_key_id(peer_certificate_list[0].pubkey, 0, subkey_id, &t, NULL); + } ret = _gnutls_copy_certificate_auth_info (info, diff --git a/lib/gnutls_pcert.c b/lib/gnutls_pcert.c index 3a6b6fee5..3341f88c5 100644 --- a/lib/gnutls_pcert.c +++ b/lib/gnutls_pcert.c @@ -336,14 +336,11 @@ gnutls_openpgp_crt_t crt; goto cleanup; } - if (keyid != NULL) + ret = gnutls_openpgp_crt_set_preferred_key_id(crt, keyid); + if (ret < 0) { - ret = gnutls_openpgp_crt_set_preferred_key_id(crt, keyid); - if (ret < 0) - { - ret = gnutls_assert_val(ret); - goto cleanup; - } + ret = gnutls_assert_val(ret); + goto cleanup; } ret = gnutls_pcert_import_openpgp(pcert, crt, flags); diff --git a/lib/openpgp/pgp.c b/lib/openpgp/pgp.c index 97f949113..9dc9cc763 100644 --- a/lib/openpgp/pgp.c +++ b/lib/openpgp/pgp.c @@ -1633,6 +1633,9 @@ gnutls_openpgp_crt_get_preferred_key_id (gnutls_openpgp_crt_t key, * 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. **/ @@ -1647,6 +1650,20 @@ gnutls_openpgp_crt_set_preferred_key_id (gnutls_openpgp_crt_t 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); diff --git a/lib/openpgp/privkey.c b/lib/openpgp/privkey.c index 9498353b0..77ef7b403 100644 --- a/lib/openpgp/privkey.c +++ b/lib/openpgp/privkey.c @@ -1264,7 +1264,11 @@ gnutls_openpgp_privkey_get_preferred_key_id (gnutls_openpgp_privkey_t key, * This allows setting a preferred key id for the given certificate. * This key will be used by functions that involve key handling. * - * Returns: On success, 0 is returned, or an error code. + * 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_privkey_set_preferred_key_id (gnutls_openpgp_privkey_t key, @@ -1279,6 +1283,20 @@ gnutls_openpgp_privkey_set_preferred_key_id (gnutls_openpgp_privkey_t key, return GNUTLS_E_INVALID_REQUEST; } + if (keyid == NULL) /* set the master as preferred */ + { + uint8_t tmp[GNUTLS_OPENPGP_KEYID_SIZE]; + + ret = gnutls_openpgp_privkey_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_privkey_get_subkey_idx (key, keyid); if (ret < 0) -- 2.11.4.GIT