The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
rlm_cipher.c
Go to the documentation of this file.
1/*
2 * This program is 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: ff5d4647dcfeb590999405b439347149b5b0897b $
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: ff5d4647dcfeb590999405b439347149b5b0897b $")
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 /*
769 * Don't auto-cast to octets if the signature
770 * isn't already in that form.
771 * It could be hexits or base64 or some other encoding.
772 */
773 if (in_head->type != FR_TYPE_OCTETS) {
774 REDEBUG("Signature argument wrong type, expected %s, got %s. "
775 "Use %%base64.decode(<text>) or %%hex_decode(<text>) if signature is armoured",
777 fr_type_to_str(in_head->type));
778 return XLAT_ACTION_FAIL;
779 }
780 sig = in_head->vb_octets;
781 sig_len = in_head->vb_length;
782
783 /*
784 * Concat (...) args to get message data
785 */
786 args = fr_value_box_list_head(in);
790 SIZE_MAX) < 0) {
791 REDEBUG("Failed concatenating arguments to form plaintext");
792 return XLAT_ACTION_FAIL;
793 }
794 msg = args->vb_strvalue;
795 msg_len = args->vb_length;
796
797 if (msg_len == 0) {
798 REDEBUG("Zero length message data");
799 return XLAT_ACTION_FAIL;
800 }
801
802 /*
803 * First produce a digest of the message
804 */
805 if (unlikely(EVP_DigestInit_ex(t->evp_md_ctx, inst->rsa->sig_digest, NULL) <= 0)) {
806 fr_tls_log(request, "Failed initialising message digest");
807 return XLAT_ACTION_FAIL;
808 }
809
810 if (EVP_DigestUpdate(t->evp_md_ctx, msg, msg_len) <= 0) {
811 fr_tls_log(request, "Failed ingesting message");
812 return XLAT_ACTION_FAIL;
813 }
814
815 if (EVP_DigestFinal_ex(t->evp_md_ctx, t->digest_buff, &digest_len) <= 0) {
816 fr_tls_log(request, "Failed finalising message digest");
817 return XLAT_ACTION_FAIL;
818 }
819 fr_assert((size_t)digest_len == talloc_array_length(t->digest_buff));
820
821 /*
822 * Now check the signature matches what we expected
823 */
824 switch (EVP_PKEY_verify(t->evp_verify_ctx, sig, sig_len, t->digest_buff, (size_t)digest_len)) {
825 case 1: /* success (signature valid) */
826 MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, NULL));
827 vb->vb_bool = true;
829 break;
830
831 case 0: /* failure (signature not valid) */
832 MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_BOOL, NULL));
833 vb->vb_bool = false;
835 break;
836
837 default:
838 fr_tls_log(request, "Failed validating signature");
839 return XLAT_ACTION_FAIL;
840 }
841
842 return XLAT_ACTION_DONE;
843}
844
846 { .required = true, .concat = false, .single = true, .type = FR_TYPE_STRING },
847 { .required = false, .concat = false, .single = true, .type = FR_TYPE_STRING }, /* Optional hash for fingerprint mode */
849};
850
851/** Return the fingerprint of the public certificate
852 *
853 * Arguments are @verbatim(<digest>)@endverbatim
854 *
855@verbatim
856%<inst>.certificate(fingerprint, <digest>)
857@endverbatim
858 *
859 * @ingroup xlat_functions
860 */
862 xlat_ctx_t const *xctx,
863 request_t *request, fr_value_box_list_t *in)
864{
866 char const *md_name;
867 EVP_MD const *md;
868 size_t md_len;
869 fr_value_box_t *vb;
870 uint8_t *digest;
871
872 if (!fr_value_box_list_next(in, fr_value_box_list_head(in))) {
873 REDEBUG("Missing digest argument");
874 return XLAT_ACTION_FAIL;
875 }
876
877 /*
878 * Second arg...
879 */
880 md_name = ((fr_value_box_t *)fr_value_box_list_next(in, fr_value_box_list_head(in)))->vb_strvalue;
881 md = EVP_get_digestbyname(md_name);
882 if (!md) {
883 REDEBUG("Specified digest \"%s\" is not a valid digest type", md_name);
884 return XLAT_ACTION_FAIL;
885 }
886
887 md_len = EVP_MD_size(md);
888 MEM(vb = fr_value_box_alloc_null(ctx));
889 MEM(fr_value_box_mem_alloc(vb, &digest, vb, NULL, md_len, false) == 0);
890
891 if (X509_digest(inst->rsa->x509_certificate_file, md, digest, (unsigned int *)&md_len) != 1) {
892 fr_tls_log(request, "Failed calculating certificate fingerprint");
893 talloc_free(vb);
894 return XLAT_ACTION_FAIL;
895 }
896
898
899 return XLAT_ACTION_DONE;
900}
901
902/** Return the serial of the public certificate
903 *
904@verbatim
905%<inst>.certificate(serial)
906@endverbatim
907 *
908 * @ingroup xlat_functions
909 */
911 xlat_ctx_t const *xctx,
912 request_t *request, UNUSED fr_value_box_list_t *in)
913{
915 ASN1_INTEGER const *serial;
916 fr_value_box_t *vb;
917
918 serial = X509_get0_serialNumber(inst->rsa->x509_certificate_file);
919 if (!serial) {
920 fr_tls_log(request, "Failed retrieving certificate serial");
921 return XLAT_ACTION_FAIL;
922 }
923
924 MEM(vb = fr_value_box_alloc_null(ctx));
925 MEM(fr_value_box_memdup(vb, vb, NULL, serial->data, serial->length, true) == 0);
926
928
929 return XLAT_ACTION_DONE;
930}
931
933 xlat_ctx_t const *xctx,
934 request_t *request, fr_value_box_list_t *in)
935{
937 char const *attribute = fr_value_box_list_head(in)->vb_strvalue;
938 fr_value_box_t *vb;
939
941 default:
942 REDEBUG("Unknown certificate attribute \"%s\"", attribute);
943 return XLAT_ACTION_FAIL;
944
946 return cipher_fingerprint_xlat(ctx, out, xctx, request, in);
947
949 return cipher_serial_xlat(ctx, out, xctx, request, in);
950
952 MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_DATE, NULL));
953 vb->vb_date = inst->rsa->not_before;
954 vb->tainted = true;
956 return XLAT_ACTION_DONE;
957
959 MEM(vb = fr_value_box_alloc(ctx, FR_TYPE_DATE, NULL));
960 vb->vb_date = inst->rsa->not_after;
961 vb->tainted = true;
963 return XLAT_ACTION_DONE;
964 }
965}
966
967/** Talloc destructor for freeing an EVP_PKEY_CTX
968 *
969 * @param[in] evp_pkey_ctx to free.
970 * @return 0
971 */
972static int _evp_pkey_ctx_free(EVP_PKEY_CTX *evp_pkey_ctx)
973{
974 EVP_PKEY_CTX_free(evp_pkey_ctx);
975
976 return 0;
977}
978
979/** Talloc destructor for freeing an EVP_MD_CTX
980 *
981 * @param[in] evp_md_ctx to free.
982 * @return 0
983 */
984static int _evp_md_ctx_free(EVP_MD_CTX *evp_md_ctx)
985{
986 EVP_MD_CTX_destroy(evp_md_ctx);
987
988 return 0;
989}
990
991static int cipher_rsa_padding_params_set(EVP_PKEY_CTX *evp_pkey_ctx, cipher_rsa_t const *rsa_inst)
992{
993 if (unlikely(EVP_PKEY_CTX_set_rsa_padding(evp_pkey_ctx, rsa_inst->padding)) <= 0) {
994 fr_tls_strerror_printf(NULL);
995 PERROR("%s: Failed setting RSA padding type", __FUNCTION__);
996 return -1;
997 }
998
999 switch (rsa_inst->padding) {
1000 case RSA_NO_PADDING:
1001 case RSA_X931_PADDING:
1002 case RSA_PKCS1_PADDING:
1003 return 0;
1004
1005 /*
1006 * Configure OAEP advanced padding options
1007 */
1008 case RSA_PKCS1_OAEP_PADDING:
1009 if (unlikely(EVP_PKEY_CTX_set_rsa_oaep_md(evp_pkey_ctx, rsa_inst->oaep->oaep_digest) <= 0)) {
1010 fr_tls_strerror_printf(NULL);
1011 PERROR("%s: Failed setting OAEP digest", __FUNCTION__);
1012 return -1;
1013 }
1014
1015 if (unlikely(EVP_PKEY_CTX_set_rsa_mgf1_md(evp_pkey_ctx, rsa_inst->oaep->mgf1_digest) <= 0)) {
1016 fr_tls_strerror_printf(NULL);
1017 PERROR("%s: Failed setting MGF1 digest", __FUNCTION__);
1018 return -1;
1019 }
1020
1021 if (rsa_inst->oaep->label) {
1022 char *label;
1023 size_t label_len = talloc_strlen(rsa_inst->oaep->label);
1024
1025 /*
1026 * OpenSSL does not duplicate the label when
1027 * EVP_PKEY_CTX_set0_rsa_oaep_label is called,
1028 * but happily frees it on subsequent calls
1029 * or when the EVP_PKEY_CTX is freed,
1030 * idiots...
1031 */
1032 MEM(label = talloc_bstrndup(evp_pkey_ctx, rsa_inst->oaep->label, label_len));
1033 if (unlikely(EVP_PKEY_CTX_set0_rsa_oaep_label(evp_pkey_ctx, label, label_len) <= 0)) {
1034 fr_tls_strerror_printf(NULL);
1035 PERROR("%s: Failed setting OAEP padding label", __FUNCTION__);
1036 OPENSSL_free(label);
1037 return -1;
1038 }
1039 }
1040 return 0;
1041
1042 default:
1043 fr_assert(0);
1044 return -1;
1045 }
1046}
1047
1048/** Pre-initialises the EVP_PKEY_CTX necessary for performing RSA encryption/decryption/sign/verify
1049 *
1050 * If reference counting is used for EVP_PKEY structs, should also prevent any mutex contention
1051 * associated with incrementing/decrementing those references.
1052 *
1053 * xlat functions MUST NOT interleave PKEY operations with yields
1054 *
1055 * @return 0.
1056 */
1058{
1059 rlm_cipher_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_cipher_t);
1060 rlm_cipher_rsa_thread_inst_t *ti = talloc_get_type_abort(mctx->thread, rlm_cipher_rsa_thread_inst_t);
1061
1062 /*
1063 * Pre-allocate different contexts for the different operations
1064 * The OpenSSL docs say this is fine, and it reduces the potential
1065 * for SEGVs and other random errors due to trying to change the
1066 * configuration of a context multiple times.
1067 */
1068 if (inst->rsa->certificate_file) {
1069 /*
1070 * Alloc encrypt
1071 */
1072 ti->evp_encrypt_ctx = EVP_PKEY_CTX_new(inst->rsa->certificate_file, NULL);
1073 if (!ti->evp_encrypt_ctx) {
1074 fr_tls_strerror_printf(NULL);
1075 PERROR("%s: Failed allocating encrypt EVP_PKEY_CTX", __FUNCTION__);
1076 return -1;
1077 }
1078 talloc_set_type(ti->evp_encrypt_ctx, EVP_PKEY_CTX);
1079 ti->evp_encrypt_ctx = talloc_steal(ti, ti->evp_encrypt_ctx); /* Bind lifetime to instance */
1080 talloc_set_destructor(ti->evp_encrypt_ctx, _evp_pkey_ctx_free); /* Free ctx correctly on chunk free */
1081
1082 /*
1083 * Configure encrypt
1084 */
1085 if (unlikely(EVP_PKEY_encrypt_init(ti->evp_encrypt_ctx) <= 0)) {
1086 fr_tls_strerror_printf(NULL);
1087 PERROR("%s: Failed initialising encrypt EVP_PKEY_CTX", __FUNCTION__);
1088 return -1;
1089 }
1091 ERROR("%s: Failed setting padding for encrypt EVP_PKEY_CTX", __FUNCTION__);
1092 return -1;
1093 }
1094
1095 /*
1096 * Alloc verify
1097 */
1098 ti->evp_verify_ctx = EVP_PKEY_CTX_new(inst->rsa->certificate_file, NULL);
1099 if (!ti->evp_verify_ctx) {
1100 fr_tls_strerror_printf(NULL);
1101 PERROR("%s: Failed allocating verify EVP_PKEY_CTX", __FUNCTION__);
1102 return -1;
1103 }
1104 talloc_set_type(ti->evp_verify_ctx, EVP_PKEY_CTX);
1105 ti->evp_verify_ctx = talloc_steal(ti, ti->evp_verify_ctx); /* Bind lifetime to instance */
1106 talloc_set_destructor(ti->evp_verify_ctx, _evp_pkey_ctx_free); /* Free ctx correctly on chunk free */
1107
1108 /*
1109 * Configure verify
1110 */
1111 if (unlikely(EVP_PKEY_verify_init(ti->evp_verify_ctx) <= 0)) {
1112 fr_tls_strerror_printf(NULL);
1113 PERROR("%s: Failed initialising verify EVP_PKEY_CTX", __FUNCTION__);
1114 return -1;
1115 }
1116
1117 /*
1118 * OAEP not valid for signing or verification
1119 */
1120 if (inst->rsa->padding != RSA_PKCS1_OAEP_PADDING) {
1122 ERROR("%s: Failed setting padding for verify EVP_PKEY_CTX", __FUNCTION__);
1123 return -1;
1124 }
1125 }
1126
1127 if (unlikely(EVP_PKEY_CTX_set_signature_md(ti->evp_verify_ctx, inst->rsa->sig_digest)) <= 0) {
1128 fr_tls_strerror_printf(NULL);
1129 PERROR("%s: Failed setting signature digest type", __FUNCTION__);
1130 return -1;
1131 }
1132 }
1133
1134 if (inst->rsa->private_key_file) {
1135 /*
1136 * Alloc decrypt
1137 */
1138 ti->evp_decrypt_ctx = EVP_PKEY_CTX_new(inst->rsa->private_key_file, NULL);
1139 if (!ti->evp_decrypt_ctx) {
1140 fr_tls_strerror_printf(NULL);
1141 PERROR("%s: Failed allocating decrypt EVP_PKEY_CTX", __FUNCTION__);
1142 return -1;
1143 }
1144 talloc_set_type(ti->evp_decrypt_ctx, EVP_PKEY_CTX);
1145 ti->evp_decrypt_ctx = talloc_steal(ti, ti->evp_decrypt_ctx); /* Bind lifetime to instance */
1146 talloc_set_destructor(ti->evp_decrypt_ctx, _evp_pkey_ctx_free); /* Free ctx correctly on chunk free */
1147
1148 /*
1149 * Configure decrypt
1150 */
1151 if (unlikely(EVP_PKEY_decrypt_init(ti->evp_decrypt_ctx) <= 0)) {
1152 fr_tls_strerror_printf(NULL);
1153 PERROR("%s: Failed initialising decrypt EVP_PKEY_CTX", __FUNCTION__);
1154 return -1;
1155 }
1157 ERROR("%s: Failed setting padding for decrypt EVP_PKEY_CTX", __FUNCTION__);
1158 return -1;
1159 }
1160
1161 /*
1162 * Alloc sign
1163 */
1164 ti->evp_sign_ctx = EVP_PKEY_CTX_new(inst->rsa->private_key_file, NULL);
1165 if (!ti->evp_sign_ctx) {
1166 fr_tls_strerror_printf(NULL);
1167 PERROR("%s: Failed allocating sign EVP_PKEY_CTX", __FUNCTION__);
1168 return -1;
1169 }
1170 talloc_set_type(ti->evp_sign_ctx, EVP_PKEY_CTX);
1171 ti->evp_sign_ctx = talloc_steal(ti, ti->evp_sign_ctx); /* Bind lifetime to instance */
1172 talloc_set_destructor(ti->evp_sign_ctx, _evp_pkey_ctx_free); /* Free ctx correctly on chunk free */
1173
1174 /*
1175 * Configure sign
1176 */
1177 if (unlikely(EVP_PKEY_sign_init(ti->evp_sign_ctx) <= 0)) {
1178 fr_tls_strerror_printf(NULL);
1179 PERROR("%s: Failed initialising sign EVP_PKEY_CTX", __FUNCTION__);
1180 return -1;
1181 }
1182
1183 /*
1184 * OAEP not valid for signing or verification
1185 */
1186 if (inst->rsa->padding != RSA_PKCS1_OAEP_PADDING) {
1188 ERROR("%s: Failed setting padding for sign EVP_PKEY_CTX", __FUNCTION__);
1189 return -1;
1190 }
1191 }
1192
1193 if (unlikely(EVP_PKEY_CTX_set_signature_md(ti->evp_sign_ctx, inst->rsa->sig_digest)) <= 0) {
1194 fr_tls_strerror_printf(NULL);
1195 PERROR("%s: Failed setting signature digest type", __FUNCTION__);
1196 return -1;
1197 }
1198
1199 /*
1200 * Alloc digest ctx for signing and verification
1201 */
1202 ti->evp_md_ctx = EVP_MD_CTX_create();
1203 if (!ti->evp_md_ctx) {
1204 fr_tls_strerror_printf(NULL);
1205 PERROR("%s: Failed allocating EVP_MD_CTX", __FUNCTION__);
1206 return -1;
1207 }
1208 talloc_set_type(ti->evp_md_ctx, EVP_MD_CTX);
1209 ti->evp_md_ctx = talloc_steal(ti, ti->evp_md_ctx); /* Bind lifetime to instance */
1210 talloc_set_destructor(ti->evp_md_ctx, _evp_md_ctx_free); /* Free ctx correctly on chunk free */
1211 MEM(ti->digest_buff = talloc_array(ti, uint8_t, EVP_MD_size(inst->rsa->sig_digest)));
1212 }
1213
1214 return 0;
1215}
1216
1218{
1219 rlm_cipher_t *inst = talloc_get_type_abort(mctx->mi->data, rlm_cipher_t);
1220
1221 switch (inst->type) {
1223 talloc_set_type(mctx->thread, rlm_cipher_rsa_thread_inst_t);
1224 return cipher_rsa_thread_instantiate(mctx);
1225
1228 fr_assert(0);
1229 }
1230
1231 return 0;
1232}
1233
1234/*
1235 * Do any per-module initialization that is separate to each
1236 * configured instance of the module. e.g. set up connections
1237 * to external databases, read configuration files, set up
1238 * dictionary entries, etc.
1239 */
1240static int mod_bootstrap(module_inst_ctx_t const *mctx)
1241{
1242 rlm_cipher_t const *inst = talloc_get_type_abort(mctx->mi->data, rlm_cipher_t);
1243 CONF_SECTION *conf = mctx->mi->conf;
1244
1245 switch (inst->type) {
1247 if (!inst->rsa) {
1248 cf_log_err(conf, "type = rsa, but no 'rsa { ... }' configuration section provided");
1249 return -1;
1250 }
1251
1252 if (!inst->rsa->private_key_file && !inst->rsa->certificate_file) {
1253 cf_log_err(conf, "type = rsa, but neither "
1254 "'private_key_file' nor 'certificate_file' configured");
1255 return -1;
1256 }
1257
1258 if (inst->rsa->private_key_file) {
1259 xlat_t *xlat;
1260
1261 /*
1262 * Register decrypt xlat
1263 */
1264 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "decrypt", cipher_rsa_decrypt_xlat, FR_TYPE_STRING);
1266
1267 /*
1268 * Verify sign xlat
1269 */
1270 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "verify", cipher_rsa_verify_xlat, FR_TYPE_BOOL);
1272 }
1273
1274 if (inst->rsa->certificate_file) {
1275 xlat_t *xlat;
1276
1277 /*
1278 * If we have both public and private keys check they're
1279 * part of the same keypair. This isn't technically a requirement
1280 * but it fixes some obscure errors where the user uses the serial
1281 * xlat, expecting it to be the serial of the keypair containing
1282 * the private key.
1283 */
1284 if (inst->rsa->private_key_file && inst->rsa->x509_certificate_file) {
1285 if (X509_check_private_key(inst->rsa->x509_certificate_file,
1286 inst->rsa->private_key_file) == 0) {
1287 fr_tls_strerror_printf(NULL);
1288 cf_log_perr(conf, "Private key does not match the certificate public key");
1289 return -1;
1290 }
1291 }
1292
1293 /*
1294 * Register encrypt xlat
1295 */
1296 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "encrypt", cipher_rsa_encrypt_xlat, FR_TYPE_OCTETS);
1298
1299 /*
1300 * Register sign xlat
1301 */
1304
1305 /*
1306 * FIXME: These should probably be split into separate xlats
1307 * so we can optimise for return types.
1308 */
1309 xlat = module_rlm_xlat_register(mctx->mi->boot, mctx, "certificate", cipher_certificate_xlat, FR_TYPE_VOID);
1311 }
1312 break;
1313
1314 /*
1315 * Populated by cipher_type_parse() so if
1316 * the value is unrecognised we've got an issue.
1317 */
1318 default:
1319 fr_assert(0);
1320 return -1;
1321 }
1322
1323 return 0;
1324}
1325
1326/*
1327 * The module name should be the only globally exported symbol.
1328 * That is, everything else should be 'static'.
1329 *
1330 * If the module needs to temporarily modify it's instantiation
1331 * data, the type should be changed to MODULE_TYPE_THREAD_UNSAFE.
1332 * The server will then take care of ensuring that the module
1333 * is single-threaded.
1334 */
1337 .common = {
1338 .magic = MODULE_MAGIC_INIT,
1339 .name = "cipher",
1340 .inst_size = sizeof(rlm_cipher_t),
1341 .thread_inst_size = sizeof(rlm_cipher_rsa_thread_inst_t),
1342 .config = module_config,
1343 .bootstrap = mod_bootstrap,
1344 .thread_instantiate = mod_thread_instantiate
1345 }
1346};
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:506
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:228
#define unlikely(_x)
Definition build.h:402
#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:1635
#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:663
char const * cf_pair_value(CONF_PAIR const *pair)
Return the value of a CONF_PAIR.
Definition cf_util.c:1574
#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:910
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:861
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:247
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:991
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:984
module_rlm_t rlm_cipher
static xlat_arg_parser_t const cipher_certificate_xlat_args[]
Definition rlm_cipher.c:845
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:932
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:972
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:6585
@ 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