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_util.h"
52#include "ssl_verify.h"
53#include "openvpn.h"
54
55#include "test_acc.h"
56
57/* Mock function to be allowed to include win32.c which is required for
58 * getting the temp directory */
59#ifdef _WIN32
60struct signal_info siginfo_static; /* GLOBAL */
61
62const char *
63strerror_win32(DWORD errnum, struct gc_arena *gc)
64{
65 ASSERT(false);
66}
67
68void
69throw_signal(const int signum)
70{
71 ASSERT(false);
72}
73#endif
74
75#if defined(ENABLE_CRYPTO_OPENSSL) && (OPENSSL_VERSION_NUMBER > 0x30000000L)
76#define HAVE_OPENSSL_STORE
77#endif
78
79/* stubs for some unused functions instead of pulling in too many dependencies */
80bool
81get_user_pass_cr(struct user_pass *up, const char *auth_file, const char *prefix,
82 const unsigned int flags, const char *auth_challenge)
83{
84 return false;
85}
86void
87purge_user_pass(struct user_pass *up, bool force)
88{
89 return;
90}
91void
95
96/* Define a dummy dco cipher option to avoid linking against all the DCO
97 * units */
98#if defined(ENABLE_DCO)
99const char *
101{
102 return "AES-192-GCM:AES-128-CBC:AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305";
103}
104#endif
105
106/* generated using
107 * openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:secp384r1 -keyout - \
108 * -noenc -sha256 -days 3650 -subj '/CN=ovpn-test-secp384r1' -nodes \
109 * -addext 'subjectAltName=DNS:unittest.example.com' \
110 * -addext 'extendedKeyUsage=clientAuth'
111 */
112static const char *const unittest_cert =
113 "-----BEGIN CERTIFICATE-----\n"
114 "MIICBjCCAYygAwIBAgIUFoXgpP4beykV7tpgrjHQTWPGi4cwCgYIKoZIzj0EAwIw\n"
115 "HjEcMBoGA1UEAwwTb3Zwbi10ZXN0LXNlY3AzODRyMTAeFw0yNTA5MDgxMzExNTBa\n"
116 "Fw0zNTA5MDYxMzExNTBaMB4xHDAaBgNVBAMME292cG4tdGVzdC1zZWNwMzg0cjEw\n"
117 "djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQVDmf+TZB3rW6zqWFox606u/PhA93ysX/h\n"
118 "1s2xyq9+QGzIdE/hks6p/Yzyu7RLOUjxvO0J45RHcYmo67DlvSOi496T3zrgvp1H\n"
119 "KfHD5ohMyvzw0+e8lmjJqJjn+PegMkOjgYowgYcwHQYDVR0OBBYEFCH1eYnaV8fh\n"
120 "E3Bv7lyrlYu24eoVMB8GA1UdIwQYMBaAFCH1eYnaV8fhE3Bv7lyrlYu24eoVMA8G\n"
121 "A1UdEwEB/wQFMAMBAf8wHwYDVR0RBBgwFoIUdW5pdHRlc3QuZXhhbXBsZS5jb20w\n"
122 "EwYDVR0lBAwwCgYIKwYBBQUHAwIwCgYIKoZIzj0EAwIDaAAwZQIxAL7q7jcwTOuq\n"
123 "5sp0Beq81Vnznd3gsDZYNs1OYRWH33xergDVKlBb6kCwus0dhghtVAIwIgT4ytkY\n"
124 "oAPx8LB3oP8ubEu1ue6V9jZln/cCiLyXDDtaiJOZHtDqHGfHqvc6rAok\n"
125 "-----END CERTIFICATE-----\n";
126
127static const char *const unittest_key =
128 "-----BEGIN PRIVATE KEY-----\n"
129 "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDAXBC7tpa9UepoMVZlM\n"
130 "OxUubkECGK7aWFebxDc3UPoEQemEPMOCdkWBSU/t7Mm4R66hZANiAAQVDmf+TZB3\n"
131 "rW6zqWFox606u/PhA93ysX/h1s2xyq9+QGzIdE/hks6p/Yzyu7RLOUjxvO0J45RH\n"
132 "cYmo67DlvSOi496T3zrgvp1HKfHD5ohMyvzw0+e8lmjJqJjn+PegMkM=\n"
133 "-----END PRIVATE KEY-----\n";
134
135
136static struct
137{
138 struct gc_arena gc;
139 const char *certfile;
140 const char *keyfile;
142
143static int
144init(void **state)
145{
146 (void)state;
147 global_state.gc = gc_new();
150
151 int certfd = open(global_state.certfile, O_RDWR);
152 int keyfd = open(global_state.keyfile, O_RDWR);
153 if (certfd < 0 || keyfd < 0)
154 {
155 fail_msg("make tmpfile for certificate or key data failed (error = %d)", errno);
156 }
157 /* Awkward casts required for MinGW with -O0 only */
158 assert_int_equal(write(certfd, unittest_cert, (unsigned int)strlen(unittest_cert)),
159 strlen(unittest_cert));
160 assert_int_equal(write(keyfd, unittest_key, (unsigned int)strlen(unittest_key)),
161 strlen(unittest_key));
162 close(certfd);
163 close(keyfd);
164 return 0;
165}
166
167static int
168cleanup(void **state)
169{
170 (void)state;
171 unlink(global_state.certfile);
172 unlink(global_state.keyfile);
174 return 0;
175}
176
177static void
179{
180 struct gc_arena gc = gc_new();
181
182 struct tls_root_ctx ctx = { 0 };
185
186 openvpn_x509_cert_t *cert = NULL;
187
188 /* we do not have methods to fetch certificates from ssl contexts, use
189 * internal TLS library methods for the unit test */
190#ifdef ENABLE_CRYPTO_OPENSSL
191 cert = SSL_CTX_get0_certificate(ctx.ctx);
192#elif defined(ENABLE_CRYPTO_MBEDTLS)
193 cert = ctx.crt_chain;
194#endif
195
196 const char *tmpfile = platform_create_temp_file(platform_get_tmp_dir(), "ut_pem", &gc);
197 backend_x509_write_pem(cert, tmpfile);
198
201
202 tls_ctx_free(&ctx);
204 gc_free(&gc);
205}
206
207static void
209{
210 (void)state;
211 struct tls_root_ctx ctx = { 0 };
212
213 /* test loading of inlined cert and key.
214 * loading the key also checks that it matches the loaded certificate
215 */
218 assert_int_equal(tls_ctx_load_priv_file(&ctx, unittest_key, true), 0);
220
221 /* test loading of cert and key from file */
223 tls_ctx_load_cert_file(&ctx, global_state.certfile, false);
224 assert_int_equal(tls_ctx_load_priv_file(&ctx, global_state.keyfile, false), 0);
226}
227
228/* test loading cert and key using file:/path URI */
229static void
231{
232 (void)state;
233
234#if !defined(HAVE_OPENSSL_STORE)
235 skip();
236#else /* HAVE_OPENSSL_STORE */
237
238 struct tls_root_ctx ctx = { 0 };
239 const char *certfile = global_state.certfile;
240 const char *keyfile = global_state.keyfile;
241 struct gc_arena *gc = &global_state.gc;
242
243 struct buffer certuri = alloc_buf_gc(6 + strlen(certfile) + 1, gc); /* 6 bytes for "file:/" */
244 struct buffer keyuri = alloc_buf_gc(6 + strlen(keyfile) + 1, gc); /* 6 bytes for "file:/" */
245
246 /* Windows temp file path starts with drive letter -- add a leading slash for URI */
247#ifdef _WIN32
248 const char *lead = "/";
249#else
250 const char *lead = "";
251#endif /* _WIN32 */
252 assert_true(buf_printf(&certuri, "file:%s%s", lead, certfile));
253 assert_true(buf_printf(&keyuri, "file:%s%s", lead, keyfile));
254
255 /* On Windows replace any '\' in path by '/' required for URI */
256#ifdef _WIN32
259#endif /* _WIN32 */
260
261 tls_ctx_new(&ctx);
262 tls_ctx_load_cert_file(&ctx, BSTR(&certuri), false);
264 tls_ctx_free(&ctx);
265#endif /* HAVE_OPENSSL_STORE */
266}
267
268
269static void
271{
272 int overhead = 0;
273
274 /* tls-auth and tls-crypt */
275 overhead += 128;
276
277 /* TCP length field and opcode */
278 overhead += 3;
279
280 /* ACK array and remote SESSION ID (part of the ACK array) */
282
283 /* Previous OpenVPN version calculated the maximum size and buffer of a
284 * control frame depending on the overhead of the data channel frame
285 * overhead and limited its maximum size to 1250. Since control frames
286 * also need to fit into data channel buffer we have the same
287 * default of 1500 + 100 as data channel buffers have. Increasing
288 * control channel mtu beyond this limit also increases the data channel
289 * buffers */
290 int tls_mtu = 1500;
291 frame->buf.payload_size = tls_mtu + 100;
292
295
296 frame->tun_mtu = tls_mtu;
297}
298
299static void
301{
302 struct gc_arena gc = gc_new();
303
304 /* initialise frame for the test */
305 struct frame frame;
307
309 struct buffer work = alloc_buf_gc(BUF_SIZE(&frame), &gc);
312
313 /* init work */
315
316 update_time();
317
318 /* Test encryption, decryption for all packet sizes */
319 for (int i = 1; i <= frame.buf.payload_size; ++i)
320 {
321 /* msg(M_INFO, "TESTING ENCRYPT/DECRYPT of packet length=%d", i); */
322
323 /*
324 * Load src with random data.
325 */
326 ASSERT(buf_init(&src, 0));
327 ASSERT(i <= src.capacity);
328 src.len = i;
329 prng_bytes(BPTR(&src), BLEN(&src));
330
331 /* copy source to input buf */
332 struct buffer buf = work;
333 void *buf_p = buf_write_alloc(&buf, BLENZ(&src));
334 ASSERT(buf_p);
335 memcpy(buf_p, BPTR(&src), BLENZ(&src));
336
337 /* initialize work buffer with buf.headroom bytes of prepend capacity */
339
340 /* encrypt */
342
343 /* decrypt */
344 openvpn_decrypt(&buf, decrypt_workspace, co, &frame, BPTR(&buf));
345
346 /* compare */
347 assert_int_equal(buf.len, src.len);
348 assert_memory_equal(BPTR(&src), BPTR(&buf), i);
349 }
350 gc_free(&gc);
351}
352
353static void
355{
356 struct frame frame;
358
359 struct gc_arena gc = gc_new();
362 struct buffer work = alloc_buf_gc(BUF_SIZE(&frame), &gc);
364 void *buf_p;
365
367
368 /*
369 * Load src with random data.
370 */
371 ASSERT(buf_init(&src, 0));
372 ASSERT(len <= src.capacity);
373 src.len = len;
374 prng_bytes(BPTR(&src), BLEN(&src));
375
376 /* copy source to input buf */
377 struct buffer buf = work;
378 buf_p = buf_write_alloc(&buf, BLENZ(&src));
379 ASSERT(buf_p);
380 memcpy(buf_p, BPTR(&src), BLENZ(&src));
381
384
385 /* decrypt */
386 openvpn_decrypt(&buf, decrypt_workspace, co, &frame, BPTR(&buf));
387
388 /* compare */
389 assert_int_equal(buf.len, src.len);
391
392 gc_free(&gc);
393}
394
395
396static void
398{
399 /* Check that we correctly react when we have a nearing AEAD limits */
400
401 /* manually increase the send counter to be past
402 * the GCM usage limit */
403 co->key_ctx_bi.encrypt.plaintext_blocks = 0x1ull << 40;
404
405
406 bool epoch = (co->flags & CO_EPOCH_DATA_KEY_FORMAT);
407
408 int expected_epoch = epoch ? 4 : 0;
409
410 /* Ensure that we are still on the initial key (our init_crypto_options
411 * unit test method iterates the initial key to 4) or that it is 0 when
412 * epoch is not in use
413 */
415
416 encrypt_one_packet(co, 1000);
417
418 /* either epoch key has been updated or warning is enabled */
419 if (epoch && !chachapoly)
420 {
422 }
423
425
426 if (!epoch)
427 {
428 /* Check always against the GCM usage limit here to see if that
429 * check works */
432 return;
433 }
434
435 /* Move to the end of the epoch data key send PID range, ChachaPoly
436 * should now also move to a new epoch data key */
438
439 encrypt_one_packet(co, 1000);
440 encrypt_one_packet(co, 1000);
441
444}
445
446
447static struct crypto_options
448init_crypto_options(const char *cipher, const char *auth, bool epoch, struct key2 *statickey)
449{
450 struct key2 key2 = { .n = 2 };
451
452 if (statickey)
453 {
454 /* Use chosen static key instead of random key when defined */
455 key2 = *statickey;
456 }
457 else
458 {
459 prng_bytes(key2.keys[0].cipher, sizeof(key2.keys[0].cipher));
460 prng_bytes(key2.keys[0].hmac, sizeof(key2.keys[0].hmac));
461 prng_bytes(key2.keys[1].cipher, sizeof(key2.keys[1].cipher));
462 prng_bytes(key2.keys[1].hmac, sizeof(key2.keys)[1].hmac);
463 }
464
465 struct crypto_options co = { 0 };
466
467 struct key_type kt = create_kt(cipher, auth, "ssl-test");
468
469 if (epoch)
470 {
471 struct epoch_key e1 = { .epoch = 1, .epoch_key = { 0 } };
472 memcpy(e1.epoch_key, key2.keys[0].cipher, sizeof(e1.epoch_key));
474 epoch_init_key_ctx(&co, &kt, &e1, &e1, 5);
475
476 /* Do a little of dancing for the epoch_send_key_iterate to test
477 * that this works too */
481 }
482 else
483 {
484 init_key_ctx_bi(&co.key_ctx_bi, &key2, KEY_DIRECTION_BIDIRECTIONAL, &kt, "unit-test-ssl");
485 }
486 packet_id_init(&co.packet_id, 5, 5, "UNITTEST", 0);
487 return co;
488}
489
490static void
497
498/* This adds a few more methods than strictly necessary but this allows
499 * us to see which exact test was run from the backtrace of the test
500 * when it fails */
501static void
503{
504 bool ischacha = !strcmp(cipher, "ChaCha20-Poly1305");
505
506 struct crypto_options co = init_crypto_options(cipher, "none", true, NULL);
508 check_aead_limits(&co, ischacha);
510}
511
512static void
513run_data_channel_with_cipher(const char *cipher, const char *auth)
514{
515 bool ischacha = !strcmp(cipher, "ChaCha20-Poly1305");
516 struct crypto_options co = init_crypto_options(cipher, auth, false, NULL);
518 check_aead_limits(&co, ischacha);
520}
521
522
523static void
525{
526 run_data_channel_with_cipher("AES-128-GCM", "none");
527}
528
529static void
534
535static void
537{
538 run_data_channel_with_cipher("AES-192-GCM", "none");
539}
540
541static void
546
547static void
549{
550 run_data_channel_with_cipher("AES-256-GCM", "none");
551}
552
553static void
558
559static void
561{
562 run_data_channel_with_cipher("AES-128-CBC", "SHA256");
563}
564
565static void
567{
568 run_data_channel_with_cipher("AES-192-CBC", "SHA256");
569}
570
571static void
573{
574 run_data_channel_with_cipher("AES-256-CBC", "SHA256");
575}
576
577static void
579{
580 if (!cipher_valid("ChaCha20-Poly1305"))
581 {
582 skip();
583 return;
584 }
585
586 run_data_channel_with_cipher("ChaCha20-Poly1305", "none");
587}
588
589static void
591{
592 if (!cipher_valid("ChaCha20-Poly1305"))
593 {
594 skip();
595 return;
596 }
597
598 run_data_channel_with_cipher_epoch("ChaCha20-Poly1305");
599}
600
601static void
603{
604 if (!cipher_valid("BF-CBC"))
605 {
606 skip();
607 return;
608 }
609 run_data_channel_with_cipher("BF-CBC", "SHA1");
610}
611
612
613static struct key2
615{
616 struct key2 key2 = { .n = 2 };
617
618 const uint8_t key[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '0', '1', '2',
619 '3', '4', '5', '6', '7', 'A', 'B', 'C', 'D', 'E', 'F',
620 'G', 'H', 'j', 'k', 'u', 'c', 'h', 'e', 'n', 'l' };
621
622 static_assert(sizeof(key) == 32, "Size of key should be 32 bytes");
623
624 /* copy the key a few times to ensure to have the size we need for
625 * Statickey but XOR it to not repeat it */
626 uint8_t keydata[sizeof(key2.keys)];
627
628 for (size_t i = 0; i < sizeof(key2.keys); i++)
629 {
630 keydata[i] = (uint8_t)(key[i % sizeof(key)] ^ i);
631 }
632
633 ASSERT(memcpy(key2.keys[0].cipher, keydata, sizeof(key2.keys[0].cipher)));
634 ASSERT(memcpy(key2.keys[0].hmac, keydata + 64, sizeof(key2.keys[0].hmac)));
635 ASSERT(memcpy(key2.keys[1].cipher, keydata + 128, sizeof(key2.keys[1].cipher)));
636 ASSERT(memcpy(key2.keys[1].hmac, keydata + 192, sizeof(key2.keys)[1].hmac));
637
638 return key2;
639}
640
641static void
643{
644 struct key2 key2 = create_key();
645
646 struct crypto_options co = init_crypto_options("AES-256-GCM", "none", epoch, &key2);
647
648 struct gc_arena gc = gc_new();
649
650 /* initialise frame for the test */
651 struct frame frame;
653
655 struct buffer work = alloc_buf_gc(BUF_SIZE(&frame), &gc);
658 void *buf_p;
659
660 /* init work */
662
663 now = 0;
664
665 /*
666 * Load src with known data.
667 */
668 ASSERT(buf_init(&src, 0));
669 const char *plaintext = "The quick little fox jumps over the bureaucratic hurdles";
670
672
673 /* copy source to input buf */
674 struct buffer buf = work;
675 buf_p = buf_write_alloc(&buf, BLENZ(&src));
676 ASSERT(buf_p);
677 memcpy(buf_p, BPTR(&src), BLENZ(&src));
678
679 /* initialize work buffer with buf.headroom bytes of prepend capacity */
681
682 /* add packet opcode and peer id */
687
688 /* encrypt */
690
691 /* separate buffer in authenticated data and encrypted data */
692 const uint8_t *ad_start = BPTR(&buf);
693 buf_advance(&buf, 4);
694
695 if (epoch)
696 {
697 uint8_t packetid1[8] = { 0, 0x04, 0, 0, 0, 0, 0, 1 };
699 }
700 else
701 {
702 uint8_t packetid1[4] = { 0, 0, 0, 1 };
704 }
705
706 if (epoch)
707 {
709 const uint8_t exp_tag_epoch[16] = { 0x0f, 0xff, 0xf5, 0x91, 0x3d, 0x39, 0xd7, 0x5b,
710 0x18, 0x57, 0x3b, 0x57, 0x48, 0x58, 0x9a, 0x7d };
711
713 }
714 else
715 {
716 uint8_t *tag_location = BPTR(&buf) + 4;
717 const uint8_t exp_tag_noepoch[16] = { 0x1f, 0xdd, 0x90, 0x8f, 0x0e, 0x9d, 0xc2, 0x5e,
718 0x79, 0xd8, 0x32, 0x02, 0x0d, 0x58, 0xe7, 0x3f };
720 }
721
722 /* Check some bytes at the beginning of the encrypted part */
723 if (epoch)
724 {
725 const uint8_t bytesat14[6] = { 0x36, 0xaa, 0xb4, 0xd4, 0x9c, 0xe6 };
726 assert_memory_equal(BPTR(&buf) + 14, bytesat14, sizeof(bytesat14));
727 }
728 else
729 {
730 const uint8_t bytesat30[6] = { 0xa8, 0x2e, 0x6b, 0x17, 0x06, 0xd9 };
731 assert_memory_equal(BPTR(&buf) + 30, bytesat30, sizeof(bytesat30));
732 }
733
734 /* decrypt */
736
737 /* compare */
740
742 gc_free(&gc);
743}
744
745static void
750
751static void
756
757#if defined(ENABLE_CRYPTO_MBEDTLS)
758static openvpn_x509_cert_t *
759get_certificate(const char *cert_str)
760{
761 mbedtls_x509_crt *cert;
763 int ret = mbedtls_x509_crt_parse(cert, (const unsigned char *)cert_str,
764 strlen(cert_str) + 1);
765
767 return cert;
768}
769
770static void
772{
774 free(cert);
775}
776#else
777static openvpn_x509_cert_t *
779{
780 BIO *in = BIO_new_mem_buf((char *)cert_str, -1);
781 assert_non_null(in);
782 X509 *cert = PEM_read_bio_X509(in, NULL, NULL, NULL);
783 assert_non_null(cert);
784 BIO_free(in);
785 return cert;
786}
787
788static void
793#endif
794
795/* Generated with:
796 * openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:secp384r1 -keyout - -noenc -sha256 -days 3650 \
797 * -subj '/CN=ovpn-test-secp384r1/O=OpenVPN Unit Test Example Corp./OU=Cert Details Dept.'
798 * -addext 'subjectAltName=DNS:unittest.example.com' -addext 'extendedKeyUsage=clientAuth' */
799static const char *cert_details_test_cert =
800 "-----BEGIN CERTIFICATE-----\n"
801 "MIICkzCCAhqgAwIBAgIUKDsZM+PApGdaD2QF9iYaxoFJAkowCgYIKoZIzj0EAwIw\n"
802 "ZTEcMBoGA1UEAwwTb3Zwbi10ZXN0LXNlY3AzODRyMTEoMCYGA1UECgwfT3BlblZQ\n"
803 "TiBVbml0IFRlc3QgRXhhbXBsZSBDb3JwLjEbMBkGA1UECwwSQ2VydCBEZXRhaWxz\n"
804 "IERlcHQuMB4XDTI2MDcwNzEwNTIxNloXDTM2MDcwNDEwNTIxNlowZTEcMBoGA1UE\n"
805 "AwwTb3Zwbi10ZXN0LXNlY3AzODRyMTEoMCYGA1UECgwfT3BlblZQTiBVbml0IFRl\n"
806 "c3QgRXhhbXBsZSBDb3JwLjEbMBkGA1UECwwSQ2VydCBEZXRhaWxzIERlcHQuMHYw\n"
807 "EAYHKoZIzj0CAQYFK4EEACIDYgAEOlKoQVk+wbBD6V/6kg+/oHfqF0Dq08LlCL+B\n"
808 "om4RhutG99QDrow251Ps+Ds/7LQYYRA8+hHyEFrmGM+j2o6KhS5K2uA6dIZL4zLK\n"
809 "vl0NeF2M61Z8tt/IjrFZd+CrEANco4GKMIGHMB0GA1UdDgQWBBSEyG6m+QdWazeg\n"
810 "0CHN7q0edJlqMjAfBgNVHSMEGDAWgBSEyG6m+QdWazeg0CHN7q0edJlqMjAPBgNV\n"
811 "HRMBAf8EBTADAQH/MB8GA1UdEQQYMBaCFHVuaXR0ZXN0LmV4YW1wbGUuY29tMBMG\n"
812 "A1UdJQQMMAoGCCsGAQUFBwMCMAoGCCqGSM49BAMCA2cAMGQCMCyK7aQcyKGW8BWQ\n"
813 "UOYqbJUJZJcviP6ACgJRzK6pgkqt9gY0E0Tb00Qh6D5dBV5i3wIwCMhSgpVJxDrc\n"
814 "pRfligoK8bmv4HEgnV6BDeoDYd41WVMpE9u1issQDHY0SnWC7d9q\n"
815 "-----END CERTIFICATE-----\n";
816const char *const cert_details_cname = "ovpn-test-secp384r1";
817const char *const cert_details_org = "OpenVPN Unit Test Example Corp.";
818const char *const cert_details_org_unit = "Cert Details Dept.";
819const char *const cert_details_serial_number = "229677570263950905252266749734450551528150860362";
820const char *const cert_details_serial_number_hex = "0x283B1933E3C0A4675A0F6405F6261AC68149024A";
821
822void
824{
826 struct gc_arena gc = gc_new();
827
828 const char *fp = backend_x509_get_serial_hex(cert, &gc);
829
830 /* we messed this up between TLS libraries. But let's at least notice in
831 * the future ...*/
832#if defined(ENABLE_CRYPTO_MBEDTLS)
833 assert_string_equal(fp, "28:3B:19:33:E3:C0:A4:67:5A:0F:64:05:F6:26:1A:C6:81:49:02:4A");
834#else
835 assert_string_equal(fp, "28:3b:19:33:e3:c0:a4:67:5a:0f:64:05:f6:26:1a:c6:81:49:02:4a");
836#endif
837
838 const char *sn = backend_x509_get_serial(cert, &gc);
839 assert_string_equal(sn, cert_details_serial_number);
840
841 char username[TLS_USERNAME_LEN + 1] = { 0 }; /* null-terminated */
842
843 int ret = backend_x509_get_username(username, sizeof(username), "CN", cert);
844
845 assert_string_equal(username, cert_details_cname);
846 assert_int_equal(ret, SUCCESS);
847
848 ret = backend_x509_get_username(username, sizeof(username), "serialNumber", cert);
849 assert_int_equal(ret, SUCCESS);
850 assert_string_equal(username, cert_details_serial_number_hex);
851
852 ret = backend_x509_get_username(username, sizeof(username), "O", cert);
853
854 assert_string_equal(username, cert_details_org);
855 assert_int_equal(ret, SUCCESS);
856
857 ret = backend_x509_get_username(username, sizeof(username), "OU", cert);
858
859 assert_string_equal(username, cert_details_org_unit);
860 assert_int_equal(ret, SUCCESS);
861
862 /* Check that FAILURE is returned if a field does not exist. */
863 ret = backend_x509_get_username(username, sizeof(username), "SN", cert);
864 assert_int_equal(ret, FAILURE);
865
866 /* Check that FAILURE is returned for invalid field names. */
867 ret = backend_x509_get_username(username, sizeof(username), "invalidField", cert);
868 assert_int_equal(ret, FAILURE);
869
870 /* Check that FAILURE is returned if the output buffer is too small. Do this separately
871 * for a subject field and for the serial number, because these are different code paths.
872 *
873 * First case: Can't fit all characters. */
874 ret = backend_x509_get_username(username, strlen(cert_details_cname) / 2, "CN", cert);
875 assert_int_equal(ret, FAILURE);
876 ret = backend_x509_get_username(username, strlen(cert_details_serial_number_hex) / 2, "serialNumber", cert);
877 assert_int_equal(ret, FAILURE);
878
879 /* Second case: Can fit the characters but not the terminating '\0'. */
880 ret = backend_x509_get_username(username, strlen(cert_details_cname), "CN", cert);
881 assert_int_equal(ret, FAILURE);
882 ret = backend_x509_get_username(username, strlen(cert_details_serial_number_hex), "serialNumber", cert);
883 assert_int_equal(ret, FAILURE);
884
885 gc_free(&gc);
886 free_certificate(cert);
887}
888
889/* Certificate with two CNs, "foo" and "bar".
890 *
891 * Generated with:
892 * openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:secp384r1 -subj "/CN=foo/CN=bar" \
893 * -noenc -out two_cns.crt -keyout two_cns.key
894 */
895static const char *cert_with_two_cns =
896 "-----BEGIN CERTIFICATE-----\n"
897 "MIIByTCCAVCgAwIBAgIUZuvd8Wfnq5jeRc3ohoJ/Vza54wQwCgYIKoZIzj0EAwIw\n"
898 "HDEMMAoGA1UEAwwDZm9vMQwwCgYDVQQDDANiYXIwHhcNMjYwODI4MTU1NjAwWhcN\n"
899 "MjYwOTI3MTU1NjAwWjAcMQwwCgYDVQQDDANmb28xDDAKBgNVBAMMA2JhcjB2MBAG\n"
900 "ByqGSM49AgEGBSuBBAAiA2IABERAfb210NOACy+QVYAu3EXrcGhTJpZDfhpDnE/h\n"
901 "PvPMWGWzqecTYdseArxZc0T/5Xma36IKCjGGsgN9ypZ5oQugQlB/NrVRCJIuHSGA\n"
902 "hGBWFvnUsqdNo765lGwVdBwhY6NTMFEwHQYDVR0OBBYEFPwnD+wK9R81Syk0qyTI\n"
903 "dFT/BNoJMB8GA1UdIwQYMBaAFPwnD+wK9R81Syk0qyTIdFT/BNoJMA8GA1UdEwEB\n"
904 "/wQFMAMBAf8wCgYIKoZIzj0EAwIDZwAwZAIwGxazGb6RRQtXzOWCPLRKId4e+E88\n"
905 "cwoCK3UwzEr8+Ddf54w5cEZC54f5J6AKFUJjAjBpT/JqF41uK57H+8i/16oZkBcm\n"
906 "OyQnlH8W/UzZo3/weTEBTcNW0iuCpIrS6im8pSk=\n"
907 "-----END CERTIFICATE-----\n";
908
909void
911{
912 /* When there are multiple fields of the same type in the certificate's subject, OpenVPN
913 * should extract the value of the last matching field. This is essentially arbitrary and there
914 * is no correct choice here, but this test exists to make sure that the behavior is consistent
915 * between different backends.
916 */
918
919 char username[TLS_USERNAME_LEN + 1] = { 0 };
920 assert_int_equal(backend_x509_get_username(username, sizeof(username), "CN", cert), SUCCESS);
921 assert_string_equal(username, "bar");
922 free_certificate(cert);
923}
924
925/* Certificate with a null-byte embedded in the CN.
926 *
927 * Generated with the following Python script:
928 *
929 * from cryptography import x509
930 * from cryptography.x509.oid import NameOID, ExtensionOID, ExtendedKeyUsageOID
931 * from cryptography.hazmat.primitives import hashes, serialization
932 * from cryptography.hazmat.primitives.asymmetric import ec
933 * import datetime
934 *
935 * private_key = ec.generate_private_key(ec.SECP384R1())
936 * now = datetime.datetime.now(datetime.timezone.utc)
937 * name = "with\x00null"
938 *
939 * cert = (x509.CertificateBuilder()
940 * .subject_name(x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, name)]))
941 * .issuer_name(x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, name)]))
942 * .public_key(private_key.public_key())
943 * .serial_number(x509.random_serial_number())
944 * .not_valid_before(now)
945 * .not_valid_after(now + datetime.timedelta(days=10 * 365))
946 * .sign(private_key, hashes.SHA256()))
947 *
948 * print(str(cert.public_bytes(serialization.Encoding.PEM), encoding='utf-8'))
949 **/
950static const char *cert_with_null =
951 "-----BEGIN CERTIFICATE-----\n"
952 "MIIBZTCB66ADAgECAhRLWdNRl+C20KKBG4QC9HFPWlOtBzAKBggqhkjOPQQDAjAU\n"
953 "MRIwEAYDVQQDDAl3aXRoAG51bGwwHhcNMjYwODI4MTQzMDA4WhcNMzYwODI1MTQz\n"
954 "MDA4WjAUMRIwEAYDVQQDDAl3aXRoAG51bGwwdjAQBgcqhkjOPQIBBgUrgQQAIgNi\n"
955 "AAT7PE+vJCBiB4CVHBcvJVF9n5n/dGQIn4C8HeYE8M2iXYCIRW5wg6/mlPaeiJY/\n"
956 "Ywh3pa8zhto1+aczbJKTvLgRwXn6N5vNpME1c5iWMzY0WHe1dJyVtoRBvkNvy5+k\n"
957 "GuEwCgYIKoZIzj0EAwIDaQAwZgIxAP2ekdQ8muG8Nv2o3PsBp0CqiaSNByGiP75i\n"
958 "k099bUFvHp/3LSp8Wf4JK2iWzc5h6gIxAINBGg2xjlmMgpXxROKA9qQqaM3d92Mp\n"
959 "EzZyRyPM3PGR83ZPbIaYDq8lCVxVlbYr/Q==\n"
960 "-----END CERTIFICATE-----\n";
961
962void
964{
966 struct gc_arena gc = gc_new();
967
968 /* Trying to get the subject as a whole should fail. */
969 assert_ptr_equal(x509_get_subject(cert, &gc), NULL);
970
971 /* Trying to extract the common name should fail. */
972 char username[TLS_USERNAME_LEN + 1] = { 0 };
973 assert_int_equal(backend_x509_get_username(username, sizeof(username), "CN", cert), FAILURE);
974 gc_free(&gc);
975 free_certificate(cert);
976}
977
978/* Cert with CN="name, O=InjectedOrg" and O=RealOrg.
979 *
980 * Generated with the following Python script:
981 *
982 * from cryptography import x509
983 * from cryptography.x509.oid import NameOID, ExtensionOID, ExtendedKeyUsageOID
984 * from cryptography.hazmat.primitives import hashes, serialization
985 * from cryptography.hazmat.primitives.asymmetric import ec
986 * import datetime
987 *
988 * private_key = ec.generate_private_key(ec.SECP384R1())
989 * now = datetime.datetime.now(datetime.timezone.utc)
990 * name = "name, O=InjectedOrg"
991 * org = "RealOrg"
992 *
993 * distinguished_name = x509.Name([
994 * x509.NameAttribute(NameOID.COMMON_NAME, name),
995 * x509.NameAttribute(NameOID.ORGANIZATION_NAME, org)
996 * ])
997 *
998 * cert = (x509.CertificateBuilder()
999 * .subject_name(distinguished_name)
1000 * .issuer_name(distinguished_name)
1001 * .public_key(private_key.public_key())
1002 * .serial_number(x509.random_serial_number())
1003 * .not_valid_before(now)
1004 * .not_valid_after(now + datetime.timedelta(days=10 * 365))
1005 * .sign(private_key, hashes.SHA256()))
1006 *
1007 * print(str(cert.public_bytes(serialization.Encoding.PEM), encoding='utf-8'))
1008 */
1009static const char *cert_with_rfc_2253_chars =
1010 "-----BEGIN CERTIFICATE-----\n"
1011 "MIIBnTCCASOgAwIBAgIUR1IGc6A800U14v/ykZNR21aVubowCgYIKoZIzj0EAwIw\n"
1012 "MDEcMBoGA1UEAwwTbmFtZSwgTz1JbmplY3RlZE9yZzEQMA4GA1UECgwHUmVhbE9y\n"
1013 "ZzAeFw0yNjA4MjgxNTQ3NDdaFw0zNjA4MjUxNTQ3NDdaMDAxHDAaBgNVBAMME25h\n"
1014 "bWUsIE89SW5qZWN0ZWRPcmcxEDAOBgNVBAoMB1JlYWxPcmcwdjAQBgcqhkjOPQIB\n"
1015 "BgUrgQQAIgNiAAR6zl9QPAbAnHWN//MRdowuhu0Sol6N+lqB/qk+D+2NHCd/t4H9\n"
1016 "cJlswUh6EPsmLxgfMYgO2QwClFWEFWvtXQs8BggoidY6i9pmAPhs8+9fmIyuNVpG\n"
1017 "3vUWZrUBRgylwaIwCgYIKoZIzj0EAwIDaAAwZQIwKzXmR8YPQZ1pratM9meVmGkH\n"
1018 "1rpHgV3U8oeg+jXmfVcZJTpDeDz4yBl4V3KBKT7HAjEAj2qkaTz7fiSwBKsxJQWH\n"
1019 "dQFPBCAYU9zZJvlNnEPtmHIwaD/qHXDeClr/HRItU3B9\n"
1020 "-----END CERTIFICATE-----\n";
1021
1022void
1024{
1026 struct gc_arena gc = gc_new();
1027
1028 char *subject = x509_get_subject(cert, &gc);
1029 assert_non_null(subject);
1030
1031 /* Mbed TLS escapes the '=' character but OpenSSL does not. */
1032 const char *expected_subject_openssl = "CN=name\\, O=InjectedOrg, O=RealOrg";
1033 const char *expected_subject_mbedtls = "CN=name\\, O\\=InjectedOrg, O=RealOrg";
1034
1035 assert_true(strcmp(subject, expected_subject_openssl) == 0 || strcmp(subject, expected_subject_mbedtls) == 0);
1036 gc_free(&gc);
1037 free_certificate(cert);
1038}
1039
1040void
1042{
1043 const char *peer_info_normal =
1044 "IV_VER=2.6_git\nIV_PLAT=mac\nIV_TCPNL=1\nIV_NCP=2\n"
1045 "IV_CIPHERS=AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305\n"
1046 "IV_PROTO=94\nIV_LZO_STUB=1\nIV_COMP_STUB=1\nP=78\nIV_COMP_STUBv2=1\n"
1047 "IV_SSL=OpenSSL_3.0.5_5_Jul_2022\nIV_LZ4v2=1";
1048
1049 const char *empty = "";
1050 const char *invalid_proto = "IV_PROTO=seven\nIV_SSL=7\nP=300\nID=xyz";
1051 const char *test_prefix = "UV_IV_PROTO=773\nNP=112\nPD=8\n";
1052
1053
1054 assert_int_equal(extract_iv_proto(peer_info_normal), 94);
1055 assert_int_equal(extract_iv_proto(empty), 0);
1056 assert_int_equal(extract_iv_proto(invalid_proto), 0);
1057 /* This should not pick up the UV_IV_PROTO that has the extra prefix */
1058 assert_int_equal(extract_iv_proto(test_prefix), 0);
1059
1060 assert_int_equal(peer_info_extract_uint(peer_info_normal, "IV_COMP_STUB="), 1);
1061 assert_int_equal(peer_info_extract_int(empty, "IV_COMP_STUB=", "%d", 0xfe0d0d), 0xfe0d0d);
1062 assert_int_equal(peer_info_extract_uint(invalid_proto, "IV_COMP_STUB="), 0);
1063
1064 assert_int_equal(peer_info_extract_int(test_prefix, "NP=", "%d", 23), 112);
1065 assert_int_equal(peer_info_extract_uint(test_prefix, "PD="), 8);
1066 assert_int_equal(peer_info_extract_int(test_prefix, "P=", "%x", 0xfe0d0d), 0xfe0d0d);
1067 assert_int_equal(peer_info_extract_uint(peer_info_normal, "P="), 78);
1068 assert_int_equal(peer_info_extract_uint(test_prefix, "UV_IV_PROTO="), 773);
1069
1070 struct gc_arena gc = gc_new();
1071
1072 const char *peer_ciphers = extract_var_peer_info(peer_info_normal, "IV_CIPHERS=", &gc);
1073 assert_string_equal(peer_ciphers, "AES-256-GCM:AES-128-GCM:CHACHA20-POLY1305");
1074
1075 /* with the extra = this should not extract anything */
1076 const char *proto = extract_var_peer_info(peer_info_normal, "IV_PROTO==", &gc);
1077 assert_null(proto);
1078
1079 proto = extract_var_peer_info(peer_info_normal, "IV_PROTO=", &gc);
1080 assert_string_equal(proto, "94");
1081
1082
1083 const char *double_eq_info = "FOO=7\nFOO==new";
1084 const char *foo_eq = extract_var_peer_info(double_eq_info, "FOO=", &gc);
1085 const char *foo = extract_var_peer_info(double_eq_info, "FOO", &gc);
1086 const char *foo_2eq = extract_var_peer_info(double_eq_info, "FOO==", &gc);
1087
1088 assert_string_equal(foo, "=7");
1089 assert_string_equal(foo_eq, "7");
1090 assert_string_equal(foo_2eq, "new");
1091
1092 assert_int_equal(extract_asymmetric_peer_id(double_eq_info), MAX_PEER_ID);
1093 assert_int_equal(extract_asymmetric_peer_id(peer_info_normal), MAX_PEER_ID);
1094 assert_int_equal(extract_asymmetric_peer_id(invalid_proto), MAX_PEER_ID);
1095 assert_int_equal(extract_asymmetric_peer_id("ID=f7"), 0xf7);
1096 assert_int_equal(extract_asymmetric_peer_id("X=foo\nID=12ab"), 0x12ab);
1097 assert_int_equal(extract_asymmetric_peer_id("X=foo\nID=34dd\nY=bar"), 0x34dd);
1098 assert_int_equal(extract_asymmetric_peer_id("X=foo\nID=12345678"), MAX_PEER_ID);
1099
1100 gc_free(&gc);
1101}
1102
1103int
1104main(void)
1105{
1107
1108 const struct CMUnitTest tests[] = {
1109 cmocka_unit_test(crypto_pem_encode_certificate),
1110 cmocka_unit_test(test_load_certificate_and_key),
1111 cmocka_unit_test(test_load_certificate_and_key_uri),
1123 cmocka_unit_test(test_data_channel_roundtrip_bf_cbc),
1124 cmocka_unit_test(test_data_channel_known_vectors_epoch),
1126 cmocka_unit_test(crypto_test_print_cert_details),
1127 cmocka_unit_test(ssl_test_extract_last_matching_field),
1128 cmocka_unit_test(ssl_test_reject_null_in_cert_subject),
1130 cmocka_unit_test(ssl_test_extract_peer_info),
1131 cmocka_unit_test(test_acc_parse_client_messages),
1132 cmocka_unit_test(test_parse_acc_parameters),
1133 cmocka_unit_test(test_acc_common_protocols),
1134 cmocka_unit_test(test_acc_send_message),
1135 cmocka_unit_test(test_list_intersection)
1136 };
1137
1138#if defined(ENABLE_CRYPTO_OPENSSL)
1139 tls_init_lib();
1140#endif
1141
1142 int ret = cmocka_run_group_tests_name("ssl tests", tests, init, cleanup);
1143
1144#if defined(ENABLE_CRYPTO_OPENSSL)
1145 tls_free_lib();
1146#endif
1147
1148 return ret;
1149}
bool buf_printf(struct buffer *buf, const char *format,...)
printf-style append to a buffer with overflow check.
Definition buffer.c:226
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Allocate a buffer of the given size under garbage collection.
Definition buffer.c:77
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:986
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:1350
Buffer management functions and garbage collection.
#define BEND(buf)
Return a pointer one past the end of the buffer content.
Definition buffer.h:143
#define BSTR(buf)
Return the buffer content pointer cast to char *.
Definition buffer.h:157
#define CC_ANY
any character
Definition buffer.h:1677
#define BPTR(buf)
Return a pointer to the start of the buffer content.
Definition buffer.h:139
static uint8_t * buf_write_alloc(struct buffer *buf, size_t size)
Reserve space at the end of a buffer for writing.
Definition buffer.h:1189
static bool buf_advance(struct buffer *buf, ssize_t size)
Advance the content start of a buffer, consuming bytes from the front.
Definition buffer.h:1165
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Append data to a buffer.
Definition buffer.h:1239
#define CC_BACKSLASH
backslash
Definition buffer.h:1694
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Append a uint8_t to a buffer.
Definition buffer.h:1283
#define BLEN(buf)
Return the length of the buffer content in bytes.
Definition buffer.h:151
#define BLENZ(buf)
Return the length of the buffer content as a size_t.
Definition buffer.h:153
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
Definition buffer.h:1965
#define ALLOC_OBJ_CLEAR(dptr, type)
Allocate and zero-initialise memory for a single object of the given type.
Definition buffer.h:2027
#define buf_init(buf, offset)
Definition buffer.h:364
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
Definition buffer.h:1949
void free_key_ctx_bi(struct key_ctx_bi *ctx)
Definition crypto.c:1103
void prng_bytes(uint8_t *output, int len)
Definition crypto.c:1697
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:763
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:684
static bool cipher_valid(const char *ciphername)
Returns if the cipher is valid, based on the given cipher name.
#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.
static const char * dco_get_supported_ciphers(void)
Definition dco.h:381
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_ack s...
Definition reliable.h:43
#define ACK_SIZE(n)
Definition reliable.h:81
@ write
#define BUF_SIZE(f)
Definition mtu.h:188
X509 openvpn_x509_cert_t
#define ASSERT(x)
Definition error.h:221
#define MAX_PEER_ID
Definition openvpn.h:552
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:91
void packet_id_free(struct packet_id *p)
Definition packet_id.c:121
#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
const char * platform_get_tmp_dir(void)
Get a directory for temporary files.
Definition platform.c:586
static char * auth_challenge
Definition ssl.c:298
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_new(struct tls_root_ctx *ctx)
Initialise a library-specific TLS context.
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.
char * extract_var_peer_info(const char *peer_info, const char *var, struct gc_arena *gc)
Extracts a variable from peer info, the returned string will be allocated using the supplied gc_arena...
Definition ssl_util.c:63
unsigned int peer_info_extract_int(const char *peer_info, const char *field, const char *format, unsigned int default_value)
Extracts the named integer variable and returns its value or default_value if it cannot be extracted.
Definition ssl_util.c:91
uint32_t extract_asymmetric_peer_id(const char *peer_info)
Extracts the ID variable and returns its value or MAX_PEER_ID if it cannot be extracted.
Definition ssl_util.c:115
unsigned int peer_info_extract_uint(const char *peer_info, const char *field)
Extracts the named integer variable and returns its value or 0 if it cannot be extracted.
Definition ssl_util.c:109
SSL utility functions.
static unsigned int extract_iv_proto(const char *peer_info)
Extracts the IV_PROTO variable and returns its value or 0 if it cannot be extracted.
Definition ssl_util.h:77
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 * x509_get_subject(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)
@ FAILURE
@ SUCCESS
Wrapper structure for dynamically allocated memory.
Definition buffer.h:71
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:76
Contains all state information for one tunnel.
Definition openvpn.h:471
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:113
int tun_mtu
the (user) configured tun-mtu.
Definition mtu.h:147
int payload_size
the maximum size that a payload that our buffers can hold from either tun device or network link.
Definition mtu.h:118
int headroom
the headroom in the buffer, this is choosen to allow all potential header to be added before the pack...
Definition mtu.h:124
struct frame::@8 buf
int tailroom
the tailroom in the buffer.
Definition mtu.h:128
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:127
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.
Definition ssl_mbedtls.h:86
SSL_CTX * ctx
Definition ssl_openssl.h:41
void test_acc_parse_client_messages(void **state)
Definition test_acc.c:79
void test_acc_send_message(void **state)
Definition test_acc.c:264
void test_acc_common_protocols(void **state)
Definition test_acc.c:236
void test_list_intersection(void **state)
Definition test_acc.c:323
void test_parse_acc_parameters(void **state)
Definition test_acc.c:175
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:63
static const char * cert_details_test_cert
Definition test_ssl.c:799
void reschedule_multi_process(struct context *c)
Reschedule tls_multi_process.
Definition test_ssl.c:92
void crypto_test_print_cert_details(void **state)
Definition test_ssl.c:823
static void test_data_channel_roundtrip_aes_192_cbc(void **state)
Definition test_ssl.c:566
static void test_load_certificate_and_key_uri(void **state)
Definition test_ssl.c:230
const char * certfile
Definition test_ssl.c:139
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:81
static openvpn_x509_cert_t * get_certificate(const char *cert_str)
Definition test_ssl.c:778
static void test_data_channel_roundtrip_aes_192_gcm_epoch(void **state)
Definition test_ssl.c:542
const char *const cert_details_org
Definition test_ssl.c:817
static void encrypt_one_packet(struct crypto_options *co, int len)
Definition test_ssl.c:354
void ssl_test_extract_peer_info(void **state)
Definition test_ssl.c:1041
static void test_data_channel_roundtrip_aes_256_cbc(void **state)
Definition test_ssl.c:572
static void test_load_certificate_and_key(void **state)
Definition test_ssl.c:208
void ssl_test_extract_last_matching_field(void **state)
Definition test_ssl.c:910
static const char * cert_with_two_cns
Definition test_ssl.c:895
static void test_data_channel_known_vectors_run(bool epoch)
Definition test_ssl.c:642
static struct key2 create_key(void)
Definition test_ssl.c:614
struct gc_arena gc
Definition test_ssl.c:138
void purge_user_pass(struct user_pass *up, bool force)
Definition test_ssl.c:87
static void check_aead_limits(struct crypto_options *co, bool chachapoly)
Definition test_ssl.c:397
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition test_ssl.c:63
static const char *const unittest_cert
Definition test_ssl.c:112
static void run_data_channel_with_cipher_epoch(const char *cipher)
Definition test_ssl.c:502
const char *const cert_details_serial_number
Definition test_ssl.c:819
static const char * cert_with_null
Definition test_ssl.c:950
static int cleanup(void **state)
Definition test_ssl.c:168
static void do_data_channel_round_trip(struct crypto_options *co)
Definition test_ssl.c:300
static void test_data_channel_roundtrip_aes_128_gcm_epoch(void **state)
Definition test_ssl.c:530
static void crypto_pem_encode_certificate(void **state)
Definition test_ssl.c:178
static void test_data_channel_roundtrip_aes_128_gcm(void **state)
Definition test_ssl.c:524
static const char * cert_with_rfc_2253_chars
Definition test_ssl.c:1009
int main(void)
Definition test_ssl.c:1104
void ssl_test_escape_rfc_2253_chars_in_subject(void **state)
Definition test_ssl.c:1023
static void test_data_channel_roundtrip_aes_192_gcm(void **state)
Definition test_ssl.c:536
void throw_signal(const int signum)
Throw a hard signal.
Definition test_ssl.c:69
const char * keyfile
Definition test_ssl.c:140
static void init_frame_parameters(struct frame *frame)
Definition test_ssl.c:270
static void test_data_channel_roundtrip_bf_cbc(void **state)
Definition test_ssl.c:602
static void test_data_channel_roundtrip_chacha20_poly1305(void **state)
Definition test_ssl.c:578
struct signal_info siginfo_static
Definition test_ssl.c:60
void ssl_test_reject_null_in_cert_subject(void **state)
Definition test_ssl.c:963
static void uninit_crypto_options(struct crypto_options *co)
Definition test_ssl.c:491
static void test_data_channel_roundtrip_aes_256_gcm(void **state)
Definition test_ssl.c:548
const char *const cert_details_cname
Definition test_ssl.c:816
static void test_data_channel_known_vectors_epoch(void **state)
Definition test_ssl.c:746
const char *const cert_details_serial_number_hex
Definition test_ssl.c:820
static void test_data_channel_roundtrip_chacha20_poly1305_epoch(void **state)
Definition test_ssl.c:590
static const char *const unittest_key
Definition test_ssl.c:127
static struct @32 global_state
static void test_data_channel_roundtrip_aes_256_gcm_epoch(void **state)
Definition test_ssl.c:554
static int init(void **state)
Definition test_ssl.c:144
static void free_certificate(openvpn_x509_cert_t *cert)
Definition test_ssl.c:789
static void test_data_channel_roundtrip_aes_128_cbc(void **state)
Definition test_ssl.c:560
static struct crypto_options init_crypto_options(const char *cipher, const char *auth, bool epoch, struct key2 *statickey)
Definition test_ssl.c:448
const char *const cert_details_org_unit
Definition test_ssl.c:818
static void run_data_channel_with_cipher(const char *cipher, const char *auth)
Definition test_ssl.c:513
static void test_data_channel_known_vectors_shortpktid(void **state)
Definition test_ssl.c:752