Compare commits

...

3 Commits

Author SHA1 Message Date
Vladimir Dubrovin
661631138a Give an intercepted certificate its key identifiers
Some checks failed
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
C/C++ CI cmake / ubuntu-latest (wolfSSL) (push) Has been cancelled
A verifier following RFC 5280 strictly looks for the issuer through a key
identifier and refuses a certificate carrying none: OpenSSL does with
x509_strict, and Python has since 3.13, so a current client rejects an
intercepted connection outright. Working around that by turning verification
off in the client removes the protection interception was meant to preserve.

Generate the identifiers rather than copying them, so they name the CA
signing here and not the one that signed upstream. wolfSSL cannot generate
extensions, so this is in the branch that already depends on that.
2026-08-26 16:55:37 +03:00
Vladimir Dubrovin
3422f780bf Make pcre_extend work
The filter walked its list of access rules but tested the first entry each
time round, so anything pcre_extend appended was never consulted and the
command did nothing at all. Test the entry the loop is on.
2026-08-26 16:55:37 +03:00
Vladimir Dubrovin
0df93bfab7 Let a Windows UDP service bind the socket it answers from
A UDP service on Windows binds a second socket to the address it listens on,
so a reply leaves the port the client sent to. Windows only allows that when
both sockets ask for it, and the listening socket was never asked, so the
bind failed and dnspr answered nothing at all on Windows.

Ask for it on the listening socket of a UDP service, and there only: the
reason it is withheld otherwise, that another local process could take a
listening port, is unchanged for everything else.
2026-08-26 16:55:37 +03:00
3 changed files with 32 additions and 6 deletions

View File

@ -277,7 +277,7 @@ static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, uns
#define pcrefd ((struct pcre_filter_data *)fc) #define pcrefd ((struct pcre_filter_data *)fc)
for(acl = pcrefd->acl; acl; acl=acl->next){ for(acl = pcrefd->acl; acl; acl=acl->next){
if(pl->ACLMatches(pcrefd->acl, param)){ if(pl->ACLMatches(acl, param)){
match = 1; match = 1;
break; break;
} }

View File

@ -830,6 +830,14 @@ int MODULEMAINFUNC (int argc, char** argv){
#ifndef _WIN32 #ifndef _WIN32
opt = 1; opt = 1;
if(srv.so._setsockopt(srv.so.state, sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)))perror("setsockopt()"); if(srv.so._setsockopt(srv.so.state, sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)))perror("setsockopt()");
#else
/* A UDP service on Windows answers from a second socket bound to
the address it listens on, and Windows only allows that bind
when both sockets ask for it. */
if(isudp){
opt = 1;
if(srv.so._setsockopt(srv.so.state, sock, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(int)))perror("setsockopt()");
}
#endif #endif
#ifdef SO_REUSEPORT #ifdef SO_REUSEPORT
opt = 1; opt = 1;

View File

@ -84,7 +84,11 @@ static int copy_ext(X509 *dst_cert, X509 *src_cert, int nid)
} }
#ifndef WITH_WOLFSSL #ifndef WITH_WOLFSSL
static int add_ext(X509 *cert, int nid, const char *value) /* issuer is the certificate the extension should describe as the issuer,
* which matters for an authority key identifier: it names the key that
* signs, not the key being signed.
*/
static int add_ext_issuer(X509 *cert, X509 *issuer, int nid, const char *value)
{ {
X509_EXTENSION *ex; X509_EXTENSION *ex;
X509V3_CTX ctx; X509V3_CTX ctx;
@ -92,10 +96,8 @@ static int add_ext(X509 *cert, int nid, const char *value)
/* This sets the 'context' of the extensions. */ /* This sets the 'context' of the extensions. */
/* No configuration database */ /* No configuration database */
X509V3_set_ctx_nodb(&ctx); X509V3_set_ctx_nodb(&ctx);
/* Issuer and subject certs: both the target since it is self signed, /* No request and no CRL */
* no request and no CRL X509V3_set_ctx(&ctx, issuer, cert, NULL, NULL, 0);
*/
X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
/* value is char * prior to OpenSSL 1.1.0 */ /* value is char * prior to OpenSSL 1.1.0 */
ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, (char *)value); ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, (char *)value);
if (!ex) if (!ex)
@ -105,6 +107,12 @@ static int add_ext(X509 *cert, int nid, const char *value)
X509_EXTENSION_free(ex); X509_EXTENSION_free(ex);
return err > 0; return err > 0;
} }
static int add_ext(X509 *cert, int nid, const char *value)
{
/* Issuer and subject: both the target, for a self signed certificate */
return add_ext_issuer(cert, cert, nid, value);
}
#endif #endif
SSL_CERT ssl_copy_cert(SSL_CERT cert, SSL_CONFIG *config) SSL_CERT ssl_copy_cert(SSL_CERT cert, SSL_CONFIG *config)
@ -199,6 +207,16 @@ SSL_CERT ssl_copy_cert(SSL_CERT cert, SSL_CONFIG *config)
add_ext(dst_cert, NID_basic_constraints, "critical,CA:FALSE"); add_ext(dst_cert, NID_basic_constraints, "critical,CA:FALSE");
if(!copy_ext(dst_cert, src_cert, NID_ext_key_usage)) if(!copy_ext(dst_cert, src_cert, NID_ext_key_usage))
add_ext(dst_cert, NID_ext_key_usage, "serverAuth"); add_ext(dst_cert, NID_ext_key_usage, "serverAuth");
/* A verifier following RFC 5280 strictly looks for the issuer through a
* key identifier and refuses a certificate carrying none: OpenSSL does
* with x509_strict, and Python has since 3.13. The identifiers are
* generated rather than copied, so they name the CA signing here
* instead of the one that signed upstream. keyid,issuer keeps working
* when the CA certificate has no subject key identifier of its own.
*/
add_ext(dst_cert, NID_subject_key_identifier, "hash");
add_ext_issuer(dst_cert, config->CA_cert, NID_authority_key_identifier,
"keyid,issuer");
#else #else
copy_ext(dst_cert, src_cert, NID_basic_constraints); copy_ext(dst_cert, src_cert, NID_basic_constraints);
copy_ext(dst_cert, src_cert, NID_ext_key_usage); copy_ext(dst_cert, src_cert, NID_ext_key_usage);