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-2024 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, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "syshead.h"
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <stdarg.h>
33#include <string.h>
34#include <setjmp.h>
35#include <cmocka.h>
36
37#include "crypto.h"
38#include "crypto_epoch.h"
39#include "options.h"
40#include "ssl_backend.h"
41#include "options_util.h"
42
43#include "mock_msg.h"
44#include "mss.h"
45#include "ssl_verify_backend.h"
46#include "win32.h"
47#include "test_common.h"
48#include "ssl.h"
49#include "buffer.h"
50#include "packet_id.h"
51
52/* Mock function to be allowed to include win32.c which is required for
53 * getting the temp directory */
54#ifdef _WIN32
55struct signal_info siginfo_static; /* GLOBAL */
56
57const char *
58strerror_win32(DWORD errnum, struct gc_arena *gc)
59{
60 ASSERT(false);
61}
62
63void
64throw_signal(const int signum)
65{
66 ASSERT(false);
67}
68#endif
69
70#if defined(ENABLE_CRYPTO_OPENSSL) && (OPENSSL_VERSION_NUMBER > 0x30000000L)
71#define HAVE_OPENSSL_STORE
72#endif
73
74/* stubs for some unused functions instead of pulling in too many dependencies */
75bool
76get_user_pass_cr(struct user_pass *up, const char *auth_file, const char *prefix,
77 const unsigned int flags, const char *auth_challenge)
78{
79 return false;
80}
81void
82purge_user_pass(struct user_pass *up, bool force)
83{
84 return;
85}
86
87static const char *const unittest_cert =
88 "-----BEGIN CERTIFICATE-----\n"
89 "MIIDYzCCAkugAwIBAgIRALrXTx4lqa8QgF7uGjISxmcwDQYJKoZIhvcNAQELBQAw\n"
90 "GDEWMBQGA1UEAwwNT1ZQTiBURVNUIENBMTAgFw0yMzAzMTMxNjA5MThaGA8yMTIz\n"
91 "MDIxNzE2MDkxOFowGTEXMBUGA1UEAwwOb3Zwbi10ZXN0LXJzYTEwggEiMA0GCSqG\n"
92 "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7xFoR6fmoyfsJIQDKKgbYgFw0MzVuDAmp\n"
93 "Rx6KTEihgTchkQx9fHddWbKiOUbcEnQi3LNux7P4QVl/4dRR3skisBug6Vd5LXeB\n"
94 "GZqmpu5XZiF4DgLz1lX21G0aOogFWkie2qGEcso40159x9FBDl5A3sLP18ubeex0\n"
95 "pd/BzDFv6SLOTyVWO/GCNc8IX/i0uN4mLvoVU00SeqwTPnS+CRXrSq4JjGDJLsXl\n"
96 "0/PlxkjsgU0yOOA0Z2d8Fzk3wClwP6Hc49BOMWKstUIhLbG2DcIv8l29EuEj2w3j\n"
97 "u/7gkewol96XQ2twpPvpoVAaiVh/m7hQUcQORQCD6eJcDjOZVCArAgMBAAGjgaQw\n"
98 "gaEwCQYDVR0TBAIwADAdBgNVHQ4EFgQUqYnRaBHrZmKLtMZES5AuwqzJkGYwUwYD\n"
99 "VR0jBEwwSoAU3MLDNDOK13DqflQ8ra7FeGBXK06hHKQaMBgxFjAUBgNVBAMMDU9W\n"
100 "UE4gVEVTVCBDQTGCFD55ErHXpK2JXS3WkfBm0NB1r3vKMBMGA1UdJQQMMAoGCCsG\n"
101 "AQUFBwMCMAsGA1UdDwQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAZVcXrezA9Aby\n"
102 "sfUNHAsMxrex/EO0PrIPSrmSmc9sCiD8cCIeB6kL8c5iPPigoWW0uLA9zteDRFes\n"
103 "ez+Z8wBY6g8VQ0tFPURDooUg5011GZPDcuw7/PsI4+I2J9q6LHEp+6Oo4faSn/kl\n"
104 "yWYCLjM4FZdGXbOijDacQJiN6HcRv0UdodBrEVRf7YHJJmMCbCI7ZUGW2zef/+rO\n"
105 "e4Lkxh0MLYqCkNKH5ZfoGTC4Oeb0xKykswAanqgR60r+upaLU8PFuI2L9M3vc6KU\n"
106 "F6MgVGSxl6eylJgDYckvJiAbmcp2PD/LRQQOxQA0yqeAMg2cbdvclETuYD6zoFfu\n"
107 "Y8aO7dvDlw==\n"
108 "-----END CERTIFICATE-----\n";
109
110static const char *const unittest_key =
111 "-----BEGIN PRIVATE KEY-----\n"
112 "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC7xFoR6fmoyfsJ\n"
113 "IQDKKgbYgFw0MzVuDAmpRx6KTEihgTchkQx9fHddWbKiOUbcEnQi3LNux7P4QVl/\n"
114 "4dRR3skisBug6Vd5LXeBGZqmpu5XZiF4DgLz1lX21G0aOogFWkie2qGEcso40159\n"
115 "x9FBDl5A3sLP18ubeex0pd/BzDFv6SLOTyVWO/GCNc8IX/i0uN4mLvoVU00SeqwT\n"
116 "PnS+CRXrSq4JjGDJLsXl0/PlxkjsgU0yOOA0Z2d8Fzk3wClwP6Hc49BOMWKstUIh\n"
117 "LbG2DcIv8l29EuEj2w3ju/7gkewol96XQ2twpPvpoVAaiVh/m7hQUcQORQCD6eJc\n"
118 "DjOZVCArAgMBAAECggEACqkuWAAJ3cyCBVWrXs8eDmLTWV9i9DmYvtS75ixIn2rf\n"
119 "v3cl12YevN0f6FgKLuqZT3Vqdqq+DCVhuIIQ9QkKMH8BQpSdE9NCCsFyZ23o8Gtr\n"
120 "EQ7ymfecb+RFwYx7NpqWrvZI32VJGArgPZH/zorLTTGYrAZbmBtHEqRsXOuEDw97\n"
121 "slwwcWaa9ztaYC8/N/7fgsnydaCFSaOByRlWuyvSmHvn6ZwLv8ANOshY6fstC0Jb\n"
122 "BW0GpSe9eZPjpl71VT2RtpghqLV5+iAoFDHoT+eZvBospcUGtfcZSU7RrBjKB8+a\n"
123 "U1d6hwKhduVs2peIQzl+FiOSdWriLcsZv79q4sBhsQKBgQDUDVTf5BGJ8apOs/17\n"
124 "YVk+Ad8Ey8sXvsfk49psmlCRa8Z4g0LVXfrP94qzhtl8U5kE9hs3nEF4j/kX1ZWG\n"
125 "k11tdsNTZN5x5bbAgEgPA6Ap6J/uto0HS8G0vSv0lyBymdKA3p/i5Dx+8Nc9cGns\n"
126 "LGI9MvviLX7pQFIkvbaCkdKwYwKBgQDirowjWZnm7BgVhF0G1m3DY9nQTYYU185W\n"
127 "UESaO5/nVzwUrA+FypJamD+AvmlSuY8rJeQAGAS6nQr9G8/617r+GwJnzRtxC6Vl\n"
128 "4OF5BJRsD70oX4CFOOlycMoJ8tzcYVH7NI8KVocjxb+QW82hqSvEwSsvnwwn3eOW\n"
129 "nr5u5vIHmQKBgCuc3lL6Dl1ntdZgEIdau0cUjXDoFUo589TwxBDIID/4gaZxoMJP\n"
130 "hPFXAVDxMDPw4azyjSB/47tPKTUsuYcnMfT8kynIujOEwnSPLcLgxQU5kgM/ynuw\n"
131 "qhNpQOwaVRMc7f2RTCMXPBYDpNE/GJn5eu8JWGLpZovEreBeoHX0VffvAoGAVrWn\n"
132 "+3mxykhzaf+oyg3KDNysG+cbq+tlDVVE+K5oG0kePVYX1fjIBQmJ+QhdJ3y9jCbB\n"
133 "UVveqzeZVXqHEw/kgoD4aZZmsdZfnVnpRa5/y9o1ZDUr50n+2nzUe/u/ijlb77iK\n"
134 "Is04gnGJNoI3ZWhdyrSNfXjcYH+bKClu9OM4n7kCgYAorc3PAX7M0bsQrrqYxUS8\n"
135 "56UU0YdhAgYitjM7Fm/0iIm0vDpSevxL9js4HnnsSMVR77spCBAGOCCZrTcI3Ejg\n"
136 "xKDYzh1xlfMRjJBuBu5Pd55ZAv9NXFGpsX5SO8fDZQJMwpcbQH36+UdqRRFDpjJ0\n"
137 "ZbX6nKcJ7jciJVKJds59Jg==\n"
138 "-----END PRIVATE KEY-----\n";
139
140static const char *
142{
143 const char *ret;
144#ifdef _WIN32
145 ret = win_get_tempdir();
146#else
147 ret = "/tmp";
148#endif
149 assert_non_null(ret);
150 return ret;
151}
152
153static struct
154{
155 struct gc_arena gc;
156 const char *certfile;
157 const char *keyfile;
159
160static int
161init(void **state)
162{
163 (void) state;
164 global_state.gc = gc_new();
167
168 int certfd = open(global_state.certfile, O_RDWR);
169 int keyfd = open(global_state.keyfile, O_RDWR);
170 if (certfd < 0 || keyfd < 0)
171 {
172 fail_msg("make tmpfile for certificate or key data failed (error = %d)", errno);
173 }
174 assert_int_equal(write(certfd, unittest_cert, strlen(unittest_cert)), strlen(unittest_cert));
175 assert_int_equal(write(keyfd, unittest_key, strlen(unittest_key)), strlen(unittest_key));
176 close(certfd);
177 close(keyfd);
178 return 0;
179}
180
181static int
182cleanup(void **state)
183{
184 (void) state;
185 unlink(global_state.certfile);
186 unlink(global_state.keyfile);
188 return 0;
189}
190
191static void
193{
194 struct gc_arena gc = gc_new();
195
196 struct tls_root_ctx ctx = { 0 };
199
200 openvpn_x509_cert_t *cert = NULL;
201
202 /* we do not have methods to fetch certificates from ssl contexts, use
203 * internal TLS library methods for the unit test */
204#ifdef ENABLE_CRYPTO_OPENSSL
205 cert = SSL_CTX_get0_certificate(ctx.ctx);
206#elif defined(ENABLE_CRYPTO_MBEDTLS)
207 cert = ctx.crt_chain;
208#endif
209
210 const char *tmpfile = platform_create_temp_file(get_tmp_dir(), "ut_pem", &gc);
211 backend_x509_write_pem(cert, tmpfile);
212
215
216 tls_ctx_free(&ctx);
218 gc_free(&gc);
219}
220
221static void
223{
224 (void) state;
225 struct tls_root_ctx ctx = { 0 };
226
227 /* test loading of inlined cert and key.
228 * loading the key also checks that it matches the loaded certificate
229 */
232 assert_int_equal(tls_ctx_load_priv_file(&ctx, unittest_key, true), 0);
234
235 /* test loading of cert and key from file */
237 tls_ctx_load_cert_file(&ctx, global_state.certfile, false);
238 assert_int_equal(tls_ctx_load_priv_file(&ctx, global_state.keyfile, false), 0);
240}
241
242/* test loading cert and key using file:/path URI */
243static void
245{
246 (void) state;
247
248#if !defined(HAVE_OPENSSL_STORE)
249 skip();
250#else /* HAVE_OPENSSL_STORE */
251
252 struct tls_root_ctx ctx = { 0 };
253 const char *certfile = global_state.certfile;
254 const char *keyfile = global_state.keyfile;
255 struct gc_arena *gc = &global_state.gc;
256
257 struct buffer certuri = alloc_buf_gc(6 + strlen(certfile) + 1, gc); /* 6 bytes for "file:/" */
258 struct buffer keyuri = alloc_buf_gc(6 + strlen(keyfile) + 1, gc); /* 6 bytes for "file:/" */
259
260 /* Windows temp file path starts with drive letter -- add a leading slash for URI */
261 const char *lead = "";
262#ifdef _WIN32
263 lead = "/";
264#endif /* _WIN32 */
265 assert_true(buf_printf(&certuri, "file:%s%s", lead, certfile));
266 assert_true(buf_printf(&keyuri, "file:%s%s", lead, keyfile));
267
268 /* On Windows replace any '\' in path by '/' required for URI */
269#ifdef _WIN32
272#endif /* _WIN32 */
273
274 tls_ctx_client_new(&ctx);
275 tls_ctx_load_cert_file(&ctx, BSTR(&certuri), false);
277 tls_ctx_free(&ctx);
278#endif /* HAVE_OPENSSL_STORE */
279}
280
281
282static void
284{
285 int overhead = 0;
286
287 /* tls-auth and tls-crypt */
288 overhead += 128;
289
290 /* TCP length field and opcode */
291 overhead += 3;
292
293 /* ACK array and remote SESSION ID (part of the ACK array) */
295
296 /* Previous OpenVPN version calculated the maximum size and buffer of a
297 * control frame depending on the overhead of the data channel frame
298 * overhead and limited its maximum size to 1250. Since control frames
299 * also need to fit into data channel buffer we have the same
300 * default of 1500 + 100 as data channel buffers have. Increasing
301 * control channel mtu beyond this limit also increases the data channel
302 * buffers */
303 int tls_mtu = 1500;
304 frame->buf.payload_size = tls_mtu + 100;
305
308
309 frame->tun_mtu = tls_mtu;
310
311}
312
313static void
315{
316 struct gc_arena gc = gc_new();
317
318 /* initialise frame for the test */
319 struct frame frame;
321
323 struct buffer work = alloc_buf_gc(BUF_SIZE(&frame), &gc);
326 struct buffer buf = clear_buf();
327 void *buf_p;
328
329 /* init work */
331
332 update_time();
333
334 /* Test encryption, decryption for all packet sizes */
335 for (int i = 1; i <= frame.buf.payload_size; ++i)
336 {
337
338 /* msg(M_INFO, "TESTING ENCRYPT/DECRYPT of packet length=%d", i); */
339
340 /*
341 * Load src with random data.
342 */
343 ASSERT(buf_init(&src, 0));
344 ASSERT(i <= src.capacity);
345 src.len = i;
347
348 /* copy source to input buf */
349 buf = work;
350 buf_p = buf_write_alloc(&buf, BLEN(&src));
351 ASSERT(buf_p);
352 memcpy(buf_p, BPTR(&src), BLEN(&src));
353
354 /* initialize work buffer with buf.headroom bytes of prepend capacity */
356
357 /* encrypt */
359
360 /* decrypt */
361 openvpn_decrypt(&buf, decrypt_workspace, co, &frame, BPTR(&buf));
362
363 /* compare */
364 assert_int_equal(buf.len, src.len);
365 assert_memory_equal(BPTR(&src), BPTR(&buf), i);
366 }
367 gc_free(&gc);
368}
369
370static void
372{
373 struct frame frame;
375
376 struct gc_arena gc = gc_new();
379 struct buffer work = alloc_buf_gc(BUF_SIZE(&frame), &gc);
380 struct buffer buf = clear_buf();
382 void *buf_p;
383
385
386 /*
387 * Load src with random data.
388 */
389 ASSERT(buf_init(&src, 0));
390 ASSERT(len <= src.capacity);
391 src.len = len;
393
394 /* copy source to input buf */
395 buf = work;
396 buf_p = buf_write_alloc(&buf, BLEN(&src));
397 ASSERT(buf_p);
398 memcpy(buf_p, BPTR(&src), BLEN(&src));
399
402
403 /* decrypt */
404 openvpn_decrypt(&buf, decrypt_workspace, co, &frame, BPTR(&buf));
405
406 /* compare */
407 assert_int_equal(buf.len, src.len);
409
410 gc_free(&gc);
411}
412
413
414static void
416{
417
418 /* Check that we correctly react when we have a nearing AEAD limits */
419
420 /* manually increase the send counter to be past
421 * the GCM usage limit */
422 co->key_ctx_bi.encrypt.plaintext_blocks = 0x1ull << 40;
423
424
425 bool epoch = (co->flags & CO_EPOCH_DATA_KEY_FORMAT);
426
427 int expected_epoch = epoch ? 4 : 0;
428
429 /* Ensure that we are still on the initial key (our init_crypto_options
430 * unit test method iterates the initial key to 4) or that it is 0 when
431 * epoch is not in use
432 */
434
435 encrypt_one_packet(co, 1000);
436
437 /* either epoch key has been updated or warning is enabled */
438 if (epoch && !chachapoly)
439 {
441 }
442
444
445 if (!epoch)
446 {
447 /* Check always against the GCM usage limit here to see if that
448 * check works */
450 &co->key_ctx_bi.encrypt,
451 co->packet_id.send.id));
452 return;
453 }
454
455 /* Move to the end of the epoch data key send PID range, ChachaPoly
456 * should now also move to a new epoch data key */
458
459 encrypt_one_packet(co, 1000);
460 encrypt_one_packet(co, 1000);
461
464}
465
466
467static struct crypto_options
468init_crypto_options(const char *cipher, const char *auth, bool epoch,
469 struct key2 *statickey)
470{
471 struct key2 key2 = { .n = 2};
472
473 if (statickey)
474 {
475 /* Use chosen static key instead of random key when defined */
476 key2 = *statickey;
477 }
478 else
479 {
480 ASSERT(rand_bytes(key2.keys[0].cipher, sizeof(key2.keys[0].cipher)));
481 ASSERT(rand_bytes(key2.keys[0].hmac, sizeof(key2.keys[0].hmac)));
482 ASSERT(rand_bytes(key2.keys[1].cipher, sizeof(key2.keys[1].cipher)));
483 ASSERT(rand_bytes(key2.keys[1].hmac, sizeof(key2.keys)[1].hmac));
484 }
485
486 struct crypto_options co = { 0 };
487
488 struct key_type kt = create_kt(cipher, auth, "ssl-test");
489
490 if (epoch)
491 {
492 struct epoch_key e1 = { .epoch = 1, .epoch_key = { 0 }};
493 memcpy(e1.epoch_key, key2.keys[0].cipher, sizeof(e1.epoch_key));
495 epoch_init_key_ctx(&co, &kt, &e1, &e1, 5);
496
497 /* Do a little of dancing for the epoch_send_key_iterate to test
498 * that this works too */
502 }
503 else
504 {
505 init_key_ctx_bi(&co.key_ctx_bi, &key2, KEY_DIRECTION_BIDIRECTIONAL, &kt, "unit-test-ssl");
506 }
507 packet_id_init(&co.packet_id, 5, 5, "UNITTEST", 0);
508 return co;
509}
510
511static void
518
519/* This adds a few more methods than strictly necessary but this allows
520 * us to see which exact test was run from the backtrace of the test
521 * when it fails */
522static void
524{
525 bool ischacha = !strcmp(cipher, "ChaCha20-Poly1305");
526
527 struct crypto_options co = init_crypto_options(cipher, "none", true, NULL);
529 check_aead_limits(&co, ischacha);
531}
532
533static void
534run_data_channel_with_cipher(const char *cipher, const char *auth)
535{
536 bool ischacha = !strcmp(cipher, "ChaCha20-Poly1305");
537 struct crypto_options co = init_crypto_options(cipher, auth, false, NULL);
539 check_aead_limits(&co, ischacha);
541}
542
543
544static void
546{
547 run_data_channel_with_cipher("AES-128-GCM", "none");
548}
549
550static void
555
556static void
558{
559 run_data_channel_with_cipher("AES-192-GCM", "none");
560}
561
562static void
567
568static void
570{
571 run_data_channel_with_cipher("AES-256-GCM", "none");
572}
573
574static void
579
580static void
582{
583 run_data_channel_with_cipher("AES-128-CBC", "SHA256");
584}
585
586static void
588{
589 run_data_channel_with_cipher("AES-192-CBC", "SHA256");
590}
591
592static void
594{
595 run_data_channel_with_cipher("AES-256-CBC", "SHA256");
596}
597
598static void
600{
601 if (!cipher_valid("ChaCha20-Poly1305"))
602 {
603 skip();
604 return;
605 }
606
607 run_data_channel_with_cipher("ChaCha20-Poly1305", "none");
608}
609
610static void
612{
613 if (!cipher_valid("ChaCha20-Poly1305"))
614 {
615 skip();
616 return;
617 }
618
619 run_data_channel_with_cipher_epoch("ChaCha20-Poly1305");
620}
621
622static void
624{
625 if (!cipher_valid("BF-CBC"))
626 {
627 skip();
628 return;
629 }
630 run_data_channel_with_cipher("BF-CBC", "SHA1");
631}
632
633
634static struct key2
636{
637 struct key2 key2 = {.n = 2};
638
639 const uint8_t key[] =
640 {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '0', '1', '2', '3', '4', '5', '6', '7', 'A', 'B', 'C', 'D', 'E', 'F',
641 'G', 'H', 'j', 'k', 'u', 'c', 'h', 'e', 'n', 'l'};
642
643 static_assert(sizeof(key) == 32, "Size of key should be 32 bytes");
644
645 /* copy the key a few times to ensure to have the size we need for
646 * Statickey but XOR it to not repeat it */
647 uint8_t keydata[sizeof(key2.keys)];
648
649 for (int i = 0; i < sizeof(key2.keys); i++)
650 {
651 keydata[i] = (uint8_t) (key[i % sizeof(key)] ^ i);
652 }
653
654 ASSERT(memcpy(key2.keys[0].cipher, keydata, sizeof(key2.keys[0].cipher)));
655 ASSERT(memcpy(key2.keys[0].hmac, keydata + 64, sizeof(key2.keys[0].hmac)));
656 ASSERT(memcpy(key2.keys[1].cipher, keydata + 128, sizeof(key2.keys[1].cipher)));
657 ASSERT(memcpy(key2.keys[1].hmac, keydata + 192, sizeof(key2.keys)[1].hmac));
658
659 return key2;
660}
661
662static void
664{
665 struct key2 key2 = create_key();
666
667 struct crypto_options co = init_crypto_options("AES-256-GCM", "none", epoch,
668 &key2);
669
670 struct gc_arena gc = gc_new();
671
672 /* initialise frame for the test */
673 struct frame frame;
675
677 struct buffer work = alloc_buf_gc(BUF_SIZE(&frame), &gc);
680 struct buffer buf = clear_buf();
681 void *buf_p;
682
683 /* init work */
685
686 now = 0;
687
688 /*
689 * Load src with known data.
690 */
691 ASSERT(buf_init(&src, 0));
692 const char *plaintext = "The quick little fox jumps over the bureaucratic hurdles";
693
695
696 /* copy source to input buf */
697 buf = work;
698 buf_p = buf_write_alloc(&buf, BLEN(&src));
699 ASSERT(buf_p);
700 memcpy(buf_p, BPTR(&src), BLEN(&src));
701
702 /* initialize work buffer with buf.headroom bytes of prepend capacity */
704
705 /* add packet opcode and peer id */
710
711 /* encrypt */
713
714 /* separate buffer in authenticated data and encrypted data */
715 uint8_t *ad_start = BPTR(&buf);
716 buf_advance(&buf, 4);
717
718 if (epoch)
719 {
720 uint8_t packetid1[8] = {0, 0x04, 0, 0, 0, 0, 0, 1};
722 }
723 else
724 {
725 uint8_t packetid1[4] = {0, 0, 0, 1};
727 }
728
729 if (epoch)
730 {
732 const uint8_t exp_tag_epoch[16] =
733 {0x0f, 0xff, 0xf5, 0x91, 0x3d, 0x39, 0xd7, 0x5b,
734 0x18, 0x57, 0x3b, 0x57, 0x48, 0x58, 0x9a, 0x7d};
735
737 }
738 else
739 {
740 uint8_t *tag_location = BPTR(&buf) + 4;
741 const uint8_t exp_tag_noepoch[16] =
742 {0x1f, 0xdd, 0x90, 0x8f, 0x0e, 0x9d, 0xc2, 0x5e, 0x79, 0xd8, 0x32, 0x02, 0x0d, 0x58, 0xe7, 0x3f};
744 }
745
746 /* Check some bytes at the beginning of the encrypted part */
747 if (epoch)
748 {
749 const uint8_t bytesat14[6] = {0x36, 0xaa, 0xb4, 0xd4, 0x9c, 0xe6};
750 assert_memory_equal(BPTR(&buf) + 14, bytesat14, sizeof(bytesat14));
751 }
752 else
753 {
754 const uint8_t bytesat30[6] = {0xa8, 0x2e, 0x6b, 0x17, 0x06, 0xd9};
755 assert_memory_equal(BPTR(&buf) + 30, bytesat30, sizeof(bytesat30));
756 }
757
758 /* decrypt */
760
761 /* compare */
764
766 gc_free(&gc);
767}
768
769static void
774
775static void
780
781
782int
783main(void)
784{
786
787 const struct CMUnitTest tests[] = {
788 cmocka_unit_test(crypto_pem_encode_certificate),
789 cmocka_unit_test(test_load_certificate_and_key),
790 cmocka_unit_test(test_load_certificate_and_key_uri),
802 cmocka_unit_test(test_data_channel_roundtrip_bf_cbc),
805 };
806
807#if defined(ENABLE_CRYPTO_OPENSSL)
808 tls_init_lib();
809#endif
810
811 int ret = cmocka_run_group_tests_name("ssl tests", tests, init, cleanup);
812
813#if defined(ENABLE_CRYPTO_OPENSSL)
814 tls_free_lib();
815#endif
816
817 return ret;
818}
bool buf_printf(struct buffer *buf, const char *format,...)
Definition buffer.c:240
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition buffer.c:88
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:1041
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:1358
#define BEND(buf)
Definition buffer.h:125
#define BSTR(buf)
Definition buffer.h:129
static struct buffer clear_buf(void)
Return an empty struct buffer.
Definition buffer.h:222
#define CC_ANY
any character
Definition buffer.h:883
#define BPTR(buf)
Definition buffer.h:124
static bool buf_advance(struct buffer *buf, int size)
Definition buffer.h:618
static uint8_t * buf_write_alloc(struct buffer *buf, size_t size)
Definition buffer.h:635
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition buffer.h:668
#define CC_BACKSLASH
backslash
Definition buffer.h:900
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Definition buffer.h:692
#define BLEN(buf)
Definition buffer.h:127
static void gc_free(struct gc_arena *a)
Definition buffer.h:1033
#define buf_init(buf, offset)
Definition buffer.h:209
static struct gc_arena gc_new(void)
Definition buffer.h:1025
#define key2
Definition cert_data.h:82
void free_key_ctx_bi(struct key_ctx_bi *ctx)
Definition crypto.c:1125
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:1087
Data Channel Cryptography Module.
#define CO_EPOCH_DATA_KEY_FORMAT
Bit-flag indicating the epoch the data format.
Definition crypto.h:376
#define KEY_DIRECTION_BIDIRECTIONAL
Definition crypto.h:230
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:765
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:685
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:336
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:794
#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:44
#define ACK_SIZE(n)
Definition reliable.h:68
@ write
#define BUF_SIZE(f)
Definition mtu.h:172
#define ASSERT(x)
Definition error.h:195
time_t now
Definition otime.c:34
static void update_time(void)
Definition otime.h:77
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:127
#define PACKET_ID_EPOCH_MAX
Definition packet_id.h:48
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:541
static char * auth_challenge
Definition ssl.c:285
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:99
void tls_init_lib(void)
Perform any static initialisation necessary by the library.
Definition ssl_openssl.c:92
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 library-specific backend interface.
result_t backend_x509_write_pem(openvpn_x509_cert_t *cert, const char *filename)
mbedtls_x509_crt openvpn_x509_cert_t
Wrapper structure for dynamically allocated memory.
Definition buffer.h:61
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:66
Security parameter state for processing data channel packets.
Definition crypto.h:292
unsigned int flags
Bit-flags determining behavior of security operation functions.
Definition crypto.h:383
struct key_ctx_bi key_ctx_bi
OpenSSL cipher and HMAC contexts for both sending and receiving directions.
Definition crypto.h:293
struct packet_id packet_id
Current packet ID state for both sending and receiving directions.
Definition crypto.h:330
uint8_t epoch_key[SHA256_DIGEST_LENGTH]
Definition crypto.h:192
uint16_t epoch
Definition crypto.h:193
Packet geometry parameters.
Definition mtu.h:98
int tun_mtu
the (user) configured tun-mtu.
Definition mtu.h:131
int payload_size
the maximum size that a payload that our buffers can hold from either tun device or network link.
Definition mtu.h:102
int headroom
the headroom in the buffer, this is choosen to allow all potential header to be added before the pack...
Definition mtu.h:108
struct frame::@8 buf
int tailroom
the tailroom in the buffer.
Definition mtu.h:112
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
Container for bidirectional cipher and HMAC key material.
Definition crypto.h:239
int n
The number of key objects stored in the key2.keys array.
Definition crypto.h:240
struct key keys[2]
Two unidirectional sets of key material.
Definition crypto.h:242
struct key_ctx encrypt
Cipher and/or HMAC contexts for sending direction.
Definition crypto.h:280
uint16_t epoch
OpenVPN data channel epoch, this variable holds the epoch number this key belongs to.
Definition crypto.h:227
uint64_t plaintext_blocks
Counter for the number of plaintext block encrypted using this cipher with the current key in number ...
Definition crypto.h:221
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:154
struct packet_id_send send
Definition packet_id.h:201
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:36
static void test_data_channel_roundtrip_aes_192_cbc(void **state)
Definition test_ssl.c:587
static void test_load_certificate_and_key_uri(void **state)
Definition test_ssl.c:244
const char * certfile
Definition test_ssl.c:156
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:76
static void test_data_channel_roundtrip_aes_192_gcm_epoch(void **state)
Definition test_ssl.c:563
static void encrypt_one_packet(struct crypto_options *co, int len)
Definition test_ssl.c:371
static void test_data_channel_roundtrip_aes_256_cbc(void **state)
Definition test_ssl.c:593
static void test_load_certificate_and_key(void **state)
Definition test_ssl.c:222
static void test_data_channel_known_vectors_run(bool epoch)
Definition test_ssl.c:663
static struct key2 create_key(void)
Definition test_ssl.c:635
struct gc_arena gc
Definition test_ssl.c:155
void purge_user_pass(struct user_pass *up, bool force)
Definition test_ssl.c:82
static void check_aead_limits(struct crypto_options *co, bool chachapoly)
Definition test_ssl.c:415
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition test_ssl.c:58
static const char *const unittest_cert
Definition test_ssl.c:87
static void run_data_channel_with_cipher_epoch(const char *cipher)
Definition test_ssl.c:523
static int cleanup(void **state)
Definition test_ssl.c:182
static struct @27 global_state
static void do_data_channel_round_trip(struct crypto_options *co)
Definition test_ssl.c:314
static void test_data_channel_roundtrip_aes_128_gcm_epoch(void **state)
Definition test_ssl.c:551
static void crypto_pem_encode_certificate(void **state)
Definition test_ssl.c:192
static void test_data_channel_roundtrip_aes_128_gcm(void **state)
Definition test_ssl.c:545
int main(void)
Definition test_ssl.c:783
static void test_data_channel_roundtrip_aes_192_gcm(void **state)
Definition test_ssl.c:557
void throw_signal(const int signum)
Throw a hard signal.
Definition test_ssl.c:64
const char * keyfile
Definition test_ssl.c:157
static void init_frame_parameters(struct frame *frame)
Definition test_ssl.c:283
static void test_data_channel_roundtrip_bf_cbc(void **state)
Definition test_ssl.c:623
static void test_data_channel_roundtrip_chacha20_poly1305(void **state)
Definition test_ssl.c:599
struct signal_info siginfo_static
Definition test_ssl.c:55
static const char * get_tmp_dir(void)
Definition test_ssl.c:141
static void uninit_crypto_options(struct crypto_options *co)
Definition test_ssl.c:512
static void test_data_channel_roundtrip_aes_256_gcm(void **state)
Definition test_ssl.c:569
static void test_data_channel_known_vectors_epoch(void **state)
Definition test_ssl.c:770
static void test_data_channel_roundtrip_chacha20_poly1305_epoch(void **state)
Definition test_ssl.c:611
static const char *const unittest_key
Definition test_ssl.c:110
static void test_data_channel_roundtrip_aes_256_gcm_epoch(void **state)
Definition test_ssl.c:575
static int init(void **state)
Definition test_ssl.c:161
static void test_data_channel_roundtrip_aes_128_cbc(void **state)
Definition test_ssl.c:581
static struct crypto_options init_crypto_options(const char *cipher, const char *auth, bool epoch, struct key2 *statickey)
Definition test_ssl.c:468
static void run_data_channel_with_cipher(const char *cipher, const char *auth)
Definition test_ssl.c:534
static void test_data_channel_known_vectors_shortpktid(void **state)
Definition test_ssl.c:776
const char * win_get_tempdir(void)
Definition win32-util.c:152