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