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