From 2f1d58f9c376429ca3ff84d0489824603d2bcd52 Mon Sep 17 00:00:00 2001 From: Jacob Champion Date: Mon, 16 Nov 2020 08:55:33 -0800 Subject: [PATCH] nss: fix hang when hashing certificates --- src/backend/libpq/be-secure-nss.c | 19 ++++++++++++------- src/interfaces/libpq/fe-secure-nss.c | 22 ++++++++++++++++------ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/backend/libpq/be-secure-nss.c b/src/backend/libpq/be-secure-nss.c index e7540c4756..b1982ee596 100644 --- a/src/backend/libpq/be-secure-nss.c +++ b/src/backend/libpq/be-secure-nss.c @@ -813,6 +813,7 @@ be_tls_get_certificate_hash(Port *port, size_t *len) SECOidTag signature_alg; SECOidTag digest_alg; int digest_len; + const NSSSignatureAlgorithms *candidate; SECStatus status; PLArenaPool *arena = NULL; SECItem digest; @@ -824,20 +825,24 @@ be_tls_get_certificate_hash(Port *port, size_t *len) return NULL; signature_alg = SECOID_GetAlgorithmTag(&certificate->signature); - /* Set sha-256 as a default */ - digest_alg = SEC_OID_SHA256; - digest_len = SHA256_LENGTH; - while (NSS_SCRAMDigestAlgorithm->signature) + candidate = NSS_SCRAMDigestAlgorithm; + while (candidate->signature) { - if (signature_alg == NSS_SCRAMDigestAlgorithm->signature) + if (signature_alg == candidate->signature) { - digest_alg = NSS_SCRAMDigestAlgorithm->hash; - digest_len = NSS_SCRAMDigestAlgorithm->len; + digest_alg = candidate->hash; + digest_len = candidate->len; break; } + + candidate++; } + if (!candidate->signature) + elog(ERROR, "could not find digest for OID '%s'", + SECOID_FindOIDTagDescription(signature_alg)); + arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); digest.data = PORT_ArenaZAlloc(arena, sizeof(unsigned char) * digest_len); digest.len = digest_len; diff --git a/src/interfaces/libpq/fe-secure-nss.c b/src/interfaces/libpq/fe-secure-nss.c index 787bc140a6..2f10e94f72 100644 --- a/src/interfaces/libpq/fe-secure-nss.c +++ b/src/interfaces/libpq/fe-secure-nss.c @@ -540,6 +540,7 @@ pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len) SECOidTag signature_alg; SECOidTag digest_alg; int digest_len; + const NSSSignatureAlgorithms *candidate; PLArenaPool *arena; SECItem digest; char *ret; @@ -552,17 +553,26 @@ pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len) return NULL; signature_alg = SECOID_GetAlgorithmTag(&server_cert->signature); - digest_alg = SEC_OID_SHA256; - digest_len = SHA256_LENGTH; - while (NSS_SCRAMDigestAlgorithm->signature) + candidate = NSS_SCRAMDigestAlgorithm; + while (candidate->signature) { - if (signature_alg == NSS_SCRAMDigestAlgorithm->signature) + if (signature_alg == candidate->signature) { - digest_alg = NSS_SCRAMDigestAlgorithm->hash; - digest_len = NSS_SCRAMDigestAlgorithm->len; + digest_alg = candidate->hash; + digest_len = candidate->len; break; } + + candidate++; + } + + if (!candidate->signature) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("could not find digest for OID '%s'\n"), + SECOID_FindOIDTagDescription(signature_alg)); + return NULL; } arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); -- 2.24.1