blob: 5462dba54cea9d75f8539a1c8a53ed671ca7eef9 [file] [log] [blame]
William Lallemand15e16942020-05-15 00:25:08 +02001/*
2 * This file contains the sample fetches related to the SSL
3 *
4 * Copyright (C) 2012 EXCELIANCE, Emeric Brun <ebrun@exceliance.fr>
5 * Copyright (C) 2020 HAProxy Technologies, William Lallemand <wlallemand@haproxy.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13#define _GNU_SOURCE
14#include <ctype.h>
15#include <dirent.h>
16#include <errno.h>
17#include <fcntl.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <unistd.h>
22
Willy Tarreau4c7e4b72020-05-27 12:58:42 +020023#include <haproxy/api.h>
Willy Tarreau2741c8c2020-06-02 11:28:02 +020024#include <haproxy/buf-t.h>
Willy Tarreau8efbdfb2020-06-04 11:29:21 +020025#include <haproxy/obj_type.h>
Willy Tarreau6019fab2020-05-27 16:26:00 +020026#include <haproxy/openssl-compat.h>
Willy Tarreau48fbcae2020-06-03 18:09:46 +020027#include <haproxy/tools.h>
William Lallemand15e16942020-05-15 00:25:08 +020028
29#include <types/sample.h>
30#include <types/ssl_sock.h>
31
32#include <proto/acl.h>
Willy Tarreauaa74c4e2020-06-04 10:19:23 +020033#include <haproxy/arg.h>
William Lallemand15e16942020-05-15 00:25:08 +020034#include <proto/ssl_sock.h>
William Lallemand6a66a5e2020-05-15 12:01:17 +020035#include <proto/ssl_utils.h>
William Lallemand15e16942020-05-15 00:25:08 +020036#include <proto/sample.h>
37
38
39/***** Below are some sample fetching functions for ACL/patterns *****/
40
41static int
42smp_fetch_ssl_fc_has_early(const struct arg *args, struct sample *smp, const char *kw, void *private)
43{
44 SSL *ssl;
45 struct connection *conn;
46
47 conn = objt_conn(smp->sess->origin);
48 ssl = ssl_sock_get_ssl_object(conn);
49 if (!ssl)
50 return 0;
51
52 smp->flags = 0;
53 smp->data.type = SMP_T_BOOL;
54#ifdef OPENSSL_IS_BORINGSSL
55 {
56 smp->data.u.sint = (SSL_in_early_data(ssl) &&
57 SSL_early_data_accepted(ssl));
58 }
59#else
60 smp->data.u.sint = ((conn->flags & CO_FL_EARLY_DATA) &&
61 (conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_SSL_WAIT_HS))) ? 1 : 0;
62#endif
63 return 1;
64}
65
66/* boolean, returns true if client cert was present */
67static int
68smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
69{
70 struct connection *conn;
71 struct ssl_sock_ctx *ctx;
72
73 conn = objt_conn(smp->sess->origin);
74 if (!conn || conn->xprt != &ssl_sock)
75 return 0;
76
77 ctx = conn->xprt_ctx;
78
79 if (conn->flags & CO_FL_WAIT_XPRT) {
80 smp->flags |= SMP_F_MAY_CHANGE;
81 return 0;
82 }
83
84 smp->flags = 0;
85 smp->data.type = SMP_T_BOOL;
86 smp->data.u.sint = SSL_SOCK_ST_FL_VERIFY_DONE & ctx->xprt_st ? 1 : 0;
87
88 return 1;
89}
90
91/* binary, returns a certificate in a binary chunk (der/raw).
92 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
93 * should be use.
94 */
95static int
96smp_fetch_ssl_x_der(const struct arg *args, struct sample *smp, const char *kw, void *private)
97{
98 int cert_peer = (kw[4] == 'c') ? 1 : 0;
99 X509 *crt = NULL;
100 int ret = 0;
101 struct buffer *smp_trash;
102 struct connection *conn;
103 SSL *ssl;
104
105 conn = objt_conn(smp->sess->origin);
106 ssl = ssl_sock_get_ssl_object(conn);
107 if (!ssl)
108 return 0;
109
110 if (conn->flags & CO_FL_WAIT_XPRT) {
111 smp->flags |= SMP_F_MAY_CHANGE;
112 return 0;
113 }
114
115 if (cert_peer)
116 crt = SSL_get_peer_certificate(ssl);
117 else
118 crt = SSL_get_certificate(ssl);
119
120 if (!crt)
121 goto out;
122
123 smp_trash = get_trash_chunk();
124 if (ssl_sock_crt2der(crt, smp_trash) <= 0)
125 goto out;
126
127 smp->data.u.str = *smp_trash;
128 smp->data.type = SMP_T_BIN;
129 ret = 1;
130out:
131 /* SSL_get_peer_certificate, it increase X509 * ref count */
132 if (cert_peer && crt)
133 X509_free(crt);
134 return ret;
135}
136
137/* binary, returns serial of certificate in a binary chunk.
138 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
139 * should be use.
140 */
141static int
142smp_fetch_ssl_x_serial(const struct arg *args, struct sample *smp, const char *kw, void *private)
143{
144 int cert_peer = (kw[4] == 'c') ? 1 : 0;
145 X509 *crt = NULL;
146 int ret = 0;
147 struct buffer *smp_trash;
148 struct connection *conn;
149 SSL *ssl;
150
151 conn = objt_conn(smp->sess->origin);
152 ssl = ssl_sock_get_ssl_object(conn);
153 if (!ssl)
154 return 0;
155
156 if (conn->flags & CO_FL_WAIT_XPRT) {
157 smp->flags |= SMP_F_MAY_CHANGE;
158 return 0;
159 }
160
161 if (cert_peer)
162 crt = SSL_get_peer_certificate(ssl);
163 else
164 crt = SSL_get_certificate(ssl);
165
166 if (!crt)
167 goto out;
168
169 smp_trash = get_trash_chunk();
170 if (ssl_sock_get_serial(crt, smp_trash) <= 0)
171 goto out;
172
173 smp->data.u.str = *smp_trash;
174 smp->data.type = SMP_T_BIN;
175 ret = 1;
176out:
177 /* SSL_get_peer_certificate, it increase X509 * ref count */
178 if (cert_peer && crt)
179 X509_free(crt);
180 return ret;
181}
182
183/* binary, returns the client certificate's SHA-1 fingerprint (SHA-1 hash of DER-encoded certificate) in a binary chunk.
184 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
185 * should be use.
186 */
187static int
188smp_fetch_ssl_x_sha1(const struct arg *args, struct sample *smp, const char *kw, void *private)
189{
190 int cert_peer = (kw[4] == 'c') ? 1 : 0;
191 X509 *crt = NULL;
192 const EVP_MD *digest;
193 int ret = 0;
194 unsigned int len = 0;
195 struct buffer *smp_trash;
196 struct connection *conn;
197 SSL *ssl;
198
199 conn = objt_conn(smp->sess->origin);
200 ssl = ssl_sock_get_ssl_object(conn);
201 if (!ssl)
202 return 0;
203
204 if (conn->flags & CO_FL_WAIT_XPRT) {
205 smp->flags |= SMP_F_MAY_CHANGE;
206 return 0;
207 }
208
209 if (cert_peer)
210 crt = SSL_get_peer_certificate(ssl);
211 else
212 crt = SSL_get_certificate(ssl);
213 if (!crt)
214 goto out;
215
216 smp_trash = get_trash_chunk();
217 digest = EVP_sha1();
218 X509_digest(crt, digest, (unsigned char *) smp_trash->area, &len);
219 smp_trash->data = len;
220 smp->data.u.str = *smp_trash;
221 smp->data.type = SMP_T_BIN;
222 ret = 1;
223out:
224 /* SSL_get_peer_certificate, it increase X509 * ref count */
225 if (cert_peer && crt)
226 X509_free(crt);
227 return ret;
228}
229
230/* string, returns certificate's notafter date in ASN1_UTCTIME format.
231 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
232 * should be use.
233 */
234static int
235smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char *kw, void *private)
236{
237 int cert_peer = (kw[4] == 'c') ? 1 : 0;
238 X509 *crt = NULL;
239 int ret = 0;
240 struct buffer *smp_trash;
241 struct connection *conn;
242 SSL *ssl;
243
244 conn = objt_conn(smp->sess->origin);
245 ssl = ssl_sock_get_ssl_object(conn);
246 if (!ssl)
247 return 0;
248
249 if (conn->flags & CO_FL_WAIT_XPRT) {
250 smp->flags |= SMP_F_MAY_CHANGE;
251 return 0;
252 }
253
254 if (cert_peer)
255 crt = SSL_get_peer_certificate(ssl);
256 else
257 crt = SSL_get_certificate(ssl);
258 if (!crt)
259 goto out;
260
261 smp_trash = get_trash_chunk();
262 if (ssl_sock_get_time(X509_getm_notAfter(crt), smp_trash) <= 0)
263 goto out;
264
265 smp->data.u.str = *smp_trash;
266 smp->data.type = SMP_T_STR;
267 ret = 1;
268out:
269 /* SSL_get_peer_certificate, it increase X509 * ref count */
270 if (cert_peer && crt)
271 X509_free(crt);
272 return ret;
273}
274
275/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's issuer
276 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
277 * should be use.
278 */
279static int
280smp_fetch_ssl_x_i_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
281{
282 int cert_peer = (kw[4] == 'c') ? 1 : 0;
283 X509 *crt = NULL;
284 X509_NAME *name;
285 int ret = 0;
286 struct buffer *smp_trash;
287 struct connection *conn;
288 SSL *ssl;
289
290 conn = objt_conn(smp->sess->origin);
291 ssl = ssl_sock_get_ssl_object(conn);
292 if (!ssl)
293 return 0;
294
295 if (conn->flags & CO_FL_WAIT_XPRT) {
296 smp->flags |= SMP_F_MAY_CHANGE;
297 return 0;
298 }
299
300 if (cert_peer)
301 crt = SSL_get_peer_certificate(ssl);
302 else
303 crt = SSL_get_certificate(ssl);
304 if (!crt)
305 goto out;
306
307 name = X509_get_issuer_name(crt);
308 if (!name)
309 goto out;
310
311 smp_trash = get_trash_chunk();
312 if (args && args[0].type == ARGT_STR && args[0].data.str.data > 0) {
313 int pos = 1;
314
315 if (args[1].type == ARGT_SINT)
316 pos = args[1].data.sint;
317
318 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
319 goto out;
320 }
321 else if (args && args[2].type == ARGT_STR && args[2].data.str.data > 0) {
322 if (ssl_sock_get_dn_formatted(name, &args[2].data.str, smp_trash) <= 0)
323 goto out;
324 }
325 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
326 goto out;
327
328 smp->data.type = SMP_T_STR;
329 smp->data.u.str = *smp_trash;
330 ret = 1;
331out:
332 /* SSL_get_peer_certificate, it increase X509 * ref count */
333 if (cert_peer && crt)
334 X509_free(crt);
335 return ret;
336}
337
338/* string, returns notbefore date in ASN1_UTCTIME format.
339 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
340 * should be use.
341 */
342static int
343smp_fetch_ssl_x_notbefore(const struct arg *args, struct sample *smp, const char *kw, void *private)
344{
345 int cert_peer = (kw[4] == 'c') ? 1 : 0;
346 X509 *crt = NULL;
347 int ret = 0;
348 struct buffer *smp_trash;
349 struct connection *conn;
350 SSL *ssl;
351
352 conn = objt_conn(smp->sess->origin);
353 ssl = ssl_sock_get_ssl_object(conn);
354 if (!ssl)
355 return 0;
356
357 if (conn->flags & CO_FL_WAIT_XPRT) {
358 smp->flags |= SMP_F_MAY_CHANGE;
359 return 0;
360 }
361
362 if (cert_peer)
363 crt = SSL_get_peer_certificate(ssl);
364 else
365 crt = SSL_get_certificate(ssl);
366 if (!crt)
367 goto out;
368
369 smp_trash = get_trash_chunk();
370 if (ssl_sock_get_time(X509_getm_notBefore(crt), smp_trash) <= 0)
371 goto out;
372
373 smp->data.u.str = *smp_trash;
374 smp->data.type = SMP_T_STR;
375 ret = 1;
376out:
377 /* SSL_get_peer_certificate, it increase X509 * ref count */
378 if (cert_peer && crt)
379 X509_free(crt);
380 return ret;
381}
382
383/* string, returns a string of a formatted full dn \C=..\O=..\OU=.. \CN=.. of certificate's subject
384 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
385 * should be use.
386 */
387static int
388smp_fetch_ssl_x_s_dn(const struct arg *args, struct sample *smp, const char *kw, void *private)
389{
390 int cert_peer = (kw[4] == 'c') ? 1 : 0;
391 X509 *crt = NULL;
392 X509_NAME *name;
393 int ret = 0;
394 struct buffer *smp_trash;
395 struct connection *conn;
396 SSL *ssl;
397
398 conn = objt_conn(smp->sess->origin);
399 ssl = ssl_sock_get_ssl_object(conn);
400 if (!ssl)
401 return 0;
402
403 if (conn->flags & CO_FL_WAIT_XPRT) {
404 smp->flags |= SMP_F_MAY_CHANGE;
405 return 0;
406 }
407
408 if (cert_peer)
409 crt = SSL_get_peer_certificate(ssl);
410 else
411 crt = SSL_get_certificate(ssl);
412 if (!crt)
413 goto out;
414
415 name = X509_get_subject_name(crt);
416 if (!name)
417 goto out;
418
419 smp_trash = get_trash_chunk();
420 if (args && args[0].type == ARGT_STR && args[0].data.str.data > 0) {
421 int pos = 1;
422
423 if (args[1].type == ARGT_SINT)
424 pos = args[1].data.sint;
425
426 if (ssl_sock_get_dn_entry(name, &args[0].data.str, pos, smp_trash) <= 0)
427 goto out;
428 }
429 else if (args && args[2].type == ARGT_STR && args[2].data.str.data > 0) {
430 if (ssl_sock_get_dn_formatted(name, &args[2].data.str, smp_trash) <= 0)
431 goto out;
432 }
433 else if (ssl_sock_get_dn_oneline(name, smp_trash) <= 0)
434 goto out;
435
436 smp->data.type = SMP_T_STR;
437 smp->data.u.str = *smp_trash;
438 ret = 1;
439out:
440 /* SSL_get_peer_certificate, it increase X509 * ref count */
441 if (cert_peer && crt)
442 X509_free(crt);
443 return ret;
444}
445
446/* integer, returns true if current session use a client certificate */
447static int
448smp_fetch_ssl_c_used(const struct arg *args, struct sample *smp, const char *kw, void *private)
449{
450 X509 *crt;
451 struct connection *conn;
452 SSL *ssl;
453
454 conn = objt_conn(smp->sess->origin);
455 ssl = ssl_sock_get_ssl_object(conn);
456 if (!ssl)
457 return 0;
458
459 if (conn->flags & CO_FL_WAIT_XPRT) {
460 smp->flags |= SMP_F_MAY_CHANGE;
461 return 0;
462 }
463
464 /* SSL_get_peer_certificate returns a ptr on allocated X509 struct */
465 crt = SSL_get_peer_certificate(ssl);
466 if (crt) {
467 X509_free(crt);
468 }
469
470 smp->data.type = SMP_T_BOOL;
471 smp->data.u.sint = (crt != NULL);
472 return 1;
473}
474
475/* integer, returns the certificate version
476 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
477 * should be use.
478 */
479static int
480smp_fetch_ssl_x_version(const struct arg *args, struct sample *smp, const char *kw, void *private)
481{
482 int cert_peer = (kw[4] == 'c') ? 1 : 0;
483 X509 *crt;
484 struct connection *conn;
485 SSL *ssl;
486
487 conn = objt_conn(smp->sess->origin);
488 ssl = ssl_sock_get_ssl_object(conn);
489 if (!ssl)
490 return 0;
491
492 if (conn->flags & CO_FL_WAIT_XPRT) {
493 smp->flags |= SMP_F_MAY_CHANGE;
494 return 0;
495 }
496
497 if (cert_peer)
498 crt = SSL_get_peer_certificate(ssl);
499 else
500 crt = SSL_get_certificate(ssl);
501 if (!crt)
502 return 0;
503
504 smp->data.u.sint = (unsigned int)(1 + X509_get_version(crt));
505 /* SSL_get_peer_certificate increase X509 * ref count */
506 if (cert_peer)
507 X509_free(crt);
508 smp->data.type = SMP_T_SINT;
509
510 return 1;
511}
512
513/* string, returns the certificate's signature algorithm.
514 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
515 * should be use.
516 */
517static int
518smp_fetch_ssl_x_sig_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
519{
520 int cert_peer = (kw[4] == 'c') ? 1 : 0;
521 X509 *crt;
522 __OPENSSL_110_CONST__ ASN1_OBJECT *algorithm;
523 int nid;
524 struct connection *conn;
525 SSL *ssl;
526
527 conn = objt_conn(smp->sess->origin);
528 ssl = ssl_sock_get_ssl_object(conn);
529 if (!ssl)
530 return 0;
531
532 if (conn->flags & CO_FL_WAIT_XPRT) {
533 smp->flags |= SMP_F_MAY_CHANGE;
534 return 0;
535 }
536
537 if (cert_peer)
538 crt = SSL_get_peer_certificate(ssl);
539 else
540 crt = SSL_get_certificate(ssl);
541 if (!crt)
542 return 0;
543
544 X509_ALGOR_get0(&algorithm, NULL, NULL, X509_get0_tbs_sigalg(crt));
545 nid = OBJ_obj2nid(algorithm);
546
547 smp->data.u.str.area = (char *)OBJ_nid2sn(nid);
548 if (!smp->data.u.str.area) {
549 /* SSL_get_peer_certificate increase X509 * ref count */
550 if (cert_peer)
551 X509_free(crt);
552 return 0;
553 }
554
555 smp->data.type = SMP_T_STR;
556 smp->flags |= SMP_F_CONST;
557 smp->data.u.str.data = strlen(smp->data.u.str.area);
558 /* SSL_get_peer_certificate increase X509 * ref count */
559 if (cert_peer)
560 X509_free(crt);
561
562 return 1;
563}
564
565/* string, returns the certificate's key algorithm.
566 * The 5th keyword char is used to know if SSL_get_certificate or SSL_get_peer_certificate
567 * should be use.
568 */
569static int
570smp_fetch_ssl_x_key_alg(const struct arg *args, struct sample *smp, const char *kw, void *private)
571{
572 int cert_peer = (kw[4] == 'c') ? 1 : 0;
573 X509 *crt;
574 ASN1_OBJECT *algorithm;
575 int nid;
576 struct connection *conn;
577 SSL *ssl;
578
579 conn = objt_conn(smp->sess->origin);
580 ssl = ssl_sock_get_ssl_object(conn);
581 if (!ssl)
582 return 0;
583
584 if (conn->flags & CO_FL_WAIT_XPRT) {
585 smp->flags |= SMP_F_MAY_CHANGE;
586 return 0;
587 }
588
589 if (cert_peer)
590 crt = SSL_get_peer_certificate(ssl);
591 else
592 crt = SSL_get_certificate(ssl);
593 if (!crt)
594 return 0;
595
596 X509_PUBKEY_get0_param(&algorithm, NULL, NULL, NULL, X509_get_X509_PUBKEY(crt));
597 nid = OBJ_obj2nid(algorithm);
598
599 smp->data.u.str.area = (char *)OBJ_nid2sn(nid);
600 if (!smp->data.u.str.area) {
601 /* SSL_get_peer_certificate increase X509 * ref count */
602 if (cert_peer)
603 X509_free(crt);
604 return 0;
605 }
606
607 smp->data.type = SMP_T_STR;
608 smp->flags |= SMP_F_CONST;
609 smp->data.u.str.data = strlen(smp->data.u.str.area);
610 if (cert_peer)
611 X509_free(crt);
612
613 return 1;
614}
615
616/* boolean, returns true if front conn. transport layer is SSL.
617 * This function is also usable on backend conn if the fetch keyword 5th
618 * char is 'b'.
619 */
620static int
621smp_fetch_ssl_fc(const struct arg *args, struct sample *smp, const char *kw, void *private)
622{
623 struct connection *conn;
624
625 if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
626 conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
627 else
628 conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
629 smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
630
631 smp->data.type = SMP_T_BOOL;
632 smp->data.u.sint = (conn && conn->xprt == &ssl_sock);
633 return 1;
634}
635
636/* boolean, returns true if client present a SNI */
637static int
638smp_fetch_ssl_fc_has_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
639{
640#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
641 struct connection *conn = objt_conn(smp->sess->origin);
642 SSL *ssl = ssl_sock_get_ssl_object(conn);
643
644 smp->data.type = SMP_T_BOOL;
645 smp->data.u.sint = ssl && SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name) != NULL;
646 return 1;
647#else
648 return 0;
649#endif
650}
651
652/* boolean, returns true if client session has been resumed.
653 * This function is also usable on backend conn if the fetch keyword 5th
654 * char is 'b'.
655 */
656static int
657smp_fetch_ssl_fc_is_resumed(const struct arg *args, struct sample *smp, const char *kw, void *private)
658{
659 struct connection *conn;
660 SSL *ssl;
661
662 if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
663 conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
664 else
665 conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
666 smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
667
668 ssl = ssl_sock_get_ssl_object(conn);
669
670 smp->data.type = SMP_T_BOOL;
671 smp->data.u.sint = ssl && SSL_session_reused(ssl);
672 return 1;
673}
674
675/* string, returns the used cipher if front conn. transport layer is SSL.
676 * This function is also usable on backend conn if the fetch keyword 5th
677 * char is 'b'.
678 */
679static int
680smp_fetch_ssl_fc_cipher(const struct arg *args, struct sample *smp, const char *kw, void *private)
681{
682 struct connection *conn;
683 SSL *ssl;
684
685 if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
686 conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
687 else
688 conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
689 smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
690
691 smp->flags = 0;
692 ssl = ssl_sock_get_ssl_object(conn);
693 if (!ssl)
694 return 0;
695
696 smp->data.u.str.area = (char *)SSL_get_cipher_name(ssl);
697 if (!smp->data.u.str.area)
698 return 0;
699
700 smp->data.type = SMP_T_STR;
701 smp->flags |= SMP_F_CONST;
702 smp->data.u.str.data = strlen(smp->data.u.str.area);
703
704 return 1;
705}
706
707/* integer, returns the algoritm's keysize if front conn. transport layer
708 * is SSL.
709 * This function is also usable on backend conn if the fetch keyword 5th
710 * char is 'b'.
711 */
712static int
713smp_fetch_ssl_fc_alg_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
714{
715 struct connection *conn;
716 SSL *ssl;
717 int sint;
718
719 if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
720 conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
721 else
722 conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
723 smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
724
725 smp->flags = 0;
726 ssl = ssl_sock_get_ssl_object(conn);
727 if (!ssl)
728 return 0;
729
730 if (!SSL_get_cipher_bits(ssl, &sint))
731 return 0;
732
733 smp->data.u.sint = sint;
734 smp->data.type = SMP_T_SINT;
735
736 return 1;
737}
738
739/* integer, returns the used keysize if front conn. transport layer is SSL.
740 * This function is also usable on backend conn if the fetch keyword 5th
741 * char is 'b'.
742 */
743static int
744smp_fetch_ssl_fc_use_keysize(const struct arg *args, struct sample *smp, const char *kw, void *private)
745{
746 struct connection *conn;
747 SSL *ssl;
748
749 if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
750 conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
751 else
752 conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
753 smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
754
755 smp->flags = 0;
756 ssl = ssl_sock_get_ssl_object(conn);
757 if (!ssl)
758 return 0;
759
760 smp->data.u.sint = (unsigned int)SSL_get_cipher_bits(ssl, NULL);
761 if (!smp->data.u.sint)
762 return 0;
763
764 smp->data.type = SMP_T_SINT;
765
766 return 1;
767}
768
769#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
770static int
771smp_fetch_ssl_fc_npn(const struct arg *args, struct sample *smp, const char *kw, void *private)
772{
773 struct connection *conn;
774 SSL *ssl;
775 unsigned int len = 0;
776
777 smp->flags = SMP_F_CONST;
778 smp->data.type = SMP_T_STR;
779
780 if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
781 conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
782 else
783 conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
784 smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
785
786 ssl = ssl_sock_get_ssl_object(conn);
787 if (!ssl)
788 return 0;
789
790 smp->data.u.str.area = NULL;
791 SSL_get0_next_proto_negotiated(ssl,
792 (const unsigned char **)&smp->data.u.str.area,
793 &len);
794
795 if (!smp->data.u.str.area)
796 return 0;
797
798 smp->data.u.str.data = len;
799 return 1;
800}
801#endif
802
803#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
804static int
805smp_fetch_ssl_fc_alpn(const struct arg *args, struct sample *smp, const char *kw, void *private)
806{
807 struct connection *conn;
808 SSL *ssl;
809 unsigned int len = 0;
810
811 smp->flags = SMP_F_CONST;
812 smp->data.type = SMP_T_STR;
813
814 if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
815 conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
816 else
817 conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
818 smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
819
820 ssl = ssl_sock_get_ssl_object(conn);
821 if (!ssl)
822 return 0;
823
824 smp->data.u.str.area = NULL;
825 SSL_get0_alpn_selected(ssl,
826 (const unsigned char **)&smp->data.u.str.area,
827 &len);
828
829 if (!smp->data.u.str.area)
830 return 0;
831
832 smp->data.u.str.data = len;
833 return 1;
834}
835#endif
836
837/* string, returns the used protocol if front conn. transport layer is SSL.
838 * This function is also usable on backend conn if the fetch keyword 5th
839 * char is 'b'.
840 */
841static int
842smp_fetch_ssl_fc_protocol(const struct arg *args, struct sample *smp, const char *kw, void *private)
843{
844 struct connection *conn;
845 SSL *ssl;
846
847 if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
848 conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
849 else
850 conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
851 smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
852
853 smp->flags = 0;
854 ssl = ssl_sock_get_ssl_object(conn);
855 if (!ssl)
856 return 0;
857
858 smp->data.u.str.area = (char *)SSL_get_version(ssl);
859 if (!smp->data.u.str.area)
860 return 0;
861
862 smp->data.type = SMP_T_STR;
863 smp->flags = SMP_F_CONST;
864 smp->data.u.str.data = strlen(smp->data.u.str.area);
865
866 return 1;
867}
868
869/* binary, returns the SSL stream id if front conn. transport layer is SSL.
870 * This function is also usable on backend conn if the fetch keyword 5th
871 * char is 'b'.
872 */
873#if HA_OPENSSL_VERSION_NUMBER > 0x0090800fL
874static int
875smp_fetch_ssl_fc_session_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
876{
877 struct connection *conn;
878 SSL_SESSION *ssl_sess;
879 SSL *ssl;
880 unsigned int len = 0;
881
882 smp->flags = SMP_F_CONST;
883 smp->data.type = SMP_T_BIN;
884
885 if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
886 conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
887 else
888 conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
889 smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
890
891 ssl = ssl_sock_get_ssl_object(conn);
892 if (!ssl)
893 return 0;
894
895 ssl_sess = SSL_get_session(ssl);
896 if (!ssl_sess)
897 return 0;
898
899 smp->data.u.str.area = (char *)SSL_SESSION_get_id(ssl_sess, &len);
900 if (!smp->data.u.str.area || !len)
901 return 0;
902
903 smp->data.u.str.data = len;
904 return 1;
905}
906#endif
907
908
909#if HA_OPENSSL_VERSION_NUMBER >= 0x10100000L
910static int
911smp_fetch_ssl_fc_random(const struct arg *args, struct sample *smp, const char *kw, void *private)
912{
913 struct connection *conn;
914 struct buffer *data;
915 SSL *ssl;
916
917 if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
918 conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
919 else
920 conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
921 smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
922
923 ssl = ssl_sock_get_ssl_object(conn);
924 if (!ssl)
925 return 0;
926
927 data = get_trash_chunk();
928 if (kw[7] == 'c')
929 data->data = SSL_get_client_random(ssl,
930 (unsigned char *) data->area,
931 data->size);
932 else
933 data->data = SSL_get_server_random(ssl,
934 (unsigned char *) data->area,
935 data->size);
936 if (!data->data)
937 return 0;
938
939 smp->flags = 0;
940 smp->data.type = SMP_T_BIN;
941 smp->data.u.str = *data;
942
943 return 1;
944}
945
946static int
947smp_fetch_ssl_fc_session_key(const struct arg *args, struct sample *smp, const char *kw, void *private)
948{
949 struct connection *conn;
950 SSL_SESSION *ssl_sess;
951 struct buffer *data;
952 SSL *ssl;
953
954 if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
955 conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
956 else
957 conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
958 smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
959
960 ssl = ssl_sock_get_ssl_object(conn);
961 if (!ssl)
962 return 0;
963
964 ssl_sess = SSL_get_session(ssl);
965 if (!ssl_sess)
966 return 0;
967
968 data = get_trash_chunk();
969 data->data = SSL_SESSION_get_master_key(ssl_sess,
970 (unsigned char *) data->area,
971 data->size);
972 if (!data->data)
973 return 0;
974
975 smp->flags = 0;
976 smp->data.type = SMP_T_BIN;
977 smp->data.u.str = *data;
978
979 return 1;
980}
981#endif
982
983#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
984static int
985smp_fetch_ssl_fc_sni(const struct arg *args, struct sample *smp, const char *kw, void *private)
986{
987 struct connection *conn;
988 SSL *ssl;
989
990 smp->flags = SMP_F_CONST;
991 smp->data.type = SMP_T_STR;
992
993 conn = objt_conn(smp->sess->origin);
994 ssl = ssl_sock_get_ssl_object(conn);
995 if (!ssl)
996 return 0;
997
998 smp->data.u.str.area = (char *)SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
999 if (!smp->data.u.str.area)
1000 return 0;
1001
1002 smp->data.u.str.data = strlen(smp->data.u.str.area);
1003 return 1;
1004}
1005#endif
1006
1007static int
1008smp_fetch_ssl_fc_cl_bin(const struct arg *args, struct sample *smp, const char *kw, void *private)
1009{
1010 struct connection *conn;
1011 struct ssl_capture *capture;
1012 SSL *ssl;
1013
1014 conn = objt_conn(smp->sess->origin);
1015 ssl = ssl_sock_get_ssl_object(conn);
1016 if (!ssl)
1017 return 0;
1018
1019 capture = SSL_get_ex_data(ssl, ssl_capture_ptr_index);
1020 if (!capture)
1021 return 0;
1022
1023 smp->flags = SMP_F_CONST;
1024 smp->data.type = SMP_T_BIN;
1025 smp->data.u.str.area = capture->ciphersuite;
1026 smp->data.u.str.data = capture->ciphersuite_len;
1027 return 1;
1028}
1029
1030static int
1031smp_fetch_ssl_fc_cl_hex(const struct arg *args, struct sample *smp, const char *kw, void *private)
1032{
1033 struct buffer *data;
1034
1035 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
1036 return 0;
1037
1038 data = get_trash_chunk();
1039 dump_binary(data, smp->data.u.str.area, smp->data.u.str.data);
1040 smp->data.type = SMP_T_BIN;
1041 smp->data.u.str = *data;
1042 return 1;
1043}
1044
1045static int
1046smp_fetch_ssl_fc_cl_xxh64(const struct arg *args, struct sample *smp, const char *kw, void *private)
1047{
1048 struct connection *conn;
1049 struct ssl_capture *capture;
1050 SSL *ssl;
1051
1052 conn = objt_conn(smp->sess->origin);
1053 ssl = ssl_sock_get_ssl_object(conn);
1054 if (!ssl)
1055 return 0;
1056
1057 capture = SSL_get_ex_data(ssl, ssl_capture_ptr_index);
1058 if (!capture)
1059 return 0;
1060
1061 smp->data.type = SMP_T_SINT;
1062 smp->data.u.sint = capture->xxh64;
1063 return 1;
1064}
1065
1066static int
1067smp_fetch_ssl_fc_cl_str(const struct arg *args, struct sample *smp, const char *kw, void *private)
1068{
1069#if (HA_OPENSSL_VERSION_NUMBER >= 0x1000200fL)
1070 struct buffer *data;
1071 int i;
1072
1073 if (!smp_fetch_ssl_fc_cl_bin(args, smp, kw, private))
1074 return 0;
1075
1076 data = get_trash_chunk();
1077 for (i = 0; i + 1 < smp->data.u.str.data; i += 2) {
1078 const char *str;
1079 const SSL_CIPHER *cipher;
1080 const unsigned char *bin = (const unsigned char *) smp->data.u.str.area + i;
1081 uint16_t id = (bin[0] << 8) | bin[1];
1082#if defined(OPENSSL_IS_BORINGSSL)
1083 cipher = SSL_get_cipher_by_value(id);
1084#else
1085 struct connection *conn = __objt_conn(smp->sess->origin);
1086 SSL *ssl = ssl_sock_get_ssl_object(conn);
1087 cipher = SSL_CIPHER_find(ssl, bin);
1088#endif
1089 str = SSL_CIPHER_get_name(cipher);
1090 if (!str || strcmp(str, "(NONE)") == 0)
1091 chunk_appendf(data, "%sUNKNOWN(%04x)", i == 0 ? "" : ",", id);
1092 else
1093 chunk_appendf(data, "%s%s", i == 0 ? "" : ",", str);
1094 }
1095 smp->data.type = SMP_T_STR;
1096 smp->data.u.str = *data;
1097 return 1;
1098#else
1099 return smp_fetch_ssl_fc_cl_xxh64(args, smp, kw, private);
1100#endif
1101}
1102
1103#if HA_OPENSSL_VERSION_NUMBER > 0x0090800fL
1104static int
1105smp_fetch_ssl_fc_unique_id(const struct arg *args, struct sample *smp, const char *kw, void *private)
1106{
1107 struct connection *conn;
1108 int finished_len;
1109 struct buffer *finished_trash;
1110 SSL *ssl;
1111
1112 if (obj_type(smp->sess->origin) == OBJ_TYPE_CHECK)
1113 conn = (kw[4] != 'b') ? cs_conn(__objt_check(smp->sess->origin)->cs) : NULL;
1114 else
1115 conn = (kw[4] != 'b') ? objt_conn(smp->sess->origin) :
1116 smp->strm ? cs_conn(objt_cs(smp->strm->si[1].end)) : NULL;
1117
1118 smp->flags = 0;
1119 ssl = ssl_sock_get_ssl_object(conn);
1120 if (!ssl)
1121 return 0;
1122
1123 if (conn->flags & CO_FL_WAIT_XPRT) {
1124 smp->flags |= SMP_F_MAY_CHANGE;
1125 return 0;
1126 }
1127
1128 finished_trash = get_trash_chunk();
1129 if (!SSL_session_reused(ssl))
1130 finished_len = SSL_get_peer_finished(ssl,
1131 finished_trash->area,
1132 finished_trash->size);
1133 else
1134 finished_len = SSL_get_finished(ssl,
1135 finished_trash->area,
1136 finished_trash->size);
1137
1138 if (!finished_len)
1139 return 0;
1140
1141 finished_trash->data = finished_len;
1142 smp->data.u.str = *finished_trash;
1143 smp->data.type = SMP_T_BIN;
1144
1145 return 1;
1146}
1147#endif
1148
1149/* integer, returns the first verify error in CA chain of client certificate chain. */
1150static int
1151smp_fetch_ssl_c_ca_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
1152{
1153 struct connection *conn;
1154 struct ssl_sock_ctx *ctx;
1155
1156 conn = objt_conn(smp->sess->origin);
1157 if (!conn || conn->xprt != &ssl_sock)
1158 return 0;
1159 ctx = conn->xprt_ctx;
1160
1161 if (conn->flags & CO_FL_WAIT_XPRT) {
1162 smp->flags = SMP_F_MAY_CHANGE;
1163 return 0;
1164 }
1165
1166 smp->data.type = SMP_T_SINT;
1167 smp->data.u.sint = (unsigned long long int)SSL_SOCK_ST_TO_CA_ERROR(ctx->xprt_st);
1168 smp->flags = 0;
1169
1170 return 1;
1171}
1172
1173/* integer, returns the depth of the first verify error in CA chain of client certificate chain. */
1174static int
1175smp_fetch_ssl_c_ca_err_depth(const struct arg *args, struct sample *smp, const char *kw, void *private)
1176{
1177 struct connection *conn;
1178 struct ssl_sock_ctx *ctx;
1179
1180 conn = objt_conn(smp->sess->origin);
1181 if (!conn || conn->xprt != &ssl_sock)
1182 return 0;
1183
1184 if (conn->flags & CO_FL_WAIT_XPRT) {
1185 smp->flags = SMP_F_MAY_CHANGE;
1186 return 0;
1187 }
1188 ctx = conn->xprt_ctx;
1189
1190 smp->data.type = SMP_T_SINT;
1191 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CAEDEPTH(ctx->xprt_st);
1192 smp->flags = 0;
1193
1194 return 1;
1195}
1196
1197/* integer, returns the first verify error on client certificate */
1198static int
1199smp_fetch_ssl_c_err(const struct arg *args, struct sample *smp, const char *kw, void *private)
1200{
1201 struct connection *conn;
1202 struct ssl_sock_ctx *ctx;
1203
1204 conn = objt_conn(smp->sess->origin);
1205 if (!conn || conn->xprt != &ssl_sock)
1206 return 0;
1207
1208 if (conn->flags & CO_FL_WAIT_XPRT) {
1209 smp->flags = SMP_F_MAY_CHANGE;
1210 return 0;
1211 }
1212
1213 ctx = conn->xprt_ctx;
1214
1215 smp->data.type = SMP_T_SINT;
1216 smp->data.u.sint = (long long int)SSL_SOCK_ST_TO_CRTERROR(ctx->xprt_st);
1217 smp->flags = 0;
1218
1219 return 1;
1220}
1221
1222/* integer, returns the verify result on client cert */
1223static int
1224smp_fetch_ssl_c_verify(const struct arg *args, struct sample *smp, const char *kw, void *private)
1225{
1226 struct connection *conn;
1227 SSL *ssl;
1228
1229 conn = objt_conn(smp->sess->origin);
1230 ssl = ssl_sock_get_ssl_object(conn);
1231 if (!ssl)
1232 return 0;
1233
1234 if (conn->flags & CO_FL_WAIT_XPRT) {
1235 smp->flags = SMP_F_MAY_CHANGE;
1236 return 0;
1237 }
1238
1239 smp->data.type = SMP_T_SINT;
1240 smp->data.u.sint = (long long int)SSL_get_verify_result(ssl);
1241 smp->flags = 0;
1242
1243 return 1;
1244}
1245
1246/* Argument validation functions */
1247
1248/* This function is used to validate the arguments passed to any "x_dn" ssl
1249 * keywords. These keywords support specifying a third parameter that must be
1250 * either empty or the value "rfc2253". Returns 0 on error, non-zero if OK.
1251 */
1252int val_dnfmt(struct arg *arg, char **err_msg)
1253{
1254 if (arg && arg[2].type == ARGT_STR && arg[2].data.str.data > 0 && (strcmp(arg[2].data.str.area, "rfc2253") != 0)) {
1255 memprintf(err_msg, "only rfc2253 or a blank value are currently supported as the format argument.");
1256 return 0;
1257 }
1258 return 1;
1259}
1260
1261/* Note: must not be declared <const> as its list will be overwritten.
1262 * Please take care of keeping this list alphabetically sorted.
1263 */
1264static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
1265 { "ssl_bc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
1266 { "ssl_bc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV },
1267#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
1268 { "ssl_bc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
1269#endif
1270 { "ssl_bc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
1271#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
1272 { "ssl_bc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
1273#endif
1274 { "ssl_bc_is_resumed", smp_fetch_ssl_fc_is_resumed, 0, NULL, SMP_T_BOOL, SMP_USE_L5SRV },
1275 { "ssl_bc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5SRV },
1276 { "ssl_bc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
1277 { "ssl_bc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV },
1278#if HA_OPENSSL_VERSION_NUMBER > 0x0090800fL
1279 { "ssl_bc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
1280#endif
1281#if HA_OPENSSL_VERSION_NUMBER >= 0x10100000L
1282 { "ssl_bc_client_random", smp_fetch_ssl_fc_random, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
1283 { "ssl_bc_server_random", smp_fetch_ssl_fc_random, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
1284 { "ssl_bc_session_key", smp_fetch_ssl_fc_session_key, 0, NULL, SMP_T_BIN, SMP_USE_L5SRV },
1285#endif
1286 { "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
1287 { "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
1288 { "ssl_c_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
1289 { "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
1290 { "ssl_c_i_dn", smp_fetch_ssl_x_i_dn, ARG3(0,STR,SINT,STR),val_dnfmt, SMP_T_STR, SMP_USE_L5CLI },
1291 { "ssl_c_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1292 { "ssl_c_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1293 { "ssl_c_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1294 { "ssl_c_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1295 { "ssl_c_s_dn", smp_fetch_ssl_x_s_dn, ARG3(0,STR,SINT,STR),val_dnfmt, SMP_T_STR, SMP_USE_L5CLI },
1296 { "ssl_c_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
1297 { "ssl_c_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
1298 { "ssl_c_used", smp_fetch_ssl_c_used, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
1299 { "ssl_c_verify", smp_fetch_ssl_c_verify, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
1300 { "ssl_c_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
1301 { "ssl_f_der", smp_fetch_ssl_x_der, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
1302 { "ssl_f_i_dn", smp_fetch_ssl_x_i_dn, ARG3(0,STR,SINT,STR),val_dnfmt, SMP_T_STR, SMP_USE_L5CLI },
1303 { "ssl_f_key_alg", smp_fetch_ssl_x_key_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1304 { "ssl_f_notafter", smp_fetch_ssl_x_notafter, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1305 { "ssl_f_notbefore", smp_fetch_ssl_x_notbefore, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1306 { "ssl_f_sig_alg", smp_fetch_ssl_x_sig_alg, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1307 { "ssl_f_s_dn", smp_fetch_ssl_x_s_dn, ARG3(0,STR,SINT,STR),val_dnfmt, SMP_T_STR, SMP_USE_L5CLI },
1308 { "ssl_f_serial", smp_fetch_ssl_x_serial, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
1309 { "ssl_f_sha1", smp_fetch_ssl_x_sha1, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
1310 { "ssl_f_version", smp_fetch_ssl_x_version, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
1311 { "ssl_fc", smp_fetch_ssl_fc, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
1312 { "ssl_fc_alg_keysize", smp_fetch_ssl_fc_alg_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
1313 { "ssl_fc_cipher", smp_fetch_ssl_fc_cipher, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1314 { "ssl_fc_has_crt", smp_fetch_ssl_fc_has_crt, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
1315 { "ssl_fc_has_early", smp_fetch_ssl_fc_has_early, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
1316 { "ssl_fc_has_sni", smp_fetch_ssl_fc_has_sni, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
1317 { "ssl_fc_is_resumed", smp_fetch_ssl_fc_is_resumed, 0, NULL, SMP_T_BOOL, SMP_USE_L5CLI },
1318#if defined(OPENSSL_NPN_NEGOTIATED) && !defined(OPENSSL_NO_NEXTPROTONEG)
1319 { "ssl_fc_npn", smp_fetch_ssl_fc_npn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1320#endif
1321#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
1322 { "ssl_fc_alpn", smp_fetch_ssl_fc_alpn, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1323#endif
1324 { "ssl_fc_protocol", smp_fetch_ssl_fc_protocol, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1325#if HA_OPENSSL_VERSION_NUMBER > 0x0090800fL
1326 { "ssl_fc_unique_id", smp_fetch_ssl_fc_unique_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
1327#endif
1328 { "ssl_fc_use_keysize", smp_fetch_ssl_fc_use_keysize, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
1329#if HA_OPENSSL_VERSION_NUMBER > 0x0090800fL
1330 { "ssl_fc_session_id", smp_fetch_ssl_fc_session_id, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
1331#endif
1332#if HA_OPENSSL_VERSION_NUMBER >= 0x10100000L
1333 { "ssl_fc_client_random", smp_fetch_ssl_fc_random, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
1334 { "ssl_fc_server_random", smp_fetch_ssl_fc_random, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
1335 { "ssl_fc_session_key", smp_fetch_ssl_fc_session_key, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
1336#endif
1337#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
1338 { "ssl_fc_sni", smp_fetch_ssl_fc_sni, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1339#endif
1340 { "ssl_fc_cipherlist_bin", smp_fetch_ssl_fc_cl_bin, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1341 { "ssl_fc_cipherlist_hex", smp_fetch_ssl_fc_cl_hex, 0, NULL, SMP_T_BIN, SMP_USE_L5CLI },
1342 { "ssl_fc_cipherlist_str", smp_fetch_ssl_fc_cl_str, 0, NULL, SMP_T_STR, SMP_USE_L5CLI },
1343 { "ssl_fc_cipherlist_xxh", smp_fetch_ssl_fc_cl_xxh64, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI },
1344 { NULL, NULL, 0, 0, 0 },
1345}};
1346
1347INITCALL1(STG_REGISTER, sample_register_fetches, &sample_fetch_keywords);
1348
1349/* Note: must not be declared <const> as its list will be overwritten.
1350 * Please take care of keeping this list alphabetically sorted.
1351 */
1352static struct acl_kw_list acl_kws = {ILH, {
1353 { "ssl_fc_sni_end", "ssl_fc_sni", PAT_MATCH_END },
1354 { "ssl_fc_sni_reg", "ssl_fc_sni", PAT_MATCH_REG },
1355 { /* END */ },
1356}};
1357
1358INITCALL1(STG_REGISTER, acl_register_keywords, &acl_kws);