Changeset 2cde8111 in mod_gnutls for src/gnutls_config.c


Ignore:
Timestamp:
Apr 5, 2015, 6:20:59 PM (5 years ago)
Author:
Thomas Klute <thomas2.klute@…>
Branches:
debian/master, debian/stretch-backports, jessie-backports, master, upstream
Children:
d04f7da
Parents:
351b51f
Message:

Workarounds for OpenPGP key handling

Commit 031acac9c6541034777f8917633164b51f6bd10a 'Use the new (3.1.3+)
GnuTLS APIs to obtain private keys' led to failed handshakes when using
OpenPGP keys for authentication. Debugging revealed two separate issues,
this commit adds workarounds for both.

The first problem was that the supported certificate types for the
session were not set correctly. This is a known bug in
gnutls_certificate_set_retrieve_function2 [1], the workaround comes from
[2]. The bug should be fixed in GnuTLS 3.3.12, hence the version guard.

After this problem was fixed, segfaults occurred during handshake. A
Valgrind trace showed attemts to access memory that had been free'd in
gnutls_privkey_import_openpgp_raw. I could work around the issue by
loading the key into a gnutls_openpgp_privkey_t structure first and then
importing it into the gnutls_privkey_t using
gnutls_privkey_import_openpgp afterwards.

Thank you to Nikos Mavrogiannopoulos for very fast help with debugging!

[1] https://lists.gnupg.org/pipermail/gnutls-devel/2015-January/007377.html
[2] https://github.com/vanrein/tlspool/commit/4938102d3d1b086491d147e6c8e4e2a02825fc12

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/gnutls_config.c

    r351b51f r2cde8111  
    422422        }
    423423
    424         ret =
    425             gnutls_privkey_import_openpgp_raw(sc->privkey_pgp, &data,
    426                                               GNUTLS_OPENPGP_FMT_BASE64,
    427                                               NULL, NULL);
     424        /* Theoretically, this chain of gnutls_openpgp_privkey_init,
     425         * gnutls_openpgp_privkey_import and
     426         * gnutls_privkey_import_openpgp could be replaced with one
     427         * call to gnutls_privkey_import_openpgp_raw as shown
     428         * below. However, that led to a segfault during handshake
     429         * which disappeared with the three step method.
     430         *
     431         * ret = gnutls_privkey_import_openpgp_raw(sc->privkey_pgp, &data,
     432         *                                         GNUTLS_OPENPGP_FMT_BASE64,
     433         *                                         NULL, NULL); */
     434        ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp_internal);
     435        if (ret != 0) {
     436            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     437                         "GnuTLS: Failed to initialize "
     438                         "PGP Private Key '%s': (%d) %s",
     439                         sc->pgp_key_file, ret, gnutls_strerror(ret));
     440            ret = -1;
     441            goto cleanup;
     442        }
     443
     444        ret = gnutls_openpgp_privkey_import(sc->privkey_pgp_internal, &data,
     445                                            GNUTLS_OPENPGP_FMT_BASE64, NULL, 0);
    428446        if (ret != 0) {
    429447            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     
    431449                         "PGP Private Key '%s': (%d) %s",
    432450                         sc->pgp_key_file, ret, gnutls_strerror(ret));
     451            ret = -1;
     452            goto cleanup;
     453        }
     454
     455        ret = gnutls_privkey_import_openpgp(sc->privkey_pgp,
     456                                            sc->privkey_pgp_internal, 0);
     457        if (ret != 0)
     458        {
     459            ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
     460                         "GnuTLS: Failed to assign PGP Private Key '%s' "
     461                         "to gnutls_privkey_t structure: (%d) %s",
     462                         sc->pgp_key_file, ret, gnutls_strerror(ret));
    433463            ret = -1;
    434464            goto cleanup;
Note: See TracChangeset for help on using the changeset viewer.