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