The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_cipher.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 2ca593d3f706c201394dcdefa861f3ad88b44b51 $
19 * @file rlm_cipher.c
20 * @brief Creates dynamic expansions for encrypting/decrypting data.
21 *
22 * @author Arran Cudbard-Bell (a.cudbardb@freeradius.org)
23 *
24 * @copyright 2018 The FreeRADIUS server project
25 * @copyright 2018 Network RADIUS (legal@networkradius.com)
26 *
27 */
28RCSID("$Id: 2ca593d3f706c201394dcdefa861f3ad88b44b51 $")
29
30#include <freeradius-devel/server/base.h>
31#include <freeradius-devel/server/module_rlm.h>
32#include <freeradius-devel/tls/base.h>
33#include <freeradius-devel/tls/cert.h>
34#include <freeradius-devel/tls/log.h>
35#include <freeradius-devel/tls/utils.h>
36#include <freeradius-devel/tls/strerror.h>
37#include <freeradius-devel/unlang/xlat_func.h>
38
39#include <openssl/crypto.h>
40#include <openssl/pem.h>
41#include <openssl/evp.h>
42#include <openssl/rsa.h>
43
44static int digest_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
45 CONF_ITEM *ci, UNUSED conf_parser_t const *rule);
46static int cipher_rsa_padding_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
47 CONF_ITEM *ci, UNUSED conf_parser_t const *rule);
48static int cipher_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
49 CONF_ITEM *ci, UNUSED conf_parser_t const *rule);
50
51static int cipher_rsa_private_key_file_load(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
52 CONF_ITEM *ci, UNUSED conf_parser_t const *rule);
53static int cipher_rsa_certificate_file_load(TALLOC_CTX *ctx, void *out, UNUSED void *parent,
54 CONF_ITEM *ci, UNUSED conf_parser_t const *rule);
55
56typedef enum {
59 RLM_CIPHER_TYPE_SYMMETRIC = 2 //!< Any symmetric cipher available via
60 ///< OpenSSL's EVP interface.
62
63/** Certificate validation modes
64 *
65 */
66typedef enum {
68
69 CIPHER_CERT_VERIFY_HARD, //!< Fail if the certificate isn't valid.
70 CIPHER_CERT_VERIFY_SOFT, //!< Warn if the certificate isn't valid.
71 CIPHER_CERT_VERIFY_NONE //!< Don't check to see if the we're between
72 ///< notBefore or notAfter.
74
75typedef enum {
76 CIPHER_CERT_ATTR_UNKNOWN = 0, //!< Unrecognised attribute.
77 CIPHER_CERT_ATTR_SERIAL, //!< Certificate's serial number.
78 CIPHER_CERT_ATTR_FINGERPRINT, //!< Dynamically calculated fingerprint.
79 CIPHER_CERT_ATTR_NOT_BEFORE, //!< Time the certificate becomes valid.
80 CIPHER_CERT_ATTR_NOT_AFTER //!< Time the certificate expires.
82
83/** Public key types
84 *
85 */
87 { L("DH"), EVP_PKEY_DH },
88 { L("DSA"), EVP_PKEY_DSA },
89 { L("EC"), EVP_PKEY_EC },
90 { L("RSA"), EVP_PKEY_RSA }
91};
93
94/** The type of padding used
95 *
96 */
98 { L("none"), RSA_NO_PADDING },
99 { L("oaep"), RSA_PKCS1_OAEP_PADDING }, /* PKCS OAEP padding */
100 { L("pkcs"), RSA_PKCS1_PADDING }, /* PKCS 1.5 */
101 { L("x931"), RSA_X931_PADDING }
102};
104
106 { L("rsa"), RLM_CIPHER_TYPE_RSA },
107 { L("symmetric"), RLM_CIPHER_TYPE_SYMMETRIC }
108};
110
112 { L("hard"), CIPHER_CERT_VERIFY_HARD },
113 { L("none"), CIPHER_CERT_VERIFY_NONE },
114 { L("soft"), CIPHER_CERT_VERIFY_SOFT }
115};
117
118/** Public key types
119 *
120 */
122 { L("fingerprint"), CIPHER_CERT_ATTR_FINGERPRINT },
123 { L("notAfter"), CIPHER_CERT_ATTR_NOT_AFTER },
124 { L("notBefore"), CIPHER_CERT_ATTR_NOT_BEFORE },
125 { L("serial"), CIPHER_CERT_ATTR_SERIAL },
126};
128
129typedef struct {
130 EVP_PKEY_CTX *evp_encrypt_ctx; //!< Pre-allocated evp_pkey_ctx.
131 EVP_PKEY_CTX *evp_sign_ctx; //!< Pre-allocated evp_pkey_ctx.
132 EVP_PKEY_CTX *evp_decrypt_ctx; //!< Pre-allocated evp_pkey_ctx.
133 EVP_PKEY_CTX *evp_verify_ctx; //!< Pre-allocated evp_pkey_ctx.
134
135 EVP_MD_CTX *evp_md_ctx; //!< Pre-allocated evp_md_ctx for sign and verify.
136 uint8_t *digest_buff; //!< Pre-allocated digest buffer.
138
139/** Configuration for the OAEP padding method
140 *
141 */
142typedef struct {
143 EVP_MD *oaep_digest; //!< Padding digest type.
144 EVP_MD *mgf1_digest; //!< Masking function digest.
145
146 char const *label; //!< Additional input to the hashing function.
148
149
150
151/** Configuration for RSA encryption/decryption/signing
152 *
153 */
154typedef struct {
155 char const *private_key_password; //!< Password to decrypt the private key.
156 char const *random_file; //!< If set, we read 10K of data (or the complete file)
157 //!< and use it to seed OpenSSL's PRNG.
158
159 EVP_PKEY *private_key_file; //!< Private key file.
160 EVP_PKEY *certificate_file; //!< Public (certificate) file.
161 X509 *x509_certificate_file; //!< Needed for extracting certificate attributes.
162
163 cipher_cert_verify_mode_t verify_mode; //!< How hard we try to verify the certificate.
164 fr_unix_time_t not_before; //!< Certificate isn't valid before this time.
165 fr_unix_time_t not_after; //!< Certificate isn't valid after this time.
166
167 int padding; //!< Type of padding to apply to the plaintext
168 ///< or ciphertext before feeding it to RSA crypto
169 ///< functions.
170
171 EVP_MD *sig_digest; //!< Signature digest type.
172
173 cipher_rsa_oaep_t *oaep; //!< OAEP can use a configurable message digest type
175
176/** Instance configuration
177 *
178 */
179typedef struct {
180 cipher_type_t type; //!< Type of encryption to use.
181
182 /** Supported cipher types
183 *
184 */
185 union {
186 cipher_rsa_t *rsa; //!< Use RSA encryption (with optional padding).
187 };
189
190/** Configuration for the RSA-PCKS1-OAEP padding scheme
191 *
192 */
194 { FR_CONF_OFFSET_TYPE_FLAGS("oaep_digest", FR_TYPE_VOID, CONF_FLAG_NOT_EMPTY, cipher_rsa_oaep_t, oaep_digest), .func = digest_type_parse, .dflt = "sha256" },
195 { FR_CONF_OFFSET_TYPE_FLAGS("mgf1_digest", FR_TYPE_VOID, CONF_FLAG_NOT_EMPTY, cipher_rsa_oaep_t, mgf1_digest), .func = digest_type_parse, .dflt = "sha256" },
196 { FR_CONF_OFFSET("label", cipher_rsa_oaep_t, label) },
197
199};
200
201/** Configuration for the RSA cipher type
202 *
203 */
204static const conf_parser_t rsa_config[] = {
205 { FR_CONF_OFFSET("verify_mode", cipher_rsa_t, verify_mode),
207 .uctx = &(cf_table_parse_ctx_t){
210 },
211 .dflt = "hard" }, /* Must come before certificate file */
212
213 { FR_CONF_OFFSET_FLAGS("private_key_password", CONF_FLAG_SECRET, cipher_rsa_t, private_key_password) }, /* Must come before private_key */
216
217 { FR_CONF_OFFSET("random_file", cipher_rsa_t, random_file) },
218
219 { FR_CONF_OFFSET_TYPE_FLAGS("signature_digest", FR_TYPE_VOID, CONF_FLAG_NOT_EMPTY, cipher_rsa_t, sig_digest), .func = digest_type_parse, .dflt = "sha256" },
220
221 { FR_CONF_OFFSET_TYPE_FLAGS("padding_type", FR_TYPE_VOID, CONF_FLAG_NOT_EMPTY, cipher_rsa_t, padding), .func = cipher_rsa_padding_type_parse, .dflt = "pkcs" },
222
224 .subcs_size = sizeof(cipher_rsa_oaep_t), .subcs_type = "cipher_rsa_oaep_t" },
225
227};
228
229/*
230 * A mapping of configuration file names to internal variables.
231 */
232static const conf_parser_t module_config[] = {
234 { FR_CONF_OFFSET_SUBSECTION("rsa", 0, rlm_cipher_t, rsa, rsa_config), .subcs_size = sizeof(cipher_rsa_t), .subcs_type = "cipher_rsa_t" },
236};
237
238/** Calls EVP_get_digestbyname() to convert the digest type
239 *
240 * @param[in] ctx to allocate data in.
241 * @param[out] out EVP_MD representing the OpenSSL digest type.
242 * @param[in] parent Base structure address.
243 * @param[in] ci #CONF_PAIR specifying the name of the digest.
244 * @param[in] rule unused.
245 * @return
246 * - 0 on success.
247 * - -1 on failure.
248 */
249static int digest_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
250 CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
251{
252 EVP_MD const *md;
253 char const *type_str;
254
255 type_str = cf_pair_value(cf_item_to_pair(ci));
256 md = EVP_get_digestbyname(type_str);
257 if (!md) {
258 cf_log_err(ci, "Invalid digest type \"%s\"", type_str);
259 return -1;
260 }
261
262 *((EVP_MD const **)out) = md;
263
264 return 0;
265}
266
267/** Checks if the specified padding type is valid
268 *
269 * @param[in] ctx to allocate data in.
270 * @param[out] out Padding type.
271 * @param[in] parent Base structure address.
272 * @param[in] ci #CONF_PAIR specifying the padding type..
273 * @param[in] rule unused.
274 * @return
275 * - 0 on success.
276 * - -1 on failure.
277 */
278static int cipher_rsa_padding_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent,
279 CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
280{
281 int type;
282 char const *type_str;
283
284 type_str = cf_pair_value(cf_item_to_pair(ci));
286 if (type == -1) {
287 cf_log_err(ci, "Invalid padding type \"%s\"", type_str);
288 return -1;
289 }
290
291 *((int *)out) = type;
292
293 return 0;
294}
295
296/** Checks if the specified cipher type is valid
297 *
298 * @param[in] ctx to allocate data in.
299 * @param[out] out Cipher enumeration type.
300 * @param[in] parent Base structure address.
301 * @param[in] ci #CONF_PAIR specifying the name of the type module.
302 * @param[in] rule unused.
303 * @return
304 * - 0 on success.
305 * - -1 on failure.
306 */
307static int cipher_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
308{
310 char const *type_str;
311
312 type_str = cf_pair_value(cf_item_to_pair(ci));
314 switch (type) {
316 break;
317
320 cf_log_err(ci, "Invalid cipher type \"%s\"", type_str);
321 return -1;
322 }
323
324 *((cipher_type_t *)out) = type;
325
326 return 0;
327}
328
329/** Talloc destructor for freeing an EVP_PKEY (representing a certificate)
330 *
331 * @param[in] pkey to free.
332 * @return 0
333 */
334static int _evp_pkey_free(EVP_PKEY *pkey)
335{
336 EVP_PKEY_free(pkey);
337
338 return 0;
339}
340
341/** Talloc destructor for freeing an X509 struct (representing a public certificate)
342 *
343 * @param[in] cert to free.
344 * @return 0
345 */
346static int _x509_cert_free(X509 *cert)
347{
348 X509_free(cert);
349
350 return 0;
351}
352
353/** Load and (optionally decrypt) an RSA private key using OpenSSL functions
354 *
355 * @param[in] ctx UNUSED. Although the EVP_PKEY struct will be allocated
356 * with talloc, we need to call the specialised free
357 * function anyway.
358 * @param[out] out Where to write the EVP_PKEY * representing the
359 * certificate we just loaded.
360 * @param[in] parent Base structure address.
361 * @param[in] ci Config item containing the certificate path.
362 * @param[in] rule this callback was attached to.
363 * @return
364 * - -1 on failure.
365 * - 0 on success.
366 */
367static int cipher_rsa_private_key_file_load(TALLOC_CTX *ctx, void *out, void *parent,
368 CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
369{
370 FILE *fp;
371 char const *filename;
372 cipher_rsa_t *rsa_inst = talloc_get_type_abort(parent, cipher_rsa_t);
373 EVP_PKEY *pkey;
374 int pkey_type;
375
376 filename = cf_pair_value(cf_item_to_pair(ci));
377
378 fp = fopen(filename, "r");
379 if (!fp) {
380 cf_log_err(ci, "Failed opening private_key file \"%s\": %s", filename, fr_syserror(errno));
381 return -1;
382 }
383
384 pkey = PEM_read_PrivateKey(fp, (EVP_PKEY **)out, fr_utils_get_private_key_password,
385 UNCONST(void *, rsa_inst->private_key_password));
386 fclose(fp);
387
388 if (!pkey) {
389 fr_tls_strerror_printf(NULL);
390 cf_log_perr(ci, "Error loading private certificate file \"%s\"", filename);
391
392 return -1;
393 }
394
395 pkey_type = EVP_PKEY_type(EVP_PKEY_id(pkey));
396 if (pkey_type != EVP_PKEY_RSA) {
397 cf_log_err(ci, "Expected certificate to contain %s private key, got %s private key",
398 fr_table_str_by_value(pkey_types, EVP_PKEY_RSA, OBJ_nid2sn(pkey_type)),
399 fr_table_str_by_value(pkey_types, pkey_type, OBJ_nid2sn(pkey_type)));
400
401 EVP_PKEY_free(pkey);
402 return -1;
403 }
404
405 talloc_set_type(pkey, EVP_PKEY);
406 (void)talloc_steal(ctx, pkey); /* Bind lifetime to config */
407 talloc_set_destructor(pkey, _evp_pkey_free); /* Free pkey correctly on chunk free */
408
409 return 0;
410}
411
412/** Load an RSA public key using OpenSSL functions
413 *
414 * @param[in] ctx UNUSED. Although the EVP_PKEY struct will be allocated
415 * with talloc, we need to call the specialised free
416 * function anyway.
417 * @param[out] out Where to write the EVP_PKEY * representing the
418 * certificate we just loaded.
419 * @param[in] parent Base structure address.
420 * @param[in] ci Config item containing the certificate path.
421 * @param[in] rule this callback was attached to.
422 * @return
423 * - -1 on failure.
424 * - 0 on success.
425 */
426static int cipher_rsa_certificate_file_load(TALLOC_CTX *ctx, void *out, void *parent,
427 CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
428{
429 FILE *fp;
430 char const *filename;
431 cipher_rsa_t *rsa_inst = talloc_get_type_abort(parent, cipher_rsa_t);
432
433 X509 *cert; /* X509 certificate */
434 EVP_PKEY *pkey; /* Wrapped public key */
435 int pkey_type;
436
437 filename = cf_pair_value(cf_item_to_pair(ci));
438
439 fp = fopen(filename, "r");
440 if (!fp) {
441 cf_log_err(ci, "Failed opening certificate_file \"%s\": %s", filename, fr_syserror(errno));
442 return -1;
443 }
444
445 /*
446 * Load the PEM encoded X509 certificate
447 */
448 cert = PEM_read_X509(fp, NULL, NULL, NULL);
449 fclose(fp);
450
451 if (!cert) {
452 fr_tls_strerror_printf(NULL);
453 cf_log_perr(ci, "Error loading certificate file \"%s\"", filename);
454
455 return -1;
456 }
457
458 /*
459 * Keep the x509 structure around as we may want
460 * to extract information from fields in the cert
461 * or calculate its fingerprint.
462 */
463 talloc_set_type(cert, X509);
464 (void)talloc_steal(ctx, cert); /* Bind lifetime to config */
465 talloc_set_destructor(cert, _x509_cert_free); /* Free x509 cert correctly on chunk free */
466
467 /*
468 * Extract the public key from the certificate
469 */
470 pkey = X509_get_pubkey(cert);
471 if (!pkey) {
472 fr_tls_strerror_printf(NULL);
473 cf_log_perr(ci, "Failed extracting public key from certificate");
474
475 return -1;
476 }
477
478 pkey_type = EVP_PKEY_type(EVP_PKEY_id(pkey));
479 if (pkey_type != EVP_PKEY_RSA) {
480 cf_log_err(ci, "Expected certificate to contain %s public key, got %s public key",
481 fr_table_str_by_value(pkey_types, EVP_PKEY_RSA, "?Unknown?"),
482 fr_table_str_by_value(pkey_types, pkey_type, "?Unknown?"));
483 error:
484 EVP_PKEY_free(pkey);
485 return -1;
486 }
487
488 /*
489 * Certificate validity checks
490 */
491 switch (fr_tls_cert_is_valid(&rsa_inst->not_before, &rsa_inst->not_after, cert)) {
492 case 0:
493 cf_log_debug(ci, "Certificate validity starts at %pV and ends at %pV",
494 fr_box_date(rsa_inst->not_before), fr_box_date(rsa_inst->not_after));
495 break;
496
497 case -1:
498 cf_log_perr(ci, "Malformed certificate");
499 return -1;
500
501 case -2:
502 case -3:
503 switch (rsa_inst->verify_mode) {
505 cf_log_pwarn(ci, "Certificate validation failed");
506 break;
507
509 cf_log_perr(ci, "Certificate validation failed");
510 goto error;
511
513 break;
514
516 fr_assert(0);
517 break;
518 }
519 }
520
521 talloc_set_type(pkey, EVP_PKEY);
522 (void)talloc_steal(cert, pkey); /* Bind lifetime to config */
523 talloc_set_destructor(pkey, _evp_pkey_free); /* Free pkey correctly on chunk free */
524
525 rsa_inst->x509_certificate_file = cert; /* Not great, but shouldn't cause any issues */
526 *(EVP_PKEY **)out = pkey;
527
528 return 0;
529}
530
532 { .required = true, .concat = true, .type = FR_TYPE_STRING },
534};
535
536/** Encrypt input data
537 *
538 * Arguments are @verbatim(<plaintext>...)@endverbatim
539 *
540@verbatim
541%<inst>.encrypt(<plaintext>...)
542@endverbatim
543 *
544 * If multiple arguments are provided they will be concatenated.
545 *
546 * @ingroup xlat_functions
547 */
549 xlat_ctx_t const *xctx,
550 request_t *request, fr_value_box_list_t *in)
551{
552 rlm_cipher_rsa_thread_inst_t *t = talloc_get_type_abort(xctx->mctx->thread, rlm_cipher_rsa_thread_inst_t);
553
554 char const *plaintext;
555 size_t plaintext_len;
556
557 uint8_t *ciphertext;
558 size_t ciphertext_len;
559
560 fr_value_box_t *vb;
561 fr_value_box_t *in_head = fr_value_box_list_head(in);
562
563 plaintext = in_head->vb_strvalue;
564 plaintext_len = in_head->vb_length;
565
566 /*
567 * Figure out the buffer we need
568 */
569 RHEXDUMP3((uint8_t const *)plaintext, plaintext_len, "Plaintext (%zu bytes)", plaintext_len);
570 if (EVP_PKEY_encrypt(t->evp_encrypt_ctx, NULL, &ciphertext_len,
571 (unsigned char const *)plaintext, plaintext_len) <= 0) {
572 fr_tls_log(request, "Failed getting length of encrypted plaintext");
573 return XLAT_ACTION_FAIL;
574 }
575
576 MEM(vb = fr_value_box_alloc_null(ctx));
577 MEM(fr_value_box_mem_alloc(vb, &ciphertext, vb, NULL, ciphertext_len, false) == 0);
578 if (EVP_PKEY_encrypt(t->evp_encrypt_ctx, ciphertext, &ciphertext_len,
579 (unsigned char const *)plaintext, plaintext_len) <= 0) {
580 fr_tls_log(request, "Failed encrypting plaintext");
581 talloc_free(vb);
582 return XLAT_ACTION_FAIL;
583 }
584 RHEXDUMP3(ciphertext, ciphertext_len, "Ciphertext (%zu bytes)", ciphertext_len);
585 MEM(fr_value_box_mem_realloc(vb, NULL, vb, ciphertext_len) == 0);
587
588 return XLAT_ACTION_DONE;
589}
590
591
593 { .required = true, .concat = true, .type = FR_TYPE_STRING },
595};
596
597/** Sign input data
598 *
599 * Arguments are @verbatim(<plaintext>...)@endverbatim
600 *
601@verbatim
602%<inst>.sign(<plaintext>...)
603@endverbatim
604 *
605 * If multiple arguments are provided they will be concatenated.
606 *
607 * @ingroup xlat_functions
608 */
610 xlat_ctx_t const *xctx,
611 request_t *request, fr_value_box_list_t *in)
612{
614 rlm_cipher_rsa_thread_inst_t *t = talloc_get_type_abort(xctx->mctx->thread, rlm_cipher_rsa_thread_inst_t);
615
616 char const *msg;
617 size_t msg_len;
618
619 uint8_t *sig;
620 size_t sig_len;
621
622 unsigned int digest_len = 0;
623
624 fr_value_box_t *vb;
625 fr_value_box_t *in_head = fr_value_box_list_head(in);
626
627 msg = in_head->vb_strvalue;
628 msg_len = in_head->vb_length;
629
630 /*
631 * First produce a digest of the message
632 */
633 if (unlikely(EVP_DigestInit_ex(t->evp_md_ctx, inst->rsa->sig_digest, NULL) <= 0)) {
634 fr_tls_log(request, "Failed initialising message digest");
635 return XLAT_ACTION_FAIL;
636 }
637
638 if (EVP_DigestUpdate(t->evp_md_ctx, msg, msg_len) <= 0) {
639 fr_tls_log(request, "Failed ingesting message");
640 return XLAT_ACTION_FAIL;
641 }
642
643 if (EVP_DigestFinal_ex(t->evp_md_ctx, t->digest_buff, &digest_len) <= 0) {
644 fr_tls_log(request, "Failed finalising message digest");
645 return XLAT_ACTION_FAIL;
646 }
647 fr_assert((size_t)digest_len == talloc_array_length(t->digest_buff));
648
649 /*
650 * Then sign the digest
651 */
652 if (EVP_PKEY_sign(t->evp_sign_ctx, NULL, &sig_len, t->digest_buff, (size_t)digest_len) <= 0) {
653 fr_tls_log(request, "Failed getting length of digest");
654 return XLAT_ACTION_FAIL;
655 }
656
657 MEM(vb = fr_value_box_alloc_null(ctx));
658 MEM(fr_value_box_mem_alloc(vb, &sig, vb, NULL, sig_len, false) == 0);
659 if (EVP_PKEY_sign(t->evp_sign_ctx, sig, &sig_len, t->digest_buff, (size_t)digest_len) <= 0) {
660 fr_tls_log(request, "Failed signing message digest");
661 talloc_free(vb);
662 return XLAT_ACTION_FAIL;
663 }
664 MEM(fr_value_box_mem_realloc(vb, NULL, vb, sig_len) == 0);
666
667 return XLAT_ACTION_DONE;
668}
669
671 { .required = true, .concat = true, .type = FR_TYPE_OCTETS },
673};
674
675/** Decrypt input data
676 *
677 * Arguments are @verbatim(<ciphertext>...)@endverbatim
678 *
679@verbatim
680%<inst>.decrypt(<ciphertext>...)
681@endverbatim
682 *
683 * If multiple arguments are provided they will be concatenated.
684 *
685 * @ingroup xlat_functions
686 */
688 xlat_ctx_t const *xctx,
689 request_t *request, fr_value_box_list_t *in)
690{
691 rlm_cipher_rsa_thread_inst_t *t = talloc_get_type_abort(xctx->mctx->thread, rlm_cipher_rsa_thread_inst_t);
692
693 uint8_t const *ciphertext;
694 size_t ciphertext_len;
695
696 char *plaintext;
697 size_t plaintext_len;
698
699 fr_value_box_t *vb;
700 fr_value_box_t *in_head = fr_value_box_list_head(in);
701
702 ciphertext = in_head->vb_octets;
703 ciphertext_len = in_head->vb_length;
704
705 /*
706 * Decrypt the ciphertext
707 */
708 RHEXDUMP3(ciphertext, ciphertext_len, "Ciphertext (%zu bytes)", ciphertext_len);
709 if (EVP_PKEY_decrypt(t->evp_decrypt_ctx, NULL, &plaintext_len, ciphertext, ciphertext_len) <= 0) {
710 fr_tls_log(request, "Failed getting length of cleartext");
711 return XLAT_ACTION_FAIL;
712 }
713
714 MEM(vb = fr_value_box_alloc_null(ctx));
715 MEM(fr_value_box_bstr_alloc(vb, &plaintext, vb, NULL, plaintext_len, true) == 0);
716 if (EVP_PKEY_decrypt(t->evp_decrypt_ctx, (unsigned char *)plaintext, &plaintext_len,
717 ciphertext, ciphertext_len) <= 0) {
718 fr_tls_log(request, "Failed decrypting ciphertext");
719 talloc_free(vb);
720 return XLAT_ACTION_FAIL;
721 }
722 RHEXDUMP3((uint8_t const *)plaintext, plaintext_len, "Plaintext (%zu bytes)", plaintext_len);
723 MEM(fr_value_box_bstr_realloc(vb, NULL, vb, plaintext_len) == 0);
725
726 return XLAT_ACTION_DONE;
727}
728
730 { .required = true, .concat = false, .single = true, .type = FR_TYPE_VOID },
731 { .required = true, .concat = true, .type = FR_TYPE_STRING },
732 { .variadic = XLAT_ARG_VARIADIC_EMPTY_SQUASH, .concat = true, .type = FR_TYPE_STRING },
734};
735
736/** Verify input data
737 *
738 * Arguments are @verbatim(<signature>, <plaintext>...)@endverbatim
739 *
740@verbatim
741%<inst>.verify(<signature>, <plaintext>...)
742@endverbatim
743 *
744 * If multiple arguments are provided (after @verbatim<signature>@endverbatim)
745 * they will be concatenated.
746 *
747 * @ingroup xlat_functions
748 */
750 xlat_ctx_t const *xctx,
751 request_t *request, fr_value_box_list_t *in)
752{
754 rlm_cipher_rsa_thread_inst_t *t = talloc_get_type_abort(xctx->mctx->thread, rlm_cipher_rsa_thread_inst_t);
755
756 uint8_t const *sig;
757 size_t sig_len;
758
759 char const *msg;
760 size_t msg_len;
761
762 unsigned int digest_len = 0;
763
764 fr_value_box_t *vb;
765 fr_value_box_t *in_head = fr_value_box_list_pop_head(in);
767
768 fr_assert(in_head);
769
770 /*
771 * Don't auto-cast to octets if the signature
772 * isn't already in that form.
773 * It could be hexits or base64 or some other encoding.
774 */
775 if (in_head->type != FR_TYPE_OCTETS) {
776 REDEBUG("Signature argument wrong type, expected %s, got %s. "
777 "Use %%base64.decode(<text>) or %%hex_decode(<text>) if signature is armoured",
779 fr_type_to_str(in_head->type));
780 return XLAT_ACTION_FAIL;
781 }
782 sig = in_head->vb_octets;
783 sig_len = in_head->vb_length;
784
785 /*
786 * Concat (...) args to get message data
787 */
788 args = fr_value_box_list_head(in);
792 SIZE_MAX) < 0) {
793 REDEBUG("Failed concatenating arguments to form plaintext");
794 return XLAT_ACTION_FAIL;
795 }
796 msg = args->vb_strvalue;
797 msg_len = args->vb_length;
798
799 if (msg_len == 0) {
800 REDEBUG("Zero length message data");
801 return XLAT_ACTION_FAIL;
802 }
803
804 /*
805 * First produce a digest of the message
806 */
807 if (unlikely(EVP_DigestInit_ex(t->evp_md_ctx, inst->rsa->sig_digest, NULL) <= 0)) {
808 fr_tls_log(request, "Failed initialising message digest");
809 return XLAT_ACTION_FAIL;
810 }
811
812 if (EVP_DigestUpdate(t->evp_md_ctx, msg, msg_len) <= 0) {
813 fr_tls_log(request, "Failed ingesting message");
814 return XLAT_ACTION_FAIL;
815 }
816
817 if (EVP_DigestFinal_ex(t->evp_md_ctx, t->digest_buff, &digest_len) <= 0) {
818 fr_tls_log(request, "Failed finalising message digest");
819 return XLAT_ACTION_FAIL;
820 }
821 fr_assert((size_t)digest_len == talloc_array_length(t->digest_buff));
822
823 /*
824 * Now check the signature matches what we expected
825 */
826 switch (EVP_PKEY_verify(t->evp_verify_ctx, sig, sig_len, t->digest_buff, (size_t)digest_len)) {
827 case 1: /* success (signature valid) */
828 MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, NULL));
829 vb->vb_bool = true;
831 break;
832
833 case 0: /* failure (signature not valid) */
834 MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, NULL));
835 vb->vb_bool = false;
837 break;
838
839 default:
840 fr_tls_log(request, "Failed validating signature");
841 return XLAT_ACTION_FAIL;
842 }
843
844 return XLAT_ACTION_DONE;
845}
846
848 { .required = true, .concat = false, .single = true, .type = FR_TYPE_STRING },
849 { .required = false, .concat = false, .single = true, .type = FR_TYPE_STRING }, /* Optional hash for fingerprint mode */
851};
852
853/** Return the fingerprint of the public certificate
854 *
855 * Arguments are @verbatim(<digest>)@endverbatim
856 *
857@verbatim
858%<inst>.certificate(fingerprint, <digest>)
859@endverbatim
860 *
861 * @ingroup xlat_functions
862 */
864 xlat_ctx_t const *xctx,
865 request_t *request, fr_value_box_list_t *in)
866{
868 char const *md_name;
869 EVP_MD const *md;
870 size_t md_len;
871 fr_value_box_t *vb;
872 uint8_t *digest;
873
874 if (!fr_value_box_list_next(in, fr_value_box_list_head(in))) {
875 REDEBUG("Missing digest argument");
876 return XLAT_ACTION_FAIL;
877 }
878
879 /*
880 * Second arg...
881 */
882 md_name = ((fr_value_box_t *)fr_value_box_list_next(in, fr_value_box_list_head(in)))->vb_strvalue;
883 md = EVP_get_digestbyname(md_name);
884 if (!md) {
885 REDEBUG("Specified digest \"%s\" is not a valid digest type", md_name);
886 return XLAT_ACTION_FAIL;
887 }
888
889 md_len = EVP_MD_size(md);
890 MEM(vb = fr_value_box_alloc_null(ctx));
891 MEM(fr_value_box_mem_alloc(vb, &digest, vb, NULL, md_len, false) == 0);
892
893 if (X509_digest(inst->rsa->x509_certificate_file, md, digest, (unsigned int *)&md_len) != 1) {
894 fr_tls_log(request, "Failed calculating certificate fingerprint");
895 talloc_free(vb);
896 return XLAT_ACTION_FAIL;
897 }
898
900
901 return XLAT_ACTION_DONE;
902}
903
904/** Return the serial of the public certificate
905 *
906@verbatim
907%<inst>.certificate(serial)
908@endverbatim
909 *
910 * @ingroup xlat_functions
911 */
913 xlat_ctx_t const *xctx,
914 request_t *request, UNUSED fr_value_box_list_t *in)
915{
917 ASN1_INTEGER const *serial;
918 fr_value_box_t *vb;
919
920 serial = X509_get0_serialNumber(inst->rsa->x509_certificate_file);
921 if (!serial) {
922 fr_tls_log(request, "Failed retrieving certificate serial");
923 return XLAT_ACTION_FAIL;
924 }
925
926 MEM(vb = fr_value_box_alloc_null(ctx));
927 MEM(fr_value_box_memdup(vb, vb, NULL, serial->data, serial->length, true) == 0);
928
930
931 return XLAT_ACTION_DONE;
932}
933
935 xlat_ctx_t const *xctx,
936 request_t *request, fr_value_box_list_t *in)
937{
939 char const *attribute = fr_value_box_list_head(in)->vb_strvalue;
940 fr_value_box_t *vb;
941
943 default:
944 REDEBUG("Unknown certificate attribute \"%s\"", attribute);
945 return XLAT_ACTION_FAIL;
946
948 return cipher_fingerprint_xlat(ctx, out, xctx, request, in);
949
951 return cipher_serial_xlat(ctx, out, xctx, request, in);
952
954 MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_DATE, NULL));
955 vb->vb_date = inst->rsa->not_before;
956 vb->tainted = true;
958 return XLAT_ACTION_DONE;
959
961 MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_DATE, NULL));
962 vb->vb_date = inst->rsa->not_after;
963 vb->tainted = true;
965 return XLAT_ACTION_DONE;
966 }
967}
968
969/** Talloc destructor for freeing an EVP_PKEY_CTX
970 *
971 * @param[in] evp_pkey_ctx to free.
972 * @return 0
973 */
974static int _evp_pkey_ctx_free(EVP_PKEY_CTX *evp_pkey_ctx)
975{
976 EVP_PKEY_CTX_free(evp_pkey_ctx);
977
978 return 0;
979}
980
981/** Talloc destructor for freeing an EVP_MD_CTX
982 *
983 * @param[in] evp_md_ctx to free.
984 * @return 0
985 */
986static int _evp_md_ctx_free(EVP_MD_CTX *evp_md_ctx)
987{
988 EVP_MD_CTX_destroy(evp_md_ctx);
989
990 return 0;
991}
992
993static int cipher_rsa_padding_params_set(EVP_PKEY_CTX *evp_pkey_ctx, cipher_rsa_t const *rsa_inst)
994{
995 if (unlikely(EVP_PKEY_CTX_set_rsa_padding(evp_pkey_ctx, rsa_inst->padding)) <= 0) {
996 fr_tls_strerror_printf(NULL);
997 PERROR("%s: Failed setting RSA padding type", __FUNCTION__);
998 return -1;
999 }
1000
1001 switch (rsa_inst->padding) {
1002 case RSA_NO_PADDING:
1003 case RSA_X931_PADDING:
1004 case RSA_PKCS1_PADDING:
1005 return 0;
1006
1007 /*
1008 * Configure OAEP advanced padding options
1009 */
1010 case RSA_PKCS1_OAEP_PADDING:
1011 if (unlikely(EVP_PKEY_CTX_set_rsa_oaep_md(evp_pkey_ctx, rsa_inst->oaep->oaep_digest) <= 0)) {
1012 fr_tls_strerror_printf(NULL);
1013 PERROR("%s: Failed setting OAEP digest", __FUNCTION__);
1014 return -1;
1015 }
1016
1017 if (unlikely(EVP_PKEY_CTX_set_rsa_mgf1_md(evp_pkey_ctx, rsa_inst->oaep->mgf1_digest) <= 0)) {
1018 fr_tls_strerror_printf(NULL);
1019 PERROR("%s: Failed setting MGF1 digest", __FUNCTION__);
1020 return -1;
1021 }
1022
1023 if (rsa_inst->oaep->label) {
1024 char *label;
1025 size_t label_len = talloc_strlen(rsa_inst->oaep->label);
1026
1027 /*
1028 * OpenSSL does not duplicate the label when
1029 * EVP_PKEY_CTX_set0_rsa_oaep_label is called,
1030 * but happily frees it on subsequent calls
1031 * or when the EVP_PKEY_CTX is freed,
1032 * idiots...
1033 */
1034 MEM(label = talloc_bstrndup(evp_pkey_ctx, rsa_inst->oaep->label, label_len));
1035 if (unlikely(EVP_PKEY_CTX_set0_rsa_oaep_label(evp_pkey_ctx, label, label_len) <= 0)) {
1036 fr_tls_strerror_printf(NULL);
1037 PERROR("%s: Failed setting OAEP padding label", __FUNCTION__);
1038 OPENSSL_free(label);
1039 return -1;
1040 }
1041 }
1042 return 0;
1043
1044 default:
1045 fr_assert(0);
1046 return -1;
1047 }
1048}
1049
1050/** Pre-initialises the EVP_PKEY_CTX necessary for performing RSA encryption/decryption/sign/verify
1051 *
1052 * If reference counting is used for EVP_PKEY structs, should also prevent any mutex contention
1053 * associated with incrementing/decrementing those references.
1054 *
1055 * xlat functions MUST NOT interleave PKEY operations with yields
1056 *
1057 * @return 0.
1058 */
1060{
1061 rlm_cipher_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_cipher_t);
1062 rlm_cipher_rsa_thread_inst_t *ti = talloc_get_type_abort(mctx->thread, rlm_cipher_rsa_thread_inst_t);
1063
1064 /*
1065 * Pre-allocate different contexts for the different operations
1066 * The OpenSSL docs say this is fine, and it reduces the potential
1067 * for SEGVs and other random errors due to trying to change the
1068 * configuration of a context multiple times.
1069 */
1070 if (inst->rsa->certificate_file) {
1071 /*
1072 * Alloc encrypt
1073 */
1074 ti->evp_encrypt_ctx = EVP_PKEY_CTX_new(inst->rsa->certificate_file, NULL);
1075 if (!ti->evp_encrypt_ctx) {
1076 fr_tls_strerror_printf(NULL);
1077 PERROR("%s: Failed allocating encrypt EVP_PKEY_CTX", __FUNCTION__);
1078 return -1;
1079 }
1080 talloc_set_type(ti->evp_encrypt_ctx, EVP_PKEY_CTX);
1081 ti->evp_encrypt_ctx = talloc_steal(ti, ti->evp_encrypt_ctx); /* Bind lifetime to instance */
1082 talloc_set_destructor(ti->evp_encrypt_ctx, _evp_pkey_ctx_free); /* Free ctx correctly on chunk free */
1083
1084 /*
1085 * Configure encrypt
1086 */
1087 if (unlikely(EVP_PKEY_encrypt_init(ti->evp_encrypt_ctx) <= 0)) {
1088 fr_tls_strerror_printf(NULL);
1089 PERROR("%s: Failed initialising encrypt EVP_PKEY_CTX", __FUNCTION__);
1090 return -1;
1091 }
1093 ERROR("%s: Failed setting padding for encrypt EVP_PKEY_CTX", __FUNCTION__);
1094 return -1;
1095 }
1096
1097 /*
1098 * Alloc verify
1099 */
1100 ti->evp_verify_ctx = EVP_PKEY_CTX_new(inst->rsa->certificate_file, NULL);
1101 if (!ti->evp_verify_ctx) {
1102 fr_tls_strerror_printf(NULL);
1103 PERROR("%s: Failed allocating verify EVP_PKEY_CTX", __FUNCTION__);
1104 return -1;
1105 }
1106 talloc_set_type(ti->evp_verify_ctx, EVP_PKEY_CTX);
1107 ti->evp_verify_ctx = talloc_steal(ti, ti->evp_verify_ctx); /* Bind lifetime to instance */
1108 talloc_set_destructor(ti->evp_verify_ctx, _evp_pkey_ctx_free); /* Free ctx correctly on chunk free */
1109
1110 /*
1111 * Configure verify
1112 */
1113 if (unlikely(EVP_PKEY_verify_init(ti->evp_verify_ctx) <= 0)) {
1114 fr_tls_strerror_printf(NULL);
1115 PERROR("%s: Failed initialising verify EVP_PKEY_CTX", __FUNCTION__);
1116 return -1;
1117 }
1118
1119 /*
1120 * OAEP not valid for signing or verification
1121 */
1122 if (inst->rsa->padding != RSA_PKCS1_OAEP_PADDING) {
1124 ERROR("%s: Failed setting padding for verify EVP_PKEY_CTX", __FUNCTION__);
1125 return -1;
1126 }
1127 }
1128
1129 if (unlikely(EVP_PKEY_CTX_set_signature_md(ti->evp_verify_ctx, inst->rsa->sig_digest)) <= 0) {
1130 fr_tls_strerror_printf(NULL);
1131 PERROR("%s: Failed setting signature digest type", __FUNCTION__);
1132 return -1;
1133 }
1134 }
1135
1136 if (inst->rsa->private_key_file) {
1137 /*
1138 * Alloc decrypt
1139 */
1140 ti->evp_decrypt_ctx = EVP_PKEY_CTX_new(inst->rsa->private_key_file, NULL);
1141 if (!ti->evp_decrypt_ctx) {
1142 fr_tls_strerror_printf(NULL);
1143 PERROR("%s: Failed allocating decrypt EVP_PKEY_CTX", __FUNCTION__);
1144 return -1;
1145 }
1146 talloc_set_type(ti->evp_decrypt_ctx, EVP_PKEY_CTX);
1147 ti->evp_decrypt_ctx = talloc_steal(ti, ti->evp_decrypt_ctx); /* Bind lifetime to instance */
1148 talloc_set_destructor(ti->evp_decrypt_ctx, _evp_pkey_ctx_free); /* Free ctx correctly on chunk free */
1149
1150 /*
1151 * Configure decrypt
1152 */
1153 if (unlikely(EVP_PKEY_decrypt_init(ti->evp_decrypt_ctx) <= 0)) {
1154 fr_tls_strerror_printf(NULL);
1155 PERROR("%s: Failed initialising decrypt EVP_PKEY_CTX", __FUNCTION__);
1156 return -1;
1157 }
1159 ERROR("%s: Failed setting padding for decrypt EVP_PKEY_CTX", __FUNCTION__);
1160 return -1;
1161 }
1162
1163 /*
1164 * Alloc sign
1165 */
1166 ti->evp_sign_ctx = EVP_PKEY_CTX_new(inst->rsa->private_key_file, NULL);
1167 if (!ti->evp_sign_ctx) {
1168 fr_tls_strerror_printf(NULL);
1169 PERROR("%s: Failed allocating sign EVP_PKEY_CTX", __FUNCTION__);
1170 return -1;
1171 }
1172 talloc_set_type(ti->evp_sign_ctx, EVP_PKEY_CTX);
1173 ti->evp_sign_ctx = talloc_steal(ti, ti->evp_sign_ctx); /* Bind lifetime to instance */
1174 talloc_set_destructor(ti->evp_sign_ctx, _evp_pkey_ctx_free); /* Free ctx correctly on chunk free */
1175
1176 /*
1177 * Configure sign
1178 */
1179 if (unlikely(EVP_PKEY_sign_init(ti->evp_sign_ctx) <= 0)) {
1180 fr_tls_strerror_printf(NULL);
1181 PERROR("%s: Failed initialising sign EVP_PKEY_CTX", __FUNCTION__);
1182 return -1;
1183 }
1184
1185 /*
1186 * OAEP not valid for signing or verification
1187 */
1188 if (inst->rsa->padding != RSA_PKCS1_OAEP_PADDING) {
1190 ERROR("%s: Failed setting padding for sign EVP_PKEY_CTX", __FUNCTION__);
1191 return -1;
1192 }
1193 }
1194
1195 if (unlikely(EVP_PKEY_CTX_set_signature_md(ti->evp_sign_ctx, inst->rsa->sig_digest)) <= 0) {
1196 fr_tls_strerror_printf(NULL);
1197 PERROR("%s: Failed setting signature digest type", __FUNCTION__);
1198 return -1;
1199 }
1200
1201 /*
1202 * Alloc digest ctx for signing and verification
1203 */
1204 ti->evp_md_ctx = EVP_MD_CTX_create();
1205 if (!ti->evp_md_ctx) {
1206 fr_tls_strerror_printf(NULL);
1207 PERROR("%s: Failed allocating EVP_MD_CTX", __FUNCTION__);
1208 return -1;
1209 }
1210 talloc_set_type(ti->evp_md_ctx, EVP_MD_CTX);
1211 ti->evp_md_ctx = talloc_steal(ti, ti->evp_md_ctx); /* Bind lifetime to instance */
1212 talloc_set_destructor(ti->evp_md_ctx, _evp_md_ctx_free); /* Free ctx correctly on chunk free */
1213 MEM(ti->digest_buff = talloc_array(ti, uint8_t, EVP_MD_size(inst->rsa->sig_digest)));
1214 }
1215
1216 return 0;
1217}
1218
1220{
1221 rlm_cipher_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_cipher_t);
1222
1223 switch (inst->type) {
1225 talloc_set_type(mctx->thread, rlm_cipher_rsa_thread_inst_t);
1226 return cipher_rsa_thread_instantiate(mctx);
1227
1230 fr_assert(0);
1231 }
1232
1233 return 0;
1234}
1235
1236/*
1237 * Do any per-module initialization that is separate to each
1238 * configured instance of the module. e.g. set up connections
1239 * to external databases, read configuration files, set up
1240 * dictionary entries, etc.
1241 */
1242static int mod_bootstrap(module_inst_ctx_t const *mctx)
1243{
1244 rlm_cipher_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_cipher_t);
1245 CONF_SECTION *conf = mctx->mi->conf;
1246
1247 switch (inst->type) {
1249 if (!inst->rsa) {
1250 cf_log_err(conf, "type = rsa, but no 'rsa { ... }' configuration section provided");
1251 return -1;
1252 }
1253
1254 if (!inst->rsa->private_key_file && !inst->rsa->certificate_file) {
1255 cf_log_err(conf, "type = rsa, but neither "
1256 "'private_key_file' nor 'certificate_file' configured");
1257 return -1;
1258 }
1259
1260 if (inst->rsa->private_key_file) {
1261 xlat_t *xlat;
1262
1263 /*
1264 * Register decrypt xlat
1265 */
1266 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "decrypt", cipher_rsa_decrypt_xlat, FR_TYPE_STRING);
1268
1269 /*
1270 * Verify sign xlat
1271 */
1272 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "verify", cipher_rsa_verify_xlat, FR_TYPE_BOOL);
1274 }
1275
1276 if (inst->rsa->certificate_file) {
1277 xlat_t *xlat;
1278
1279 /*
1280 * If we have both public and private keys check they're
1281 * part of the same keypair. This isn't technically a requirement
1282 * but it fixes some obscure errors where the user uses the serial
1283 * xlat, expecting it to be the serial of the keypair containing
1284 * the private key.
1285 */
1286 if (inst->rsa->private_key_file && inst->rsa->x509_certificate_file) {
1287 if (X509_check_private_key(inst->rsa->x509_certificate_file,
1288 inst->rsa->private_key_file) == 0) {
1289 fr_tls_strerror_printf(NULL);
1290 cf_log_perr(conf, "Private key does not match the certificate public key");
1291 return -1;
1292 }
1293 }
1294
1295 /*
1296 * Register encrypt xlat
1297 */
1298 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "encrypt", cipher_rsa_encrypt_xlat, FR_TYPE_OCTETS);
1300
1301 /*
1302 * Register sign xlat
1303 */
1306
1307 /*
1308 * FIXME: These should probably be split into separate xlats
1309 * so we can optimise for return types.
1310 */
1311 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "certificate", cipher_certificate_xlat, FR_TYPE_VOID);
1313 }
1314 break;
1315
1316 /*
1317 * Populated by cipher_type_parse() so if
1318 * the value is unrecognised we've got an issue.
1319 */
1320 default:
1321 fr_assert(0);
1322 return -1;
1323 }
1324
1325 return 0;
1326}
1327
1328/*
1329 * The module name should be the only globally exported symbol.
1330 * That is, everything else should be 'static'.
1331 *
1332 * If the module needs to temporarily modify it's instantiation
1333 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
1334 * The server will then take care of ensuring that the module
1335 * is single-threaded.
1336 */
1339 .common = {
1340 .magic = MODULE_MAGIC_INIT,
1341 .name = "cipher",
1342 .inst_size = sizeof(rlm_cipher_t),
1343 .thread_inst_size = sizeof(rlm_cipher_rsa_thread_inst_t),
1344 .config = module_config,
1345 .bootstrap = mod_bootstrap,
1346 .thread_instantiate = mod_thread_instantiate
1347 }
1348};
log_entry msg
Definition acutest.h:794
va_list args
Definition acutest.h:770
#define UNCONST(_type, _ptr)
Remove const qualification from a pointer.
Definition build.h:186
#define RCSID(id)
Definition build.h:512
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:228
#define unlikely(_x)
Definition build.h:407
#define UNUSED
Definition build.h:336
#define NUM_ELEMENTS(_t)
Definition build.h:358
int cf_table_parse_int(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, conf_parser_t const *rule)
Generic function for parsing conf pair values as int.
Definition cf_parse.c:1636
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:657
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
Definition cf_parse.h:611
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:280
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:268
#define FR_CONF_OFFSET_SUBSECTION(_name, _flags, _struct, _field, _subcs)
conf_parser_t which populates a sub-struct using a CONF_SECTION
Definition cf_parse.h:309
@ CONF_FLAG_SECRET
Only print value if debug level >= 3.
Definition cf_parse.h:433
@ CONF_FLAG_NOT_EMPTY
CONF_PAIR is required to have a non zero length value.
Definition cf_parse.h:447
#define FR_CONF_OFFSET_TYPE_FLAGS(_name, _type, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition cf_parse.h:238
Defines a CONF_PAIR to C data type mapping.
Definition cf_parse.h:594
Common header for all CONF_* types.
Definition cf_priv.h:49
A section grouping multiple CONF_PAIR.
Definition cf_priv.h:101
CONF_PAIR * cf_item_to_pair(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_PAIR.
Definition cf_util.c:665
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition cf_util.c:1581
#define cf_log_err(_cf, _fmt,...)
Definition cf_util.h:285
#define cf_log_perr(_cf, _fmt,...)
Definition cf_util.h:292
#define cf_log_pwarn(_cf, _fmt,...)
Definition cf_util.h:293
#define cf_log_debug(_cf, _fmt,...)
Definition cf_util.h:288
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
Definition dcursor.h:406
#define MEM(x)
Definition debug.h:46
#define ERROR(fmt,...)
Definition dhcpclient.c:40
static fr_slen_t in
Definition dict.h:882
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
static xlat_action_t cipher_rsa_decrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Decrypt input data.
Definition rlm_cipher.c:687
static xlat_action_t cipher_rsa_encrypt_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Encrypt input data.
Definition rlm_cipher.c:548
static xlat_action_t cipher_rsa_sign_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Sign input data.
Definition rlm_cipher.c:609
static xlat_action_t cipher_serial_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, UNUSED fr_value_box_list_t *in)
Return the serial of the public certificate.
Definition rlm_cipher.c:912
static xlat_action_t cipher_rsa_verify_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Verify input data.
Definition rlm_cipher.c:749
static xlat_action_t cipher_fingerprint_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Return the fingerprint of the public certificate.
Definition rlm_cipher.c:863
talloc_free(hp)
#define PERROR(_fmt,...)
Definition log.h:228
#define RHEXDUMP3(_data, _len, _fmt,...)
Definition log.h:717
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_DATE
Unix time stamp, always has value >2^31.
@ FR_TYPE_VOID
User data.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_OCTETS
Raw octets.
unsigned char uint8_t
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
void * thread
Thread specific instance data.
Definition module_ctx.h:43
void * thread
Thread instance data.
Definition module_ctx.h:67
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:64
module_instance_t * mi
Instance of the module being instantiated.
Definition module_ctx.h:51
Temporary structure to hold arguments for instantiation calls.
Definition module_ctx.h:50
Temporary structure to hold arguments for thread_instantiation calls.
Definition module_ctx.h:63
xlat_t * module_rlm_xlat_register(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
Definition module_rlm.c:232
module_t common
Common fields presented by all modules.
Definition module_rlm.h:39
#define fr_assert(_expr)
Definition rad_assert.h:37
#define REDEBUG(fmt,...)
static rs_t * conf
Definition radsniff.c:52
EVP_PKEY_CTX * evp_verify_ctx
Pre-allocated evp_pkey_ctx.
Definition rlm_cipher.c:133
static size_t cipher_rsa_padding_len
Definition rlm_cipher.c:103
static int cipher_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
Checks if the specified cipher type is valid.
Definition rlm_cipher.c:307
static const conf_parser_t rsa_oaep_config[]
Configuration for the RSA-PCKS1-OAEP padding scheme.
Definition rlm_cipher.c:193
static int cipher_rsa_private_key_file_load(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
cipher_rsa_oaep_t * oaep
OAEP can use a configurable message digest type.
Definition rlm_cipher.c:173
X509 * x509_certificate_file
Needed for extracting certificate attributes.
Definition rlm_cipher.c:161
cipher_cert_verify_mode_t verify_mode
How hard we try to verify the certificate.
Definition rlm_cipher.c:163
static xlat_arg_parser_t const cipher_rsa_verify_xlat_arg[]
Definition rlm_cipher.c:729
static fr_table_num_sorted_t const cipher_rsa_padding[]
The type of padding used.
Definition rlm_cipher.c:97
static fr_table_num_sorted_t const cert_attributes[]
Public key types.
Definition rlm_cipher.c:121
cipher_cert_verify_mode_t
Certificate validation modes.
Definition rlm_cipher.c:66
@ CIPHER_CERT_VERIFY_HARD
Fail if the certificate isn't valid.
Definition rlm_cipher.c:69
@ CIPHER_CERT_VERIFY_SOFT
Warn if the certificate isn't valid.
Definition rlm_cipher.c:70
@ CIPHER_CERT_VERIFY_NONE
Don't check to see if the we're between notBefore or notAfter.
Definition rlm_cipher.c:71
@ CIPHER_CERT_VERIFY_INVALID
Definition rlm_cipher.c:67
static const conf_parser_t rsa_config[]
Configuration for the RSA cipher type.
Definition rlm_cipher.c:204
static int cipher_rsa_padding_params_set(EVP_PKEY_CTX *evp_pkey_ctx, cipher_rsa_t const *rsa_inst)
Definition rlm_cipher.c:993
cipher_type_t type
Type of encryption to use.
Definition rlm_cipher.c:180
static size_t cipher_cert_verify_mode_table_len
Definition rlm_cipher.c:116
cipher_cert_attributes_t
Definition rlm_cipher.c:75
@ CIPHER_CERT_ATTR_NOT_AFTER
Time the certificate expires.
Definition rlm_cipher.c:80
@ CIPHER_CERT_ATTR_SERIAL
Certificate's serial number.
Definition rlm_cipher.c:77
@ CIPHER_CERT_ATTR_UNKNOWN
Unrecognised attribute.
Definition rlm_cipher.c:76
@ CIPHER_CERT_ATTR_FINGERPRINT
Dynamically calculated fingerprint.
Definition rlm_cipher.c:78
@ CIPHER_CERT_ATTR_NOT_BEFORE
Time the certificate becomes valid.
Definition rlm_cipher.c:79
char const * label
Additional input to the hashing function.
Definition rlm_cipher.c:146
EVP_MD_CTX * evp_md_ctx
Pre-allocated evp_md_ctx for sign and verify.
Definition rlm_cipher.c:135
int padding
Type of padding to apply to the plaintext or ciphertext before feeding it to RSA crypto functions.
Definition rlm_cipher.c:167
static int mod_bootstrap(module_inst_ctx_t const *mctx)
static int digest_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
Calls EVP_get_digestbyname() to convert the digest type.
Definition rlm_cipher.c:249
uint8_t * digest_buff
Pre-allocated digest buffer.
Definition rlm_cipher.c:136
EVP_MD * mgf1_digest
Masking function digest.
Definition rlm_cipher.c:144
static xlat_arg_parser_t const cipher_rsa_decrypt_xlat_arg[]
Definition rlm_cipher.c:670
static fr_table_num_sorted_t const cipher_cert_verify_mode_table[]
Definition rlm_cipher.c:111
cipher_type_t
Definition rlm_cipher.c:56
@ RLM_CIPHER_TYPE_SYMMETRIC
Any symmetric cipher available via OpenSSL's EVP interface.
Definition rlm_cipher.c:59
@ RLM_CIPHER_TYPE_RSA
Definition rlm_cipher.c:58
@ RLM_CIPHER_TYPE_INVALID
Definition rlm_cipher.c:57
static xlat_arg_parser_t const cipher_rsa_sign_xlat_arg[]
Definition rlm_cipher.c:592
static int _evp_pkey_free(EVP_PKEY *pkey)
Talloc destructor for freeing an EVP_PKEY (representing a certificate)
Definition rlm_cipher.c:334
fr_unix_time_t not_before
Certificate isn't valid before this time.
Definition rlm_cipher.c:164
static xlat_arg_parser_t const cipher_rsa_encrypt_xlat_arg[]
Definition rlm_cipher.c:531
fr_unix_time_t not_after
Certificate isn't valid after this time.
Definition rlm_cipher.c:165
char const * private_key_password
Password to decrypt the private key.
Definition rlm_cipher.c:155
static int cipher_rsa_thread_instantiate(module_thread_inst_ctx_t const *mctx)
Pre-initialises the EVP_PKEY_CTX necessary for performing RSA encryption/decryption/sign/verify.
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
EVP_PKEY * certificate_file
Public (certificate) file.
Definition rlm_cipher.c:160
EVP_PKEY * private_key_file
Private key file.
Definition rlm_cipher.c:159
static size_t cipher_type_len
Definition rlm_cipher.c:109
static int cipher_rsa_padding_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
Checks if the specified padding type is valid.
Definition rlm_cipher.c:278
static int _x509_cert_free(X509 *cert)
Talloc destructor for freeing an X509 struct (representing a public certificate)
Definition rlm_cipher.c:346
static int _evp_md_ctx_free(EVP_MD_CTX *evp_md_ctx)
Talloc destructor for freeing an EVP_MD_CTX.
Definition rlm_cipher.c:986
module_rlm_t rlm_cipher
static xlat_arg_parser_t const cipher_certificate_xlat_args[]
Definition rlm_cipher.c:847
static fr_table_num_sorted_t const cipher_type[]
Definition rlm_cipher.c:105
EVP_PKEY_CTX * evp_decrypt_ctx
Pre-allocated evp_pkey_ctx.
Definition rlm_cipher.c:132
EVP_PKEY_CTX * evp_encrypt_ctx
Pre-allocated evp_pkey_ctx.
Definition rlm_cipher.c:130
static const conf_parser_t module_config[]
Definition rlm_cipher.c:232
static int cipher_rsa_certificate_file_load(TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED conf_parser_t const *rule)
static xlat_action_t cipher_certificate_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Definition rlm_cipher.c:934
static size_t cert_attributes_len
Definition rlm_cipher.c:127
EVP_PKEY_CTX * evp_sign_ctx
Pre-allocated evp_pkey_ctx.
Definition rlm_cipher.c:131
static int _evp_pkey_ctx_free(EVP_PKEY_CTX *evp_pkey_ctx)
Talloc destructor for freeing an EVP_PKEY_CTX.
Definition rlm_cipher.c:974
static size_t pkey_types_len
Definition rlm_cipher.c:92
EVP_MD * sig_digest
Signature digest type.
Definition rlm_cipher.c:171
char const * random_file
If set, we read 10K of data (or the complete file) and use it to seed OpenSSL's PRNG.
Definition rlm_cipher.c:156
static fr_table_num_sorted_t const pkey_types[]
Public key types.
Definition rlm_cipher.c:86
EVP_MD * oaep_digest
Padding digest type.
Definition rlm_cipher.c:143
Configuration for the OAEP padding method.
Definition rlm_cipher.c:142
Configuration for RSA encryption/decryption/signing.
Definition rlm_cipher.c:154
Instance configuration.
Definition rlm_cipher.c:179
CONF_SECTION * conf
Module's instance configuration.
Definition module.h:351
size_t inst_size
Size of the module's instance data.
Definition module.h:212
void * data
Module's instance data.
Definition module.h:293
void * boot
Data allocated during the boostrap phase.
Definition module.h:296
eap_aka_sim_process_conf_t * inst
fr_aka_sim_id_type_t type
eap_type_t type
The preferred EAP-Type of this instance of the EAP-SIM/AKA/AKA' state machine.
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition syserror.c:243
#define fr_table_value_by_str(_table, _name, _def)
Convert a string to a value using a sorted or ordered table.
Definition table.h:653
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition table.h:772
An element in a lexicographically sorted array of name to num mappings.
Definition table.h:49
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
Definition talloc.c:617
#define talloc_get_type_abort_const
Definition talloc.h:110
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
Definition talloc.h:136
"Unix" time.
Definition time.h:95
@ XLAT_ARG_VARIADIC_EMPTY_SQUASH
Empty argument groups are removed.
Definition xlat.h:136
unsigned int required
Argument must be present, and non-empty.
Definition xlat.h:146
#define XLAT_ARG_PARSER_TERMINATOR
Definition xlat.h:170
xlat_action_t
Definition xlat.h:37
@ XLAT_ACTION_FAIL
An xlat function failed.
Definition xlat.h:44
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition xlat.h:43
Definition for a single argument consumed by an xlat function.
Definition xlat.h:145
static fr_slen_t parent
Definition pair.h:858
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
Definition types.h:454
int fr_utils_get_private_key_password(char *buf, int size, UNUSED int rwflag, void *u)
Return the static private key password we have configured.
Definition utils.c:190
int fr_value_box_mem_alloc(TALLOC_CTX *ctx, uint8_t **out, fr_value_box_t *dst, fr_dict_attr_t const *enumv, size_t len, bool tainted)
Pre-allocate an octets buffer for filling by the caller.
Definition value.c:4970
int fr_value_box_mem_realloc(TALLOC_CTX *ctx, uint8_t **out, fr_value_box_t *dst, size_t len)
Change the length of a buffer already allocated to a value box.
Definition value.c:5003
int fr_value_box_bstr_alloc(TALLOC_CTX *ctx, char **out, fr_value_box_t *dst, fr_dict_attr_t const *enumv, size_t len, bool tainted)
Alloc and assign an empty \0 terminated string to a fr_value_box_t.
Definition value.c:4749
int fr_value_box_bstr_realloc(TALLOC_CTX *ctx, char **out, fr_value_box_t *dst, size_t len)
Change the length of a buffer already allocated to a value box.
Definition value.c:4782
int fr_value_box_memdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, uint8_t const *src, size_t len, bool tainted)
Copy a buffer to a fr_value_box_t.
Definition value.c:5064
int fr_value_box_list_concat_in_place(TALLOC_CTX *ctx, fr_value_box_t *out, fr_value_box_list_t *list, fr_type_t type, fr_value_box_list_action_t proc_action, bool flatten, size_t max_size)
Concatenate a list of value boxes.
Definition value.c:6589
@ FR_VALUE_BOX_LIST_FREE
Definition value.h:238
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
Definition value.h:644
#define fr_value_box_alloc_null(_ctx)
Allocate a value box for later use with a value assignment function.
Definition value.h:655
static size_t char ** out
Definition value.h:1030
#define fr_box_date(_val)
Definition value.h:347
module_ctx_t const * mctx
Synthesised module calling ctx.
Definition xlat_ctx.h:52
An xlat calling ctx.
Definition xlat_ctx.h:49
int xlat_func_args_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the arguments of an xlat.
Definition xlat_func.c:363