Skip to content

Commit

Permalink
Merge pull request #441 from radiator-software/GH-71-add-ctx_set_clie…
Browse files Browse the repository at this point in the history
…nt_hello_cb

GH-71 Expose SSL_CTX_set_client_hello_cb and related functions
  • Loading branch information
h-vn authored Sep 6, 2023
2 parents 8434d9a + a91f2bb commit 3fdcaab
Show file tree
Hide file tree
Showing 9 changed files with 2,744 additions and 960 deletions.
23 changes: 23 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,29 @@ Revision history for Perl extension Net::SSLeay.
Update the previous minor releases to their latest versions. Add
NetBSD to BSDs job and update the other BSDs and Alpine Linux jobs to
cover additional and latest releases. Use the latest MacOS runners.
- Expose SSL_CTX_set_client_hello_cb for setting a callback
the server calls when it processes a ClientHello. Expose the
following functions that can be called only from the
callback.
- SSL_client_hello_isv2
- SSL_client_hello_get0_legacy_version
- SSL_client_hello_get0_random
- SSL_client_hello_get0_session_id
- SSL_client_hello_get0_ciphers
- SSL_client_hello_get0_compression_methods
- SSL_client_hello_get1_extensions_present
- SSL_client_hello_get_extension_order
- SSL_client_hello_get0_ext
- Expose constants used by SSL_CTX_set_client_hello_cb related
functions:
- AD_ prefixed constants naming TLS alert codes for
returning from a ClientHello callback or where alert types
are used
- CLIENT_HELLO_ERROR, CLIENT_HELLO_RETRY and
CLIENT_HELLO_SUCCESS for returning from a ClientHello
callback
- TLSEXT_TYPE_ prefixed contants for naming TLS extension
types

1.93_02 2023-02-22
- Update ppport.h to version 3.68. This eliminates thousands of
Expand Down
1 change: 1 addition & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ t/local/44_sess.t
t/local/45_exporter.t
t/local/46_msg_callback.t
t/local/47_keylog.t
t/local/48_client_hello_callback.t
t/local/50_digest.t
t/local/61_threads-cb-crash.t
t/local/62_threads-ctx_new-deadlock.t
Expand Down
166 changes: 166 additions & 0 deletions SSLeay.xs
Original file line number Diff line number Diff line change
Expand Up @@ -1810,6 +1810,47 @@ void ssl_ctx_keylog_cb_func_invoke(const SSL *ssl, const char *line)
}
#endif

#if OPENSSL_VERSION_NUMBER >= 0x10101001L && !defined(LIBRESSL_VERSION_NUMBER)
int ssl_client_hello_cb_fn_invoke(SSL *ssl, int *al, void *arg)
{
dSP;
int count, res;
SV *cb_func, *cb_arg;
SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);

PR1("STARTED: ssl_client_hello_cb_fn_invoke\n");
cb_func = cb_data_advanced_get(ctx, "ssleay_ssl_ctx_client_hello_cb!!func");
cb_arg = cb_data_advanced_get(ctx, "ssleay_ssl_ctx_client_hello_cb!!arg");
if(!SvOK(cb_func))
croak ("Net::SSLeay: ssl_client_hello_cb_fn_invoke called, but not set to point to any perl function.\n");

ENTER;
SAVETMPS;

PUSHMARK(SP);
XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl))));
XPUSHs(sv_2mortal(newSVsv(cb_arg)));

PUTBACK;

count = call_sv(cb_func, G_LIST);

SPAGAIN;

if (count < 1 || count > 2)
croak ("Net::SSLeay: ssl_client_hello_cb_fn perl function returned %d values, 1 or 2 expected\n", count);
if (count == 2)
*al = POPi;
res = POPi;

PUTBACK;
FREETMPS;
LEAVE;

return res;
}
#endif

/* ============= end of callback stuff, begin helper functions ============== */

