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: 5611496345d62f83b2c6125f95d0f3585a2f33ce $
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: 5611496345d62f83b2c6125f95d0f3585a2f33ce $")
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 {
875 fr_value_box_t *digest_vb = fr_value_box_list_next(in, fr_value_box_list_head(in));
876
877 if (!digest_vb || fr_type_is_null(digest_vb->type)) {
878 REDEBUG("Missing digest argument");
879 return XLAT_ACTION_FAIL;
880 }
881
882 /*
883 * Second arg...
884 */
885 md_name = digest_vb->vb_strvalue;
886 }
887 md = EVP_get_digestbyname(md_name);
888 if (!md) {
889 REDEBUG("Specified digest \"%s\" is not a valid digest type", md_name);
890 return XLAT_ACTION_FAIL;
891 }
892
893 md_len = EVP_MD_size(md);
894 MEM(vb = fr_value_box_alloc_null(ctx));
895 MEM(fr_value_box_mem_alloc(vb, &digest, vb, NULL, md_len, false) == 0);
896
897 if (X509_digest(inst->rsa->x509_certificate_file, md, digest, (unsigned int *)&md_len) != 1) {
898 fr_tls_log(request, "Failed calculating certificate fingerprint");
899 talloc_free(vb);
900 return XLAT_ACTION_FAIL;
901 }
902
904
905 return XLAT_ACTION_DONE;
906}
907
908/** Return the serial of the public certificate
909 *
910@verbatim
911%<inst>.certificate(serial)
912@endverbatim
913 *
914 * @ingroup xlat_functions
915 */
917 xlat_ctx_t const *xctx,
918 request_t *request, UNUSED fr_value_box_list_t *in)
919{
921 ASN1_INTEGER const *serial;
922 fr_value_box_t *vb;
923
924 serial = X509_get0_serialNumber(inst->rsa->x509_certificate_file);
925 if (!serial) {
926 fr_tls_log(request, "Failed retrieving certificate serial");
927 return XLAT_ACTION_FAIL;
928 }
929
930 MEM(vb = fr_value_box_alloc_null(ctx));
931 MEM(fr_value_box_memdup(vb, vb, NULL, serial->data, serial->length, true) == 0);
932
934
935 return XLAT_ACTION_DONE;
936}
937
939 xlat_ctx_t const *xctx,
940 request_t *request, fr_value_box_list_t *in)
941{
943 char const *attribute = fr_value_box_list_head(in)->vb_strvalue;
944 fr_value_box_t *vb;
945
947 default:
948 REDEBUG("Unknown certificate attribute \"%s\"", attribute);
949 return XLAT_ACTION_FAIL;
950
952 return cipher_fingerprint_xlat(ctx, out, xctx, request, in);
953
955 return cipher_serial_xlat(ctx, out, xctx, request, in);
956
958 MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_DATE, NULL));
959 vb->vb_date = inst->rsa->not_before;
960 vb->tainted = true;
962 return XLAT_ACTION_DONE;
963
965 MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_DATE, NULL));
966 vb->vb_date = inst->rsa->not_after;
967 vb->tainted = true;
969 return XLAT_ACTION_DONE;
970 }
971}
972
973/** Talloc destructor for freeing an EVP_PKEY_CTX
974 *
975 * @param[in] evp_pkey_ctx to free.
976 * @return 0
977 */
978static int _evp_pkey_ctx_free(EVP_PKEY_CTX *evp_pkey_ctx)
979{
980 EVP_PKEY_CTX_free(evp_pkey_ctx);
981
982 return 0;
983}
984
985/** Talloc destructor for freeing an EVP_MD_CTX
986 *
987 * @param[in] evp_md_ctx to free.
988 * @return 0
989 */
990static int _evp_md_ctx_free(EVP_MD_CTX *evp_md_ctx)
991{
992 EVP_MD_CTX_destroy(evp_md_ctx);
993
994 return 0;
995}
996
997static int cipher_rsa_padding_params_set(EVP_PKEY_CTX *evp_pkey_ctx, cipher_rsa_t const *rsa_inst)
998{
999 if (unlikely(EVP_PKEY_CTX_set_rsa_padding(evp_pkey_ctx, rsa_inst->padding)) <= 0) {
1000 fr_tls_strerror_printf(NULL);
1001 PERROR("%s: Failed setting RSA padding type", __FUNCTION__);
1002 return -1;
1003 }
1004
1005 switch (rsa_inst->padding) {
1006 case RSA_NO_PADDING:
1007 case RSA_X931_PADDING:
1008 case RSA_PKCS1_PADDING:
1009 return 0;
1010
1011 /*
1012 * Configure OAEP advanced padding options
1013 */
1014 case RSA_PKCS1_OAEP_PADDING:
1015 if (unlikely(EVP_PKEY_CTX_set_rsa_oaep_md(evp_pkey_ctx, rsa_inst->oaep->oaep_digest) <= 0)) {
1016 fr_tls_strerror_printf(NULL);
1017 PERROR("%s: Failed setting OAEP digest", __FUNCTION__);
1018 return -1;
1019 }
1020
1021 if (unlikely(EVP_PKEY_CTX_set_rsa_mgf1_md(evp_pkey_ctx, rsa_inst->oaep->mgf1_digest) <= 0)) {
1022 fr_tls_strerror_printf(NULL);
1023 PERROR("%s: Failed setting MGF1 digest", __FUNCTION__);
1024 return -1;
1025 }
1026
1027 if (rsa_inst->oaep->label) {
1028 char *label;
1029 size_t label_len = talloc_strlen(rsa_inst->oaep->label);
1030
1031 /*
1032 * OpenSSL does not duplicate the label when
1033 * EVP_PKEY_CTX_set0_rsa_oaep_label is called,
1034 * but happily frees it on subsequent calls
1035 * or when the EVP_PKEY_CTX is freed,
1036 * idiots...
1037 */
1038 MEM(label = talloc_bstrndup(evp_pkey_ctx, rsa_inst->oaep->label, label_len));
1039 if (unlikely(EVP_PKEY_CTX_set0_rsa_oaep_label(evp_pkey_ctx, label, label_len) <= 0)) {
1040 fr_tls_strerror_printf(NULL);
1041 PERROR("%s: Failed setting OAEP padding label", __FUNCTION__);
1042 OPENSSL_free(label);
1043 return -1;
1044 }
1045 }
1046 return 0;
1047
1048 default:
1049 fr_assert(0);
1050 return -1;
1051 }
1052}
1053
1054/** Pre-initialises the EVP_PKEY_CTX necessary for performing RSA encryption/decryption/sign/verify
1055 *
1056 * If reference counting is used for EVP_PKEY structs, should also prevent any mutex contention
1057 * associated with incrementing/decrementing those references.
1058 *
1059 * xlat functions MUST NOT interleave PKEY operations with yields
1060 *
1061 * @return 0.
1062 */
1064{
1065 rlm_cipher_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_cipher_t);
1066 rlm_cipher_rsa_thread_inst_t *ti = talloc_get_type_abort(mctx->thread, rlm_cipher_rsa_thread_inst_t);
1067
1068 /*
1069 * Pre-allocate different contexts for the different operations
1070 * The OpenSSL docs say this is fine, and it reduces the potential
1071 * for SEGVs and other random errors due to trying to change the
1072 * configuration of a context multiple times.
1073 */
1074 if (inst->rsa->certificate_file) {
1075 /*
1076 * Alloc encrypt
1077 */
1078 ti->evp_encrypt_ctx = EVP_PKEY_CTX_new(inst->rsa->certificate_file, NULL);
1079 if (!ti->evp_encrypt_ctx) {
1080 fr_tls_strerror_printf(NULL);
1081 PERROR("%s: Failed allocating encrypt EVP_PKEY_CTX", __FUNCTION__);
1082 return -1;
1083 }
1084 talloc_set_type(ti->evp_encrypt_ctx, EVP_PKEY_CTX);
1085 ti->evp_encrypt_ctx = talloc_steal(ti, ti->evp_encrypt_ctx); /* Bind lifetime to instance */
1086 talloc_set_destructor(ti->evp_encrypt_ctx, _evp_pkey_ctx_free); /* Free ctx correctly on chunk free */
1087
1088 /*
1089 * Configure encrypt
1090 */
1091 if (unlikely(EVP_PKEY_encrypt_init(ti->evp_encrypt_ctx) <= 0)) {
1092 fr_tls_strerror_printf(NULL);
1093 PERROR("%s: Failed initialising encrypt EVP_PKEY_CTX", __FUNCTION__);
1094 return -1;
1095 }
1097 ERROR("%s: Failed setting padding for encrypt EVP_PKEY_CTX", __FUNCTION__);
1098 return -1;
1099 }
1100
1101 /*
1102 * Alloc verify
1103 */
1104 ti->evp_verify_ctx = EVP_PKEY_CTX_new(inst->rsa->certificate_file, NULL);
1105 if (!ti->evp_verify_ctx) {
1106 fr_tls_strerror_printf(NULL);
1107 PERROR("%s: Failed allocating verify EVP_PKEY_CTX", __FUNCTION__);
1108 return -1;
1109 }
1110 talloc_set_type(ti->evp_verify_ctx, EVP_PKEY_CTX);
1111 ti->evp_verify_ctx = talloc_steal(ti, ti->evp_verify_ctx); /* Bind lifetime to instance */
1112 talloc_set_destructor(ti->evp_verify_ctx, _evp_pkey_ctx_free); /* Free ctx correctly on chunk free */
1113
1114 /*
1115 * Configure verify
1116 */
1117 if (unlikely(EVP_PKEY_verify_init(ti->evp_verify_ctx) <= 0)) {
1118 fr_tls_strerror_printf(NULL);
1119 PERROR("%s: Failed initialising verify EVP_PKEY_CTX", __FUNCTION__);
1120 return -1;
1121 }
1122
1123 /*
1124 * OAEP not valid for signing or verification
1125 */
1126 if (inst->rsa->padding != RSA_PKCS1_OAEP_PADDING) {
1128 ERROR("%s: Failed setting padding for verify EVP_PKEY_CTX", __FUNCTION__);
1129 return -1;
1130 }
1131 }
1132
1133 if (unlikely(EVP_PKEY_CTX_set_signature_md(ti->evp_verify_ctx, inst->rsa->sig_digest)) <= 0) {
1134 fr_tls_strerror_printf(NULL);
1135 PERROR("%s: Failed setting signature digest type", __FUNCTION__);
1136 return -1;
1137 }
1138 }
1139
1140 if (inst->rsa->private_key_file) {
1141 /*
1142 * Alloc decrypt
1143 */
1144 ti->evp_decrypt_ctx = EVP_PKEY_CTX_new(inst->rsa->private_key_file, NULL);
1145 if (!ti->evp_decrypt_ctx) {
1146 fr_tls_strerror_printf(NULL);
1147 PERROR("%s: Failed allocating decrypt EVP_PKEY_CTX", __FUNCTION__);
1148 return -1;
1149 }
1150 talloc_set_type(ti->evp_decrypt_ctx, EVP_PKEY_CTX);
1151 ti->evp_decrypt_ctx = talloc_steal(ti, ti->evp_decrypt_ctx); /* Bind lifetime to instance */
1152 talloc_set_destructor(ti->evp_decrypt_ctx, _evp_pkey_ctx_free); /* Free ctx correctly on chunk free */
1153
1154 /*
1155 * Configure decrypt
1156 */
1157 if (unlikely(EVP_PKEY_decrypt_init(ti->evp_decrypt_ctx) <= 0)) {
1158 fr_tls_strerror_printf(NULL);
1159 PERROR("%s: Failed initialising decrypt EVP_PKEY_CTX", __FUNCTION__);
1160 return -1;
1161 }
1163 ERROR("%s: Failed setting padding for decrypt EVP_PKEY_CTX", __FUNCTION__);
1164 return -1;
1165 }
1166
1167 /*
1168 * Alloc sign
1169 */
1170 ti->evp_sign_ctx = EVP_PKEY_CTX_new(inst->rsa->private_key_file, NULL);
1171 if (!ti->evp_sign_ctx) {
1172 fr_tls_strerror_printf(NULL);
1173 PERROR("%s: Failed allocating sign EVP_PKEY_CTX", __FUNCTION__);
1174 return -1;
1175 }
1176 talloc_set_type(ti->evp_sign_ctx, EVP_PKEY_CTX);
1177 ti->evp_sign_ctx = talloc_steal(ti, ti->evp_sign_ctx); /* Bind lifetime to instance */
1178 talloc_set_destructor(ti->evp_sign_ctx, _evp_pkey_ctx_free); /* Free ctx correctly on chunk free */
1179
1180 /*
1181 * Configure sign
1182 */
1183 if (unlikely(EVP_PKEY_sign_init(ti->evp_sign_ctx) <= 0)) {
1184 fr_tls_strerror_printf(NULL);
1185 PERROR("%s: Failed initialising sign EVP_PKEY_CTX", __FUNCTION__);
1186 return -1;
1187 }
1188
1189 /*
1190 * OAEP not valid for signing or verification
1191 */
1192 if (inst->rsa->padding != RSA_PKCS1_OAEP_PADDING) {
1194 ERROR("%s: Failed setting padding for sign EVP_PKEY_CTX", __FUNCTION__);
1195 return -1;
1196 }
1197 }
1198
1199 if (unlikely(EVP_PKEY_CTX_set_signature_md(ti->evp_sign_ctx, inst->rsa->sig_digest)) <= 0) {
1200 fr_tls_strerror_printf(NULL);
1201 PERROR("%s: Failed setting signature digest type", __FUNCTION__);
1202 return -1;
1203 }
1204
1205 /*
1206 * Alloc digest ctx for signing and verification
1207 */
1208 ti->evp_md_ctx = EVP_MD_CTX_create();
1209 if (!ti->evp_md_ctx) {
1210 fr_tls_strerror_printf(NULL);
1211 PERROR("%s: Failed allocating EVP_MD_CTX", __FUNCTION__);
1212 return -1;
1213 }
1214 talloc_set_type(ti->evp_md_ctx, EVP_MD_CTX);
1215 ti->evp_md_ctx = talloc_steal(ti, ti->evp_md_ctx); /* Bind lifetime to instance */
1216 talloc_set_destructor(ti->evp_md_ctx, _evp_md_ctx_free); /* Free ctx correctly on chunk free */
1217 MEM(ti->digest_buff = talloc_array(ti, uint8_t, EVP_MD_size(inst->rsa->sig_digest)));
1218 }
1219
1220 return 0;
1221}
1222
1224{
1225 rlm_cipher_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_cipher_t);
1226
1227 switch (inst->type) {
1229 talloc_set_type(mctx->thread, rlm_cipher_rsa_thread_inst_t);
1230 return cipher_rsa_thread_instantiate(mctx);
1231
1234 fr_assert(0);
1235 }
1236
1237 return 0;
1238}
1239
1240/*
1241 * Do any per-module initialization that is separate to each
1242 * configured instance of the module. e.g. set up connections
1243 * to external databases, read configuration files, set up
1244 * dictionary entries, etc.
1245 */
1246static int mod_bootstrap(module_inst_ctx_t const *mctx)
1247{
1248 rlm_cipher_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_cipher_t);
1249 CONF_SECTION *conf = mctx->mi->conf;
1250
1251 switch (inst->type) {
1253 if (!inst->rsa) {
1254 cf_log_err(conf, "type = rsa, but no 'rsa { ... }' configuration section provided");
1255 return -1;
1256 }
1257
1258 if (!inst->rsa->private_key_file && !inst->rsa->certificate_file) {
1259 cf_log_err(conf, "type = rsa, but neither "
1260 "'private_key_file' nor 'certificate_file' configured");
1261 return -1;
1262 }
1263
1264 if (inst->rsa->private_key_file) {
1265 xlat_t *xlat;
1266
1267 /*
1268 * Register decrypt xlat
1269 */
1270 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "decrypt", cipher_rsa_decrypt_xlat, FR_TYPE_STRING);
1272
1273 /*
1274 * Verify sign xlat
1275 */
1276 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "verify", cipher_rsa_verify_xlat, FR_TYPE_BOOL);
1278 }
1279
1280 if (inst->rsa->certificate_file) {
1281 xlat_t *xlat;
1282
1283 /*
1284 * If we have both public and private keys check they're
1285 * part of the same keypair. This isn't technically a requirement
1286 * but it fixes some obscure errors where the user uses the serial
1287 * xlat, expecting it to be the serial of the keypair containing
1288 * the private key.
1289 */
1290 if (inst->rsa->private_key_file && inst->rsa->x509_certificate_file) {
1291 if (X509_check_private_key(inst->rsa->x509_certificate_file,
1292 inst->rsa->private_key_file) == 0) {
1293 fr_tls_strerror_printf(NULL);
1294 cf_log_perr(conf, "Private key does not match the certificate public key");
1295 return -1;
1296 }
1297 }
1298
1299 /*
1300 * Register encrypt xlat
1301 */
1302 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "encrypt", cipher_rsa_encrypt_xlat, FR_TYPE_OCTETS);
1304
1305 /*
1306 * Register sign xlat
1307 */
1310
1311 /*
1312 * FIXME: These should probably be split into separate xlats
1313 * so we can optimise for return types.
1314 */
1315 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "certificate", cipher_certificate_xlat, FR_TYPE_VOID);
1317 }
1318 break;
1319
1320 /*
1321 * Populated by cipher_type_parse() so if
1322 * the value is unrecognised we've got an issue.
1323 */
1324 default:
1325 fr_assert(0);
1326 return -1;
1327 }
1328
1329 return 0;
1330}
1331
1332/*
1333 * The module name should be the only globally exported symbol.
1334 * That is, everything else should be 'static'.
1335 *
1336 * If the module needs to temporarily modify it's instantiation
1337 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
1338 * The server will then take care of ensuring that the module
1339 * is single-threaded.
1340 */
1343 .common = {
1344 .magic = MODULE_MAGIC_INIT,
1345 .name = "cipher",
1346 .inst_size = sizeof(rlm_cipher_t),
1347 .thread_inst_size = sizeof(rlm_cipher_rsa_thread_inst_t),
1348 .config = module_config,
1349 .bootstrap = mod_bootstrap,
1350 .thread_instantiate = mod_thread_instantiate
1351 }
1352};
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:1707
#define CONF_PARSER_TERMINATOR
Definition cf_parse.h:669
cf_parse_t func
Override default parsing behaviour for the specified type with a custom parsing function.
Definition cf_parse.h:623
#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:606
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:287
#define cf_log_perr(_cf, _fmt,...)
Definition cf_util.h:294
#define cf_log_pwarn(_cf, _fmt,...)
Definition cf_util.h:295
#define cf_log_debug(_cf, _fmt,...)
Definition cf_util.h:290
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:36
#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:916
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:997
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:990
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:938
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:978
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:618
#define talloc_get_type_abort_const
Definition talloc.h:117
static size_t talloc_strlen(char const *s)
Returns the length of a talloc array containing a string.
Definition talloc.h:143
"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
#define fr_type_is_null(_x)
Definition types.h:347
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:4985
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:5018
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:4764
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:4797
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:5079
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:6604
@ 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