MINOR: ssl: add the ssl_s_* sample fetches for server side certificate

This commit adds some sample fetches that were lacking on the server
side:

ssl_s_key_alg, ssl_s_notafter, ssl_s_notbefore, ssl_s_sig_alg,
ssl_s_i_dn, ssl_s_s_dn, ssl_s_serial, ssl_s_sha1, ssl_s_der,
ssl_s_version
This commit is contained in:
William Lallemand 2020-06-25 20:07:18 +02:00 committed by William Lallemand
parent 99cc21851f
commit bfa3e81a7b
3 changed files with 222 additions and 20 deletions

View File

@ -17077,6 +17077,74 @@ ssl_fc_use_keysize : integer
Returns the symmetric cipher key size used in bits when the incoming
connection was made over an SSL/TLS transport layer.
ssl_s_der : binary
Returns the DER formatted certificate presented by the server when the
outgoing connection was made over an SSL/TLS transport layer. When used for
an ACL, the value(s) to match against can be passed in hexadecimal form.
ssl_s_key_alg : string
Returns the name of the algorithm used to generate the key of the certificate
presented by the server when the outgoing connection was made over an
SSL/TLS transport layer.
ssl_s_notafter : string
Returns the end date presented by the server as a formatted string
YYMMDDhhmmss[Z] when the outgoing connection was made over an SSL/TLS
transport layer.
ssl_s_notbefore : string
Returns the start date presented by the server as a formatted string
YYMMDDhhmmss[Z] when the outgoing connection was made over an SSL/TLS
transport layer.
ssl_s_i_dn([<entry>[,<occ>[,<format>]]]) : string
When the outgoing connection was made over an SSL/TLS transport layer,
returns the full distinguished name of the issuer of the certificate
presented by the server when no <entry> is specified, or the value of the
first given entry found from the beginning of the DN. If a positive/negative
occurrence number is specified as the optional second argument, it returns
the value of the nth given entry value from the beginning/end of the DN.
For instance, "ssl_f_i_dn(OU,2)" the second organization unit, and
"ssl_f_i_dn(CN)" retrieves the common name.
The <format> parameter allows you to receive the DN suitable for
consumption by different protocols. Currently supported is rfc2253 for
LDAP v3.
If you'd like to modify the format only you can specify an empty string
and zero for the first two parameters. Example: ssl_s_i_dn(,0,rfc2253)
ssl_s_s_dn([<entry>[,<occ>[,<format>]]]) : string
When the outgoing connection was made over an SSL/TLS transport layer,
returns the full distinguished name of the subject of the certificate
presented by the server when no <entry> is specified, or the value of the
first given entry found from the beginning of the DN. If a positive/negative
occurrence number is specified as the optional second argument, it returns
the value of the nth given entry value from the beginning/end of the DN.
For instance, "ssl_f_s_dn(OU,2)" the second organization unit, and
"ssl_f_s_dn(CN)" retrieves the common name.
The <format> parameter allows you to receive the DN suitable for
consumption by different protocols. Currently supported is rfc2253 for
LDAP v3.
If you'd like to modify the format only you can specify an empty string
and zero for the first two parameters. Example: ssl_s_s_dn(,0,rfc2253)
ssl_s_serial : binary
Returns the serial of the certificate presented by the server when the
outgoing connection was made over an SSL/TLS transport layer. When used for
an ACL, the value(s) to match against can be passed in hexadecimal form.
ssl_s_sha1 : binary
Returns the SHA-1 fingerprint of the certificate presented by the server
when the outgoing connection was made over an SSL/TLS transport layer. This
can be used to know which certificate was chosen using SNI.
ssl_s_sig_alg : string
Returns the name of the algorithm used to sign the certificate presented by
the server when the outgoing connection was made over an SSL/TLS transport
layer.
ssl_s_version : integer
Returns the version of the certificate presented by the server when the
outgoing connection was made over an SSL/TLS transport layer.
7.3.5. Fetching samples from buffer contents (Layer 6)
------------------------------------------------------

View File

