1
0
mirror of https://github.com/stefanocasazza/ULib.git synced 2025-09-28 19:05:55 +08:00
This commit is contained in:
stefanocasazza 2017-04-13 19:31:48 +02:00
parent 7bdd9e906b
commit 8f1b15d0f9
7 changed files with 1105 additions and 51 deletions

View File

@ -283,7 +283,7 @@ public:
char buffer4[512];
char buffer5[512];
char buffer6[512];
char buffer7[439];
char buffer7[431];
// ---------------------------------
uint8_t flag_sigterm;
// ---------------------------------
@ -310,8 +310,10 @@ public:
sem_t lock_ssl_session;
char spinlock_ssl_session[1];
# if defined(ENABLE_THREAD) && !defined(OPENSSL_NO_OCSP) && defined(SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB) && !defined(_MSWINDOWS_)
sem_t lock_ocsp_staple;
char spinlock_ocsp_staple[1];
uint32_t len_ocsp_staple;
uint32_t valid_ocsp_staple;
sem_t lock_ocsp_staple;
char spinlock_ocsp_staple[1];
# endif
# endif
// ------------------------------------------------------------------------------
@ -343,6 +345,8 @@ public:
#define U_SRV_CNT_USR9 UServer_Base::ptr_shared_data->cnt_usr9
#define U_SRV_MY_LOAD UServer_Base::ptr_shared_data->my_load
#define U_SRV_FLAG_SIGTERM UServer_Base::ptr_shared_data->flag_sigterm
#define U_SRV_LEN_OCSP_STAPLE UServer_Base::ptr_shared_data->len_ocsp_staple
#define U_SRV_VALID_OCSP_STAPLE UServer_Base::ptr_shared_data->valid_ocsp_staple
#define U_SRV_MIN_LOAD_REMOTE UServer_Base::ptr_shared_data->min_load_remote
#define U_SRV_MIN_LOAD_REMOTE_IP UServer_Base::ptr_shared_data->min_load_remote_ip
#define U_SRV_TOT_CONNECTION UServer_Base::ptr_shared_data->tot_connection

View File

@ -245,8 +245,6 @@ public:
OCSP_REQUEST* req;
STACK_OF(X509)* chain;
UHttpClient<UTCPSocket>* client;
long valid;
int len, verify;
} stapling;
static bool ocsp_nonce;
@ -256,7 +254,7 @@ public:
static void cleanupStapling();
static bool setDataForStapling();
static void certificate_status_callback(SSL* _ssl, void* data);
static int OCSP_resp_callback(SSL* _ssl, void* data);
#endif
#if defined(U_STDCPP_ENABLE) && defined(DEBUG)

View File

