mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-14 10:13:05 +02:00
OpenSSL 3 support.
There are two changes: * Suppress deprecation warnings so we can build with -Werror and -Wfatal-errors. At some point we'll need to migrate to the new APIs but there does not seem to be a good reason to support two sets of code right now. * Update the handling for unexpected EOF to handle EOF or error. The error code for EOF has changed and become harder to identify, but we probably don't care whether it is an error or EOF.
This commit is contained in:
parent
f92ce674f7
commit
08242ee6ac
@ -21,6 +21,17 @@
|
||||
</text>
|
||||
|
||||
<release-improvement-list>
|
||||
<release-item>
|
||||
<github-pull-request id="1767"/>
|
||||
|
||||
<release-item-contributor-list>
|
||||
<release-item-contributor id="david.steele"/>
|
||||
<release-item-reviewer id="stephen.frost"/>
|
||||
</release-item-contributor-list>
|
||||
|
||||
<p><proper>OpenSSL 3</proper> support.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<github-pull-request id="1758"/>
|
||||
|
||||
|
@ -107,7 +107,10 @@ tlsServerDh(SSL_CTX *const context)
|
||||
|
||||
TRY_BEGIN()
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
DH *const dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
TRY_BEGIN()
|
||||
{
|
||||
@ -115,7 +118,10 @@ tlsServerDh(SSL_CTX *const context)
|
||||
}
|
||||
FINALLY()
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
DH_free(dh);
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
TRY_END();
|
||||
}
|
||||
@ -145,7 +151,10 @@ tlsServerEcdh(SSL_CTX *const context)
|
||||
const int nid = OBJ_sn2nid(ECHD_CURVE);
|
||||
cryptoError(nid == NID_undef, "unrecognized ECDH curve " ECHD_CURVE);
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
EC_KEY *const ecdh = EC_KEY_new_by_curve_name(nid);
|
||||
#pragma GCC diagnostic pop
|
||||
cryptoError(ecdh == NULL, "could not create ecdh key");
|
||||
|
||||
SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
|
||||
@ -156,7 +165,10 @@ tlsServerEcdh(SSL_CTX *const context)
|
||||
}
|
||||
FINALLY()
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
EC_KEY_free(ecdh);
|
||||
#pragma GCC diagnostic pop
|
||||
}
|
||||
TRY_END();
|
||||
|
||||
|
@ -126,29 +126,6 @@ tlsSessionResultProcess(TlsSession *this, int errorTls, long unsigned int errorT
|
||||
|
||||
switch (errorTls)
|
||||
{
|
||||
// The connection was closed
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
// A syscall failed (this usually indicates unexpected eof)
|
||||
case SSL_ERROR_SYSCALL:
|
||||
{
|
||||
// Error on SSL_ERROR_SYSCALL if unexpected EOF is not allowed
|
||||
if (errorTls == SSL_ERROR_SYSCALL && !this->ignoreUnexpectedEof)
|
||||
{
|
||||
THROW_SYS_ERROR_CODE(errorSys, KernelError, "TLS syscall error");
|
||||
}
|
||||
// Else close the connection if we are in a state where it is allowed, e.g. not connecting
|
||||
else
|
||||
{
|
||||
if (!closeOk)
|
||||
THROW(ProtocolError, "unexpected TLS eof");
|
||||
|
||||
this->shutdownOnClose = false;
|
||||
tlsSessionClose(this);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Try again after waiting for read ready
|
||||
case SSL_ERROR_WANT_READ:
|
||||
ioReadReadyP(ioSessionIoReadP(this->ioSession), .error = true);
|
||||
@ -161,15 +138,30 @@ tlsSessionResultProcess(TlsSession *this, int errorTls, long unsigned int errorT
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
// Any other error that we cannot handle
|
||||
// Handle graceful termination by the server or unexpected EOF/error
|
||||
default:
|
||||
{
|
||||
// Get detailed error message when available
|
||||
const char *errorTlsDetailMessage = ERR_reason_error_string(errorTlsDetail);
|
||||
// Close connection on graceful termination by the server or unexpected EOF/error when allowed
|
||||
if (errorTls == SSL_ERROR_ZERO_RETURN || this->ignoreUnexpectedEof)
|
||||
{
|
||||
if (!closeOk)
|
||||
THROW(ProtocolError, "unexpected TLS eof");
|
||||
|
||||
THROW_FMT(
|
||||
ServiceError, "TLS error [%d:%lu] %s", errorTls, errorTlsDetail,
|
||||
errorTlsDetailMessage == NULL ? "no details available" : errorTlsDetailMessage);
|
||||
this->shutdownOnClose = false;
|
||||
tlsSessionClose(this);
|
||||
}
|
||||
// Else error
|
||||
else
|
||||
{
|
||||
// Get detailed error message when available
|
||||
const char *errorTlsDetailMessage = ERR_reason_error_string(errorTlsDetail);
|
||||
|
||||
THROW_FMT(
|
||||
ServiceError, "TLS error [%d:%lu] %s", errorTls, errorTlsDetail,
|
||||
errorTlsDetailMessage == NULL ? "no details available" : errorTlsDetailMessage);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,13 @@ testRun(void)
|
||||
EVP_MD_CTX *context = EVP_MD_CTX_create();
|
||||
TEST_ERROR(
|
||||
cryptoError(EVP_DigestInit_ex(context, NULL, NULL) != 1, "unable to initialize hash context"), CryptoError,
|
||||
"unable to initialize hash context: [101187723] no digest set");
|
||||
"unable to initialize hash context: "
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
"[50331787]"
|
||||
#else
|
||||
"[101187723]"
|
||||
#endif
|
||||
" no digest set");
|
||||
EVP_MD_CTX_destroy(context);
|
||||
|
||||
TEST_ERROR(cryptoError(true, "no error"), CryptoError, "no error: [0] no details available");
|
||||
|
@ -398,7 +398,12 @@ testRun(void)
|
||||
tlsClientNewP(
|
||||
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
|
||||
.caFile = STRDEF("bogus.crt"), .caPath = STRDEF("/bogus"))),
|
||||
CryptoError, "unable to set user-defined CA certificate location: [33558530] No such file or directory");
|
||||
CryptoError, "unable to set user-defined CA certificate location: "
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
"[2147483650] no details available");
|
||||
#else
|
||||
"[33558530] No such file or directory");
|
||||
#endif
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("missing client cert");
|
||||
@ -408,7 +413,12 @@ testRun(void)
|
||||
tlsClientNewP(
|
||||
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
|
||||
.certFile = STRDEF("/bogus"), .keyFile = STRDEF("/bogus"))),
|
||||
CryptoError, "unable to load cert file '/bogus': [33558530] No such file or directory");
|
||||
CryptoError, "unable to load cert file '/bogus': "
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
"[2147483650] no details available");
|
||||
#else
|
||||
"[33558530] No such file or directory");
|
||||
#endif
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("missing client key");
|
||||
@ -418,7 +428,12 @@ testRun(void)
|
||||
tlsClientNewP(
|
||||
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
|
||||
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF("/bogus"))),
|
||||
CryptoError, "unable to load key file '/bogus': [33558530] No such file or directory");
|
||||
CryptoError, "unable to load key file '/bogus': "
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
"[2147483650] no details available");
|
||||
#else
|
||||
"[33558530] No such file or directory");
|
||||
#endif
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("client cert and key do not match");
|
||||
@ -428,9 +443,13 @@ testRun(void)
|
||||
tlsClientNewP(
|
||||
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
|
||||
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(HRN_SERVER_KEY))),
|
||||
CryptoError,
|
||||
"unable to load key file '" HRN_PATH_REPO "/test/certificate/pgbackrest-test-server.key': [185073780] key values"
|
||||
" mismatch");
|
||||
CryptoError, "unable to load key file '" HRN_PATH_REPO "/test/certificate/pgbackrest-test-server.key': "
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
"[92274804]"
|
||||
#else
|
||||
"[185073780]"
|
||||
#endif
|
||||
" key values mismatch");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("client cert with passphrase");
|
||||
@ -443,7 +462,13 @@ testRun(void)
|
||||
tlsClientNewP(
|
||||
sckClientNew(STRDEF("localhost"), hrnServerPort(0), 5000, 5000), STRDEF("X"), 0, 0, true,
|
||||
.certFile = STRDEF(HRN_SERVER_CLIENT_CERT), .keyFile = STRDEF(TEST_PATH "/client-pwd.key")),
|
||||
CryptoError, "unable to load key file '" TEST_PATH "/client-pwd.key': [101077092] bad decrypt");
|
||||
CryptoError, "unable to load key file '" TEST_PATH "/client-pwd.key': "
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
"[478150756]"
|
||||
#else
|
||||
"[101077092]"
|
||||
#endif
|
||||
" bad decrypt");
|
||||
}
|
||||
CATCH(TestError)
|
||||
{
|
||||
@ -653,7 +678,13 @@ testRun(void)
|
||||
|
||||
TEST_ERROR(
|
||||
ioServerAccept(tlsServer, socketSession), ServiceError,
|
||||
"TLS error [1:337100934] certificate verify failed");
|
||||
"TLS error "
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
"[1:167772294]"
|
||||
#else
|
||||
"[1:337100934]"
|
||||
#endif
|
||||
" certificate verify failed");
|
||||
|
||||
// Valid client cert
|
||||
socketSession = ioServerAccept(socketServer, NULL);
|
||||
@ -699,7 +730,13 @@ testRun(void)
|
||||
|
||||
TEST_ERROR(
|
||||
ioRead(ioSessionIoReadP(clientSession), bufNew(1)), ServiceError,
|
||||
"TLS error [1:336151576] tlsv1 alert unknown ca");
|
||||
"TLS error "
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
"[1:167773208]"
|
||||
#else
|
||||
"[1:336151576]"
|
||||
#endif
|
||||
" tlsv1 alert unknown ca");
|
||||
|
||||
TEST_RESULT_VOID(ioSessionFree(clientSession), "free client session");
|
||||
|
||||
@ -784,7 +821,12 @@ testRun(void)
|
||||
TEST_RESULT_INT(tlsSessionResultProcess(tlsSession, SSL_ERROR_WANT_WRITE, 0, 0, false), 0, "write ready");
|
||||
TEST_ERROR(
|
||||
tlsSessionResultProcess(tlsSession, SSL_ERROR_WANT_X509_LOOKUP, 336031996, 0, false), ServiceError,
|
||||
"TLS error [4:336031996] unknown protocol");
|
||||
"TLS error [4:336031996] "
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
"no details available");
|
||||
#else
|
||||
"unknown protocol");
|
||||
#endif
|
||||
TEST_ERROR(
|
||||
tlsSessionResultProcess(tlsSession, SSL_ERROR_WANT_X509_LOOKUP, 0, 0, false), ServiceError,
|
||||
"TLS error [4:0] no details available");
|
||||
@ -867,7 +909,14 @@ testRun(void)
|
||||
socketLocal.block = false;
|
||||
|
||||
output = bufNew(13);
|
||||
TEST_ERROR(ioRead(ioSessionIoReadP(session), output), KernelError, "TLS syscall error");
|
||||
TEST_ERROR(
|
||||
ioRead(ioSessionIoReadP(session), output), ServiceError,
|
||||
"TLS error "
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
"[1:167772454] unexpected eof while reading");
|
||||
#else
|
||||
"[5:0] no details available");
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("aborted connection ignored and read complete (non-blocking socket)");
|
||||
|
Loading…
Reference in New Issue
Block a user