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