@ -0,0 +1,73 @@
#REGTEST_TYPE=devel
varnishtest "Test the ssl_s_* sample fetches"
#REQUIRE_VERSION=2.2
#REQUIRE_OPTIONS=OPENSSL
feature ignore_unknown_macro
server s1 -repeat 3 {
rxreq
txresp
} -start
haproxy h1 -conf {
global
tune.ssl.default-dh-param 2048
tune.ssl.capture-cipherlist-size 1
crt-base ${testdir}
stats socket "${tmpdir}/h1/stats" level admin
defaults
mode http
option httplog
${no-htx} option http-use-htx
log stderr local0 debug err
option logasap
timeout connect 1s
timeout client 1s
timeout server 1s
listen clear-lst
bind "fd@${clearlst}"
balance roundrobin
http-response add-header x-ssl-sha1 %[ssl_s_sha1,hex]
http-response add-header x-ssl-notafter %[ssl_s_notafter]
http-response add-header x-ssl-notbefore %[ssl_s_notbefore]
http-response add-header x-ssl-sig_alg %[ssl_s_sig_alg]
http-response add-header x-ssl-i_dn %[ssl_s_i_dn]
http-response add-header x-ssl-s_dn %[ssl_s_s_dn]
http-response add-header x-ssl-s_serial %[ssl_s_serial,hex]
http-response add-header x-ssl-key_alg %[ssl_s_key_alg]
http-response add-header x-ssl-der %[ssl_s_der,hex]
http-response add-header x-ssl-version %[ssl_s_version]
server s1 "${tmpdir}/ssl.sock" ssl verify none sni str(www.test1.com)
listen ssl-lst
mode http
${no-htx} option http-use-htx
bind "${tmpdir}/ssl.sock" ssl strict-sni crt-list ${testdir}/localhost.crt-list
server s1 ${s1_addr}:${s1_port}
} -start
client c1 -connect ${h1_clearlst_sock} {
txreq
rxresp
expect resp.status == 200
expect resp.http.x-ssl-sha1 == "2195C9F0FD58470313013FC27C1B9CF9864BD1C6"
expect resp.http.x-ssl-notafter == "180116230238Z"
expect resp.http.x-ssl-notbefore == "160117230238Z"
expect resp.http.x-ssl-sig_alg == "RSA-SHA256"
expect resp.http.x-ssl-i_dn == "/C=FR/ST=Ile-de-France/L=Paris/O=ozon.io/CN=Ozon Test CA/emailAddress=support@ozon.io"
expect resp.http.x-ssl-s_dn == "/C=FR/ST=Ile-de-France/L=Neuilly-sur-Seine/O=TOAD Consulting/OU=eParapher Team/CN=www.test1.com/emailAddress=arnault.michel@toad-consulting.fr"
expect resp.http.x-ssl-s_serial == "02"
expect resp.http.x-ssl-key_alg == "rsaEncryption"
expect resp.http.x-ssl-version == "3"
expect resp.http.x-ssl-der ~ 3082067930820461A0030201020201.*
} -run

View File