@ -370,6 +370,21 @@ public:
// Equal with ignore case
bool equalnocase(char c) const
{
U_TRACE(0, "UStringRep::equalnocase(%C)", c)
U_CHECK_MEMORY
if (_length == 1 &&
u__tolower(*str) == u__tolower(c))
{
U_RETURN(true);
}
U_RETURN(false);
}
bool equalnocase(const char* s, uint32_t n) const
{
U_TRACE(0, "UStringRep::equalnocase(%.*S,%u)", n, s, n)
@ -1771,6 +1786,7 @@ public:
// Equal with ignore case
bool equalnocase(char c) const { return rep->equalnocase(c); }
bool equalnocase(const char* s) const { return rep->equalnocase(s, u__strlen(s, __PRETTY_FUNCTION__)); }
bool equalnocase(const char* s, uint32_t n) const { return rep->equalnocase(s, n); }
bool equalnocase(UStringRep* _rep) const { return same(_rep) || rep->equalnocase(_rep); }

View File

@ -490,14 +490,16 @@ int UHttpPlugIn::handlerInit()
* #endif
*/
// Configure TLS extensions support
# if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_set_tlsext_host_name)
if (SSL_CTX_set_tlsext_servername_callback(USSLSocket::sctx, USSLSocket::callback_ServerNameIndication) == false) // Server name indication (SNI)
{
U_WARNING("SSL: Unable to initialize TLS servername extension callback");
}
# endif
/**
* Configure TLS extensions support
*
* #if !defined(OPENSSL_NO_TLSEXT) && defined(SSL_set_tlsext_host_name)
* if (SSL_CTX_set_tlsext_servername_callback(USSLSocket::sctx, USSLSocket::callback_ServerNameIndication) == false) // Server name indication (SNI)
* {
* U_WARNING("SSL: Unable to initialize TLS servername extension callback");
* }
* #endif
*/
U_SRV_LOG("SSL: server use configuration model: %s, protocol list: %s",
((USSLSocket*)UServer_Base::socket)->getConfigurationModel(), ((USSLSocket*)UServer_Base::socket)->getProtocolList());

View File

@ -1055,7 +1055,7 @@ public:
struct timespec ts;
ts.tv_sec = 5L;
ts.tv_sec =
ts.tv_nsec = 0L;
U_SRV_LOG("SSL: OCSP Stapling thread activated (tid %u)", u_gettid());
@ -1086,6 +1086,8 @@ public:
U_INTERNAL_DUMP("UServer_Base::pthread_ocsp = %p", UServer_Base::pthread_ocsp)
// NB: we must run before fork...
UServer_Base::pthread_ocsp->start(0);
U_RETURN(true);

View File

@ -1349,7 +1349,7 @@ next:
if (staple.pkey) (void) U_SYSCALL(OCSP_request_sign, "%p,%p,%p,%p,%p,%ld", staple.req, staple.cert, staple.pkey, EVP_sha1(), 0, 0); // sign the request
SSL_CTX_set_tlsext_status_cb(sctx, USSLSocket::certificate_status_callback);
SSL_CTX_set_tlsext_status_cb(sctx, USSLSocket::OCSP_resp_callback);
result = true;
@ -1370,11 +1370,11 @@ next:
staple.request->size_adjust(i2d_OCSP_REQUEST(staple.req, &p));
/*
# ifdef DEBUG
(void) UFile::writeToTmp(U_STRING_TO_PARAM(*(staple.request)), O_RDWR | O_TRUNC, U_CONSTANT_TO_PARAM("ocsp.request.%P"), 0);
# endif
/*
UString buffer(U_CAPACITY);
UString path = staple.client->getUrlPath(),
@ -1404,6 +1404,7 @@ uint32_t USSLSocket::doStapling()
U_INTERNAL_ASSERT_POINTER(staple.client)
bool result = false;
uint32_t tv_sec = 30;
OCSP_RESPONSE* ocsp = 0;
OCSP_BASICRESP* basic = 0;
@ -1514,7 +1515,7 @@ uint32_t USSLSocket::doStapling()
goto end;
}
result = (U_SYSCALL(OCSP_basic_verify, "%p,%p,%p,%lu", basic, staple.chain, UServices::store, staple.verify ? OCSP_TRUSTOTHER : OCSP_NOVERIFY) == 1);
result = (U_SYSCALL(OCSP_basic_verify, "%p,%p,%p,%lu", basic, staple.chain, UServices::store, OCSP_NOVERIFY) == 1);
if (result == false)
{
@ -1530,7 +1531,7 @@ uint32_t USSLSocket::doStapling()
U_DEBUG("ocsp: no status found");
# ifdef DEBUG
(void) UFile::writeToTmp(U_STRING_TO_PARAM(response), O_RDWR | O_TRUNC, U_CONSTANT_TO_PARAM("ocsp.response.%P"), 0);
// (void) UFile::writeToTmp(U_STRING_TO_PARAM(response), O_RDWR | O_TRUNC, U_CONSTANT_TO_PARAM("ocsp.response.%P"), 0);
# endif
goto end;
@ -1538,9 +1539,6 @@ uint32_t USSLSocket::doStapling()
nextupdate_str = UStringExt::ASN1TimetoString(nextupdate);
U_DEBUG("ocsp: OCSP_resp_find_status() - %d: %s This update: %V Next update: %V", status,
OCSP_cert_status_str(status), UStringExt::ASN1TimetoString(thisupdate).rep, nextupdate_str.rep)
if (status != V_OCSP_CERTSTATUS_GOOD)
{
result = false;
@ -1554,25 +1552,27 @@ uint32_t USSLSocket::doStapling()
if (result == false) goto end;
staple.valid = u_now->tv_sec + UTimeDate::getSecondFromTime(nextupdate_str.data(), true);
U_INTERNAL_DUMP("staple.valid = %ld now = %ld", staple.valid, u_now->tv_sec)
p = (unsigned char*) staple.data;
# if defined(ENABLE_THREAD) && !defined(_MSWINDOWS_)
UServer_Base::lock_ocsp_staple->lock();
# endif
staple.len = i2d_OCSP_RESPONSE(ocsp, (unsigned char**)&p);
U_INTERNAL_ASSERT_POINTER(staple.data)
p = (const unsigned char*) staple.data;
U_SRV_LEN_OCSP_STAPLE = i2d_OCSP_RESPONSE(ocsp, (unsigned char**)&p);
U_SRV_VALID_OCSP_STAPLE = UTimeDate::getSecondFromTime(nextupdate_str.data(), true);
# if defined(ENABLE_THREAD) && !defined(_MSWINDOWS_)
UServer_Base::lock_ocsp_staple->unlock();
# endif
U_INTERNAL_DUMP("staple.data(%d) = %p %#.*S", staple.len, staple.data, staple.len, staple.data)
U_DEBUG("ocsp: OCSP_resp_find_status() - %d: %s This update: %V Next update: %V now = %#19D U_SRV_VALID_OCSP_STAPLE = %#19D staple.data(%d) = %p %#.*S",
status, OCSP_cert_status_str(status), UStringExt::ASN1TimetoString(thisupdate).rep, nextupdate_str.rep, u_now->tv_sec,
U_SRV_VALID_OCSP_STAPLE, U_SRV_LEN_OCSP_STAPLE, staple.data, U_SRV_LEN_OCSP_STAPLE, staple.data)
U_INTERNAL_ASSERT_MINOR(staple.len, U_OCSP_MAX_RESPONSE_SIZE)
U_INTERNAL_ASSERT_MINOR(U_SRV_LEN_OCSP_STAPLE, U_OCSP_MAX_RESPONSE_SIZE)
}
}
@ -1582,36 +1582,42 @@ end:
if (staple.client->isOpen()) staple.client->close();
if (result)
if (result == false)
{
ERR_print_errors_fp(stderr);
U_DEBUG("SSL: OCSP request for stapling to %V has FAILED", staple.url->rep);
}
else
{
U_DEBUG("SSL: OCSP request for stapling to %V has succes", staple.url->rep);
uint32_t tv_sec = U_min(staple.valid - u_now->tv_sec, 3600);
U_RETURN(tv_sec);
tv_sec = U_min(U_SRV_VALID_OCSP_STAPLE - u_now->tv_sec - 30, 3600);
}
ERR_print_errors_fp(stderr);
U_DEBUG("SSL: OCSP request for stapling to %V has FAILED", staple.url->rep);
U_RETURN(30);
U_RETURN(tv_sec);
}
void USSLSocket::certificate_status_callback(SSL* _ssl, void* data)
/**
* Certificate Status callback. This is called when a client includes a certificate status request extension.
* Check for cached responses in session cache. If valid send back to client. If absent or no longer valid query responder and update cache
*/
int USSLSocket::OCSP_resp_callback(SSL* _ssl, void* data)
{
U_TRACE(0, "USSLSocket::certificate_status_callback(%p,%p)", _ssl, data)
U_TRACE(0, "USSLSocket::OCSP_resp_callback(%p,%p)", _ssl, data)
U_INTERNAL_ASSERT_POINTER(sctx)
U_INTERNAL_DUMP("staple.data(%d) = %p %#.*S", staple.len, staple.data, staple.len, staple.data)
U_DEBUG("ocsp: OCSP_resp_callback(%p) - U_SRV_VALID_OCSP_STAPLE = %#19D now = %#19D", _ssl, U_SRV_VALID_OCSP_STAPLE, u_now->tv_sec)
if (staple.len &&
staple.valid < u_now->tv_sec)
if (U_SRV_LEN_OCSP_STAPLE &&
U_SRV_VALID_OCSP_STAPLE >= u_now->tv_sec)
{
long result;
unsigned char* p;
U_INTERNAL_ASSERT_MINOR(staple.len, U_OCSP_MAX_RESPONSE_SIZE)
U_INTERNAL_ASSERT_MINOR(U_SRV_LEN_OCSP_STAPLE, U_OCSP_MAX_RESPONSE_SIZE)
# if defined(ENABLE_THREAD) && !defined(_MSWINDOWS_)
UServer_Base::lock_ocsp_staple->lock();
@ -1619,16 +1625,27 @@ void USSLSocket::certificate_status_callback(SSL* _ssl, void* data)
// we have to copy ocsp response as OpenSSL will free it by itself
p = (unsigned char*) OPENSSL_malloc(staple.len);
p = (unsigned char*) OPENSSL_malloc(U_SRV_LEN_OCSP_STAPLE);
U_MEMCPY(p, staple.data, staple.len);
U_MEMCPY(p, staple.data, U_SRV_LEN_OCSP_STAPLE);
result = SSL_set_tlsext_status_ocsp_resp(_ssl, p, U_SRV_LEN_OCSP_STAPLE);
# if defined(ENABLE_THREAD) && !defined(_MSWINDOWS_)
UServer_Base::lock_ocsp_staple->unlock();
# endif
SSL_set_tlsext_status_ocsp_resp(_ssl, p, staple.len);
U_DEBUG("ocsp: OCSP_resp_callback() - SSL_set_tlsext_status_ocsp_resp(%p,%#.*S,%d) = %ld", _ssl, U_SRV_LEN_OCSP_STAPLE, p, U_SRV_LEN_OCSP_STAPLE, result)
/**
* The callback when used on the server side should return with either SSL_TLSEXT_ERR_OK (meaning that the OCSP response that has been set should be returned),
* SSL_TLSEXT_ERR_NOACK (meaning that an OCSP response should not be returned) or SSL_TLSEXT_ERR_ALERT_FATAL (meaning that a fatal error has occurred)
*/
U_RETURN(SSL_TLSEXT_ERR_OK);
}
U_RETURN(SSL_TLSEXT_ERR_NOACK);
}
void USSLSocket::cleanupStapling()
@ -1640,9 +1657,9 @@ void USSLSocket::cleanupStapling()
if (staple.request) delete staple.request;
if (staple.cert) U_SYSCALL_VOID(X509_free, "%p", staple.cert);
if (staple.issuer) U_SYSCALL_VOID(X509_free, "%p", staple.issuer);
if (staple.pkey) U_SYSCALL_VOID(EVP_PKEY_free, "%p", staple.pkey);
if (staple.id) U_SYSCALL_VOID(OCSP_CERTID_free, "%p", staple.id);
if (staple.issuer) U_SYSCALL_VOID(X509_free, "%p", staple.issuer);
// if (staple.id) U_SYSCALL_VOID(OCSP_CERTID_free, "%p", staple.id);
if (staple.req) U_SYSCALL_VOID(OCSP_REQUEST_free, "%p", staple.req);
staple.id = 0;

File diff suppressed because it is too large Load Diff