time_t ASN1_TIME_timet(ASN1_TIME *asn1t, time_t *gmtoff) {
Expand Down Expand Up @@ -5837,6 +5878,131 @@ SSL_CTX_get_keylog_callback(const SSL_CTX *ctx)

#endif

#if OPENSSL_VERSION_NUMBER >= 0x10101001L && !defined(LIBRESSL_VERSION_NUMBER)

void
SSL_CTX_set_client_hello_cb(SSL_CTX *ctx, SV *callback, SV *arg=&PL_sv_undef)
CODE:
if (callback==NULL || !SvOK(callback)) {
SSL_CTX_set_client_hello_cb(ctx, NULL, NULL);
cb_data_advanced_put(ctx, "ssleay_ssl_ctx_client_hello_cb!!func", NULL);
cb_data_advanced_put(ctx, "ssleay_ssl_ctx_client_hello_cb!!arg", NULL);
} else {
cb_data_advanced_put(ctx, "ssleay_ssl_ctx_client_hello_cb!!func", newSVsv(callback));
cb_data_advanced_put(ctx, "ssleay_ssl_ctx_client_hello_cb!!arg", newSVsv(arg));
SSL_CTX_set_client_hello_cb(ctx, ssl_client_hello_cb_fn_invoke, NULL);
}

int
SSL_client_hello_isv2(SSL *s)

unsigned int
SSL_client_hello_get0_legacy_version(SSL *s)

void
SSL_client_hello_get0_random(SSL *s)
PREINIT:
const unsigned char *out = NULL;
size_t outlen;
CODE:
outlen = SSL_client_hello_get0_random(s, &out);
if (outlen == 0) XSRETURN_PV("");
ST(0) = sv_newmortal();
sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);

void
SSL_client_hello_get0_session_id(SSL *s)
PREINIT:
const unsigned char *out = NULL;
size_t outlen;
CODE:
outlen = SSL_client_hello_get0_session_id(s, &out);
if (outlen == 0) XSRETURN_PV("");
ST(0) = sv_newmortal();
sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);

void
SSL_client_hello_get0_ciphers(SSL *s)
PREINIT:
const unsigned char *out = NULL;
size_t outlen;
CODE:
outlen = SSL_client_hello_get0_ciphers(s, &out);
if (outlen == 0) XSRETURN_PV("");
ST(0) = sv_newmortal();
sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);

void
SSL_client_hello_get0_compression_methods(SSL *s)
PREINIT:
const unsigned char *out = NULL;
size_t outlen;
CODE:
outlen = SSL_client_hello_get0_compression_methods(s, &out);
if (outlen == 0) XSRETURN_PV("");
ST(0) = sv_newmortal();
sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);

void
SSL_client_hello_get1_extensions_present(SSL *s)
PREINIT:
int ret, *out = NULL, i;
size_t outlen;
AV *av;
PPCODE:
ret = SSL_client_hello_get1_extensions_present(s, &out, &outlen);
if (ret != 1) XSRETURN_UNDEF;

av = newAV();
mXPUSHs(newRV_noinc((SV*)av));
for (i=0; i < outlen; i++) {
av_push(av, newSViv(*(out + i)));
}
OPENSSL_free(out);

#if OPENSSL_VERSION_NUMBER >= 0x30200000L && !defined(LIBRESSL_VERSION_NUMBER)

void
SSL_client_hello_get_extension_order(SSL *s)
PREINIT:
int ret, i;
uint16_t *exts;
size_t num_exts;
AV *av;
PPCODE:
ret = SSL_client_hello_get_extension_order(s, NULL, &num_exts);
if (ret != 1) XSRETURN_UNDEF;

Newx(exts, num_exts, uint16_t);
ret = SSL_client_hello_get_extension_order(s, exts, &num_exts);
if (ret != 1) {
Safefree(exts);
XSRETURN_UNDEF;
}

av = newAV();
mXPUSHs(newRV_noinc((SV*)av));
for (i=0; i < num_exts; i++) {
av_push(av, newSViv(*(exts + i)));
}
Safefree(exts);

#endif

void
SSL_client_hello_get0_ext(SSL *s, unsigned int type)
PREINIT:
int ret;
const unsigned char *out = NULL;
size_t outlen;
CODE:
ret = SSL_client_hello_get0_ext(s, type, &out, &outlen);
if (ret != 1) XSRETURN_UNDEF;

ST(0) = sv_newmortal();
sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);

#endif

int
SSL_set_purpose(s,purpose)
Expand Down
Loading

0 comments on commit 3fdcaab

Please sign in to comment.