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
55 struct signal_info siginfo_static; /* GLOBAL */
56 
57 const char *
58 strerror_win32(DWORD errnum, struct gc_arena *gc)
59 {
60  ASSERT(false);
61 }
62 
63 void
64 throw_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 */
75 bool
76 get_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 }
81 void
82 purge_user_pass(struct user_pass *up, bool force)
83 {
84  return;
85 }
86 
87 static 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 
110 static 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 
140 static 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 
153 static struct
154 {
155  struct gc_arena gc;
156  const char *certfile;
157  const char *keyfile;
158 } global_state;
159 
160 static int
161 init(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 
181 static int
182 cleanup(void **state)
183 {
184  (void) state;
185  unlink(global_state.certfile);
186  unlink(global_state.keyfile);
187  gc_free(&global_state.gc);
188  return 0;
189 }
190 
191 static 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 
213  struct buffer exported_pem = buffer_read_from_file(tmpfile, &gc);
214  assert_string_equal(BSTR(&exported_pem), unittest_cert);
215 
216  tls_ctx_free(&ctx);
217  unlink(tmpfile);
218  gc_free(&gc);
219 }
220 
221 static 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);
233  tls_ctx_free(&ctx);
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);
239  tls_ctx_free(&ctx);
240 }
241 
242 /* test loading cert and key using file:/path URI */
243 static 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
270  string_mod(BSTR(&certuri), CC_ANY, CC_BACKSLASH, '/');
271  string_mod(BSTR(&keyuri), CC_ANY, CC_BACKSLASH, '/');
272 #endif /* _WIN32 */
273 
274  tls_ctx_client_new(&ctx);
275  tls_ctx_load_cert_file(&ctx, BSTR(&certuri), false);
276  assert_int_equal(tls_ctx_load_priv_file(&ctx, BSTR(&keyuri), false), 0);
277  tls_ctx_free(&ctx);
278 #endif /* HAVE_OPENSSL_STORE */
279 }
280 
281 
282 static 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) */
294  overhead += ACK_SIZE(RELIABLE_ACK_SIZE);
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 
306  frame->buf.headroom = overhead;
307  frame->buf.tailroom = overhead;
308 
309  frame->tun_mtu = tls_mtu;
310 
311 }
312 
313 static void
315 {
316  struct gc_arena gc = gc_new();
317 
318  /* initialise frame for the test */
319  struct frame frame;
321 
322  struct buffer src = alloc_buf_gc(frame.buf.payload_size, &gc);
323  struct buffer work = alloc_buf_gc(BUF_SIZE(&frame), &gc);
324  struct buffer encrypt_workspace = alloc_buf_gc(BUF_SIZE(&frame), &gc);
325  struct buffer decrypt_workspace = alloc_buf_gc(BUF_SIZE(&frame), &gc);
326  struct buffer buf = clear_buf();
327  void *buf_p;
328 
329  /* init work */
330  ASSERT(buf_init(&work, frame.buf.headroom));
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;
346  ASSERT(rand_bytes(BPTR(&src), BLEN(&src)));
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 */
355  ASSERT(buf_init(&encrypt_workspace, frame.buf.headroom));
356 
357  /* encrypt */
358  openvpn_encrypt(&buf, encrypt_workspace, co);
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 
370 static void
372 {
373  struct frame frame;
375 
376  struct gc_arena gc = gc_new();
377  struct buffer encrypt_workspace = alloc_buf_gc(BUF_SIZE(&frame), &gc);
378  struct buffer decrypt_workspace = alloc_buf_gc(BUF_SIZE(&frame), &gc);
379  struct buffer work = alloc_buf_gc(BUF_SIZE(&frame), &gc);
380  struct buffer buf = clear_buf();
381  struct buffer src = alloc_buf_gc(frame.buf.payload_size, &gc);
382  void *buf_p;
383 
384  ASSERT(buf_init(&work, frame.buf.headroom));
385 
386  /*
387  * Load src with random data.
388  */
389  ASSERT(buf_init(&src, 0));
390  ASSERT(len <= src.capacity);
391  src.len = len;
392  ASSERT(rand_bytes(BPTR(&src), BLEN(&src)));
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 
400  ASSERT(buf_init(&encrypt_workspace, frame.buf.headroom));
401  openvpn_encrypt(&buf, encrypt_workspace, co);
402 
403  /* decrypt */
404  openvpn_decrypt(&buf, decrypt_workspace, co, &frame, BPTR(&buf));
405 
406  /* compare */
407  assert_int_equal(buf.len, src.len);
408  assert_memory_equal(BPTR(&src), BPTR(&buf), len);
409 
410  gc_free(&gc);
411 }
412 
413 
414 static void
415 check_aead_limits(struct crypto_options *co, bool chachapoly)
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  */
433  assert_int_equal(co->key_ctx_bi.encrypt.epoch, expected_epoch);
434 
435  encrypt_one_packet(co, 1000);
436 
437  /* either epoch key has been updated or warning is enabled */
438  if (epoch && !chachapoly)
439  {
440  expected_epoch++;
441  }
442 
443  assert_int_equal(co->key_ctx_bi.encrypt.epoch, expected_epoch);
444 
445  if (!epoch)
446  {
447  /* Check always against the GCM usage limit here to see if that
448  * check works */
449  assert_true(aead_usage_limit_reached((1ull << 36),
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 
462  expected_epoch++;
463  assert_int_equal(co->key_ctx_bi.encrypt.epoch, expected_epoch);
464 }
465 
466 
467 static struct crypto_options
468 init_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 
511 static void
513 {
516  free_epoch_key_ctx(co);
517 }
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 */
522 static 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 
533 static void
534 run_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 
544 static void
546 {
547  run_data_channel_with_cipher("AES-128-GCM", "none");
548 }
549 
550 static void
552 {
553  run_data_channel_with_cipher_epoch("AES-128-GCM");
554 }
555 
556 static void
558 {
559  run_data_channel_with_cipher("AES-192-GCM", "none");
560 }
561 
562 static void
564 {
565  run_data_channel_with_cipher_epoch("AES-192-GCM");
566 }
567 
568 static void
570 {
571  run_data_channel_with_cipher("AES-256-GCM", "none");
572 }
573 
574 static void
576 {
577  run_data_channel_with_cipher_epoch("AES-256-GCM");
578 }
579 
580 static void
582 {
583  run_data_channel_with_cipher("AES-128-CBC", "SHA256");
584 }
585 
586 static void
588 {
589  run_data_channel_with_cipher("AES-192-CBC", "SHA256");
590 }
591 
592 static void
594 {
595  run_data_channel_with_cipher("AES-256-CBC", "SHA256");
596 }
597 
598 static 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 
610 static 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 
622 static 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 
634 static 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 
662 static 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 
676  struct buffer src = alloc_buf_gc(frame.buf.payload_size, &gc);
677  struct buffer work = alloc_buf_gc(BUF_SIZE(&frame), &gc);
678  struct buffer encrypt_workspace = alloc_buf_gc(BUF_SIZE(&frame), &gc);
679  struct buffer decrypt_workspace = alloc_buf_gc(BUF_SIZE(&frame), &gc);
680  struct buffer buf = clear_buf();
681  void *buf_p;
682 
683  /* init work */
684  ASSERT(buf_init(&work, frame.buf.headroom));
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 
694  ASSERT(buf_write(&src, plaintext, strlen(plaintext)));
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 */
703  ASSERT(buf_init(&encrypt_workspace, frame.buf.headroom));
704 
705  /* add packet opcode and peer id */
706  buf_write_u8(&encrypt_workspace, 7);
707  buf_write_u8(&encrypt_workspace, 0);
708  buf_write_u8(&encrypt_workspace, 0);
709  buf_write_u8(&encrypt_workspace, 23);
710 
711  /* encrypt */
712  openvpn_encrypt(&buf, encrypt_workspace, &co);
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};
721  assert_memory_equal(BPTR(&buf), packetid1, 8);
722  }
723  else
724  {
725  uint8_t packetid1[4] = {0, 0, 0, 1};
726  assert_memory_equal(BPTR(&buf), packetid1, 4);
727  }
728 
729  if (epoch)
730  {
731  uint8_t *tag_location = BEND(&buf) - OPENVPN_AEAD_TAG_LENGTH;
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 
736  assert_memory_equal(tag_location, exp_tag_epoch, OPENVPN_AEAD_TAG_LENGTH);
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};
743  assert_memory_equal(tag_location, exp_tag_noepoch, OPENVPN_AEAD_TAG_LENGTH);
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 */
759  openvpn_decrypt(&buf, decrypt_workspace, &co, &frame, ad_start);
760 
761  /* compare */
762  assert_int_equal(buf.len, strlen(plaintext));
763  assert_memory_equal(BPTR(&buf), plaintext, strlen(plaintext));
764 
766  gc_free(&gc);
767 }
768 
769 static void
771 {
773 }
774 
775 static void
777 {
779 }
780 
781 
782 int
783 main(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),
791  cmocka_unit_test(test_data_channel_roundtrip_aes_128_gcm),
793  cmocka_unit_test(test_data_channel_roundtrip_aes_192_gcm),
795  cmocka_unit_test(test_data_channel_roundtrip_aes_256_gcm),
799  cmocka_unit_test(test_data_channel_roundtrip_aes_128_cbc),
800  cmocka_unit_test(test_data_channel_roundtrip_aes_192_cbc),
801  cmocka_unit_test(test_data_channel_roundtrip_aes_256_cbc),
802  cmocka_unit_test(test_data_channel_roundtrip_bf_cbc),
803  cmocka_unit_test(test_data_channel_known_vectors_epoch),
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 }
buffer_read_from_file
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
platform_create_temp_file
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
free_epoch_key_ctx
void free_epoch_key_ctx(struct crypto_options *co)
Frees the extra data structures used by epoch keys in crypto_options.
Definition: crypto_epoch.c:338
CC_BACKSLASH
#define CC_BACKSLASH
backslash
Definition: buffer.h:900
tls_ctx_load_cert_file
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.
Definition: ssl_openssl.c:1257
cipher_valid
static bool cipher_valid(const char *ciphername)
Returns if the cipher is valid, based on the given cipher name.
Definition: crypto_backend.h:205
key2::n
int n
The number of key objects stored in the key2.keys array.
Definition: crypto.h:240
epoch_init_key_ctx
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...
Definition: crypto_epoch.c:353
create_key
static struct key2 create_key(void)
Definition: test_ssl.c:635
ssl_backend.h
KEY_DIRECTION_BIDIRECTIONAL
#define KEY_DIRECTION_BIDIRECTIONAL
Definition: crypto.h:230
gc_new
static struct gc_arena gc_new(void)
Definition: buffer.h:1025
epoch_iterate_send_key
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.
Definition: crypto_epoch.c:275
key2
#define key2
Definition: cert_data.h:82
ssl_verify_backend.h
tls_init_lib
void tls_init_lib(void)
Perform any static initialisation necessary by the library.
Definition: ssl_openssl.c:92
RELIABLE_ACK_SIZE
#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
tls_ctx_load_priv_file
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.
Definition: ssl_openssl.c:1271
buffer::len
int len
Length in bytes of the actual content within the allocated memory.
Definition: buffer.h:66
packet_id_init
void packet_id_init(struct packet_id *p, int seq_backtrack, int time_backtrack, const char *name, int unit)
Definition: packet_id.c:96
win32.h
epoch_key::epoch_key
uint8_t epoch_key[SHA256_DIGEST_LENGTH]
Definition: crypto.h:192
check_aead_limits
static void check_aead_limits(struct crypto_options *co, bool chachapoly)
Definition: test_ssl.c:415
test_data_channel_roundtrip_aes_128_gcm_epoch
static void test_data_channel_roundtrip_aes_128_gcm_epoch(void **state)
Definition: test_ssl.c:551
test_data_channel_roundtrip_bf_cbc
static void test_data_channel_roundtrip_bf_cbc(void **state)
Definition: test_ssl.c:623
buf_init
#define buf_init(buf, offset)
Definition: buffer.h:209
test_common.h
global_state
static struct @27 global_state
static_assert
#define static_assert(expr, diagnostic)
Definition: error.h:212
BSTR
#define BSTR(buf)
Definition: buffer.h:129
test_data_channel_roundtrip_aes_128_gcm
static void test_data_channel_roundtrip_aes_128_gcm(void **state)
Definition: test_ssl.c:545
tls_ctx_client_new
void tls_ctx_client_new(struct tls_root_ctx *ctx)
Initialises a library-specific TLS context for a client.
Definition: ssl_openssl.c:122
buffer::capacity
int capacity
Size in bytes of memory allocated by malloc().
Definition: buffer.h:62
alloc_buf_gc
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
Definition: buffer.c:88
throw_signal
void throw_signal(const int signum)
Throw a hard signal.
Definition: test_ssl.c:64
CO_EPOCH_DATA_KEY_FORMAT
#define CO_EPOCH_DATA_KEY_FORMAT
Bit-flag indicating the epoch the data format.
Definition: crypto.h:376
frame::tailroom
int tailroom
the tailroom in the buffer.
Definition: mtu.h:112
aead_usage_limit_reached
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
key_ctx_bi::encrypt
struct key_ctx encrypt
Cipher and/or HMAC contexts for sending direction.
Definition: crypto.h:280
tls_free_lib
void tls_free_lib(void)
Free any global SSL library-specific data structures.
Definition: ssl_openssl.c:99
clear_buf
static struct buffer clear_buf(void)
Return an empty struct buffer.
Definition: buffer.h:222
BEND
#define BEND(buf)
Definition: buffer.h:125
options.h
run_data_channel_with_cipher_epoch
static void run_data_channel_with_cipher_epoch(const char *cipher)
Definition: test_ssl.c:523
key::hmac
uint8_t hmac[MAX_HMAC_KEY_LENGTH]
Key material for HMAC operations.
Definition: crypto.h:155
frame
Packet geometry parameters.
Definition: mtu.h:98
init_crypto_options
static struct crypto_options init_crypto_options(const char *cipher, const char *auth, bool epoch, struct key2 *statickey)
Definition: test_ssl.c:468
backend_x509_write_pem
result_t backend_x509_write_pem(openvpn_x509_cert_t *cert, const char *filename)
Definition: ssl_verify_openssl.c:325
crypto_pem_encode_certificate
static void crypto_pem_encode_certificate(void **state)
Definition: test_ssl.c:192
get_tmp_dir
static const char * get_tmp_dir(void)
Definition: test_ssl.c:141
test_data_channel_roundtrip_aes_256_gcm_epoch
static void test_data_channel_roundtrip_aes_256_gcm_epoch(void **state)
Definition: test_ssl.c:575
init_key_ctx_bi
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
key
Container for unidirectional cipher and HMAC key material.
Definition: crypto.h:151
test_data_channel_known_vectors_epoch
static void test_data_channel_known_vectors_epoch(void **state)
Definition: test_ssl.c:770
test_data_channel_roundtrip_aes_192_gcm
static void test_data_channel_roundtrip_aes_192_gcm(void **state)
Definition: test_ssl.c:557
options_util.h
free_key_ctx_bi
void free_key_ctx_bi(struct key_ctx_bi *ctx)
Definition: crypto.c:1125
key_ctx::epoch
uint16_t epoch
OpenVPN data channel epoch, this variable holds the epoch number this key belongs to.
Definition: crypto.h:227
ASSERT
#define ASSERT(x)
Definition: error.h:195
frame::buf
struct frame::@8 buf
buf_advance
static bool buf_advance(struct buffer *buf, int size)
Definition: buffer.h:618
OPENVPN_AEAD_TAG_LENGTH
#define OPENVPN_AEAD_TAG_LENGTH
Definition: crypto_backend.h:43
packet_id.h
write
@ write
Definition: interactive.c:224
BLEN
#define BLEN(buf)
Definition: buffer.h:127
buf_write_u8
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Definition: buffer.h:692
frame::payload_size
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
auth_challenge
static char * auth_challenge
Definition: ssl.c:285
update_time
static void update_time(void)
Definition: otime.h:77
test_data_channel_roundtrip_aes_256_cbc
static void test_data_channel_roundtrip_aes_256_cbc(void **state)
Definition: test_ssl.c:593
test_load_certificate_and_key
static void test_load_certificate_and_key(void **state)
Definition: test_ssl.c:222
string_mod
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
openvpn_encrypt
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
test_data_channel_roundtrip_chacha20_poly1305
static void test_data_channel_roundtrip_chacha20_poly1305(void **state)
Definition: test_ssl.c:599
keyfile
const char * keyfile
Definition: test_ssl.c:157
siginfo_static
struct signal_info siginfo_static
Definition: test_ssl.c:55
cleanup
static int cleanup(void **state)
Definition: test_ssl.c:182
test_data_channel_roundtrip_chacha20_poly1305_epoch
static void test_data_channel_roundtrip_chacha20_poly1305_epoch(void **state)
Definition: test_ssl.c:611
crypto.h
tls_ctx_free
void tls_ctx_free(struct tls_root_ctx *ctx)
Frees the library-specific TLSv1 context.
Definition: ssl_openssl.c:140
PACKET_ID_EPOCH_MAX
#define PACKET_ID_EPOCH_MAX
Definition: packet_id.h:48
test_data_channel_roundtrip_aes_192_gcm_epoch
static void test_data_channel_roundtrip_aes_192_gcm_epoch(void **state)
Definition: test_ssl.c:563
purge_user_pass
void purge_user_pass(struct user_pass *up, bool force)
Definition: test_ssl.c:82
openvpn_decrypt
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
certfile
const char * certfile
Definition: test_ssl.c:156
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
test_data_channel_roundtrip_aes_256_gcm
static void test_data_channel_roundtrip_aes_256_gcm(void **state)
Definition: test_ssl.c:569
rand_bytes
int rand_bytes(uint8_t *output, int len)
Wrapper for secure random number generator.
Definition: crypto_openssl.c:593
key_type
Definition: crypto.h:140
mock_msg.h
buf_write
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Definition: buffer.h:668
strerror_win32
const char * strerror_win32(DWORD errnum, struct gc_arena *gc)
Definition: test_ssl.c:58
ssl.h
CC_ANY
#define CC_ANY
any character
Definition: buffer.h:883
init
static int init(void **state)
Definition: test_ssl.c:161
buffer.h
syshead.h
BPTR
#define BPTR(buf)
Definition: buffer.h:124
create_kt
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
encrypt_one_packet
static void encrypt_one_packet(struct crypto_options *co, int len)
Definition: test_ssl.c:371
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
key_type::cipher
const char * cipher
const name of the cipher
Definition: crypto.h:142
init_frame_parameters
static void init_frame_parameters(struct frame *frame)
Definition: test_ssl.c:283
do_data_channel_round_trip
static void do_data_channel_round_trip(struct crypto_options *co)
Definition: test_ssl.c:314
openvpn_unit_test_setup
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
openvpn_x509_cert_t
X509 openvpn_x509_cert_t
Definition: openvpn-plugin.h:40
key_ctx::plaintext_blocks
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
unittest_key
static const char *const unittest_key
Definition: test_ssl.c:110
epoch_key
Definition: crypto.h:191
unittest_cert
static const char *const unittest_cert
Definition: test_ssl.c:87
test_data_channel_known_vectors_run
static void test_data_channel_known_vectors_run(bool epoch)
Definition: test_ssl.c:663
main
int main(void)
Definition: test_ssl.c:783
test_data_channel_known_vectors_shortpktid
static void test_data_channel_known_vectors_shortpktid(void **state)
Definition: test_ssl.c:776
tls_root_ctx
Structure that wraps the TLS context.
Definition: ssl_mbedtls.h:107
signal_info
Definition: sig.h:41
packet_id::send
struct packet_id_send send
Definition: packet_id.h:201
gc_free
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1033
BUF_SIZE
#define BUF_SIZE(f)
Definition: mtu.h:172
win_get_tempdir
const char * win_get_tempdir(void)
Definition: win32-util.c:152
epoch_key::epoch
uint16_t epoch
Definition: crypto.h:193
mss.h
packet_id_send::id
uint64_t id
Definition: packet_id.h:154
key::cipher
uint8_t cipher[MAX_CIPHER_KEY_LENGTH]
Key material for cipher operations.
Definition: crypto.h:153
crypto_options::key_ctx_bi
struct key_ctx_bi key_ctx_bi
OpenSSL cipher and HMAC contexts for both sending and receiving directions.
Definition: crypto.h:293
now
time_t now
Definition: otime.c:34
buf_write_alloc
static uint8_t * buf_write_alloc(struct buffer *buf, size_t size)
Definition: buffer.h:635
config.h
run_data_channel_with_cipher
static void run_data_channel_with_cipher(const char *cipher, const char *auth)
Definition: test_ssl.c:534
test_data_channel_roundtrip_aes_128_cbc
static void test_data_channel_roundtrip_aes_128_cbc(void **state)
Definition: test_ssl.c:581
test_data_channel_roundtrip_aes_192_cbc
static void test_data_channel_roundtrip_aes_192_cbc(void **state)
Definition: test_ssl.c:587
tls_root_ctx::ctx
SSL_CTX * ctx
Definition: ssl_openssl.h:41
key2
Container for bidirectional cipher and HMAC key material.
Definition: crypto.h:238
test_load_certificate_and_key_uri
static void test_load_certificate_and_key_uri(void **state)
Definition: test_ssl.c:244
crypto_epoch.h
crypto_options::packet_id
struct packet_id packet_id
Current packet ID state for both sending and receiving directions.
Definition: crypto.h:330
crypto_options::flags
unsigned int flags
Bit-flags determining behavior of security operation functions.
Definition: crypto.h:383
user_pass
Definition: misc.h:56
key2::keys
struct key keys[2]
Two unidirectional sets of key material.
Definition: crypto.h:242
packet_id_free
void packet_id_free(struct packet_id *p)
Definition: packet_id.c:127
uninit_crypto_options
static void uninit_crypto_options(struct crypto_options *co)
Definition: test_ssl.c:512
ACK_SIZE
#define ACK_SIZE(n)
Definition: reliable.h:68
frame::tun_mtu
int tun_mtu
the (user) configured tun-mtu.
Definition: mtu.h:131
buf_printf
bool buf_printf(struct buffer *buf, const char *format,...)
Definition: buffer.c:240
get_user_pass_cr
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
frame::headroom
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
crypto_options
Security parameter state for processing data channel packets.
Definition: crypto.h:291
gc
struct gc_arena gc
Definition: test_ssl.c:155