OpenVPN
test_ssl.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2023-2026 OpenVPN Inc <sales@openvpn.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "syshead.h"
28
29#include <stdio.h>
30#include <stdlib.h>
31#include <stdarg.h>
32#include <string.h>
33#include <setjmp.h>
34#include <cmocka.h>
35
36#include "crypto.h"
37#include "crypto_epoch.h"
38#include "options.h"
39#include "ssl_backend.h"
40#include "options_util.h"
41
42#include "mock_msg.h"
43#include "mss.h"
44#include "ssl_verify_backend.h"
45#include "win32.h"
46#include "test_common.h"
47#include "ssl.h"
48#include "buffer.h"
49#include "cert_data.h"
50#include "packet_id.h"
51#include "ssl_verify.h"
52
53/* Mock function to be allowed to include win32.c which is required for
54 * getting the temp directory */
55#ifdef _WIN32
56struct signal_info siginfo_static; /* GLOBAL */
57
58const char *
59strerror_win32(DWORD errnum, struct gc_arena *gc)
60{
61 ASSERT(false);
62}
63
64void
65throw_signal(const int signum)
66{
67 ASSERT(false);
68}
69#endif
70
71#if defined(ENABLE_CRYPTO_OPENSSL) && (OPENSSL_VERSION_NUMBER > 0x30000000L)
72#define HAVE_OPENSSL_STORE
73#endif
74
75/* stubs for some unused functions instead of pulling in too many dependencies */
76bool
77get_user_pass_cr(struct user_pass *up, const char *auth_file, const char *prefix,
78 const unsigned int flags, const char *auth_challenge)
79{
80 return false;
81}
82void
83purge_user_pass(struct user_pass *up, bool force)
84{
85 return;
86}
87
88/* generated using
89 * openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:secp384r1 -keyout - \
90 * -noenc -sha256 -days 3650 -subj '/CN=ovpn-test-secp384r1' -nodes \
91 * -addext 'subjectAltName=DNS:unittest.example.com' \
92 * -addext 'extendedKeyUsage=clientAuth'
93 */
94static const char *const unittest_cert =
95 "-----BEGIN CERTIFICATE-----\n"
96 "MIICBjCCAYygAwIBAgIUFoXgpP4beykV7tpgrjHQTWPGi4cwCgYIKoZIzj0EAwIw\n"
97 "HjEcMBoGA1UEAwwTb3Zwbi10ZXN0LXNlY3AzODRyMTAeFw0yNTA5MDgxMzExNTBa\n"
98 "Fw0zNTA5MDYxMzExNTBaMB4xHDAaBgNVBAMME292cG4tdGVzdC1zZWNwMzg0cjEw\n"
99 "djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQVDmf+TZB3rW6zqWFox606u/PhA93ysX/h\n"
100 "1s2xyq9+QGzIdE/hks6p/Yzyu7RLOUjxvO0J45RHcYmo67DlvSOi496T3zrgvp1H\n"
101 "KfHD5ohMyvzw0+e8lmjJqJjn+PegMkOjgYowgYcwHQYDVR0OBBYEFCH1eYnaV8fh\n"
102 "E3Bv7lyrlYu24eoVMB8GA1UdIwQYMBaAFCH1eYnaV8fhE3Bv7lyrlYu24eoVMA8G\n"
103 "A1UdEwEB/wQFMAMBAf8wHwYDVR0RBBgwFoIUdW5pdHRlc3QuZXhhbXBsZS5jb20w\n"
104 "EwYDVR0lBAwwCgYIKwYBBQUHAwIwCgYIKoZIzj0EAwIDaAAwZQIxAL7q7jcwTOuq\n"
105 "5sp0Beq81Vnznd3gsDZYNs1OYRWH33xergDVKlBb6kCwus0dhghtVAIwIgT4ytkY\n"
106 "oAPx8LB3oP8ubEu1ue6V9jZln/cCiLyXDDtaiJOZHtDqHGfHqvc6rAok\n"
107 "-----END CERTIFICATE-----\n";
108
109static const char *const unittest_key =
110 "-----BEGIN PRIVATE KEY-----\n"
111 "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDAXBC7tpa9UepoMVZlM\n"
112 "OxUubkECGK7aWFebxDc3UPoEQemEPMOCdkWBSU/t7Mm4R66hZANiAAQVDmf+TZB3\n"
113 "rW6zqWFox606u/PhA93ysX/h1s2xyq9+QGzIdE/hks6p/Yzyu7RLOUjxvO0J45RH\n"
114 "cYmo67DlvSOi496T3zrgvp1HKfHD5ohMyvzw0+e8lmjJqJjn+PegMkM=\n"
115 "-----END PRIVATE KEY-----\n";
116
117
118static const char *
120{
121 const char *ret;
122#ifdef _WIN32
123 ret = win_get_tempdir();
124#else
125 ret = "/tmp";
126#endif
127 assert_non_null(ret);
128 return ret;
129}
130
131static struct
132{
133 struct gc_arena gc;
134 const char *certfile;
135 const char *keyfile;
137
138static int
139init(void **state)
140{
141 (void)state;
142 global_state.gc = gc_new();
145
146 int certfd = open(global_state.certfile, O_RDWR);
147 int keyfd = open(global_state.keyfile, O_RDWR);
148 if (certfd < 0 || keyfd < 0)
149 {
150 fail_msg("make tmpfile for certificate or key data failed (error = %d)", errno);
151 }
152 /* Awkward casts required for MinGW with -O0 only */
153 assert_int_equal(write(certfd, unittest_cert, (unsigned int)strlen(unittest_cert)),
154 strlen(unittest_cert));
155 assert_int_equal(write(keyfd, unittest_key, (unsigned int)strlen(unittest_key)),
156 strlen(unittest_key));
157 close(certfd);
158 close(keyfd);
159 return 0;
160}
161
162static int
163cleanup(void **state)
164{
165 (void)state;
166 unlink(global_state.certfile);
167 unlink(global_state.keyfile);
169 return 0;
170}
171
172static void
174{
175 struct gc_arena gc = gc_new();
176
177 struct tls_root_ctx ctx = { 0 };
180
181 openvpn_x509_cert_t *cert = NULL;
182
183 /* we do not have methods to fetch certificates from ssl contexts, use
184 * internal TLS library methods for the unit test */
185#ifdef ENABLE_CRYPTO_OPENSSL
186 cert = SSL_CTX_get0_certificate(ctx.ctx);
187#elif defined(ENABLE_CRYPTO_MBEDTLS)
188 cert = ctx.crt_chain;
189#endif
190
191 const char *tmpfile = platform_create_temp_file(get_tmp_dir(), "ut_pem", &gc);
192 backend_x509_write_pem(cert, tmpfile);
193
196
197 tls_ctx_free(&ctx);
199 gc_free(&gc);
200}
201
202static void
204{
205 (void)state;
206 struct tls_root_ctx ctx = { 0 };
207
208 /* test loading of inlined cert and key.
209 * loading the key also checks that it matches the loaded certificate
210 */
213 assert_int_equal(tls_ctx_load_priv_file(&ctx, unittest_key, true), 0);
215
216 /* test loading of cert and key from file */
218 tls_ctx_load_cert_file(&ctx, global_state.certfile, false);
219 assert_int_equal(tls_ctx_load_priv_file(&ctx, global_state.keyfile, false), 0);
221}
222
223/* test loading cert and key using file:/path URI */
224static void
226{
227 (void)state;
228
229#if !defined(HAVE_OPENSSL_STORE)
230 skip();
231#else /* HAVE_OPENSSL_STORE */
232
233 struct tls_root_ctx ctx = { 0 };
234 const char *certfile = global_state.certfile;
235 const char *keyfile = global_state.keyfile;
236 struct gc_arena *gc = &global_state.gc;
237
238 struct buffer certuri = alloc_buf_gc(6 + strlen(certfile) + 1, gc); /* 6 bytes for "file:/" */
239 struct buffer keyuri = alloc_buf_gc(6 + strlen(keyfile) + 1, gc); /* 6 bytes for "file:/" */
240
241 /* Windows temp file path starts with drive letter -- add a leading slash for URI */
242 const char *lead = "";
243#ifdef _WIN32
244 lead = "/";
245#endif /* _WIN32 */
246 assert_true(buf_printf(&certuri, "file:%s%s", lead, certfile));
247 assert_true(buf_printf(&keyuri, "file:%s%s", lead, keyfile));
248
249 /* On Windows replace any '\' in path by '/' required for URI */
250#ifdef _WIN32
253#endif /* _WIN32 */
254
255 tls_ctx_client_new(&ctx);
256 tls_ctx_load_cert_file(&ctx, BSTR(&certuri), false);
258 tls_ctx_free(&ctx);
259#endif /* HAVE_OPENSSL_STORE */
260}
261
262
263static void
265{
266 int overhead = 0;
267
268 /* tls-auth and tls-crypt */
269 overhead += 128;
270
271 /* TCP length field and opcode */
272 overhead += 3;
273
274 /* ACK array and remote SESSION ID (part of the ACK array) */
276
277 /* Previous OpenVPN version calculated the maximum size and buffer of a
278 * control frame depending on the overhead of the data channel frame
279 * overhead and limited its maximum size to 1250. Since control frames
280 * also need to fit into data channel buffer we have the same
281 * default of 1500 + 100 as data channel buffers have. Increasing
282 * control channel mtu beyond this limit also increases the data channel
283 * buffers */
284 int tls_mtu = 1500;
285 frame->buf.payload_size = tls_mtu + 100;
286
289
290 frame->tun_mtu = tls_mtu;
291}
292
293static void
295{
296 struct gc_arena gc = gc_new();
297
298 /* initialise frame for the test */
299 struct frame frame;
301
303 struct buffer work = alloc_buf_gc(BUF_SIZE(&frame), &gc);
306 struct buffer buf = clear_buf();
307 void *buf_p;
308
309 /* init work */
311
312 update_time();
313
314 /* Test encryption, decryption for all packet sizes */
315 for (int i = 1; i <= frame.buf.payload_size; ++i)
316 {
317 /* msg(M_INFO, "TESTING ENCRYPT/DECRYPT of packet length=%d", i); */
318
319 /*
320 * Load src with random data.
321 */
322 ASSERT(buf_init(&src, 0));
323 ASSERT(i <= src.capacity);
324 src.len = i;
326
327 /* copy source to input buf */
328 buf = work;
329 buf_p = buf_write_alloc(&buf, BLENZ(&src));
330 ASSERT(buf_p);
331 memcpy(buf_p, BPTR(&src), BLENZ(&src));
332
333 /* initialize work buffer with buf.headroom bytes of prepend capacity */
335
336 /* encrypt */
338
339 /* decrypt */
340 openvpn_decrypt(&buf, decrypt_workspace, co, &frame, BPTR(&buf));
341
342 /* compare */
343 assert_int_equal(buf.len, src.len);
344 assert_memory_equal(BPTR(&src), BPTR(&buf), i);
345 }
346 gc_free(&gc);
347}
348
349static void
351{
352 struct frame frame;
354
355 struct gc_arena gc = gc_new();
358 struct buffer work = alloc_buf_gc(BUF_SIZE(&frame), &gc);
359 struct buffer buf = clear_buf();
361 void *buf_p;
362
364
365 /*
366 * Load src with random data.
367 */
368 ASSERT(buf_init(&src, 0));
369 ASSERT(len <= src.capacity);
370 src.len = len;
372
373 /* copy source to input buf */
374 buf = work;
375 buf_p = buf_write_alloc(&buf, BLENZ(&src));
376 ASSERT(buf_p);
377 memcpy(buf_p, BPTR(&src), BLENZ(&src));
378
381
382 /* decrypt */
383 openvpn_decrypt(&buf, decrypt_workspace, co, &frame, BPTR(&buf));
384
385 /* compare */
386 assert_int_equal(buf.len, src.len);
388
389 gc_free(&gc);
390}
391
392
393static void
395{
396 /* Check that we correctly react when we have a nearing AEAD limits */
397
398 /* manually increase the send counter to be past
399 * the GCM usage limit */
400 co->key_ctx_bi.encrypt.plaintext_blocks = 0x1ull << 40;
401
402
403 bool epoch = (co->flags & CO_EPOCH_DATA_KEY_FORMAT);
404
405 int expected_epoch = epoch ? 4 : 0;
406
407 /* Ensure that we are still on the initial key (our init_crypto_options
408 * unit test method iterates the initial key to 4) or that it is 0 when
409 * epoch is not in use
410 */
412
413 encrypt_one_packet(co, 1000);
414
415 /* either epoch key has been updated or warning is enabled */
416 if (epoch && !chachapoly)
417 {
419 }
420
422
423 if (!epoch)
424 {
425 /* Check always against the GCM usage limit here to see if that
426 * check works */
429 return;
430 }
431
432 /* Move to the end of the epoch data key send PID range, ChachaPoly
433 * should now also move to a new epoch data key */
435
436 encrypt_one_packet(co, 1000);
437 encrypt_one_packet(co, 1000);
438
441}
442
443
444static struct crypto_options
445init_crypto_options(const char *cipher, const char *auth, bool epoch, struct key2 *statickey)
446{
447 struct key2 key2 = { .n = 2 };
448
449 if (statickey)
450 {
451 /* Use chosen static key instead of random key when defined */
452 key2 = *statickey;
453 }
454 else
455 {
456 ASSERT(rand_bytes(key2.keys[0].cipher, sizeof(key2.keys[0].cipher)));
457 ASSERT(rand_bytes(key2.keys[0].hmac, sizeof(key2.keys[0].hmac)));
458 ASSERT(rand_bytes(key2.keys[1].cipher, sizeof(key2.keys[1].cipher)));
459 ASSERT(rand_bytes(key2.keys[1].hmac, sizeof(key2.keys)[1].hmac));
460 }
461
462 struct crypto_options co = { 0 };
463
464 struct key_type kt = create_kt(cipher, auth, "ssl-test");
465
466 if (epoch)
467 {
468 struct epoch_key e1 = { .epoch = 1, .epoch_key = { 0 } };
469 memcpy(e1.epoch_key, key2.keys[0].cipher, sizeof(e1.epoch_key));
471 epoch_init_key_ctx(&co, &kt, &e1, &e1, 5);
472
473 /* Do a little of dancing for the epoch_send_key_iterate to test
474 * that this works too */
478 }
479 else
480 {
481 init_key_ctx_bi(&co.key_ctx_bi, &key2, KEY_DIRECTION_BIDIRECTIONAL, &kt, "unit-test-ssl");
482 }
483 packet_id_init(&co.packet_id, 5, 5, "UNITTEST", 0);
484 return co;
485}
486
487static void
494
495/* This adds a few more methods than strictly necessary but this allows
496 * us to see which exact test was run from the backtrace of the test
497 * when it fails */
498static void
500{
501 bool ischacha = !strcmp(cipher, "ChaCha20-Poly1305");
502
503 struct crypto_options co = init_crypto_options(cipher, "none", true, NULL);
505 check_aead_limits(&co, ischacha);
507}
508
509static void
510run_data_channel_with_cipher(const char *cipher, const char *auth)
511{
512 bool ischacha = !strcmp(cipher, "ChaCha20-Poly1305");
513 struct crypto_options co = init_crypto_options(cipher, auth, false, NULL);
515 check_aead_limits(&co, ischacha);
517}
518
519
520static void
522{
523 run_data_channel_with_cipher("AES-128-GCM", "none");
524}
525
526static void
531
532static void
534{
535 run_data_channel_with_cipher("AES-192-GCM", "none");
536}
537
538static void
543
544static void
546{
547 run_data_channel_with_cipher("AES-256-GCM", "none");
548}
549
550static void
555
556static void
558{
559 run_data_channel_with_cipher("AES-128-CBC", "SHA256");
560}
561
562static void
564{
565 run_data_channel_with_cipher("AES-192-CBC", "SHA256");
566}
567
568static void
570{
571 run_data_channel_with_cipher("AES-256-CBC", "SHA256");
572}
573
574static void
576{
577 if (!cipher_valid("ChaCha20-Poly1305"))
578 {
579 skip();
580 return;
581 }
582
583 run_data_channel_with_cipher("ChaCha20-Poly1305", "none");
584}
585
586static void
588{
589 if (!cipher_valid("ChaCha20-Poly1305"))
590 {
591 skip();
592 return;
593 }
594
595 run_data_channel_with_cipher_epoch("ChaCha20-Poly1305");
596}
597
598static void
600{
601 if (!cipher_valid("BF-CBC"))
602 {
603 skip();
604 return;
605 }
606 run_data_channel_with_cipher("BF-CBC", "SHA1");
607}
608
609
610static struct key2
612{
613 struct key2 key2 = { .n = 2 };
614
615 const uint8_t key[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '0', '1', '2',
616 '3', '4', '5', '6', '7', 'A', 'B', 'C', 'D', 'E', 'F',
617 'G', 'H', 'j', 'k', 'u', 'c', 'h', 'e', 'n', 'l' };
618
619 static_assert(sizeof(key) == 32, "Size of key should be 32 bytes");
620
621 /* copy the key a few times to ensure to have the size we need for
622 * Statickey but XOR it to not repeat it */
623 uint8_t keydata[sizeof(key2.keys)];
624
625 for (size_t i = 0; i < sizeof(key2.keys); i++)
626 {
627 keydata[i] = (uint8_t)(key[i % sizeof(key)] ^ i);
628 }
629
630 ASSERT(memcpy(key2.keys[0].cipher, keydata, sizeof(key2.keys[0].cipher)));
631 ASSERT(memcpy(key2.keys[0].hmac, keydata + 64, sizeof(key2.keys[0].hmac)));
632 ASSERT(memcpy(key2.keys[1].cipher, keydata + 128, sizeof(key2.keys[1].cipher)));
633 ASSERT(memcpy(key2.keys[1].hmac, keydata + 192, sizeof(key2.keys)[1].hmac));
634
635 return key2;
636}
637
638static void
640{
641 struct key2 key2 = create_key();
642
643 struct crypto_options co = init_crypto_options("AES-256-GCM", "none", epoch, &key2);
644
645 struct gc_arena gc = gc_new();
646
647 /* initialise frame for the test */
648 struct frame frame;
650
652 struct buffer work = alloc_buf_gc(BUF_SIZE(&frame), &gc);
655 struct buffer buf = clear_buf();
656 void *buf_p;
657
658 /* init work */
660
661 now = 0;
662
663 /*
664 * Load src with known data.
665 */
666 ASSERT(buf_init(&src, 0));
667 const char *plaintext = "The quick little fox jumps over the bureaucratic hurdles";
668
670
671 /* copy source to input buf */
672 buf = work;
673 buf_p = buf_write_alloc(&buf, BLENZ(&src));
674 ASSERT(buf_p);
675 memcpy(buf_p, BPTR(&src), BLENZ(&src));
676
677 /* initialize work buffer with buf.headroom bytes of prepend capacity */
679
680 /* add packet opcode and peer id */
685
686 /* encrypt */
688
689 /* separate buffer in authenticated data and encrypted data */
690 uint8_t *ad_start = BPTR(&buf);
691 buf_advance(&buf, 4);
692
693 if (epoch)
694 {
695 uint8_t packetid1[8] = { 0, 0x04, 0, 0, 0, 0, 0, 1 };
697 }
698 else
699 {
700 uint8_t packetid1[4] = { 0, 0, 0, 1 };
702 }
703
704 if (epoch)
705 {
707 const uint8_t exp_tag_epoch[16] = { 0x0f, 0xff, 0xf5, 0x91, 0x3d, 0x39, 0xd7, 0x5b,
708 0x18, 0x57, 0x3b, 0x57, 0x48, 0x58, 0x9a, 0x7d };
709
711 }
712 else
713 {
714 uint8_t *tag_location = BPTR(&buf) + 4;
715 const uint8_t exp_tag_noepoch[16] = { 0x1f, 0xdd, 0x90, 0x8f, 0x0e, 0x9d, 0xc2, 0x5e,
716 0x79, 0xd8, 0x32, 0x02, 0x0d, 0x58, 0xe7, 0x3f };
718 }
719
720 /* Check some bytes at the beginning of the encrypted part */
721 if (epoch)
722 {
723 const uint8_t bytesat14[6] = { 0x36, 0xaa, 0xb4, 0xd4, 0x9c, 0xe6 };
724 assert_memory_equal(BPTR(&buf) + 14, bytesat14, sizeof(bytesat14));
725 }
726 else
727 {
728 const uint8_t bytesat30[6] = { 0xa8, 0x2e, 0x6b, 0x17, 0x06, 0xd9 };
729 assert_memory_equal(BPTR(&buf) + 30, bytesat30, sizeof(bytesat30));
730 }
731
732 /* decrypt */
734
735 /* compare */
738
740 gc_free(&gc);
741}
742
743static void
748
749static void
754
755#if defined(ENABLE_CRYPTO_MBEDTLS)
756static openvpn_x509_cert_t *
757get_certificate(const char *cert_str)
758{
759 mbedtls_x509_crt *cert;
761 int ret = mbedtls_x509_crt_parse(cert, (const unsigned char *)cert_str,
762 strlen(cert_str) + 1);
763
765 return cert;
766}
767
768static void
770{
772 free(cert);
773}
774#else
775static openvpn_x509_cert_t *
777{
778 BIO *in = BIO_new_mem_buf((char *)cert1, -1);
779 assert_non_null(in);
780 X509 *cert = PEM_read_bio_X509(in, NULL, NULL, NULL);
781 assert_non_null(cert);
782 BIO_free(in);
783 return cert;
784}
785
786static void
791#endif
792
793void
795{
797 struct gc_arena gc = gc_new();
798
799 const char *fp = backend_x509_get_serial_hex(cert, &gc);
800
801 /* we messed this up between TLS libraries. But let's at least notice in
802 * the future ...*/
803#if defined(ENABLE_CRYPTO_MBEDTLS)
804 assert_string_equal(fp, "82:6B:DD:CC:BD:E5:5E:B7:08:F1:2D:68:00:3C:24:DE");
805#else
806 assert_string_equal(fp, "82:6b:dd:cc:bd:e5:5e:b7:08:f1:2d:68:00:3c:24:de");
807#endif
808
809 const char *sn = backend_x509_get_serial(cert, &gc);
810 assert_string_equal(sn, "173359713849739808110610111821055272158");
811
812 char username[TLS_USERNAME_LEN + 1] = { 0 }; /* null-terminated */
813
814 int ret = backend_x509_get_username(username, sizeof(username), "CN",
815 cert);
816
817 assert_string_equal(username, "ovpn-test-ec1");
818 assert_int_equal(ret, SUCCESS);
819
820#ifndef ENABLE_CRYPTO_MBEDTLS
821 /* mbed TLS does not implement this */
822 ret = backend_x509_get_username(username, sizeof(username), "serialNumber",
823 cert);
824 assert_int_equal(ret, SUCCESS);
825 assert_string_equal(username, "0x826BDDCCBDE55EB708F12D68003C24DE");
826#endif
827
828 gc_free(&gc);
829 free_certificate(cert);
830}
831
832
833int
834main(void)
835{
837
838 const struct CMUnitTest tests[] = {
839 cmocka_unit_test(crypto_pem_encode_certificate),
840 cmocka_unit_test(test_load_certificate_and_key),
841 cmocka_unit_test(test_load_certificate_and_key_uri),
853 cmocka_unit_test(test_data_channel_roundtrip_bf_cbc),
856 cmocka_unit_test(crypto_test_print_cert_details)
857
858 };
859
860#if defined(ENABLE_CRYPTO_OPENSSL)
861 tls_init_lib();
862#endif
863
864 int ret = cmocka_run_group_tests_name("ssl tests", tests, init, cleanup);
865
866#if defined(ENABLE_CRYPTO_OPENSSL)
867 tls_free_lib();
868#endif
869
870 return ret;
871}
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:241
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:89
bool string_mod(char *str, const unsigned int inclusive, const unsigned int exclusive, const char replace)
Modifies a string in place by replacing certain classes of characters of it with a specified characte...
Definition buffer.c:1054
struct buffer buffer_read_from_file(const char *filename, struct gc_arena *gc)
buffer_read_from_file - copy the content of a file into a buffer
Definition buffer.c:1373
#define BEND(buf)
Definition buffer.h:124
#define BSTR(buf)
Definition buffer.h:129
static struct buffer clear_buf(void)
Return an empty struct buffer.
Definition buffer.h:223
#define CC_ANY
any character
Definition buffer.h:878
#define BPTR(buf)
Definition buffer.h:123
static uint8_t * buf_write_alloc(struct buffer *buf, size_t size)
Definition buffer.h:634
static bool buf_advance(struct buffer *buf, ssize_t size)
Definition buffer.h:617
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition buffer.h:661
#define CC_BACKSLASH
backslash
Definition buffer.h:895
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Definition buffer.h:685
#define BLEN(buf)
Definition buffer.h:126
#define BLENZ(buf)
Definition buffer.h:127
static void gc_free(struct gc_arena *a)
Definition buffer.h:1049
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition buffer.h:1088
#define buf_init(buf, offset)
Definition buffer.h:210
static struct gc_arena gc_new(void)
Definition buffer.h:1041
static const char *const cert1
Definition cert_data.h:38
void free_key_ctx_bi(struct key_ctx_bi *ctx)
Definition crypto.c:1100
void init_key_ctx_bi(struct key_ctx_bi *ctx, const struct key2 *key2, int key_direction, const struct key_type *kt, const char *name)
Definition crypto.c:1062
Data Channel Cryptography Module.
#define CO_EPOCH_DATA_KEY_FORMAT
Bit-flag indicating the epoch the data format.
Definition crypto.h:379
#define KEY_DIRECTION_BIDIRECTIONAL
Definition crypto.h:231
static bool aead_usage_limit_reached(const uint64_t limit, const struct key_ctx *key_ctx, int64_t higest_pid)
Checks if the usage limit for an AEAD cipher is reached.
Definition crypto.h:760
static struct key_type create_kt(const char *cipher, const char *md, const char *optname)
Creates and validates an instance of struct key_type with the provided algs.
Definition crypto.h:681
static bool cipher_valid(const char *ciphername)
Returns if the cipher is valid, based on the given cipher name.
int rand_bytes(uint8_t *output, int len)
Wrapper for secure random number generator.
#define OPENVPN_AEAD_TAG_LENGTH
void free_epoch_key_ctx(struct crypto_options *co)
Frees the extra data structures used by epoch keys in crypto_options.
void epoch_init_key_ctx(struct crypto_options *co, const struct key_type *key_type, const struct epoch_key *e1_send, const struct epoch_key *e1_recv, uint16_t future_key_count)
Initialises data channel keys and internal structures for epoch data keys using the provided E0 epoch...
void epoch_iterate_send_key(struct crypto_options *co)
Updates the send key and send_epoch_key in cryptio_options->key_ctx_bi to use the next epoch.
void openvpn_encrypt(struct buffer *buf, struct buffer work, struct crypto_options *opt)
Encrypt and HMAC sign a packet so that it can be sent as a data channel VPN tunnel packet to a remote...
Definition crypto.c:329
bool openvpn_decrypt(struct buffer *buf, struct buffer work, struct crypto_options *opt, const struct frame *frame, const uint8_t *ad_start)
HMAC verify and decrypt a data channel packet received from a remote OpenVPN peer.
Definition crypto.c:779
#define RELIABLE_ACK_SIZE
The maximum number of packet IDs \ waiting to be acknowledged which can \ be stored in one reliable_a...
Definition reliable.h:43
#define ACK_SIZE(n)
Definition reliable.h:70
@ write
#define BUF_SIZE(f)
Definition mtu.h:183
#define ASSERT(x)
Definition error.h:219
time_t now
Definition otime.c:33
static void update_time(void)
Definition otime.h:84
void packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit)
Definition packet_id.c:96
void packet_id_free(struct packet_id *p)
Definition packet_id.c:126
#define PACKET_ID_EPOCH_MAX
Definition packet_id.h:47
const char * platform_create_temp_file(const char *directory, const char *prefix, struct gc_arena *gc)
Create a temporary file in directory, returns the filename of the created file.
Definition platform.c:540
static char * auth_challenge
Definition ssl.c:283
Control Channel SSL/Data channel negotiation module.
Control Channel SSL library backend module.
void tls_ctx_free(struct tls_root_ctx *ctx)
Frees the library-specific TLSv1 context.
int tls_ctx_load_priv_file(struct tls_root_ctx *ctx, const char *priv_key_file, bool priv_key_file_inline)
Load private key file into the given TLS context.
void tls_free_lib(void)
Free any global SSL library-specific data structures.
Definition ssl_openssl.c:98
void tls_init_lib(void)
Perform any static initialisation necessary by the library.
Definition ssl_openssl.c:91
void tls_ctx_client_new(struct tls_root_ctx *ctx)
Initialises a library-specific TLS context for a client.
void tls_ctx_load_cert_file(struct tls_root_ctx *ctx, const char *cert_file, bool cert_file_inline)
Load certificate file into the given TLS context.
Control Channel Verification Module.
#define TLS_USERNAME_LEN
Maximum length of common name.
Definition ssl_verify.h:54
Control Channel Verification Module library-specific backend interface.
result_t backend_x509_write_pem(openvpn_x509_cert_t *cert, const char *filename)
char * backend_x509_get_serial_hex(openvpn_x509_cert_t *cert, struct gc_arena *gc)
char * backend_x509_get_serial(openvpn_x509_cert_t *cert, struct gc_arena *gc)
result_t backend_x509_get_username(char *common_name, size_t cn_len, char *x509_username_field, openvpn_x509_cert_t *peer_cert)
@ SUCCESS
mbedtls_x509_crt openvpn_x509_cert_t
Wrapper structure for dynamically allocated memory.
Definition buffer.h:60
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:65
Security parameter state for processing data channel packets.
Definition crypto.h:293
unsigned int flags
Bit-flags determining behavior of security operation functions.
Definition crypto.h:386
struct key_ctx_bi key_ctx_bi
OpenSSL cipher and HMAC contexts for both sending and receiving directions.
Definition crypto.h:294
struct packet_id packet_id
Current packet ID state for both sending and receiving directions.
Definition crypto.h:333
uint8_t epoch_key[SHA256_DIGEST_LENGTH]
Definition crypto.h:193
uint16_t epoch
Definition crypto.h:194
Packet geometry parameters.
Definition mtu.h:108
int tun_mtu
the (user) configured tun-mtu.
Definition mtu.h:142
int payload_size
the maximum size that a payload that our buffers can hold from either tun device or network link.
Definition mtu.h:113
int headroom
the headroom in the buffer, this is choosen to allow all potential header to be added before the pack...
Definition mtu.h:119
struct frame::@8 buf
int tailroom
the tailroom in the buffer.
Definition mtu.h:123
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
Container for bidirectional cipher and HMAC key material.
Definition crypto.h:240
int n
The number of key objects stored in the key2.keys array.
Definition crypto.h:241
struct key keys[2]
Two unidirectional sets of key material.
Definition crypto.h:243
struct key_ctx encrypt
Cipher and/or HMAC contexts for sending direction.
Definition crypto.h:281
uint16_t epoch
OpenVPN data channel epoch, this variable holds the epoch number this key belongs to.
Definition crypto.h:228
uint64_t plaintext_blocks
Counter for the number of plaintext block encrypted using this cipher with the current key in number ...
Definition crypto.h:222
const char * cipher
const name of the cipher
Definition crypto.h:142
Container for unidirectional cipher and HMAC key material.
Definition crypto.h:152
uint8_t cipher[MAX_CIPHER_KEY_LENGTH]
Key material for cipher operations.
Definition crypto.h:153
uint8_t hmac[MAX_HMAC_KEY_LENGTH]
Key material for HMAC operations.
Definition crypto.h:155
uint64_t id
Definition packet_id.h:153
struct packet_id_send send
Definition packet_id.h:200
Structure that wraps the TLS context.
SSL_CTX * ctx
Definition ssl_openssl.h:41
static void openvpn_unit_test_setup(void)
Sets up the environment for unit tests like making both stderr and stdout non-buffered to avoid messa...
Definition test_common.h:61
void crypto_test_print_cert_details(void **state)
Definition test_ssl.c:794
static void test_data_channel_roundtrip_aes_192_cbc(void **state)
Definition test_ssl.c:563
static void test_load_certificate_and_key_uri(void **state)
Definition test_ssl.c:225
const char * certfile
Definition test_ssl.c:134
bool get_user_pass_cr(struct user_pass *up, const char *auth_file, const char *prefix, const unsigned int flags, const char *auth_challenge)
Retrieves the user credentials from various sources depending on the flags.
Definition test_ssl.c:77
static openvpn_x509_cert_t * get_certificate(const char *cert_str)
Definition test_ssl.c:776
static void test_data_channel_roundtrip_aes_192_gcm_epoch(void **state)
Definition test_ssl.c:539
static void encrypt_one_packet(struct crypto_options *co, int len)
Definition test_ssl.c:350
static void test_data_channel_roundtrip_aes_256_cbc(void **state)
Definition test_ssl.c:569
static void test_load_certificate_and_key(void **state)
Definition test_ssl.c:203
static void test_data_channel_known_vectors_run(bool epoch)
Definition test_ssl.c:639
static struct key2 create_key(void)
Definition test_ssl.c:611
struct gc_arena gc
Definition test_ssl.c:133
void purge_user_pass(struct user_pass *up, bool force)
Definition test_ssl.c:83
static void check_aead_limits(struct crypto_options *co, bool chachapoly)
Definition test_ssl.c:394
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition test_ssl.c:59
static const char *const unittest_cert
Definition test_ssl.c:94
static void run_data_channel_with_cipher_epoch(const char *cipher)
Definition test_ssl.c:499
static int cleanup(void **state)
Definition test_ssl.c:163
static void do_data_channel_round_trip(struct crypto_options *co)
Definition test_ssl.c:294
static void test_data_channel_roundtrip_aes_128_gcm_epoch(void **state)
Definition test_ssl.c:527
static void crypto_pem_encode_certificate(void **state)
Definition test_ssl.c:173
static void test_data_channel_roundtrip_aes_128_gcm(void **state)
Definition test_ssl.c:521
int main(void)
Definition test_ssl.c:834
static void test_data_channel_roundtrip_aes_192_gcm(void **state)
Definition test_ssl.c:533
void throw_signal(const int signum)
Throw a hard signal.
Definition test_ssl.c:65
const char * keyfile
Definition test_ssl.c:135
static void init_frame_parameters(struct frame *frame)
Definition test_ssl.c:264
static void test_data_channel_roundtrip_bf_cbc(void **state)
Definition test_ssl.c:599
static void test_data_channel_roundtrip_chacha20_poly1305(void **state)
Definition test_ssl.c:575
struct signal_info siginfo_static
Definition test_ssl.c:56
static const char * get_tmp_dir(void)
Definition test_ssl.c:119
static void uninit_crypto_options(struct crypto_options *co)
Definition test_ssl.c:488
static void test_data_channel_roundtrip_aes_256_gcm(void **state)
Definition test_ssl.c:545
static void test_data_channel_known_vectors_epoch(void **state)
Definition test_ssl.c:744
static void test_data_channel_roundtrip_chacha20_poly1305_epoch(void **state)
Definition test_ssl.c:587
static const char *const unittest_key
Definition test_ssl.c:109
static struct @32 global_state
static void test_data_channel_roundtrip_aes_256_gcm_epoch(void **state)
Definition test_ssl.c:551
static int init(void **state)
Definition test_ssl.c:139
static void free_certificate(openvpn_x509_cert_t *cert)
Definition test_ssl.c:787
static void test_data_channel_roundtrip_aes_128_cbc(void **state)
Definition test_ssl.c:557
static struct crypto_options init_crypto_options(const char *cipher, const char *auth, bool epoch, struct key2 *statickey)
Definition test_ssl.c:445
static void run_data_channel_with_cipher(const char *cipher, const char *auth)
Definition test_ssl.c:510
static void test_data_channel_known_vectors_shortpktid(void **state)
Definition test_ssl.c:750
const char * win_get_tempdir(void)
Definition win32-util.c:150