[1mdiff --git a/src/tlsrequest.c b/src/tlsrequest.c[m
[1mindex 3e6f420..ae38688 100644[m
[1m--- a/src/tlsrequest.c[m
[1m+++ b/src/tlsrequest.c[m
[36m@@ -155,7 +155,9 @@[m [mstatic iTlsCertificate *maybeReuseSession_Context_(iContext *d, SSL *ssl, const[m
iForEach(StringHash, i, d->cache) {[m
iCachedSession *cs = i.value->object;[m
if (isExpired_CachedSession_(cs)) {[m
[31m- iDebug("[TlsRequest] session for %s
has expired\n", cstr_Block(&i.value->keyBlock));[m
[32m+[m[32m iDebug("[%s] session for %s
has expired\n",[m
[32m+[m[32m cstr_String(name_Thread(current_Thread())),[m
[32m+[m[32m cstr_Block(&i.value->keyBlock));[m
remove_StringHashIterator(&i);[m
}[m
}[m
[36m@@ -164,7 +166,9 @@[m [mstatic iTlsCertificate *maybeReuseSession_Context_(iContext *d, SSL *ssl, const[m
cmp_Block(&cs->clientHash, clientHash) == 0)) {[m
reuse_CachedSession(cs, ssl);[m
cert = copy_TlsCertificate(cs->cert);[m
[31m- iDebug("[TlsRequest] reusing session for %s
\n", cstr_String(key));[m
[32m+[m[32m iDebug("[%s] reusing session for %s
\n",[m
[32m+[m[32m cstr_String(name_Thread(current_Thread())),[m
[32m+[m[32m cstr_String(key));[m
}[m
unlock_Mutex(&d->cacheMutex);[m
delete_String(key);[m
[36m@@ -176,15 +180,17 @@[m [mstatic void saveSession_Context_(iContext *d, const iString *host, uint16_t port[m
SSL_SESSION *sess, const iTlsCertificate *serverCert,[m
const iTlsCertificate *clientCert) {[m
if (sess && serverCert) {[m
[32m+[m[32m const char *tname = cstr_String(name_Thread(current_Thread()));[m
[32m+[m[32m iDebug("[%s] saveSession: host=%s port=%u\n", tname, cstr_String(host), port);[m
iString *key = cacheKey_(host, port);[m
[31m- lock_Mutex(&d->cacheMutex);[m
iCachedSession *cs = new_CachedSession(sess, serverCert);[m
if (clientCert) {[m
setClientCertificate_CachedSession_(cs, clientCert);[m
}[m
[32m+[m[32m lock_Mutex(&d->cacheMutex);[m
insert_StringHash(d->cache, key, cs);[m
unlock_Mutex(&d->cacheMutex);[m
[31m- iDebug("[TlsRequest] saved session for %s
\n", cstr_String(key));[m
[32m+[m[32m iDebug("[%s] saved session for %s
\n", tname, cstr_String(key));[m
delete_String(key);[m
}[m
}[m
[36m@@ -232,6 +238,7 @@[m [mstatic int verifyCallback_Context_(int preverifyOk, X509_STORE_CTX *storeCtx) {[m
}[m
[m
void init_Context(iContext *d) {[m
[32m+[m[32m iAssert(current_Thread() == NULL); /* must be main thread */[m
init_String(&d->libraryName);[m
#if defined (LIBRESSL_VERSION_TEXT)[m
setCStr_String(&d->libraryName, "LibreSSL");[m
[36m@@ -304,9 +311,11 @@[m [mvoid setVerifyFunc_TlsRequest(iTlsRequestVerifyFunc verifyFunc) {[m
iDefineTypeConstruction(Context)[m
[m
static void globalCleanup_TlsRequest_(void) {[m
[32m+[m[32m#if !defined (iPlatformAndroid)[m
if (context_) {[m
delete_Context(context_);[m
}[m
[32m+[m[32m#endif[m
}[m
[m
static void initContext_(void) {[m
[36m@@ -323,10 +332,31 @@[m [mstruct Impl_TlsCertificate {[m
STACK_OF(X509) *chain;[m
EVP_PKEY *pkey;[m
enum iTlsCertificateVerifyStatus *cachedVerifyStatus; /* TODO: include domain/IP check, too? */[m
[32m+[m[32m char fingerprint[SHA256_DIGEST_LENGTH];[m
};[m
[m
iDefineTypeConstruction(TlsCertificate)[m
[m
[32m+[m[32mstatic void calcSHA256_(BIO *src, void *sha256_out) {[m
[32m+[m[32m iBlock der;[m
[32m+[m[32m init_Block(&der, 0);[m
[32m+[m[32m readAllFromBIO_(src, &der);[m
[32m+[m[32m SHA256(constData_Block(&der), size_Block(&der), sha256_out);[m
[32m+[m[32m deinit_Block(&der);[m
[32m+[m[32m}[m
[32m+[m
[32m+[m[32mstatic void updateFingerprint_TlsCertificate_(iTlsCertificate *d) {[m
[32m+[m[32m if (d->cert) {[m
[32m+[m[32m BIO *buf = BIO_new(BIO_s_mem());[m
[32m+[m[32m i2d_X509_bio(buf, d->cert);[m
[32m+[m[32m calcSHA256_(buf, d->fingerprint);[m
[32m+[m[32m BIO_free(buf);[m
[32m+[m[32m }[m
[32m+[m[32m else {[m
[32m+[m[32m iZap(d->fingerprint);[m
[32m+[m[32m }[m
[32m+[m[32m}[m
[32m+[m
void init_TlsCertificate(iTlsCertificate *d) {[m
initContext_();[m
d->cert = NULL;[m
[36m@@ -334,6 +364,7 @@[m [mvoid init_TlsCertificate(iTlsCertificate *d) {[m
d->pkey = NULL;[m
d->cachedVerifyStatus = malloc(sizeof(*d->cachedVerifyStatus));[m
*d->cachedVerifyStatus = unknown_TlsCertificateVerifyStatus;[m
[32m+[m[32m iZap(d->fingerprint);[m
}[m
[m
static void freeX509Chain_(STACK_OF(X509) *chain) {[m
[36m@@ -362,6 +393,7 @@[m [mstatic iTlsCertificate *newX509Chain_TlsCertificate_(X509 *cert, STACK_OF(X509)[m
iTlsCertificate *d = new_TlsCertificate();[m
d->cert = cert;[m
d->chain = chain;[m
[32m+[m[32m updateFingerprint_TlsCertificate_(d);[m
return d;[m
}[m
[m
[36m@@ -370,6 +402,7 @@[m [miTlsCertificate *newPem_TlsCertificate(const iString *pem) {[m
BIO *buf = BIO_new_mem_buf(cstr_String(pem), (int) size_String(pem));[m
PEM_read_bio_X509(buf, &d->cert, NULL /* no passphrase callback */, "" /* empty passphrase */);[m
BIO_free(buf);[m
[32m+[m[32m updateFingerprint_TlsCertificate_(d);[m
return d;[m
}[m
[m
[36m@@ -378,6 +411,7 @@[m [miTlsCertificate *newPemKey_TlsCertificate(const iString *certPem, const iString[m
BIO *buf = BIO_new_mem_buf(cstr_String(keyPem), (int) size_String(keyPem));[m
PEM_read_bio_PrivateKey(buf, &d->pkey, NULL, "");[m
BIO_free(buf);[m
[32m+[m[32m updateFingerprint_TlsCertificate_(d);[m
return d;[m
}[m
[m
[36m@@ -500,6 +534,7 @@[m [miTlsCertificate *newSelfSignedRSA_TlsCertificate([m
}[m
X509_sign(d->cert, d->pkey, EVP_sha256());[m
checkErrors_();[m
[32m+[m[32m updateFingerprint_TlsCertificate_(d);[m
return d;[m
}[m
[m
[36m@@ -515,6 +550,7 @@[m [miTlsCertificate *copy_TlsCertificate(const iTlsCertificate *d) {[m
copy->pkey = d->pkey;[m
}[m
*copy->cachedVerifyStatus = *d->cachedVerifyStatus;[m
[32m+[m[32m memcpy(copy->fingerprint, d->fingerprint, sizeof(d->fingerprint));[m
return copy;[m
}[m
[m
[36m@@ -707,24 +743,8 @@[m [miBool equal_TlsCertificate(const iTlsCertificate *d, const iTlsCertificate *othe[m
return X509_cmp(d->cert, other->cert) == 0;[m
}[m
[m
[31m-static void calcSHA256_(BIO *src, iBlock *dst) {[m
[31m- iBlock der;[m
[31m- init_Block(&der, 0);[m
[31m- readAllFromBIO_(src, &der);[m
[31m- SHA256(constData_Block(&der), size_Block(&der), data_Block(dst));[m
[31m- deinit_Block(&der);[m
[31m-}[m
[31m-[m
iBlock *fingerprint_TlsCertificate(const iTlsCertificate *d) {[m
[31m- iBlock *sha = new_Block(SHA256_DIGEST_LENGTH);[m
[31m- if (d->cert) {[m
[31m- /* Get the DER serialization of the certificate. */[m
[31m- BIO *buf = BIO_new(BIO_s_mem());[m
[31m- i2d_X509_bio(buf, d->cert);[m
[31m- calcSHA256_(buf, sha);[m
[31m- BIO_free(buf);[m
[31m- }[m
[31m- return sha;[m
[32m+[m[32m return newData_Block(d->fingerprint, sizeof(d->fingerprint));[m
}[m
[m
iBlock *publicKeyFingerprint_TlsCertificate(const iTlsCertificate *d) {[m
[36m@@ -737,7 +757,7 @@[m [miBlock *publicKeyFingerprint_TlsCertificate(const iTlsCertificate *d) {[m
/* Get the DER serialization of the public key. */[m
BIO *buf = BIO_new(BIO_s_mem());[m
i2d_PUBKEY_bio(buf, pub);[m
[31m- calcSHA256_(buf, sha);[m
[32m+[m[32m calcSHA256_(buf, data_Block(sha));[m
BIO_free(buf);[m
EVP_PKEY_free(pub);[m
}[m
[36m@@ -750,7 +770,7 @@[m [miBlock *privateKeyFingerprint_TlsCertificate(const iTlsCertificate *d) {[m
/* Get the DER serialization of the private key. */[m
BIO *buf = BIO_new(BIO_s_mem());[m
i2d_PrivateKey_bio(buf, d->pkey);[m
[31m- calcSHA256_(buf, sha);[m
[32m+[m[32m calcSHA256_(buf, data_Block(sha));[m
BIO_free(buf);[m
}[m
return sha;[m
[36m@@ -960,6 +980,7 @@[m [mvoid deinit_TlsRequest(iTlsRequest *d) {[m
join_Thread(d->thread);[m
iRelease(d->thread);[m
}[m
[32m+[m[32m iRelease(d->socket);[m
deinit_Block(&d->sending);[m
SSL_free(d->ssl);[m
deinit_Condition(&d->requestDone);[m
[36m@@ -973,7 +994,6 @@[m [mvoid deinit_TlsRequest(iTlsRequest *d) {[m
delete_TlsCertificate(d->cert);[m
iRelease(d->result);[m
deinit_Block(&d->content);[m
[31m- iRelease(d->socket);[m
delete_String(d->hostName);[m
deinit_Mutex(&d->mtx);[m
}[m
[36m@@ -1092,7 +1112,9 @@[m [mstatic iThreadResult run_TlsRequest_(iThread *thread) {[m
iTlsRequest *d = userData_Thread(thread);[m
/* Thread-local pointer to the current request so it can be accessed in the[m
verify callback. */[m
[31m- iDebug("[TlsRequest] run_TlsRequest_: %zu bytes to send\n", size_Block(&d->sending));[m
[32m+[m[32m const char *tname = cstr_String(name_Thread(thread));[m
[32m+[m[32m iUnused(tname); /* just for debug logs */[m
[32m+[m[32m iDebug("[%s] run_TlsRequest_: %zu bytes to send\n", tname, size_Block(&d->sending));[m
setCurrentRequestForThread_Context_(context_, d);[m
doHandshake_TlsRequest_(d);[m
for (;;) {[m
[36m@@ -1109,31 +1131,36 @@[m [mstatic iThreadResult run_TlsRequest_(iThread *thread) {[m
unlock_Mutex(&d->incomingMtx);[m
}[m
else {[m
[31m- //fprintf(stderr, "[TlsRequest] run loop exiting, status %d\n", d->status);[m
[32m+[m[32m iDebug("[%s] run loop exiting, status %d\n", tname, d->status);[m
unlock_Mutex(&d->mtx);[m
break;[m
}[m
}[m
}[m
[31m- if (!SSL_session_reused(d->ssl) && d->status != error_TlsRequestStatus) {[m
[32m+[m[32m if (d->status != error_TlsRequestStatus && !SSL_session_reused(d->ssl)) {[m
[32m+[m[32m iDebug("[%s] saving session\n", tname);[m
saveSession_Context_([m
context_, d->hostName, d->port, SSL_get0_session(d->ssl), d->cert, d->clientCert);[m
[32m+[m[32m iDebug("[%s] saving session succeeded\n", tname);[m
}[m
readIncoming_TlsRequest_(d);[m
iNotifyAudience(d, finished, TlsRequestFinished);[m
[31m- iDebug("[TlsRequest] finished\n");[m
[32m+[m[32m iDebug("[%s] finished\n", tname);[m
return 0;[m
}[m
[m
static void connected_TlsRequest_(iTlsRequest *d, iSocket *sock) {[m
/* The socket has been connected. During this notification the socket remains locked[m
so we must start a different thread for carrying out the I/O. */[m
[32m+[m[32m iBeginCollect();[m
iUnused(sock);[m
iAssert(!d->thread);[m
d->thread = new_Thread(run_TlsRequest_);[m
[31m- setName_Thread(d->thread, "TlsRequest");[m
[32m+[m[32m static iAtomicInt idGen_ = 1;[m
[32m+[m[32m setName_Thread(d->thread, format_CStr("TlsRequest-%d", add_Atomic(&idGen_, 1)));[m
setUserData_Thread(d->thread, d);[m
start_Thread(d->thread);[m
[32m+[m[32m iEndCollect();[m
}[m
[m
static void disconnected_TlsRequest_(iTlsRequest *d, iSocket *sock) {[m
text/plain
This content has been proxied by September (3851b).