improve ssl error code, 2147483650

From: David Zhang <david(dot)zhang(at)highgo(dot)ca>
To: Pgsql Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: improve ssl error code, 2147483650
Date: 2024-03-07 00:12:23
Message-ID: b6fb018b-f05c-4afd-abd3-318c649faf18@highgo.ca
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Hackers,

When configuring SSL on the Postgres server side with the following
information:

ssl = on
ssl_ca_file = 'root_ca.crt'
ssl_cert_file = 'server-cn-only.crt'
ssl_key_file = 'server-cn-only.key'

If a user makes a mistake, for example, accidentally using 'root_ca.crl'
instead of 'root_ca.crt', Postgres will report an error like the one below:
FATAL:  could not load root certificate file "root_ca.crl": SSL error
code 2147483650

Here, the error code 2147483650 is not very helpful for the user. The
reason is that Postgres is missing the initial SSL file check before
passing it to the OpenSSL API. For example:

    if (ssl_ca_file[0])
    {
        STACK_OF(X509_NAME) * root_cert_list;

        if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL)
!= 1 ||
            (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) ==
NULL)
        {
            ereport(isServerStart ? FATAL : LOG,
                    (errcode(ERRCODE_CONFIG_FILE_ERROR),
                     errmsg("could not load root certificate file
\"%s\": %s",
                            ssl_ca_file, SSLerrmessage(ERR_get_error()))));
            goto error;
        }

The SSL_CTX_load_verify_locations function in OpenSSL will return NULL
if there is a system error, such as "No such file or directory" in this
case:

const char *ERR_reason_error_string(unsigned long e)
{
    ERR_STRING_DATA d, *p = NULL;
    unsigned long l, r;

    if (!RUN_ONCE(&err_string_init, do_err_strings_init)) {
        return NULL;
    }

    /*
     * ERR_reason_error_string() can't safely return system error strings,
     * since openssl_strerror_r() needs a buffer for thread safety, and we
     * haven't got one that would serve any sensible purpose.
     */
    if (ERR_SYSTEM_ERROR(e))
        return NULL;

It would be better to perform a simple SSL file check before passing the
SSL file to OpenSSL APIs so that the system error can be captured and a
meaningful message provided to the end user.

Attached is a simple patch to help address this issue for ssl_ca_file,
ssl_cert_file, and ssl_crl_file. With this patch, a similar test will
return something like the message below:
FATAL:  could not access certificate file "root_ca.crl": No such file or
directory

I believe this can help end users quickly realize the mistake.

Thank you,
David

Attachment Content-Type Size
0001-improve-ssl-files-error-code.patch text/plain 2.7 KB

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Masahiko Sawada 2024-03-07 00:22:58 Re: Improve eviction algorithm in ReorderBuffer
Previous Message Tom Lane 2024-03-06 23:49:19 Re: Stack overflow issue