alg.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /* vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80: */
  2. /*
  3. * Copyright 2016 Red Hat, Inc.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include "jose.h"
  18. #include "../lib/hooks.h"
  19. #include <string.h>
  20. #define SUMMARY "Lists all supported algorithms"
  21. typedef struct {
  22. json_t *kinds;
  23. } jcmd_opt_t;
  24. static const char *prefix = "jose alg [-k KIND]\n\n" SUMMARY;
  25. static const struct {
  26. const char *name;
  27. jose_hook_alg_kind_t kind;
  28. } kinds[] = {
  29. { "hash", JOSE_HOOK_ALG_KIND_HASH },
  30. { "sign", JOSE_HOOK_ALG_KIND_SIGN },
  31. { "wrap", JOSE_HOOK_ALG_KIND_WRAP },
  32. { "encr", JOSE_HOOK_ALG_KIND_ENCR },
  33. { "comp", JOSE_HOOK_ALG_KIND_COMP },
  34. { "exch", JOSE_HOOK_ALG_KIND_EXCH },
  35. {}
  36. };
  37. static jose_hook_alg_kind_t
  38. name2kind(const char *name)
  39. {
  40. for (size_t i = 0; name && kinds[i].name; i++) {
  41. if (strcmp(name, kinds[i].name) == 0)
  42. return kinds[i].kind;
  43. }
  44. return JOSE_HOOK_ALG_KIND_NONE;
  45. }
  46. static bool
  47. opt_set_kind(const jcmd_cfg_t *cfg, void *vopt, const char *arg)
  48. {
  49. json_t **all = vopt;
  50. if (!*all)
  51. *all = json_array();
  52. if (strcmp(arg, "?") == 0) {
  53. for (size_t i = 0; kinds[i].name; i++)
  54. fprintf(stdout, "%s\n", kinds[i].name);
  55. exit(EXIT_SUCCESS);
  56. }
  57. if (name2kind(arg) == JOSE_HOOK_ALG_KIND_NONE)
  58. return false;
  59. return json_array_append_new(*all, json_string(arg)) >= 0;
  60. }
  61. static const jcmd_doc_t doc_kind[] = {
  62. { .arg = "KIND", .doc = "Restrict algorithm list to a certain kind" },
  63. { .arg = "?", .doc = "List valid algorithm kinds" },
  64. {}
  65. };
  66. static const jcmd_cfg_t cfgs[] = {
  67. {
  68. .opt = { "kind", required_argument, .val = 'k' },
  69. .off = offsetof(jcmd_opt_t, kinds),
  70. .set = opt_set_kind,
  71. .doc = doc_kind
  72. },
  73. {}
  74. };
  75. static void
  76. jcmd_opt_cleanup(jcmd_opt_t *opt)
  77. {
  78. json_decref(opt->kinds);
  79. }
  80. static int
  81. cmp(const void *a, const void *b)
  82. {
  83. const char *const *aa = a;
  84. const char *const *bb = b;
  85. return strcasecmp(*aa, *bb);
  86. }
  87. static bool
  88. filter(const jcmd_opt_t *opt, jose_hook_alg_kind_t kind)
  89. {
  90. size_t size = 0;
  91. size = json_array_size(opt->kinds);
  92. if (size == 0)
  93. return true;
  94. for (size_t i = 0; i < size; i++) {
  95. if (kind == name2kind(json_string_value(json_array_get(opt->kinds, i))))
  96. return true;
  97. }
  98. return false;
  99. }
  100. static int
  101. jcmd_alg(int argc, char *argv[])
  102. {
  103. jcmd_opt_auto_t opt = {};
  104. size_t len = 0;
  105. if (!jcmd_opt_parse(argc, argv, cfgs, &opt, prefix))
  106. return EXIT_FAILURE;
  107. for (const jose_hook_alg_t *a = jose_hook_alg_list(); a; a = a->next) {
  108. if (filter(&opt, a->kind))
  109. len++;
  110. }
  111. const char *names[len];
  112. for (const jose_hook_alg_t *a = jose_hook_alg_list(); a; a = a->next) {
  113. if (filter(&opt, a->kind))
  114. names[--len] = a->name;
  115. }
  116. qsort(names, sizeof(names) / sizeof(*names), sizeof(*names), cmp);
  117. for (size_t i = 0; i < sizeof(names) / sizeof(*names); i++)
  118. fprintf(stdout, "%s\n", names[i]);
  119. return EXIT_SUCCESS;
  120. }
  121. JCMD_REGISTER(SUMMARY, jcmd_alg, "alg")