@ -91,14 +91,20 @@ smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char
static int
smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
int cert_peer = (kw[4] == 'c') ? 1 : 0;
int cert_peer = (kw[4] == 'c' || kw[4] == 's') ? 1 : 0;
int conn_server = (kw[4] == 's') ? 1 : 0;
X509 *crt = NULL;
int ret = 0;
struct buffer *smp_trash;
struct connection *conn;
SSL *ssl;
conn = objt_conn(smp->sess->origin);
if (conn_server)
conn = cs_conn(objt_cs(smp->strm->si[1].end));
else
conn = objt_conn(smp->sess->origin);
ssl = ssl_sock_get_ssl_object(conn);
if (!ssl)
return 0;
@ -137,14 +143,18 @@ out:
static int
smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
int cert_peer = (kw[4] == 'c') ? 1 : 0;
int cert_peer = (kw[4] == 'c' || kw[4] == 's') ? 1 : 0;
int conn_server = (kw[4] == 's') ? 1 : 0;
X509 *crt = NULL;
int ret = 0;
struct buffer *smp_trash;
struct connection *conn;
SSL *ssl;
conn = objt_conn(smp->sess->origin);
if (conn_server)
conn = cs_conn(objt_cs(smp->strm->si[1].end));
else
conn = objt_conn(smp->sess->origin);
ssl = ssl_sock_get_ssl_object(conn);
if (!ssl)
return 0;
@ -183,7 +193,8 @@ out:
static int
smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
int cert_peer = (kw[4] == 'c') ? 1 : 0;
int cert_peer = (kw[4] == 'c' || kw[4] == 's') ? 1 : 0;
int conn_server = (kw[4] == 's') ? 1 : 0;
X509 *crt = NULL;
const EVP_MD *digest;
int ret = 0;
@ -192,7 +203,11 @@ smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw,
struct connection *conn;
SSL *ssl;
conn = objt_conn(smp->sess->origin);
if (conn_server)
conn = cs_conn(objt_cs(smp->strm->si[1].end));
else
conn = objt_conn(smp->sess->origin);
ssl = ssl_sock_get_ssl_object(conn);
if (!ssl)
return 0;
@ -230,14 +245,19 @@ out:
static int
smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
int cert_peer = (kw[4] == 'c') ? 1 : 0;
int cert_peer = (kw[4] == 'c' || kw[4] == 's') ? 1 : 0;
int conn_server = (kw[4] == 's') ? 1 : 0;
X509 *crt = NULL;
int ret = 0;
struct buffer *smp_trash;
struct connection *conn;
SSL *ssl;
conn = objt_conn(smp->sess->origin);
if (conn_server)
conn = cs_conn(objt_cs(smp->strm->si[1].end));
else
conn = objt_conn(smp->sess->origin);
ssl = ssl_sock_get_ssl_object(conn);
if (!ssl)
return 0;
@ -275,7 +295,8 @@ out:
static int
smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
int cert_peer = (kw[4] == 'c') ? 1 : 0;
int cert_peer = (kw[4] == 'c' || kw[4] == 's') ? 1 : 0;
int conn_server = (kw[4] == 's') ? 1 : 0;
X509 *crt = NULL;
X509_NAME *name;
int ret = 0;
@ -283,7 +304,11 @@ smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw,
struct connection *conn;
SSL *ssl;
conn = objt_conn(smp->sess->origin);
if (conn_server)
conn = cs_conn(objt_cs(smp->strm->si[1].end));
else
conn = objt_conn(smp->sess->origin);
ssl = ssl_sock_get_ssl_object(conn);
if (!ssl)
return 0;
@ -338,14 +363,19 @@ out:
static int
smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
int cert_peer = (kw[4] == 'c') ? 1 : 0;
int cert_peer = (kw[4] == 'c' || kw[4] == 's') ? 1 : 0;
int conn_server = (kw[4] == 's') ? 1 : 0;
X509 *crt = NULL;
int ret = 0;
struct buffer *smp_trash;
struct connection *conn;
SSL *ssl;
conn = objt_conn(smp->sess->origin);
if (conn_server)
conn = cs_conn(objt_cs(smp->strm->si[1].end));
else
conn = objt_conn(smp->sess->origin);
ssl = ssl_sock_get_ssl_object(conn);
if (!ssl)
return 0;
@ -383,7 +413,8 @@ out:
static int
smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
int cert_peer = (kw[4] == 'c') ? 1 : 0;
int cert_peer = (kw[4] == 'c' || kw[4] == 's') ? 1 : 0;
int conn_server = (kw[4] == 's') ? 1 : 0;
X509 *crt = NULL;
X509_NAME *name;
int ret = 0;
@ -391,7 +422,11 @@ smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw,
struct connection *conn;
SSL *ssl;
conn = objt_conn(smp->sess->origin);
if (conn_server)
conn = cs_conn(objt_cs(smp->strm->si[1].end));
else
conn = objt_conn(smp->sess->origin);
ssl = ssl_sock_get_ssl_object(conn);
if (!ssl)
return 0;
@ -475,12 +510,17 @@ smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw,
static int
smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
int cert_peer = (kw[4] == 'c') ? 1 : 0;
int cert_peer = (kw[4] == 'c' || kw[4] == 's') ? 1 : 0;
int conn_server = (kw[4] == 's') ? 1 : 0;
X509 *crt;
struct connection *conn;
SSL *ssl;
conn = objt_conn(smp->sess->origin);
if (conn_server)
conn = cs_conn(objt_cs(smp->strm->si[1].end));
else
conn = objt_conn(smp->sess->origin);
ssl = ssl_sock_get_ssl_object(conn);
if (!ssl)
return 0;
@ -513,14 +553,19 @@ smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *
static int
smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
int cert_peer = (kw[4] == 'c') ? 1 : 0;
int cert_peer = (kw[4] == 'c' || kw[4] == 's') ? 1 : 0;
int conn_server = (kw[4] == 's') ? 1 : 0;
X509 *crt;
__OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
int nid;
struct connection *conn;
SSL *ssl;
conn = objt_conn(smp->sess->origin);
if (conn_server)
conn = cs_conn(objt_cs(smp->strm->si[1].end));
else
conn = objt_conn(smp->sess->origin);
ssl = ssl_sock_get_ssl_object(conn);
if (!ssl)
return 0;
@ -565,14 +610,18 @@ smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *
static int
smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
int cert_peer = (kw[4] == 'c') ? 1 : 0;
int cert_peer = (kw[4] == 'c' || kw[4] == 's') ? 1 : 0;
int conn_server = (kw[4] == 's') ? 1 : 0;
X509 *crt;
ASN1_OBJECT *algorithm;
int nid;
struct connection *conn;
SSL *ssl;
conn = objt_conn(smp->sess->origin);
if (conn_server)
conn = cs_conn(objt_cs(smp->strm->si[1].end));
else
conn = objt_conn(smp->sess->origin);
ssl = ssl_sock_get_ssl_object(conn);
if (!ssl)
return 0;
@ -1337,6 +1386,18 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
{ "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
{ "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
{ "ssl_fc_cipherlist_xxh", smp_fetch_ssl_fc_cl_xxh64, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
/* SSL server certificate fetches */
{ "ssl_s_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
{ "ssl_s_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
{ "ssl_s_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
{ "ssl_s_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
{ "ssl_s_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
{ "ssl_s_s_dn", smp_fetch_ssl_x_s_dn, ARG3(0,STR,SINT,STR),val_dnfmt, SMP_T_STR, SMP_USE_L5CLI },
{ "ssl_s_i_dn", smp_fetch_ssl_x_i_dn, ARG3(0,STR,SINT,STR),val_dnfmt, SMP_T_STR, SMP_USE_L5CLI },
{ "ssl_s_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
{ "ssl_s_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
{ "ssl_s_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
{ NULL, NULL, 0, 0, 0 },
}};