Asterisk - The Open Source Telephony Project  21.4.1
test_crypto.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2022, Philip Prindeville
5  *
6  * Philip Prindeville <philipp@redfish-solutions.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 /*!
20  * \file
21  * \brief Unit Tests for crypto API
22  *
23  * \author Philip Prindeville <philipp@redfish-solutions.com>
24  */
25 
26 /*** MODULEINFO
27  <depend>TEST_FRAMEWORK</depend>
28  <depend>res_crypto</depend>
29  <depend>crypto</depend>
30  <support_level>core</support_level>
31  ***/
32 
33 #include "asterisk.h"
34 
35 #include "asterisk/utils.h"
36 #include "asterisk/test.h"
37 #include "asterisk/crypto.h"
38 #include "asterisk/paths.h"
39 #include "asterisk/module.h"
40 #include "asterisk/file.h"
41 
42 #include <assert.h>
43 #include <sys/stat.h>
44 #include <linux/limits.h>
45 #include <openssl/evp.h>
46 
47 static const char *keypair1 = "rsa_key1";
48 
49 static const char *old_key_dir = NULL;
50 
51 static char *hexstring(const unsigned char *data, unsigned datalen)
52 {
53  char *buf = ast_malloc(datalen * 2 + 1);
54  unsigned n;
55 
56  for (n = 0; n < datalen; ++n) {
57  snprintf(&buf[n * 2], 3, "%02x", data[n]);
58  }
59  buf[datalen * 2] = '\0';
60 
61  return buf;
62 }
63 
64 static void push_key_dir(const char *dir)
65 {
66  assert(old_key_dir == NULL);
67 
68  old_key_dir = ast_config_AST_KEY_DIR;
69 
70  ast_config_AST_KEY_DIR = ast_strdup(dir);
71 }
72 
73 static void pop_key_dir(void)
74 {
75  assert(old_key_dir != NULL);
76 
77  ast_free((char *)ast_config_AST_KEY_DIR);
78 
79  ast_config_AST_KEY_DIR = old_key_dir;
80 
81  old_key_dir = NULL;
82 }
83 
84 AST_TEST_DEFINE(crypto_rsa_encrypt)
85 {
86  int res = AST_TEST_FAIL;
87  struct ast_key *key = NULL;
88  const unsigned char plaintext[23] = "Mary had a little lamb.";
89  char wd[PATH_MAX], key_dir[PATH_MAX], priv[PATH_MAX];
90  unsigned char buf[AST_CRYPTO_RSA_KEY_BITS / 8];
91  const char *command = "openssl";
92  char *args[] = { "openssl", "pkeyutl", "-decrypt", "-inkey", "PRIVATE", "-pkeyopt", "rsa_padding_mode:oaep", NULL };
93  enum { PRIVATE = 4 };
94  struct ast_test_capture cap;
95 
96  switch (cmd) {
97  case TEST_INIT:
98  info->name = "crypto_rsa_encrypt";
99  info->category = "/res/res_crypto/";
100  info->summary = "Encrypt w/ RSA public key";
101  info->description = "Encrypt string with RSA public key";
102  return AST_TEST_NOT_RUN;
103  case TEST_EXECUTE:
104  break;
105  }
106 
107  ast_test_status_update(test, "Executing RSA encryption test\n");
108 
109  ast_test_capture_init(&cap);
110 
111  if (!ast_check_command_in_path(command)) {
112  ast_test_status_update(test, "couldn't find %s\n", command);
113  ast_test_capture_free(&cap);
114  return res;
115  }
116 
117  if (getcwd(wd, sizeof(wd)) == NULL) {
118  ast_test_status_update(test, "Could not determine current working directory\n");
119  ast_test_capture_free(&cap);
120  return res;
121  }
122 
123  snprintf(key_dir, sizeof(key_dir), "%s/%s", wd, "tests/keys");
124  push_key_dir((const char *)key_dir);
125  snprintf(priv, sizeof(priv), "%s/%s.key", key_dir, keypair1);
126 
127  /* because git doesn't preserve permissions */
128  (void)chmod(priv, 0400);
129 
130  if (ast_crypto_reload() != 1) {
131  ast_test_status_update(test, "Couldn't force crypto reload\n");
132  goto cleanup;
133  }
134 
135  key = ast_key_get(keypair1, AST_KEY_PUBLIC);
136 
137  if (!key) {
138  ast_test_status_update(test, "Couldn't read key: %s\n", keypair1);
139  goto cleanup;
140  }
141 
142  memset(buf, 0, sizeof(buf));
143  ast_encrypt_bin(buf, plaintext, sizeof(plaintext), key);
144 
145  args[PRIVATE] = priv;
146  if (ast_test_capture_command(&cap, command, args, (const char *)buf, sizeof(buf)) != 1) {
147  ast_test_status_update(test, "ast_test_capture_command() failed\n");
148  goto cleanup;
149  }
150 
151  if (cap.outlen != sizeof(plaintext) || memcmp(cap.outbuf, plaintext, cap.outlen)) {
152  ast_test_status_update(test, "Unexpected value/length for stdout: '%.*s' (%zu)\n", (int) cap.outlen, cap.outbuf, cap.outlen);
153  goto cleanup;
154  }
155 
156  if (cap.errlen != 0) {
157  ast_test_status_update(test, "Unexpected length for stderr: '%.*s' (%zu)\n", (int) cap.errlen, cap.errbuf, cap.errlen);
158  goto cleanup;
159  }
160 
161  if (cap.pid == -1) {
162  ast_test_status_update(test, "Invalid process id\n");
163  goto cleanup;
164  }
165 
166  if (cap.exitcode != 0) {
167  ast_test_status_update(test, "Child exited %d\n", cap.exitcode);
168  goto cleanup;
169  }
170 
171  res = AST_TEST_PASS;
172 
173 cleanup:
174  ast_test_capture_free(&cap);
175  pop_key_dir();
176  return res;
177 }
178 
179 AST_TEST_DEFINE(crypto_rsa_decrypt)
180 {
181  int res = AST_TEST_FAIL;
182  struct ast_key *key = NULL;
183  const unsigned char plaintext[23] = "Mary had a little lamb.";
184  char wd[PATH_MAX], key_dir[PATH_MAX], pub[PATH_MAX];
185  unsigned char buf[AST_CRYPTO_RSA_KEY_BITS / 8];
186  const char *command = "openssl";
187  char *args[] = { "openssl", "pkeyutl", "-encrypt", "-pubin", "-inkey", "PUBLIC", "-pkeyopt", "rsa_padding_mode:oaep", NULL };
188  enum { PUBLIC = 5 };
189  struct ast_test_capture cap;
190  int len;
191 
192  switch (cmd) {
193  case TEST_INIT:
194  info->name = "crypto_decrypt_pub_key";
195  info->category = "/res/res_crypto/";
196  info->summary = "Decrypt w/ RSA public key";
197  info->description = "Decrypt string with RSA private key";
198  return AST_TEST_NOT_RUN;
199  case TEST_EXECUTE:
200  break;
201  }
202 
203  ast_test_status_update(test, "Executing RSA decryption test\n");
204 
205  ast_test_capture_init(&cap);
206 
207  if (!ast_check_command_in_path(command)) {
208  ast_test_status_update(test, "couldn't find %s\n", command);
209  ast_test_capture_free(&cap);
210  return res;
211  }
212 
213  if (getcwd(wd, sizeof(wd)) == NULL) {
214  ast_test_status_update(test, "Could not determine current working directory\n");
215  ast_test_capture_free(&cap);
216  return res;
217  }
218 
219  snprintf(key_dir, sizeof(key_dir), "%s/%s", wd, "tests/keys");
220  push_key_dir((const char *)key_dir);
221  snprintf(pub, sizeof(pub), "%s/%s.pub", key_dir, keypair1);
222 
223  if (ast_crypto_reload() != 1) {
224  ast_test_status_update(test, "Couldn't force crypto reload\n");
225  goto cleanup;
226  }
227 
228  key = ast_key_get(keypair1, AST_KEY_PRIVATE);
229 
230  if (!key) {
231  ast_test_status_update(test, "Couldn't read key: %s\n", keypair1);
232  goto cleanup;
233  }
234 
235  args[PUBLIC] = pub;
236  if (ast_test_capture_command(&cap, command, args, (const char *)plaintext, sizeof(plaintext)) != 1) {
237  ast_test_status_update(test, "ast_test_capture_command() failed\n");
238  goto cleanup;
239  }
240 
241  if (cap.outlen != sizeof(buf)) {
242  ast_test_status_update(test, "Unexpected length for stdout: %zu\n", cap.outlen);
243  goto cleanup;
244  }
245 
246  if (cap.errlen != 0) {
247  ast_test_status_update(test, "Unexpected value/length for stderr: '%.*s' (%zu)\n", (int) cap.errlen, cap.errbuf, cap.errlen);
248  goto cleanup;
249  }
250 
251  if (cap.pid == -1) {
252  ast_test_status_update(test, "Invalid process id\n");
253  goto cleanup;
254  }
255 
256  if (cap.exitcode != 0) {
257  ast_test_status_update(test, "Child exited %d\n", cap.exitcode);
258  goto cleanup;
259  }
260 
261  memset(buf, 0, sizeof(buf));
262  len = ast_decrypt_bin(buf, (unsigned char *)cap.outbuf, cap.outlen, key);
263 
264  if (len != sizeof(plaintext) || memcmp(buf, plaintext, len)) {
265  ast_test_status_update(test, "Unexpected value for decrypted text\n");
266  goto cleanup;
267  }
268 
269  res = AST_TEST_PASS;
270 
271 cleanup:
272  ast_test_capture_free(&cap);
273  pop_key_dir();
274  return res;
275 }
276 
277 AST_TEST_DEFINE(crypto_sign)
278 {
279  int res = AST_TEST_FAIL;
280  struct ast_key *key = NULL;
281  const char plaintext[23] = "Mary had a little lamb.";
282  char wd[PATH_MAX], key_dir[PATH_MAX], pub[PATH_MAX];
283  unsigned char buf[AST_CRYPTO_RSA_KEY_BITS / 8];
284  const char *command = "openssl";
285  char *args[] = { "openssl", "pkeyutl", "-verify", "-inkey", "PUBLIC", "-pubin", "-sigfile", "SIGNATURE", "-pkeyopt", "digest:sha1", NULL };
286  enum { PUBLIC = 4, SIGNATURE = 7 };
287  struct ast_test_capture cap;
288  unsigned char digest[20];
289  unsigned digestlen;
290  EVP_MD_CTX *ctx;
291  FILE *fsig = NULL;
292  char signpath[64] = "/tmp/signingXXXXXX";
293  const char success[] = "Signature Verified Successfully\n";
294 
295  switch (cmd) {
296  case TEST_INIT:
297  info->name = "crypto_sign";
298  info->category = "/res/res_crypto/";
299  info->summary = "Sign w/ RSA private key";
300  info->description = "Sign string with RSA private key";
301  return AST_TEST_NOT_RUN;
302  case TEST_EXECUTE:
303  break;
304  }
305 
306  ast_test_status_update(test, "Executing RSA signing test\n");
307 
308  ast_test_capture_init(&cap);
309 
310  if (!ast_check_command_in_path(command)) {
311  ast_test_status_update(test, "couldn't find %s\n", command);
312  ast_test_capture_free(&cap);
313  return res;
314  }
315 
316  if (getcwd(wd, sizeof(wd)) == NULL) {
317  ast_test_status_update(test, "Could not determine current working directory\n");
318  ast_test_capture_free(&cap);
319  return res;
320  }
321 
322  snprintf(key_dir, sizeof(key_dir), "%s/%s", wd, "tests/keys");
323  push_key_dir((const char *)key_dir);
324  snprintf(pub, sizeof(pub), "%s/%s.pub", key_dir, keypair1);
325 
326  ctx = EVP_MD_CTX_create();
327  EVP_DigestInit(ctx, EVP_sha1());
328  EVP_DigestUpdate(ctx, plaintext, sizeof(plaintext));
329  EVP_DigestFinal(ctx, digest, &digestlen);
330  EVP_MD_CTX_destroy(ctx);
331  ctx = NULL;
332 
333  if (ast_crypto_reload() != 1) {
334  ast_test_status_update(test, "Couldn't force crypto reload\n");
335  goto cleanup;
336  }
337 
338  key = ast_key_get(keypair1, AST_KEY_PRIVATE);
339 
340  if (!key) {
341  ast_test_status_update(test, "Couldn't read key: %s\n", keypair1);
342  goto cleanup;
343  }
344 
345  memset(buf, 0, sizeof(buf));
346  if (ast_sign_bin(key, plaintext, sizeof(plaintext), buf) != 0) {
347  ast_test_status_update(test, "ast_sign_bin() failed\n");
348  goto cleanup;
349  }
350 
351  fsig = ast_file_mkftemp(signpath, 0600);
352  if (fsig == NULL) {
353  ast_test_status_update(test, "Couldn't open temp signing file\n");
354  goto cleanup;
355  }
356  fwrite(buf, sizeof(char), sizeof(buf), fsig);
357  fclose(fsig);
358  fsig = NULL;
359 
360  args[PUBLIC] = pub;
361  args[SIGNATURE] = signpath;
362  if (ast_test_capture_command(&cap, command, args, (const char *)digest, digestlen) != 1) {
363  ast_test_status_update(test, "ast_test_capture_command() failed\n");
364  goto cleanup;
365  }
366 
367  if (cap.outlen != sizeof(success) - 1 || memcmp(cap.outbuf, success, cap.outlen)) {
368  ast_test_status_update(test, "Unexpected value/length for stdout: '%.*s' (%zu)\n", (int) cap.outlen, cap.outbuf, cap.outlen);
369  goto cleanup;
370  }
371 
372  if (cap.errlen != 0) {
373  ast_test_status_update(test, "Unexpected value for stderr: '%.*s' (%zu)\n", (int) cap.errlen, cap.errbuf, cap.errlen);
374  goto cleanup;
375  }
376 
377  if (cap.pid == -1) {
378  ast_test_status_update(test, "Invalid process id\n");
379  goto cleanup;
380  }
381 
382 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
383  if (cap.exitcode != 0) {
384 #else
385  if (cap.exitcode != 0 && cap.exitcode != 1) {
386 #endif
387  ast_test_status_update(test, "Child exited %d\n", cap.exitcode);
388  goto cleanup;
389  }
390 
391  res = AST_TEST_PASS;
392 
393 cleanup:
394  ast_test_capture_free(&cap);
395  unlink(signpath);
396  pop_key_dir();
397  return res;
398 }
399 
400 AST_TEST_DEFINE(crypto_verify)
401 {
402  int res = AST_TEST_FAIL;
403  struct ast_key *key = NULL;
404  const char plaintext[23] = "Mary had a little lamb.";
405  char wd[PATH_MAX], key_dir[PATH_MAX], priv[PATH_MAX];
406  const char *command = "openssl";
407  char *args[] = { "openssl", "pkeyutl", "-sign", "-inkey", "PRIVATE", "-pkeyopt", "digest:sha1", NULL };
408  enum { PRIVATE = 4 };
409  struct ast_test_capture cap;
410  unsigned char digest[20];
411  unsigned digestlen;
412  EVP_MD_CTX *ctx;
413 
414  switch (cmd) {
415  case TEST_INIT:
416  info->name = "crypto_verify";
417  info->category = "/res/res_crypto/";
418  info->summary = "Verify w/ RSA public key";
419  info->description = "Verify signature with RSA public key";
420  return AST_TEST_NOT_RUN;
421  case TEST_EXECUTE:
422  break;
423  }
424 
425  ast_test_status_update(test, "Executing RSA signature verification test\n");
426 
427  ast_test_capture_init(&cap);
428 
429  if (!ast_check_command_in_path(command)) {
430  ast_test_status_update(test, "couldn't find %s\n", command);
431  ast_test_capture_free(&cap);
432  return res;
433  }
434 
435  if (getcwd(wd, sizeof(wd)) == NULL) {
436  ast_test_status_update(test, "Could not determine current working directory\n");
437  ast_test_capture_free(&cap);
438  return res;
439  }
440 
441  snprintf(key_dir, sizeof(key_dir), "%s/%s", wd, "tests/keys");
442  push_key_dir((const char *)key_dir);
443  snprintf(priv, sizeof(priv), "%s/%s.key", key_dir, keypair1);
444 
445  /* because git doesn't preserve permissions */
446  (void)chmod(priv, 0400);
447 
448  if (ast_crypto_reload() != 1) {
449  ast_test_status_update(test, "Couldn't force crypto reload\n");
450  goto cleanup;
451  }
452 
453  key = ast_key_get(keypair1, AST_KEY_PUBLIC);
454 
455  if (!key) {
456  ast_test_status_update(test, "Couldn't read key: %s\n", keypair1);
457  goto cleanup;
458  }
459 
460  ctx = EVP_MD_CTX_create();
461  EVP_DigestInit(ctx, EVP_sha1());
462  EVP_DigestUpdate(ctx, plaintext, sizeof(plaintext));
463  EVP_DigestFinal(ctx, digest, &digestlen);
464  EVP_MD_CTX_destroy(ctx);
465 
466  args[PRIVATE] = priv;
467  if (ast_test_capture_command(&cap, command, args, (const char *)digest, sizeof(digest)) != 1) {
468  ast_test_status_update(test, "ast_test_capture_command() failed\n");
469  goto cleanup;
470  }
471 
472  if (cap.outlen != (AST_CRYPTO_RSA_KEY_BITS / 8)) {
473  ast_test_status_update(test, "Unexpected length for stdout: %zu\n", cap.outlen);
474  goto cleanup;
475  }
476 
477  if (cap.errlen != 0) {
478  ast_test_status_update(test, "Unexpected value/length for stderr: '%.*s'\n", (int) cap.errlen, cap.errbuf);
479  goto cleanup;
480  }
481 
482  if (cap.pid == -1) {
483  ast_test_status_update(test, "Invalid process id\n");
484  goto cleanup;
485  }
486 
487  if (cap.exitcode != 0) {
488  ast_test_status_update(test, "Child exited %d\n", cap.exitcode);
489  goto cleanup;
490  }
491 
492  if (ast_check_signature_bin(key, plaintext, sizeof(plaintext), (const unsigned char *)cap.outbuf) != 0) {
493  ast_test_status_update(test, "ast_check_signature_bin() failed\n");
494  goto cleanup;
495  }
496 
497  res = AST_TEST_PASS;
498 
499 cleanup:
500  ast_test_capture_free(&cap);
501  pop_key_dir();
502  return res;
503 }
504 
505 AST_TEST_DEFINE(crypto_aes_encrypt)
506 {
507  int res = AST_TEST_FAIL;
508  const unsigned char key[16] = {
509  0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x23, 0x45,
510  0x67, 0x89, 0x01, 0x23, 0x45, 0x67, 0x89, 0x01
511  };
512  const unsigned char plaintext[16] = "Mary had a littl";
513  const char *command = "openssl";
514  char *args[] = { "openssl", "enc", "-aes-128-ecb", "-d", "-K", "KEY", "-nopad", NULL };
515  enum { KEY = 5 };
516  struct ast_test_capture cap;
517  unsigned char buf[16];
519 
520  switch (cmd) {
521  case TEST_INIT:
522  info->name = "crypto_aes_encrypt";
523  info->category = "/res/res_crypto/";
524  info->summary = "Encrypt test AES-128-ECB";
525  info->description = "Encrypt a test string using AES-128 and ECB";
526  return AST_TEST_NOT_RUN;
527  case TEST_EXECUTE:
528  break;
529  }
530 
531  ast_test_status_update(test, "Executing AES-ECB encryption test\n");
532 
533  ast_test_capture_init(&cap);
534 
535  if (!ast_check_command_in_path(command)) {
536  ast_test_status_update(test, "couldn't find %s\n", command);
537  return res;
538  }
539 
540  memset(buf, 0, sizeof(buf));
541  ast_aes_set_encrypt_key(key, &aes_key);
542  if (ast_aes_encrypt(plaintext, buf, &aes_key) <= 0) {
543  ast_test_status_update(test, "ast_aes_encrypt() failed\n");
544  goto cleanup;
545  }
546 
547  args[KEY] = hexstring(key, sizeof(key));
548  if (ast_test_capture_command(&cap, command, args, (const char *)buf, sizeof(buf)) != 1) {
549  ast_test_status_update(test, "ast_test_capture_command() failed\n");
550  goto cleanup;
551  }
552 
553  if (cap.outlen != sizeof(plaintext) || memcmp(cap.outbuf, plaintext, cap.outlen)) {
554  ast_test_status_update(test, "Unexpected value/length for stdout: '%.*s' (%zu)\n", (int) cap.outlen, cap.outbuf, cap.outlen);
555  goto cleanup;
556  }
557 
558  if (cap.errlen != 0) {
559  ast_test_status_update(test, "Unexpected value/length for stderr: '%.*s'\n", (int) cap.errlen, cap.errbuf);
560  goto cleanup;
561  }
562 
563  if (cap.pid == -1) {
564  ast_test_status_update(test, "Invalid process id\n");
565  goto cleanup;
566  }
567 
568  if (cap.exitcode != 0) {
569  ast_test_status_update(test, "Child exited %d\n", cap.exitcode);
570  goto cleanup;
571  }
572 
573  res = AST_TEST_PASS;
574 
575 cleanup:
576  ast_free(args[KEY]);
577  ast_test_capture_free(&cap);
578  return res;
579 }
580 
581 AST_TEST_DEFINE(crypto_aes_decrypt)
582 {
583  int res = AST_TEST_FAIL;
584  const unsigned char key[16] = {
585  0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x23, 0x45,
586  0x67, 0x89, 0x01, 0x23, 0x45, 0x67, 0x89, 0x01
587  };
588  const unsigned char plaintext[16] = "Mary had a littl";
589  unsigned char buf[16];
590  const char *command = "openssl";
591  char *args[] = { "openssl", "enc", "-aes-128-ecb", "-e", "-K", "KEY", "-nopad", NULL };
592  enum { KEY = 5 };
593  struct ast_test_capture cap;
594  ast_aes_encrypt_key aes_key;
595 
596  switch (cmd) {
597  case TEST_INIT:
598  info->name = "crypto_aes_decrypt";
599  info->category = "/res/res_crypto/";
600  info->summary = "Decrypt test AES-128-ECB";
601  info->description = "Decrypt a test string using AES-128 and ECB";
602  return AST_TEST_NOT_RUN;
603  case TEST_EXECUTE:
604  break;
605  }
606 
607  ast_test_status_update(test, "Executing AES-ECB decryption test\n");
608 
609  ast_test_capture_init(&cap);
610 
611  if (!ast_check_command_in_path(command)) {
612  ast_test_status_update(test, "couldn't find %s\n", command);
613  return res;
614  }
615 
616  args[KEY] = hexstring(key, sizeof(key));
617  if (ast_test_capture_command(&cap, command, args, (const char *)plaintext, sizeof(plaintext)) != 1) {
618  ast_test_status_update(test, "ast_test_capture_command() failed\n");
619  goto cleanup;
620  }
621 
622  if (cap.outlen != sizeof(buf)) {
623  ast_test_status_update(test, "Unexpected length for stdout: %zu\n", cap.outlen);
624  goto cleanup;
625  }
626 
627  if (cap.errlen != 0) {
628  ast_test_status_update(test, "Unexpected value/length for stderr: '%.*s'\n", (int) cap.errlen, cap.errbuf);
629  goto cleanup;
630  }
631 
632  if (cap.pid == -1) {
633  ast_test_status_update(test, "Invalid process id\n");
634  goto cleanup;
635  }
636 
637  if (cap.exitcode != 0) {
638  ast_test_status_update(test, "Child exited %d\n", cap.exitcode);
639  goto cleanup;
640  }
641 
642  memset(buf, 0, sizeof(buf));
643  ast_aes_set_decrypt_key(key, &aes_key);
644  if (ast_aes_decrypt((const unsigned char *)cap.outbuf, buf, &aes_key) <= 0) {
645  ast_test_status_update(test, "ast_aes_decrypt() failed\n");
646  goto cleanup;
647  }
648 
649  if (memcmp(plaintext, buf, sizeof(plaintext))) {
650  ast_test_status_update(test, "AES decryption mismatch\n");
651  goto cleanup;
652  }
653 
654  res = AST_TEST_PASS;
655 
656 cleanup:
657  ast_free(args[KEY]);
658  ast_test_capture_free(&cap);
659  return res;
660 }
661 
662 static int unload_module(void)
663 {
664  AST_TEST_UNREGISTER(crypto_rsa_encrypt);
665  AST_TEST_UNREGISTER(crypto_rsa_decrypt);
666  AST_TEST_UNREGISTER(crypto_sign);
667  AST_TEST_UNREGISTER(crypto_verify);
668  AST_TEST_UNREGISTER(crypto_aes_encrypt);
669  AST_TEST_UNREGISTER(crypto_aes_decrypt);
670  return 0;
671 }
672 
673 static int load_module(void)
674 {
675  AST_TEST_REGISTER(crypto_rsa_encrypt);
676  AST_TEST_REGISTER(crypto_rsa_decrypt);
677  AST_TEST_REGISTER(crypto_sign);
678  AST_TEST_REGISTER(crypto_verify);
679  AST_TEST_REGISTER(crypto_aes_encrypt);
680  AST_TEST_REGISTER(crypto_aes_decrypt);
682 }
683 
684 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Crypto test module",
685  .support_level = AST_MODULE_SUPPORT_CORE,
686  .load = load_module,
687  .unload = unload_module,
688  .requires = "res_crypto",
689 );
Asterisk main include file. File version handling, generic pbx functions.
Provide cryptographic signature routines.
Test Framework API.
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
Utility functions.
static void cleanup(void)
Clean up any old apps that we don't need any more.
Definition: res_stasis.c:327
Asterisk file paths, configured in asterisk.conf.
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
int AST_OPTIONAL_API_NAME() ast_encrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
encrypt a message
Definition: res_crypto.c:549
int AST_OPTIONAL_API_NAME() ast_sign_bin(struct ast_key *key, const char *msg, int msglen, unsigned char *dsig)
signs outgoing message with public key
Definition: res_crypto.c:390
int ast_check_command_in_path(const char *cmd)
Test for the presence of an executable command in $PATH.
Definition: utils.c:3263
int AST_OPTIONAL_API_NAME() ast_check_signature_bin(struct ast_key *key, const char *msg, int msglen, const unsigned char *dsig)
check signature of a message
Definition: res_crypto.c:634
A capture of running an external process.
Definition: test.h:217
Definition: crypto.h:39
FILE * ast_file_mkftemp(char *template_name, mode_t mode)
same as mkstemp, but return a FILE
Definition: file.c:187
#define AST_TEST_DEFINE(hdr)
Definition: test.h:126
struct ast_key *AST_OPTIONAL_API_NAME() ast_key_get(const char *kname, int ktype)
return the ast_key structure for name
Definition: res_crypto.c:149
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
Asterisk module definitions.
int AST_OPTIONAL_API_NAME() ast_decrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
decrypt a message
Definition: res_crypto.c:472