26#include <openssl/evp.h>
34 const char hex_translate[] =
"0123456789abcdef";
38 fprintf(stderr,
"Unable to decode hex, buffer too small\n");
40 }
else if (
in_len % 2 != 0) {
41 fprintf(stderr,
"Unable to decode hex, wrong length\n");
46 for (
size_t i = 0; i <
in_len; i++) {
47 char *ind_ptr = strchr(hex_translate, tolower(*hex_in++));
50 index = ind_ptr - hex_translate;
52 fprintf(stderr,
"Unable to decode hex, invalid character\n");
57 *hex_out = index << 4;
67static bool parse_name(
const char *prompt,
char *
name,
char *parsed,
69 if (strlen(
name) > *parsed_len) {
70 fprintf(stdout,
"Unable to read name, buffer too small\n");
74 if (strlen(
name) == 0) {
75 if (
read_string(prompt, parsed, *parsed_len,
false) ==
false) {
82 *parsed_len = strlen(
name);
87static bool parse_key(
const char *prompt,
char *key,
uint8_t *parsed,
90 size_t buf_size =
sizeof(
buf);
92 if (strlen(key) > buf_size) {
93 fprintf(stdout,
"Unable to read key, buffer too small\n");
97 if (strlen(key) == 0) {
101 buf_size = strlen(
buf);
104 buf_size = strlen(key);
107 if (
hex_decode(
buf, buf_size, parsed, parsed_len) ==
false) {
112 fprintf(stdout,
"Unable to read key, wrong length (must be %d)\n",
120static bool parse_touch_policy(
enum enum_touch touch_policy,
121 uint8_t *touch_policy_parsed) {
123 switch (touch_policy) {
126 *touch_policy_parsed = 0;
130 *touch_policy_parsed = 1;
140 size_t name_parsed_len =
sizeof(name_parsed);
142 if (parse_name(
"Name",
name, name_parsed, &name_parsed_len) ==
false) {
148 fprintf(stderr,
"Unable to delete credential: %s\n",
ykyh_strerror(ykyhrc));
152 fprintf(stdout,
"Credential successfully deleted\n");
160 size_t list_items =
sizeof(list) /
sizeof(list[0]);
164 fprintf(stderr,
"Unable to list credentials: %s\n",
ykyh_strerror(ykyhrc));
168 if (list_items == 0) {
169 fprintf(stdout,
"No items found\n");
173 for (
size_t i = 0; i < list_items; i++) {
174 fprintf(stdout,
"%d\t%d\t%s\n", list[i].algo, list[i].ctr, list[i].
name);
181 char *derivation_password,
char *key_enc,
182 char *key_mac,
char *password,
183 enum enum_touch touch_policy) {
186 size_t name_parsed_len =
sizeof(name_parsed);
187 char dpw_parsed[256] = {0};
188 size_t dpw_parsed_len =
sizeof(dpw_parsed);
190 size_t key_enc_parsed_len =
sizeof(key_enc_parsed);
192 size_t key_mac_parsed_len =
sizeof(key_mac_parsed);
194 size_t pw_parsed_len =
sizeof(pw_parsed);
195 uint8_t touch_policy_parsed = 0;
197 if (parse_name(
"Name",
name, name_parsed, &name_parsed_len) ==
false) {
201 if (strlen(key_mac) == 0 && strlen(key_enc) == 0) {
202 if (
parse_pw(
"Derivation password", derivation_password, dpw_parsed,
203 &dpw_parsed_len) ==
false) {
210 if (dpw_parsed_len == 0) {
211 if (parse_key(
"Encryption key", key_enc, key_enc_parsed,
212 &key_enc_parsed_len) ==
false) {
216 if (parse_key(
"MAC key", key_mac, key_mac_parsed, &key_mac_parsed_len) ==
222 int ret = PKCS5_PBKDF2_HMAC((
const char *) dpw_parsed, dpw_parsed_len,
225 EVP_sha256(),
sizeof(key), key);
237 if (
parse_pw(
"Password", password, pw_parsed, &pw_parsed_len) ==
false) {
241 if (parse_touch_policy(touch_policy, &touch_policy_parsed) ==
false) {
245 ykyhrc =
ykyh_put(
state, name_parsed, key_enc_parsed, key_enc_parsed_len,
246 key_mac_parsed, key_mac_parsed_len, pw_parsed,
247 touch_policy_parsed);
249 fprintf(stderr,
"Unable to store credential: %s\n",
ykyh_strerror(ykyhrc));
253 fprintf(stdout,
"Credential successfully stored\n");
263 fprintf(stderr,
"Unable to reset device: %s\n",
ykyh_strerror(ykyhrc));
267 fprintf(stdout,
"Device successuflly reset\n");
275 size_t version_len =
sizeof(version);
279 fprintf(stderr,
"Unable to get version: %s\n",
ykyh_strerror(ykyhrc));
283 fprintf(stdout,
"Version %s\n", version);
289 struct gengetopt_args_info args_info;
293 int rc = EXIT_FAILURE;
295 if (cmdline_parser(argc,
argv, &args_info) != 0) {
301 fprintf(stderr,
"Failed to initialize libykyh\n");
307 fprintf(stderr,
"Unable to connect: %s\n",
ykyh_strerror(ykyhrc));
312 switch (args_info.action_arg) {
313 case action_arg_delete:
314 result = delete_credential(
state, args_info.name_arg);
317 case action_arg_list:
318 result = list_credentials(
state);
322 result = put_credential(
state, args_info.name_arg,
323 args_info.derivation_password_arg,
324 args_info.enckey_arg, args_info.mackey_arg,
325 args_info.password_arg, args_info.touch_arg);
328 case action_arg_reset:
332 case action_arg_version:
337 fprintf(stderr,
"No action given, nothing to do\n");
341 if (result ==
true) {
bool read_string(const char *name, char *str_buf, size_t str_buf_len, bool hidden)
bool parse_pw(const char *prompt, char *pw, char *parsed, size_t *parsed_len)
bool hex_decode(const char *in, uint8_t *out, size_t *len)
bool get_version(ykyh_state *state)
bool reset_device(ykyh_state *state)
const char * ykyh_strerror(ykyh_rc err)
ykyh_rc ykyh_put(ykyh_state *state, const char *name, const uint8_t *key_enc, size_t key_enc_len, const uint8_t *key_mac, size_t key_mac_len, const char *pw, const uint8_t touch_policy)
ykyh_rc ykyh_get_version(ykyh_state *state, char *version, size_t len)
ykyh_rc ykyh_done(ykyh_state *state)
ykyh_rc ykyh_connect(ykyh_state *state, const char *wanted)
ykyh_rc ykyh_list_keys(ykyh_state *state, ykyh_list_entry *list, size_t *list_items)
ykyh_rc ykyh_reset(ykyh_state *state)
ykyh_rc ykyh_init(ykyh_state **state, int verbose)
ykyh_rc ykyh_delete(ykyh_state *state, char *name)
#define YKYH_DEFAULT_ITERS
#define YKYH_DEFAULT_SALT
#define YKYH_MAX_NAME_LEN
memcpy((char *) pInfo->slotDescription, s, l)