Skip to content

Commit 3fdcaab

Browse files
authored
Merge pull request #441 from radiator-software/GH-71-add-ctx_set_client_hello_cb
GH-71 Expose SSL_CTX_set_client_hello_cb and related functions
2 parents 8434d9a + a91f2bb commit 3fdcaab

File tree

9 files changed

+2744
-960
lines changed

9 files changed

+2744
-960
lines changed

Changes

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,29 @@ Revision history for Perl extension Net::SSLeay.
3030
Update the previous minor releases to their latest versions. Add
3131
NetBSD to BSDs job and update the other BSDs and Alpine Linux jobs to
3232
cover additional and latest releases. Use the latest MacOS runners.
33+
- Expose SSL_CTX_set_client_hello_cb for setting a callback
34+
the server calls when it processes a ClientHello. Expose the
35+
following functions that can be called only from the
36+
callback.
37+
- SSL_client_hello_isv2
38+
- SSL_client_hello_get0_legacy_version
39+
- SSL_client_hello_get0_random
40+
- SSL_client_hello_get0_session_id
41+
- SSL_client_hello_get0_ciphers
42+
- SSL_client_hello_get0_compression_methods
43+
- SSL_client_hello_get1_extensions_present
44+
- SSL_client_hello_get_extension_order
45+
- SSL_client_hello_get0_ext
46+
- Expose constants used by SSL_CTX_set_client_hello_cb related
47+
functions:
48+
- AD_ prefixed constants naming TLS alert codes for
49+
returning from a ClientHello callback or where alert types
50+
are used
51+
- CLIENT_HELLO_ERROR, CLIENT_HELLO_RETRY and
52+
CLIENT_HELLO_SUCCESS for returning from a ClientHello
53+
callback
54+
- TLSEXT_TYPE_ prefixed contants for naming TLS extension
55+
types
3356

3457
1.93_02 2023-02-22
3558
- Update ppport.h to version 3.68. This eliminates thousands of

MANIFEST

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@ t/local/44_sess.t
221221
t/local/45_exporter.t
222222
t/local/46_msg_callback.t
223223
t/local/47_keylog.t
224+
t/local/48_client_hello_callback.t
224225
t/local/50_digest.t
225226
t/local/61_threads-cb-crash.t
226227
t/local/62_threads-ctx_new-deadlock.t

SSLeay.xs

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,6 +1810,47 @@ void ssl_ctx_keylog_cb_func_invoke(const SSL *ssl, const char *line)
18101810
}
18111811
#endif
18121812

1813+
#if OPENSSL_VERSION_NUMBER >= 0x10101001L && !defined(LIBRESSL_VERSION_NUMBER)
1814+
int ssl_client_hello_cb_fn_invoke(SSL *ssl, int *al, void *arg)
1815+
{
1816+
dSP;
1817+
int count, res;
1818+
SV *cb_func, *cb_arg;
1819+
SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1820+
1821+
PR1("STARTED: ssl_client_hello_cb_fn_invoke\n");
1822+
cb_func = cb_data_advanced_get(ctx, "ssleay_ssl_ctx_client_hello_cb!!func");
1823+
cb_arg = cb_data_advanced_get(ctx, "ssleay_ssl_ctx_client_hello_cb!!arg");
1824+
if(!SvOK(cb_func))
1825+
croak ("Net::SSLeay: ssl_client_hello_cb_fn_invoke called, but not set to point to any perl function.\n");
1826+
1827+
ENTER;
1828+
SAVETMPS;
1829+
1830+
PUSHMARK(SP);
1831+
XPUSHs(sv_2mortal(newSViv(PTR2IV(ssl))));
1832+
XPUSHs(sv_2mortal(newSVsv(cb_arg)));
1833+
1834+
PUTBACK;
1835+
1836+
count = call_sv(cb_func, G_LIST);
1837+
1838+
SPAGAIN;
1839+
1840+
if (count < 1 || count > 2)
1841+
croak ("Net::SSLeay: ssl_client_hello_cb_fn perl function returned %d values, 1 or 2 expected\n", count);
1842+
if (count == 2)
1843+
*al = POPi;
1844+
res = POPi;
1845+
1846+
PUTBACK;
1847+
FREETMPS;
1848+
LEAVE;
1849+
1850+
return res;
1851+
}
1852+
#endif
1853+
18131854
/* ============= end of callback stuff, begin helper functions ============== */
18141855

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

58385879
#endif
58395880

