Clear the OpenSSL error queue before cryptohash operations
authorDaniel Gustafsson <dgustafsson@postgresql.org>
Fri, 6 May 2022 12:41:31 +0000 (14:41 +0200)
committerDaniel Gustafsson <dgustafsson@postgresql.org>
Fri, 6 May 2022 12:41:31 +0000 (14:41 +0200)
Setting up an EVP context for ciphers banned under FIPS generate
two OpenSSL errors in the queue, and as we only consume one from
the queue the other is at the head for the next invocation:

  postgres=# select md5('foo');
  ERROR:  could not compute MD5 hash: unsupported
  postgres=# select md5('foo');
  ERROR:  could not compute MD5 hash: initialization error

Clearing the error queue when creating the context ensures that
we don't pull in an error from an earlier operation.

Discussion: https://postgr.es/m/C89D932C-501E-4473-9750-638CFCD9095E@yesql.se

src/common/cryptohash_openssl.c
src/common/hmac_openssl.c

index 6c98f1cf95a5985ead002cea4f8924767aac6653..8e76ffdee99015e5fee44fb82b3fcccdd8b5e0e3 100644 (file)
@@ -117,7 +117,10 @@ pg_cryptohash_create(pg_cryptohash_type type)
 
        /*
         * Initialization takes care of assigning the correct type for OpenSSL.
+        * Also ensure that there aren't any unconsumed errors in the queue from
+        * previous runs.
         */
+       ERR_clear_error();
        ctx->evpctx = EVP_MD_CTX_create();
 
        if (ctx->evpctx == NULL)
@@ -182,6 +185,12 @@ pg_cryptohash_init(pg_cryptohash_ctx *ctx)
        {
                ctx->errreason = SSLerrmessage(ERR_get_error());
                ctx->error = PG_CRYPTOHASH_ERROR_OPENSSL;
+               /*
+                * The OpenSSL error queue should normally be empty since we've
+                * consumed an error, but cipher initialization can in FIPS-enabled
+                * OpenSSL builds generate two errors so clear the queue here as well.
+                */
+               ERR_clear_error();
                return -1;
        }
        return 0;
index 44f36d51dcb0fe0d59a90336884e26ce9fda2bea..8874d6a240c9c82490981bfd388560f765e7857d 100644 (file)
@@ -106,9 +106,13 @@ pg_hmac_create(pg_cryptohash_type type)
        ctx->error = PG_HMAC_ERROR_NONE;
        ctx->errreason = NULL;
 
+
        /*
         * Initialization takes care of assigning the correct type for OpenSSL.
+        * Also ensure that there aren't any unconsumed errors in the queue from
+        * previous runs.
         */
+       ERR_clear_error();
 #ifdef HAVE_HMAC_CTX_NEW
 #ifndef FRONTEND
        ResourceOwnerEnlargeHMAC(CurrentResourceOwner);