resumption problem

Viktor Dukhovni openssl-users at dukhovni.org
Tue Mar 24 00:49:01 UTC 2020


On Mon, Mar 23, 2020 at 11:46:43PM +0000, Jeremy Harris wrote:

> OpenSSL 1.1.1  on Centos 8
> Ticket-based resumption

I'm testing posttls-finger with OpenSSL 1.1.1 on FreeBSD.

> 
> I'm getting a repeatable error from a client call to SSL_connect()
> of "14228044:SSL routines:construct_ca_names:internal error".

Either issues allocating space, or an explicit NULL element
on the client CA list, or a DN that for some reason can't
be serialized.  Is there an issuer with an subject DN?

> The error only occurs when the client is trying to resume
> a previous session, and (here's the odd part) only when
> the client is set up to offer a client certificate.

My test with "posttls-finger" does not exhibit this issue:

    Verified TLS connection established to [...] TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
    Reconnecting after 2 seconds
    looking for session [...] in memory cache
    reloaded session [...] from memory cache
    [...] Reusing old session
    Verified TLS connection established to [...] TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)

> Any ideas?

The entire function body is below.  There are three places where that
error could be raised:

    int construct_ca_names(SSL *s, const STACK_OF(X509_NAME) *ca_sk, WPACKET *pkt)
    {
        /* Start sub-packet for client CA list */
        if (!WPACKET_start_sub_packet_u16(pkt)) {
-->         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_CA_NAMES,
                     ERR_R_INTERNAL_ERROR);
            return 0;
        }

        if (ca_sk != NULL) {
            int i;

            for (i = 0; i < sk_X509_NAME_num(ca_sk); i++) {
                unsigned char *namebytes;
                X509_NAME *name = sk_X509_NAME_value(ca_sk, i);
                int namelen;

                if (name == NULL
                        || (namelen = i2d_X509_NAME(name, NULL)) < 0
                        || !WPACKET_sub_allocate_bytes_u16(pkt, namelen,
                                                           &namebytes)
                        || i2d_X509_NAME(name, &namebytes) != namelen) {
-->                 SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_CA_NAMES,
                             ERR_R_INTERNAL_ERROR);
                    return 0;
                }
            }
        }

        if (!WPACKET_close(pkt)) {
-->         SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_CONSTRUCT_CA_NAMES,
                     ERR_R_INTERNAL_ERROR);
            return 0;
        }

        return 1;
    }

I'm guessing it is not the first.  The second would an issue with a
particular issuer on the CA list (does Exim configure a list of CAs to
send to the server?), or the list of CAs is too long to fit in 2^16
bytes, which might fail on the packet close if not while extending
the subpacket.

It'd be useful to single-step through that function with gdb and
what happened.  How long is the CA list?  Which condition caused
the error?

-- 
    Viktor.


More information about the openssl-users mailing list