5881+
#if OPENSSL_VERSION_NUMBER >= 0x10101001L && !defined(LIBRESSL_VERSION_NUMBER)
5882+
5883+
void
5884+
SSL_CTX_set_client_hello_cb(SSL_CTX *ctx, SV *callback, SV *arg=&PL_sv_undef)
5885+
CODE:
5886+
if (callback==NULL || !SvOK(callback)) {
5887+
SSL_CTX_set_client_hello_cb(ctx, NULL, NULL);
5888+
cb_data_advanced_put(ctx, "ssleay_ssl_ctx_client_hello_cb!!func", NULL);
5889+
cb_data_advanced_put(ctx, "ssleay_ssl_ctx_client_hello_cb!!arg", NULL);
5890+
} else {
5891+
cb_data_advanced_put(ctx, "ssleay_ssl_ctx_client_hello_cb!!func", newSVsv(callback));
5892+
cb_data_advanced_put(ctx, "ssleay_ssl_ctx_client_hello_cb!!arg", newSVsv(arg));
5893+
SSL_CTX_set_client_hello_cb(ctx, ssl_client_hello_cb_fn_invoke, NULL);
5894+
}
5895+
5896+
int
5897+
SSL_client_hello_isv2(SSL *s)
5898+
5899+
unsigned int
5900+
SSL_client_hello_get0_legacy_version(SSL *s)
5901+
5902+
void
5903+
SSL_client_hello_get0_random(SSL *s)
5904+
PREINIT:
5905+
const unsigned char *out = NULL;
5906+
size_t outlen;
5907+
CODE:
5908+
outlen = SSL_client_hello_get0_random(s, &out);
5909+
if (outlen == 0) XSRETURN_PV("");
5910+
ST(0) = sv_newmortal();
5911+
sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);
5912+
5913+
void
5914+
SSL_client_hello_get0_session_id(SSL *s)
5915+
PREINIT:
5916+
const unsigned char *out = NULL;
5917+
size_t outlen;
5918+
CODE:
5919+
outlen = SSL_client_hello_get0_session_id(s, &out);
5920+
if (outlen == 0) XSRETURN_PV("");
5921+
ST(0) = sv_newmortal();
5922+
sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);
5923+
5924+
void
5925+
SSL_client_hello_get0_ciphers(SSL *s)
5926+
PREINIT:
5927+
const unsigned char *out = NULL;
5928+
size_t outlen;
5929+
CODE:
5930+
outlen = SSL_client_hello_get0_ciphers(s, &out);
5931+
if (outlen == 0) XSRETURN_PV("");
5932+
ST(0) = sv_newmortal();
5933+
sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);
5934+
5935+
void
5936+
SSL_client_hello_get0_compression_methods(SSL *s)
5937+
PREINIT:
5938+
const unsigned char *out = NULL;
5939+
size_t outlen;
5940+
CODE:
5941+
outlen = SSL_client_hello_get0_compression_methods(s, &out);
5942+
if (outlen == 0) XSRETURN_PV("");
5943+
ST(0) = sv_newmortal();
5944+
sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);
5945+
5946+
void
5947+
SSL_client_hello_get1_extensions_present(SSL *s)
5948+
PREINIT:
5949+
int ret, *out = NULL, i;
5950+
size_t outlen;
5951+
AV *av;
5952+
PPCODE:
5953+
ret = SSL_client_hello_get1_extensions_present(s, &out, &outlen);
5954+
if (ret != 1) XSRETURN_UNDEF;
5955+
5956+
av = newAV();
5957+
mXPUSHs(newRV_noinc((SV*)av));
5958+
for (i=0; i < outlen; i++) {
5959+
av_push(av, newSViv(*(out + i)));
5960+
}
5961+
OPENSSL_free(out);
5962+
5963+
#if OPENSSL_VERSION_NUMBER >= 0x30200000L && !defined(LIBRESSL_VERSION_NUMBER)
5964+
5965+
void
5966+
SSL_client_hello_get_extension_order(SSL *s)
5967+
PREINIT:
5968+
int ret, i;
5969+
uint16_t *exts;
5970+
size_t num_exts;
5971+
AV *av;
5972+
PPCODE:
5973+
ret = SSL_client_hello_get_extension_order(s, NULL, &num_exts);
5974+
if (ret != 1) XSRETURN_UNDEF;
5975+
5976+
Newx(exts, num_exts, uint16_t);
5977+
ret = SSL_client_hello_get_extension_order(s, exts, &num_exts);
5978+
if (ret != 1) {
5979+
Safefree(exts);
5980+
XSRETURN_UNDEF;
5981+
}
5982+
5983+
av = newAV();
5984+
mXPUSHs(newRV_noinc((SV*)av));
5985+
for (i=0; i < num_exts; i++) {
5986+
av_push(av, newSViv(*(exts + i)));
5987+
}
5988+
Safefree(exts);
5989+
5990+
#endif
5991+
5992+
void
5993+
SSL_client_hello_get0_ext(SSL *s, unsigned int type)
5994+
PREINIT:
5995+
int ret;
5996+
const unsigned char *out = NULL;
5997+
size_t outlen;
5998+
CODE:
5999+
ret = SSL_client_hello_get0_ext(s, type, &out, &outlen);
6000+
if (ret != 1) XSRETURN_UNDEF;
6001+
6002+
ST(0) = sv_newmortal();
6003+
sv_setpvn(ST(0), (const char *)out, (STRLEN)outlen);
6004+
6005+
#endif
58406006

58416007
int
58426008
SSL_set_purpose(s,purpose)

0 commit comments

Comments
 (0)