Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
main.c File Reference
#include <yubihsm.h>
#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/time.h>
#include "util.h"
#include "commands.h"
#include <openssl/evp.h>
#include "yubihsm-shell.h"
#include <editline/readline.h>
#include <histedit.h>
Include dependency graph for main.c:

Go to the source code of this file.

Classes

struct  Command
 

Macros

#define PROMPT   "yubihsm> "
 
#define ARGS_BUFFER_SIZE   4096
 
#define COMPLETION_CANDIDATES   256
 
#define MAX_COMMAND_NAME   32
 
#define MAX_ARGUMENTS   32
 
#define LOCAL_CONNECTOR_URL   "http://127.0.0.1:12345"
 
#define SPACES   " \f\n\r\t\v"
 
#define LIB_SUCCEED_OR_DIE(x, s)
 
#define COM_SUCCEED_OR_DIE(x, s)
 

Typedefs

typedef struct Command Command
 
typedef CommandCommandList
 

Functions

int yh_com_help (yubihsm_context *ctx, Argument *argv, cmd_format fmt)
 
int yh_com_history (yubihsm_context *ctx, Argument *argv, cmd_format fmt)
 
int yh_com_quit (yubihsm_context *ctx, Argument *argv, cmd_format fmt)
 
int yh_com_set_informat (yubihsm_context *ctx, Argument *argv, cmd_format fmt)
 
int yh_com_set_outformat (yubihsm_context *ctx, Argument *argv, cmd_format fmt)
 
Commandregister_command (CommandList list, Command command)
 
void register_subcommand (Command *parent, Command command)
 
CommandList msort_list (CommandList list)
 
void create_command_list (CommandList *c)
 
int yh_com_keepalive_on (yubihsm_context *ctx, Argument *argv, cmd_format fmt)
 
int yh_com_keepalive_off (yubihsm_context *ctx, Argument *argv, cmd_format fmt)
 
void find_lcp (const char *items[], int n_items, const char **lcp, int *lcp_len)
 
int tokenize (char *line, char **toks, int max_toks, int *cursorc, int *cursoro, const char *space)
 
unsigned char complete_arg (EditLine *el, const char *arg, char *line, int cursoro)
 
unsigned char complete_command (EditLine *el, Command *to_complete, const char *line, int cursoro)
 
unsigned char yubihsm_complete (EditLine *el, int ch)
 
int validate_arg (yubihsm_context *ctx, char type, const char *value, Argument *parsed, cmd_format fmt)
 
int validate_and_call (yubihsm_context *ctx, CommandList l, const char *line)
 
int main (int argc, char *argv[])
 

Variables

History * g_hist
 
CommandList g_commands
 
bool g_running = true
 

Macro Definition Documentation

◆ ARGS_BUFFER_SIZE

#define ARGS_BUFFER_SIZE   4096

Definition at line 41 of file main.c.

◆ COM_SUCCEED_OR_DIE

#define COM_SUCCEED_OR_DIE ( x,
s )
Value:
if ((x) != 0) { \
fprintf(stderr, s "\n"); \
rc = EXIT_FAILURE; \
break; \
}
char * s
yh_rc rc

Definition at line 72 of file main.c.

72#define COM_SUCCEED_OR_DIE(x, s) \
73 if ((x) != 0) { \
74 fprintf(stderr, s "\n"); \
75 rc = EXIT_FAILURE; \
76 break; \
77 }

◆ COMPLETION_CANDIDATES

#define COMPLETION_CANDIDATES   256

Definition at line 43 of file main.c.

◆ LIB_SUCCEED_OR_DIE

#define LIB_SUCCEED_OR_DIE ( x,
s )
Value:
if ((x) != YHR_SUCCESS) { \
fprintf(stderr, s "%s\n", yh_strerror(x)); \
rc = EXIT_FAILURE; \
break; \
}
const char * yh_strerror(yh_rc err)
Definition error.c:65
@ YHR_SUCCESS
Returned value when function was successful.
Definition yubihsm.h:172

Definition at line 65 of file main.c.

65#define LIB_SUCCEED_OR_DIE(x, s) \
66 if ((x) != YHR_SUCCESS) { \
67 fprintf(stderr, s "%s\n", yh_strerror(x)); \
68 rc = EXIT_FAILURE; \
69 break; \
70 }

◆ LOCAL_CONNECTOR_URL

#define LOCAL_CONNECTOR_URL   "http://127.0.0.1:12345"

Definition at line 47 of file main.c.

◆ MAX_ARGUMENTS

#define MAX_ARGUMENTS   32

Definition at line 45 of file main.c.

◆ MAX_COMMAND_NAME

#define MAX_COMMAND_NAME   32

Definition at line 44 of file main.c.

◆ PROMPT

#define PROMPT   "yubihsm> "

Definition at line 39 of file main.c.

◆ SPACES

#define SPACES   " \f\n\r\t\v"

Definition at line 51 of file main.c.

Typedef Documentation

◆ Command

typedef struct Command Command

Definition at line 88 of file main.c.

◆ CommandList

typedef Command* CommandList

Definition at line 109 of file main.c.

Function Documentation

◆ complete_arg()

unsigned char complete_arg ( EditLine * el,
const char * arg,
char * line,
int cursoro )

Definition at line 925 of file main.c.

926 {
927
928 const char *candidates[COMPLETION_CANDIDATES];
929 int n_candidates = 0;
930 struct winsize w;
931 const LineInfo *li = el_line(el);
932 ioctl(fileno(stdout), TIOCGWINSZ, &w);
933 int lines = (li->cursor - li->buffer + strlen(PROMPT)) / w.ws_col;
934
935 switch (arg[0]) {
936 case 'u':
937 printf("\nnumber");
938
939 break;
940
941 case 'w':
942 printf("\nword");
943
944 break;
945
946 case 'b':
947 printf("\nbyte");
948
949 break;
950
951 case 'i':
952 printf("\ninput data");
953
954 break;
955
956 case 'F':
957 printf("\noutput filename");
958
959 break;
960
961 case 's':
962 printf("\nstring");
963
964 break;
965
966 case 'k':
967 printf("\nkey");
968
969 break;
970
971 case 'e':
972 printf("\nsession");
973
974 break;
975
976 case 'd':
977 printf("\ndomains");
978
979 break;
980
981 case 'c': {
982 char *toks[COMPLETION_CANDIDATES];
983 int cursorc = cursoro;
984 int num_toks =
985 tokenize(line, toks, COMPLETION_CANDIDATES, &cursorc, &cursoro, ":,;|");
986 if (cursorc == num_toks) {
987 toks[cursorc] = "";
988 }
989 for (size_t i = 0; i < sizeof(yh_capability) / sizeof(yh_capability[0]);
990 i++) {
991 if (strncasecmp(toks[cursorc], yh_capability[i].name,
992 strlen(toks[cursorc])) == 0) {
993 candidates[n_candidates++] = yh_capability[i].name;
994 assert(n_candidates < COMPLETION_CANDIDATES);
995 }
996 }
997 } break;
998
999 case 'a':
1000 for (uint16_t i = 0; i < sizeof(yh_algorithms) / sizeof(yh_algorithms[0]);
1001 i++) {
1002 if (strncasecmp(line, yh_algorithms[i].name, strlen(line)) == 0) {
1003 candidates[n_candidates++] = yh_algorithms[i].name;
1004 assert(n_candidates < COMPLETION_CANDIDATES);
1005 }
1006 }
1007
1008 break;
1009
1010 case 't':
1011 for (uint16_t i = 0; i < sizeof(yh_types) / sizeof(yh_types[0]); i++) {
1012 if (strncasecmp(line, yh_types[i].name, strlen(line)) == 0) {
1013 candidates[n_candidates++] = yh_types[i].name;
1014 assert(n_candidates < COMPLETION_CANDIDATES);
1015 }
1016 }
1017
1018 break;
1019
1020 case 'o':
1021 for (uint16_t i = 0; i < sizeof(yh_options) / sizeof(yh_options[0]);
1022 i++) {
1023 if (strncasecmp(line, yh_options[i].name, strlen(line)) == 0) {
1024 candidates[n_candidates++] = yh_options[i].name;
1025 assert(n_candidates < COMPLETION_CANDIDATES);
1026 }
1027 }
1028
1029 break;
1030
1031 case 'I':
1032 for (uint16_t i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
1033 if (strncasecmp(line, formats[i].name, strlen(line)) == 0) {
1034 candidates[n_candidates++] = formats[i].name;
1035 assert(n_candidates < COMPLETION_CANDIDATES);
1036 }
1037 }
1038
1039 break;
1040
1041 case '\0':
1042 // NOTE(adma): completing an empty string, we reached the end, do
1043 // nothing
1044
1045 return CC_ERROR;
1046
1047 default:
1048
1049 printf("\nunknown type");
1050
1051 break;
1052 }
1053
1054 switch (n_candidates) {
1055 case 0: {
1056 int i = 1;
1057
1058 while (arg[i] != '\0' && arg[i] != ',') {
1059 i++;
1060 }
1061
1062 printf("%*.*s\n", i, i - 1, arg + 1);
1063 } break;
1064
1065 case 1:
1066 el_insertstr(el, candidates[0] + cursoro);
1067
1068 return CC_REDISPLAY;
1069
1070 default: {
1071 const char *lcp;
1072 int lcp_len;
1073
1074 qsort(candidates, n_candidates, sizeof(char *), compare_strings);
1075
1076 find_lcp(candidates, n_candidates, &lcp, &lcp_len);
1077
1078 if (cursoro == lcp_len) {
1079 // NOTE(adma): we already have lcp_len characters typed on
1080 // the prompt, display all the possible matches
1081 printf("\n");
1082 for (int i = 0; i < n_candidates; i++) {
1083 printf("%s\n", candidates[i]);
1084 }
1085 } else {
1086 // NOTE(adma): we found an lcp, autocomplete with that
1087 char prefix[MAX_COMMAND_NAME];
1088 strcpy(prefix, lcp + cursoro);
1089 prefix[lcp_len - cursoro] = '\0';
1090
1091 el_insertstr(el, prefix);
1092 return CC_REDISPLAY;
1093 }
1094 }
1095 }
1096
1097 for (int i = 0; i < lines; i++) {
1098 printf("\n");
1099 }
1100 return CC_REDISPLAY;
1101}
Catch::Generators::GeneratorWrapper< std::string > lines(std::string)
std::string name
LOGGING_API void printf(Category category, const char *format,...)
Definition Logging.cpp:30
int tokenize(char *line, char **toks, int max_toks, int *cursorc, int *cursoro, const char *space)
Definition main.c:852
#define COMPLETION_CANDIDATES
Definition main.c:43
#define MAX_COMMAND_NAME
Definition main.c:44
#define PROMPT
Definition main.c:39
void find_lcp(const char *items[], int n_items, const char **lcp, int *lcp_len)
Definition main.c:820
unsigned short uint16_t
Definition stdint.h:125
Here is the call graph for this function:
Here is the caller graph for this function:

◆ complete_command()

unsigned char complete_command ( EditLine * el,
Command * to_complete,
const char * line,
int cursoro )

Definition at line 1103 of file main.c.

1104 {
1105
1106 const char *candidates[COMPLETION_CANDIDATES];
1107 int n_candidates = 0;
1108
1109 // NOTE(adma): try to autocomplete the current command/subcomand
1110 for (Command *command = to_complete; command; command = command->next) {
1111 if (strncmp(line, command->name, strlen(line)) == 0) {
1112 // printf("%s\n", command->name);
1113
1114 candidates[n_candidates++] = command->name;
1115 assert(n_candidates < COMPLETION_CANDIDATES);
1116 } else if (n_candidates != 0) {
1117 // NOTE(adma): the list is sorted no point in continuing,
1118 // bail out
1119 break;
1120 }
1121 }
1122 // printf("Found %d candidates\n", n_candidates);
1123 switch (n_candidates) {
1124 case 0:
1125 // NOTE(adma): no matches, do nothing
1126
1127 return CC_ERROR;
1128
1129 case 1:
1130 // NOTE(adma): only one match, autocomplete!
1131 el_insertstr(el, candidates[0] + cursoro);
1132 el_insertstr(el, " ");
1133
1134 return CC_REDISPLAY;
1135
1136 default: {
1137 // NOTE(adma): several matches, find longest common prefix
1138 const char *lcp;
1139 int lcp_len;
1140
1141 find_lcp(candidates, n_candidates, &lcp, &lcp_len);
1142
1143 if (cursoro == lcp_len) {
1144 // NOTE(adma): we already have lcp_len characters typed on
1145 // the prompt, display all the possible matches
1146 printf("\n");
1147 for (int i = 0; i < n_candidates; i++) {
1148 printf("%s\n", candidates[i]);
1149 }
1150 } else {
1151 // NOTE(adma): we found an lcp, autocomplete with that
1152 char prefix[MAX_COMMAND_NAME];
1153 strcpy(prefix, lcp + cursoro);
1154 prefix[lcp_len - cursoro] = '\0';
1155
1156 el_insertstr(el, prefix);
1157 }
1158 }
1159 return CC_REDISPLAY;
1160 }
1161}
Definition main.c:98
Command * next
Definition main.c:106
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_command_list()

void create_command_list ( CommandList * c)

Definition at line 221 of file main.c.

221 {
222
223 // NOTE(adma): initialize
224 *c = NULL;
225
226 *c = register_command(*c, (Command){"audit", yh_com_noop, NULL, fmt_nofmt,
227 fmt_nofmt, "Deal with audit log", NULL,
228 NULL});
229 register_subcommand(*c, (Command){"get", yh_com_audit, "e:session,F:file=-",
230 fmt_ASCII, fmt_nofmt, "Extract log entries",
231 NULL, NULL});
233 "e:session,w:index", fmt_nofmt, fmt_nofmt,
234 "Set the log index", NULL, NULL});
235 *c = register_command(*c, (Command){"connect", yh_com_connect, NULL,
237 "Connect to a connector", NULL, NULL});
238 *c = register_command(*c, (Command){"debug", yh_com_noop, NULL, fmt_nofmt,
239 fmt_nofmt, "Change debug settings", NULL,
240 NULL});
242 fmt_nofmt, "Enable all debug messages",
243 NULL, NULL});
245 (Command){"crypto", yh_com_debug_crypto, NULL, fmt_nofmt,
246 fmt_nofmt, "Toggle crypto debug messages", NULL,
247 NULL});
250 "Toggle error debug messages", NULL, NULL});
252 fmt_nofmt, "Toggle info debug messages",
253 NULL, NULL});
255 NULL, fmt_nofmt, fmt_nofmt,
256 "Toggle intermediate debug messages", NULL,
257 NULL});
259 fmt_nofmt, "Disable all debug messages",
260 NULL, NULL});
262 fmt_nofmt, "Toggle raw debug messages",
263 NULL, NULL});
264 *c = register_command(*c, (Command){"decrypt", yh_com_noop, NULL, fmt_nofmt,
265 fmt_nofmt, "Decrypt data", NULL, NULL});
267 "e:session,w:key_id,i:data=-", fmt_binary,
269 "Decrypt data using RSAES-PKCS#1v1.5", NULL,
270 NULL});
272 *c,
274 "e:session,w:key_id,a:algorithm,i:data=-,s:label=", fmt_binary,
275 fmt_base64, "Decrypt data using RSAES-OAEP", NULL, NULL});
277 (Command){"aesccm", yh_com_decrypt_aesccm,
278 "e:session,w:key_id,i:data=-", fmt_base64,
279 fmt_binary, "Decrypt data using Yubico-AES-CCM",
280 NULL, NULL});
281 *c = register_command(*c, (Command){"derive", yh_com_noop, NULL, fmt_nofmt,
282 fmt_nofmt, "Drive data", NULL, NULL});
284 "e:session,w:key_id,i:pubkey=-", fmt_PEM,
285 fmt_hex, "Perform a ECDH key exchange",
286 NULL, NULL});
287
288 *c = register_command(*c, (Command){"encrypt", yh_com_noop, NULL, fmt_nofmt,
289 fmt_nofmt, "Encrypt data", NULL, NULL});
291 (Command){"aesccm", yh_com_encrypt_aesccm,
292 "e:session,w:key_id,i:data=-", fmt_binary,
293 fmt_base64, "Encrypt data using Yubico-AES-CCM",
294 NULL, NULL});
295 *c =
296 register_command(*c, (Command){"disconnect", yh_com_disconnect, NULL,
298 "Disconnect from a connector", NULL, NULL});
299 *c =
301 (Command){"echo", yh_com_echo, "e:session,b:byte,w:count",
303 "Send an ECHO command over a given session",
304 NULL, NULL});
305 *c = register_command(*c, (Command){"generate", yh_com_noop, NULL, fmt_nofmt,
306 fmt_nofmt, "Generate key", NULL, NULL});
308 "e:session,w:key_id,s:label,d:domains,c:"
309 "capabilities,a:algorithm",
311 "Generate an asymmetric key", NULL, NULL});
313 "e:session,w:key_id,s:label,d:domains,c:"
314 "capabilities,a:algorithm",
315 fmt_nofmt, fmt_nofmt, "Generate HMAC key",
316 NULL, NULL});
318 *c, (Command){"wrapkey", yh_com_generate_wrap,
319 "e:session,w:key_id,s:label,d:domains,c:"
320 "capabilities,c:delegated_capabilities,a:algorithm",
321 fmt_nofmt, fmt_nofmt, "Generate wrap key", NULL, NULL});
323 "e:session,w:key_id,s:label,d:domains,c:"
324 "capabilities,a:algorithm,u:nonce_id",
326 "Generate OTP AEAD key", NULL, NULL});
327 *c = register_command(*c, (Command){"get", yh_com_noop, NULL, fmt_nofmt,
328 fmt_nofmt, "Retrieve data", NULL, NULL});
330 "e:session,w:object_id,F:file=-", fmt_nofmt,
331 fmt_binary, "Get an opaque object", NULL,
332 NULL});
334 "e:session,o:option", fmt_nofmt,
335 fmt_nofmt, // FIXME: output
336 "Get a global option value", NULL, NULL});
338 (Command){"random", yh_com_get_random,
339 "e:session,w:count,F:out=-", fmt_nofmt, fmt_hex,
340 "Get pseudo-random bytes", NULL, NULL});
341 register_subcommand(*c, (Command){"storage", yh_com_get_storage, "e:session",
342 fmt_nofmt, fmt_nofmt, "Get storages stats",
343 NULL, NULL});
345 "e:session,w:key_id,F:file=-", fmt_nofmt,
346 fmt_PEM, "Get a public key", NULL, NULL});
348 (Command){"objectinfo", yh_com_get_object_info,
349 "e:session,w:id,t:type", fmt_nofmt, fmt_nofmt,
350 "Get information about an object", NULL, NULL});
352 (Command){"wrapped", yh_com_get_wrapped,
353 "e:session,w:wrapkey_id,t:type,w:id,F:file=-",
355 "Get an object under wrap", NULL, NULL});
356 register_subcommand(*c, (Command){"deviceinfo", yh_com_get_device_info, NULL,
358 "Extract the version number, serial number "
359 "and supported algorithms",
360 NULL, NULL});
362 "e:session,w:object_id,F:out=-", fmt_nofmt,
363 fmt_base64, "Get a template object", NULL,
364 NULL});
365
366 *c =
367 register_command(*c, (Command){"help", yh_com_help, "s:command=", fmt_nofmt,
368 fmt_nofmt, "Display help text", NULL, NULL});
369 *c =
370 register_command(*c, (Command){"history", yh_com_history, NULL, fmt_nofmt,
371 fmt_nofmt, "Display the command history",
372 NULL, NULL});
373 *c =
374 register_command(*c, (Command){"list", yh_com_noop, NULL, fmt_nofmt,
375 fmt_nofmt, "List information", NULL, NULL});
377 NULL, fmt_nofmt, fmt_nofmt,
378 "Prints a list of possible capabilities",
379 NULL, NULL});
380 register_subcommand(*c, (Command){"algorithms", yh_com_list_algorithms, NULL,
382 "Prints a list of possible algorithms",
383 NULL, NULL});
385 (Command){"types", yh_com_list_types, NULL, fmt_nofmt,
386 fmt_nofmt, "Prints a list of possible types",
387 NULL, NULL});
388 register_subcommand(*c, (Command){"sessions", yh_com_list_sessions, NULL,
390 "List the open session", NULL, NULL});
392 "e:session,w:id=0,t:type=any,d:domains=0,c:"
393 "capabilities=0,a:algorithm=any,s:label=",
395 "List objects according to filter", NULL,
396 NULL});
397 *c =
399 (Command){"plain", yh_com_noop, NULL, fmt_nofmt, fmt_nofmt,
400 "Send unencrypted and unauthenticated commands",
401 NULL, NULL});
402 register_subcommand(*c, (Command){"echo", yh_com_pecho, "b:byte,w:count",
404 "Send a plain echo command", NULL, NULL});
405 *c = register_command(*c, (Command){"put", yh_com_noop, NULL, fmt_nofmt,
406 fmt_nofmt, "Store data", NULL, NULL});
408 "e:session,w:key_id,s:label,d:domains,c:"
409 "capabilities,i:key=-",
411 "Store an asymmetric key", NULL, NULL});
413 "e:session,w:key_id,s:label,d:domains,c:"
414 "capabilities,c:delegated_capabilities,i:"
415 "password=-",
417 "Store an authentication key", NULL, NULL});
419 "e:session,w:object_id,s:label,d:domains,c:"
420 "capabilities,a:algorithm,i:data=-",
422 "Store an opaque object", NULL, NULL});
424 (Command){"option", yh_com_put_option,
425 "e:session,o:option,i:data", fmt_hex, fmt_nofmt,
426 "Set a global option value", NULL, NULL});
428 "e:session,w:key_id,s:label,d:domains,c:"
429 "capabilities,a:algorithm,i:key",
430 fmt_hex, fmt_nofmt, "Store a HMAC key",
431 NULL, NULL});
433 (Command){"wrapkey", yh_com_put_wrapkey,
434 "e:session,w:key_id,s:label,d:domains,c:"
435 "capabilities,c:delegated_capabilities,i:key",
436 fmt_hex, fmt_nofmt, "Store a wrapping key",
437 NULL, NULL});
439 "e:session,w:wrapkey_id,i:data=-",
441 "Store a wrapped object", NULL, NULL});
443 "e:session,w:object_id,s:label,d:domains,c:"
444 "capabilities,a:algorithm,i:data=-",
446 "Store a template object", NULL, NULL});
448 "e:session,w:key_id,s:label,d:domains,c:"
449 "capabilities,u:nonce_id,i:key",
450 fmt_hex, fmt_nofmt, "Store a OTP AEAD key",
451 NULL, NULL});
452 *c = register_command(*c,
453 (Command){"quit", yh_com_quit, NULL, fmt_nofmt,
454 fmt_nofmt, "Quit yubihsm-shell", NULL, NULL});
455 *c = register_command(*c,
456 (Command){"exit", yh_com_quit, NULL, fmt_nofmt,
457 fmt_nofmt, "Quit yubihsm-shell", NULL, NULL});
458 *c =
459 register_command(*c, (Command){"session", yh_com_noop, NULL, fmt_nofmt,
460 fmt_nofmt, "Manage sessions", NULL, NULL});
461 register_subcommand(*c, (Command){"close", yh_com_close_session, "e:session",
463 "Close a session with a connector", NULL,
464 NULL});
466 "w:authkey,i:password=-", fmt_password,
467 fmt_nofmt,
468 "Open a session with a device using a "
469 "specific Authentication Key",
470 NULL, NULL});
471 *c = register_command(*c, (Command){"sign", yh_com_noop, NULL, fmt_nofmt,
472 fmt_nofmt, "Sign data", NULL, NULL});
474 *c, (Command){"ecdsa", yh_com_sign_ecdsa,
475 "e:session,w:key_id,a:algorithm,i:data=-,F:out=-", fmt_binary,
476 fmt_base64, "Sign data using ECDSA", NULL, NULL});
478 *c, (Command){"eddsa", yh_com_sign_eddsa,
479 "e:session,w:key_id,a:algorithm,i:data=-,F:out=-", fmt_binary,
480 fmt_base64, "Sign data using EDDSA", NULL, NULL});
482 *c, (Command){"pkcs1v1_5", yh_com_sign_pkcs1v1_5,
483 "e:session,w:key_id,a:algorithm,i:data=-,F:out=-", fmt_binary,
484 fmt_base64, "Sign data using RSASSA-PKCS#1v1.5", NULL, NULL});
486 *c, (Command){"pss", yh_com_sign_pss,
487 "e:session,w:key_id,a:algorithm,i:data=-,F:out=-", fmt_binary,
488 fmt_base64, "Sign data using RSASSA-PSS", NULL, NULL});
489 *c =
491 "e:session,w:key_id,i:data=-,F:out=-",
492 fmt_hex, fmt_hex, "Hmac data", NULL, NULL});
493 *c = register_command(*c,
494 (Command){"reset", yh_com_reset, "e:session", fmt_nofmt,
495 fmt_nofmt, "Reset device", NULL, NULL});
496 *c = register_command(*c, (Command){"delete", yh_com_delete,
497 "e:session,w:id,t:type", fmt_nofmt,
498 fmt_nofmt, "Delete data", NULL, NULL});
499 *c =
501 "e:session,w:key_id,w:template_id,a:"
502 "algorithm,i:infile=-,F:outfile=-",
504 fmt_binary, // TODO: correct default formats?
505 "Sign SSH certificates", NULL, NULL});
506 *c =
508 (Command){"benchmark", yh_com_benchmark,
509 "e:session,u:count,w:key_id=0,a:algorithm=any",
510 fmt_nofmt, fmt_nofmt, "Run a set of benchmarks",
511 NULL, NULL});
512 *c = register_command(*c, (Command){"otp", yh_com_noop, NULL, fmt_nofmt,
513 fmt_nofmt, "OTP commands", NULL, NULL});
515 (Command){"aead_create", yh_com_otp_aead_create,
516 "e:session,w:key_id,i:key,i:private_id,F:aead",
517 fmt_hex, fmt_binary, "Create an OTP AEAD", NULL,
518 NULL});
520 "e:session,w:key_id,F:aead", fmt_nofmt,
521 fmt_binary, "Create a random OTP AEAD",
522 NULL, NULL});
524 "e:session,w:key_id,s:otp,i:aead",
526 "Decrypt an OTP with AEAD", NULL, NULL});
527 *c = register_command(*c, (Command){"attest", yh_com_noop, NULL, fmt_nofmt,
528 fmt_nofmt, "Attest device objects", NULL,
529 NULL});
531 (Command){"asymmetric",
533 "e:session,w:key_id,w:attest_id=0", fmt_nofmt,
534 fmt_PEM, "Sign attestation certificate", NULL,
535 NULL});
536 *c = register_command(*c, (Command){"keepalive", yh_com_noop, NULL, fmt_nofmt,
537 fmt_nofmt, "Change keepalive settings",
538 NULL, NULL});
539
541 fmt_nofmt, "Enable keepalive", NULL, NULL});
543 (Command){"off", yh_com_keepalive_off, NULL, fmt_nofmt,
544 fmt_nofmt, "Disable keepalive", NULL, NULL});
545
546 *c =
547 register_command(*c, (Command){"set", yh_com_noop, NULL, fmt_nofmt,
548 fmt_nofmt, "Set preferences", NULL, NULL});
549
550 register_subcommand(*c, (Command){"informat", yh_com_set_informat, "I:format",
551 fmt_nofmt, fmt_nofmt, "Set input format",
552 NULL, NULL});
554 "I:format", fmt_nofmt, fmt_nofmt,
555 "Set output format", NULL, NULL});
556 register_subcommand(*c, (Command){"cacert", yh_com_set_cacert, "s:file",
558 "Set CA cert to use for https to connector",
559 NULL, NULL});
560 register_subcommand(*c, (Command){"proxy", yh_com_set_proxy, "s:proxy",
562 "Set proxyserver to use for connector",
563 NULL, NULL});
564 *c =
566 "e:session,b:seconds=10", fmt_nofmt,
567 fmt_nofmt, "Blink the device", NULL, NULL});
568
569 *c = register_command(*c, (Command){"change", yh_com_noop, NULL, fmt_nofmt,
570 fmt_nofmt, "Change objects", NULL, NULL});
571
574 "e:session,w:key_id,i:password=-", fmt_password,
575 fmt_nofmt, "Change an authentication key", NULL,
576 NULL});
577
578 *c = msort_list(*c);
579
580 for (Command *t = *c; t != NULL; t = t->next) {
581 if (t->subcommands != NULL) {
582 t->subcommands = msort_list(t->subcommands);
583 }
584 }
585}
int yh_com_sign_ssh_certificate(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1995
int yh_com_change_authentication_key(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:2767
int yh_com_put_asymmetric(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1396
int yh_com_derive_ecdh(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:444
int yh_com_encrypt_aesccm(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:527
int yh_com_generate_otp_aead_key(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:2648
int yh_com_blink(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:159
int yh_com_sign_pss(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1816
int yh_com_open_session(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1208
int yh_com_set_proxy(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:2750
int yh_com_list_objects(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1146
int yh_com_generate_hmac(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:685
int yh_com_put_opaque(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1495
int yh_com_decrypt_oaep(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:2676
int yh_com_noop(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1050
int yh_com_put_authentication(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1463
int yh_com_audit(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:59
int yh_com_get_storage(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:823
int yh_com_generate_wrap(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:719
int yh_com_decrypt_aesccm(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:501
int yh_com_otp_aead_random(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:2498
int yh_com_reset(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1953
int yh_com_list_types(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1096
int yh_com_put_wrapped(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1613
int yh_com_debug_info(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:307
int yh_com_put_otp_aead_key(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:2612
int yh_com_hmac(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1929
int yh_com_connect(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:206
int yh_com_pecho(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1330
int yh_com_sign_ecdsa(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1670
int yh_com_sign_pkcs1v1_5(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1757
int yh_com_generate_asymmetric(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:644
int yh_com_get_pubkey(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:850
int yh_com_get_option(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:767
int yh_com_close_session(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:176
int yh_com_put_wrapkey(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1577
int yh_com_list_capabilities(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1061
int yh_com_list_sessions(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1111
int yh_com_get_wrapped(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1007
int yh_com_disconnect(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:550
int yh_com_debug_raw(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:368
int yh_com_debug_none(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:354
int yh_com_sign_eddsa(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1727
int yh_com_get_template(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1031
int yh_com_list_algorithms(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1079
int yh_com_get_device_info(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1876
int yh_com_put_template(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1645
int yh_com_delete(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1975
int yh_com_debug_intermediate(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:330
int yh_com_otp_decrypt(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:2526
int yh_com_get_opaque(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:743
int yh_com_debug_all(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:270
int yh_com_set_cacert(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:2735
int yh_com_benchmark(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:2111
int yh_com_put_option(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1519
int yh_com_otp_aead_create(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:2461
int yh_com_decrypt_pkcs1v1_5(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:417
int yh_com_set_log_index(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:141
int yh_com_put_hmac(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:1544
int yh_com_debug_error(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:284
int yh_com_sign_attestation_certificate(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:2567
int yh_com_get_random(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:797
int yh_com_debug_crypto(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:391
int yh_com_echo(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:582
int yh_com_get_object_info(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.c:924
CommandList msort_list(CommandList list)
Definition main.c:137
int yh_com_help(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition main.c:628
int yh_com_keepalive_on(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition main.c:763
int yh_com_set_outformat(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition main.c:800
int yh_com_keepalive_off(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition main.c:774
int yh_com_quit(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition main.c:673
int yh_com_set_informat(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition main.c:783
int yh_com_history(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition main.c:595
Command * register_command(CommandList list, Command command)
Definition main.c:112
void register_subcommand(Command *parent, Command command)
Definition main.c:124
@ fmt_nofmt
@ fmt_ASCII
@ fmt_binary
@ fmt_PEM
@ fmt_hex
@ fmt_password
@ fmt_base64
Here is the caller graph for this function:

◆ find_lcp()

void find_lcp ( const char * items[],
int n_items,
const char ** lcp,
int * lcp_len )

Definition at line 820 of file main.c.

821 {
822
823 int min = 0;
824 int max = 0;
825
826 if (items == NULL || n_items == 0) {
827 *lcp = NULL;
828 *lcp_len = 0;
829 }
830
831 for (int i = 1; i < n_items; i++) {
832 if (strcmp(items[i], items[min]) < 0) {
833 min = i;
834 } else if (strcmp(items[i], items[max]) > 0) {
835 max = i;
836 }
837 }
838
839 *lcp = items[min];
840 for (unsigned int i = 0; i < strlen(items[min]) && i < strlen(items[max]);
841 i++) {
842 if (items[min][i] != items[max][i]) {
843 *lcp_len = i;
844
845 return;
846 }
847 }
848
849 *lcp_len = strlen(items[min]);
850}
const T & min(const T &a, const T &b)
Definition utility.hpp:140
Here is the caller graph for this function:

◆ main()

int main ( int argc,
char * argv[] )

Definition at line 1699 of file main.c.

1699 {
1700
1701 yh_rc yrc;
1702 int comrc;
1703
1704 int rc = EXIT_SUCCESS;
1705
1706 struct gengetopt_args_info args_info;
1707
1708 struct stat sb;
1709 struct cmdline_parser_params params;
1710
1711 ctx.out = stdout;
1712
1713 cmdline_parser_params_init(&params);
1714 params.initialize = 1;
1715 params.check_required = 0;
1716
1717 if (cmdline_parser(argc, argv, &args_info) != 0) {
1718 return EXIT_FAILURE;
1719 }
1720
1721 if (stat(args_info.config_file_arg, &sb) == 0) {
1722 if (S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode)) {
1723 params.initialize = 0;
1724 if (cmdline_parser_config_file(args_info.config_file_arg, &args_info,
1725 &params) != 0) {
1726 return EXIT_FAILURE;
1727 }
1728 }
1729 }
1730
1731 if (cmdline_parser_required(&args_info, argv[0]) != 0) {
1732 return EXIT_FAILURE;
1733 }
1734
1735 if (parse_configured_connectors(&ctx, args_info.connector_arg,
1736 args_info.connector_given) == -1) {
1737 fprintf(stderr, "Unable to parse connector list");
1738 rc = EXIT_FAILURE;
1739 goto main_exit;
1740 }
1741
1742 if (getenv("DEBUG") != NULL) {
1743 args_info.verbose_arg = YH_VERB_ALL;
1744 }
1745 yh_set_verbosity(ctx.connector, args_info.verbose_arg);
1746
1747 yrc = yh_init();
1748 if (yrc != YHR_SUCCESS) {
1749 fprintf(stderr, "Failed to initialize libyubihsm\n");
1750 rc = EXIT_FAILURE;
1751 goto main_exit;
1752 }
1753
1754#ifdef USE_YKYH
1755 ykyh_rc ykyhrc;
1756 ykyhrc = ykyh_init(&ctx.state, 1); // TODO(adma): do something about verbosity
1757 if (ykyhrc != YKYHR_SUCCESS) {
1758 fprintf(stderr, "Failed to initialize libykyh\n");
1759 rc = EXIT_FAILURE;
1760 goto main_exit;
1761 }
1762#endif
1763
1764 if (ctx.n_connectors == 0) {
1765 fprintf(stderr, "Using default connector URL: %s\n", LOCAL_CONNECTOR_URL);
1766
1767 ctx.connector_list = calloc(1, sizeof(char *));
1768 if (ctx.connector_list == NULL) {
1769 fprintf(stderr, "Failed to allocate memory\n");
1770 rc = EXIT_FAILURE;
1771 goto main_exit;
1772 }
1773
1774 ctx.connector_list[0] = strdup(LOCAL_CONNECTOR_URL);
1775 if (ctx.connector_list[0] == NULL) {
1776 fprintf(stderr, "Failed to allocate memory\n");
1777 rc = EXIT_FAILURE;
1778 goto main_exit;
1779 }
1780
1781 ctx.n_connectors = 1;
1782 }
1783
1784 if (args_info.cacert_given) {
1785 ctx.cacert = strdup(args_info.cacert_arg);
1786 }
1787 if (args_info.proxy_given) {
1788 ctx.proxy = strdup(args_info.proxy_arg);
1789 }
1790
1791#ifndef __WIN32
1792 struct sigaction act;
1793 memset(&act, 0, sizeof(act));
1794 act.sa_handler = timer_handler;
1795 act.sa_flags = SA_RESTART;
1796 sigaction(SIGALRM, &act, NULL);
1797
1798 sigset_t set;
1799 sigemptyset(&set);
1800 sigaddset(&set, SIGALRM);
1801 sigprocmask(SIG_UNBLOCK, &set, NULL);
1802#endif
1803
1804 if (args_info.action_given) {
1805 uint8_t buf[4096] = {0};
1806
1807 ctx.out = open_file(args_info.out_arg, false);
1808 if (ctx.out == NULL) {
1809 fprintf(stderr, "Unable to open output file %s\n", args_info.out_arg);
1810 rc = EXIT_FAILURE;
1811 goto main_exit;
1812 }
1813
1814 yh_com_connect(&ctx, NULL, fmt_nofmt);
1815
1816 bool requires_session = false;
1817 for (unsigned i = 0; i < args_info.action_given; i++) {
1818 switch (args_info.action_arg[i]) {
1819 case action_arg_getMINUS_deviceMINUS_info:
1820 requires_session = false;
1821 break;
1822
1823 default:
1824 requires_session = true;
1825 }
1826
1827 if (requires_session == true) {
1828 break;
1829 }
1830 }
1831
1832 Argument arg[7];
1833
1834 if (requires_session == true) {
1835 arg[0].w = args_info.authkey_arg;
1836 arg[1].x = buf;
1837 arg[1].len = sizeof(buf);
1838 if (get_input_data(args_info.password_given ? args_info.password_arg : "-",
1839 arg[1].x, &arg[1].len, fmt_password) == false) {
1840 fprintf(stderr, "Failed to get password\n");
1841 rc = EXIT_FAILURE;
1842 goto main_exit;
1843 }
1844
1845 comrc = yh_com_open_session(&ctx, arg, fmt_nofmt);
1846 if (comrc != 0) {
1847 fprintf(stderr, "Failed to open session\n");
1848 rc = EXIT_FAILURE;
1849 goto main_exit;
1850 }
1851 }
1852
1853 for (unsigned i = 0; i < YH_MAX_SESSIONS; i++) {
1854 if (ctx.sessions[i] != NULL) {
1855 arg[0].e = ctx.sessions[i];
1856 }
1857 }
1858
1859 switch (args_info.informat_arg) {
1860 case informat_arg_base64:
1861 ctx.in_fmt = fmt_base64;
1862 break;
1863 case informat_arg_binary:
1864 ctx.in_fmt = fmt_binary;
1865 break;
1866 case informat_arg_PEM:
1867 ctx.in_fmt = fmt_PEM;
1868 break;
1869 case informat_arg_password:
1870 ctx.in_fmt = fmt_password;
1871 break;
1872 case informat_arg_hex:
1873 ctx.in_fmt = fmt_hex;
1874 break;
1875 case informat__NULL:
1876 case informat_arg_default:
1877 default:
1878 ctx.in_fmt = fmt_nofmt;
1879 break;
1880 }
1881
1882 switch (args_info.outformat_arg) {
1883 case outformat_arg_base64:
1884 ctx.out_fmt = fmt_base64;
1885 break;
1886 case outformat_arg_binary:
1887 ctx.out_fmt = fmt_binary;
1888 break;
1889 case outformat_arg_PEM:
1890 ctx.out_fmt = fmt_PEM;
1891 break;
1892 case outformat_arg_hex:
1893 ctx.out_fmt = fmt_hex;
1894 break;
1895 case outformat__NULL:
1896 case outformat_arg_default:
1897 default:
1898 ctx.out_fmt = fmt_nofmt;
1899 break;
1900 }
1901
1902 calling_device = true;
1903
1904 for (unsigned i = 0; i < args_info.action_given; i++) {
1905 switch (args_info.action_arg[i]) {
1906 case action_arg_decryptMINUS_pkcs1v15: {
1907 arg[1].w = args_info.object_id_arg;
1908 arg[2].x = buf;
1909 arg[2].len = sizeof(buf);
1910 if (get_input_data(args_info.in_arg, arg[2].x, &arg[2].len,
1911 ctx.in_fmt == fmt_nofmt ? fmt_binary
1912 : ctx.in_fmt) == false) {
1913 fprintf(stderr, "Failed to get input data\n");
1914 rc = EXIT_FAILURE;
1915 break;
1916 }
1917 comrc =
1918 yh_com_decrypt_pkcs1v1_5(&ctx, arg,
1920 : ctx.out_fmt);
1921 COM_SUCCEED_OR_DIE(comrc, "Unable to decrypt data");
1922 } break;
1923
1924 case action_arg_deriveMINUS_ecdh: {
1925 arg[1].w = args_info.object_id_arg;
1926 arg[2].x = buf;
1927 arg[2].len = sizeof(buf);
1928 if (get_input_data(args_info.in_arg, arg[2].x, &arg[2].len,
1929 ctx.in_fmt == fmt_nofmt ? fmt_binary
1930 : ctx.in_fmt) == false) {
1931 fprintf(stderr, "Failed to get input data\n");
1932 rc = EXIT_FAILURE;
1933 break;
1934 }
1935 comrc = yh_com_derive_ecdh(&ctx, arg,
1936 ctx.out_fmt == fmt_nofmt ? fmt_hex
1937 : ctx.out_fmt);
1938 COM_SUCCEED_OR_DIE(comrc, "Unable to perform ECDH key exchange");
1939 } break;
1940
1941 case action_arg_decryptMINUS_oaep:
1942 case action_arg_decryptMINUS_aesccm:
1943 case action_arg_encryptMINUS_aesccm:
1944 LIB_SUCCEED_OR_DIE(YHR_GENERIC_ERROR, "Command not implemented: ");
1945
1946 case action_arg_generateMINUS_asymmetricMINUS_key: {
1947 if (args_info.algorithm_given == 0) {
1948 fprintf(stderr, "Missing argument algorithm\n");
1949 rc = EXIT_FAILURE;
1950 break;
1951 }
1952
1953 arg[1].w = args_info.object_id_arg;
1954 arg[2].s = args_info.label_arg;
1955 arg[2].len = strlen(args_info.label_arg);
1956 yrc = yh_string_to_domains(args_info.domains_arg, &arg[3].w);
1957 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse domains: ");
1958
1959 memset(&arg[4].c, 0, sizeof(yh_capabilities));
1960 yrc =
1961 yh_string_to_capabilities(args_info.capabilities_arg, &arg[4].c);
1962 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse capabilities: ");
1963
1964 yrc = yh_string_to_algo(args_info.algorithm_arg, &arg[5].a);
1965 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse algorithm: ");
1966
1967 comrc = yh_com_generate_asymmetric(&ctx, arg, fmt_nofmt);
1968 COM_SUCCEED_OR_DIE(comrc, "Unable to generate asymmetric key");
1969 } break;
1970
1971 case action_arg_generateMINUS_hmacMINUS_key: {
1972 if (args_info.algorithm_given == 0) {
1973 fprintf(stderr, "Missing argument algorithm\n");
1974 rc = EXIT_FAILURE;
1975 break;
1976 }
1977
1978 arg[1].w = args_info.object_id_arg;
1979 arg[2].s = args_info.label_arg;
1980 arg[2].len = strlen(args_info.label_arg);
1981 yrc = yh_string_to_domains(args_info.domains_arg, &arg[3].w);
1982 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse domains: ");
1983
1984 memset(&arg[4].c, 0, sizeof(yh_capabilities));
1985 yrc =
1986 yh_string_to_capabilities(args_info.capabilities_arg, &arg[4].c);
1987 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse capabilities: ");
1988
1989 yrc = yh_string_to_algo(args_info.algorithm_arg, &arg[5].a);
1990 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse algorithm: ");
1991
1992 comrc = yh_com_generate_hmac(&ctx, arg, fmt_nofmt);
1993 COM_SUCCEED_OR_DIE(comrc, "Unable to generate hmac key");
1994 } break;
1995
1996 case action_arg_generateMINUS_wrapMINUS_key: {
1997 if (args_info.algorithm_given == 0) {
1998 fprintf(stderr, "Missing argument algorithm\n");
1999 rc = EXIT_FAILURE;
2000 break;
2001 }
2002
2003 if (args_info.delegated_given == 0) {
2004 fprintf(stderr, "Missing delegated capabilities\n");
2005 rc = EXIT_FAILURE;
2006 break;
2007 }
2008
2009 arg[1].w = args_info.object_id_arg;
2010 arg[2].s = args_info.label_arg;
2011 arg[2].len = strlen(args_info.label_arg);
2012 yrc = yh_string_to_domains(args_info.domains_arg, &arg[3].w);
2013 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse domains: ");
2014
2015 memset(&arg[4].c, 0, sizeof(yh_capabilities));
2016 yrc =
2017 yh_string_to_capabilities(args_info.capabilities_arg, &arg[4].c);
2018 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse capabilities: ");
2019
2020 yrc = yh_string_to_algo(args_info.algorithm_arg, &arg[5].a);
2021 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse algorithm: ");
2022
2023 memset(&arg[6].c, 0, sizeof(yh_capabilities));
2024 yrc = yh_string_to_capabilities(args_info.delegated_arg, &arg[6].c);
2025 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse capabilities: ");
2026
2027 comrc = yh_com_generate_wrap(&ctx, arg, fmt_nofmt);
2028 COM_SUCCEED_OR_DIE(comrc, "Unable to generate wrap key");
2029 } break;
2030
2031 case action_arg_generateMINUS_otpMINUS_aeadMINUS_key: {
2032 if (args_info.algorithm_given == 0) {
2033 fprintf(stderr, "Missing argument algorithm\n");
2034 rc = EXIT_FAILURE;
2035 break;
2036 }
2037
2038 if (args_info.nonce_given == 0) {
2039 fprintf(stderr, "Missing argument nonce\n");
2040 rc = EXIT_FAILURE;
2041 break;
2042 }
2043
2044 arg[1].w = args_info.object_id_arg;
2045 arg[2].s = args_info.label_arg;
2046 arg[2].len = strlen(args_info.label_arg);
2047 yrc = yh_string_to_domains(args_info.domains_arg, &arg[3].w);
2048 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse domains: ");
2049
2050 memset(&arg[4].c, 0, sizeof(yh_capabilities));
2051 yrc =
2052 yh_string_to_capabilities(args_info.capabilities_arg, &arg[4].c);
2053 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse capabilities: ");
2054
2055 yrc = yh_string_to_algo(args_info.algorithm_arg, &arg[5].a);
2056 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse algorithm: ");
2057
2058 arg[6].d = args_info.nonce_arg;
2059
2060 comrc = yh_com_generate_otp_aead_key(&ctx, arg, fmt_nofmt);
2061 COM_SUCCEED_OR_DIE(comrc, "Unable to generate otp key");
2062 } break;
2063
2064 case action_arg_getMINUS_opaque: {
2065 arg[1].w = args_info.object_id_arg;
2066
2067 comrc = yh_com_get_opaque(&ctx, arg,
2069 : ctx.out_fmt);
2070 COM_SUCCEED_OR_DIE(comrc, "Unable to get opaque object");
2071 } break;
2072
2073 case action_arg_getMINUS_pseudoMINUS_random: {
2074 arg[1].w = args_info.count_arg;
2075
2076 comrc =
2077 yh_com_get_random(&ctx, arg,
2078 ctx.out_fmt == fmt_nofmt ? fmt_hex : ctx.out_fmt);
2079 COM_SUCCEED_OR_DIE(comrc, "Unable to get random bytes");
2080 } break;
2081
2082 case action_arg_getMINUS_storageMINUS_info:
2083 comrc = yh_com_get_storage(&ctx, arg, fmt_nofmt);
2084 COM_SUCCEED_OR_DIE(comrc, "Unable to get storage stats");
2085 break;
2086
2087 case action_arg_getMINUS_publicMINUS_key: {
2088 arg[1].w = args_info.object_id_arg;
2089 arg[2].s = args_info.out_arg;
2090 arg[2].len = strlen(args_info.out_arg);
2091
2092 comrc =
2093 yh_com_get_pubkey(&ctx, arg,
2094 ctx.out_fmt == fmt_nofmt ? fmt_PEM : ctx.out_fmt);
2095 COM_SUCCEED_OR_DIE(comrc, "Unable to get public key");
2096 } break;
2097
2098 case action_arg_getMINUS_objectMINUS_info: {
2099 if (args_info.object_type_given == 0) {
2100 fprintf(stderr, "Missing argument object type\n");
2101 rc = EXIT_FAILURE;
2102 break;
2103 }
2104
2105 arg[1].w = args_info.object_id_arg;
2106 yrc = yh_string_to_type(args_info.object_type_arg, &arg[2].t);
2107 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse type: ");
2108
2109 comrc = yh_com_get_object_info(&ctx, arg, fmt_nofmt);
2110 COM_SUCCEED_OR_DIE(comrc, "Unable to get object info");
2111 } break;
2112
2113 case action_arg_getMINUS_wrapped: {
2114 if (args_info.object_type_given == 0) {
2115 fprintf(stderr, "Missing argument object-type\n");
2116 rc = EXIT_FAILURE;
2117 break;
2118 }
2119
2120 if (args_info.wrap_id_given == 0) {
2121 fprintf(stderr, "Missing argument wrap-id\n");
2122 rc = EXIT_FAILURE;
2123 break;
2124 }
2125
2126 arg[1].w = args_info.object_id_arg;
2127 yrc = yh_string_to_type(args_info.object_type_arg, &arg[2].t);
2128 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse type: ");
2129
2130 arg[3].w = args_info.wrap_id_arg;
2131
2132 arg[4].s = args_info.out_arg;
2133 arg[4].len = strlen(args_info.out_arg);
2134
2135 comrc = yh_com_get_wrapped(&ctx, arg,
2137 : ctx.out_fmt);
2138 COM_SUCCEED_OR_DIE(comrc, "Unable to get wrapped object");
2139 } break;
2140
2141 case action_arg_getMINUS_deviceMINUS_info:
2142 comrc = yh_com_get_device_info(&ctx, arg, fmt_nofmt);
2143 COM_SUCCEED_OR_DIE(comrc, "Unable to get device info");
2144 break;
2145
2146 case action_arg_getMINUS_template: {
2147 arg[1].w = args_info.object_id_arg;
2148
2149 comrc = yh_com_get_template(&ctx, arg,
2151 : ctx.out_fmt);
2152 COM_SUCCEED_OR_DIE(comrc, "Unable to get template object");
2153 } break;
2154
2155 case action_arg_listMINUS_objects: {
2156 if (args_info.algorithm_given == 0) {
2157 fprintf(stderr, "Missing argument algorithm\n");
2158 rc = EXIT_FAILURE;
2159 break;
2160 }
2161
2162 if (args_info.object_type_given == 0) {
2163 fprintf(stderr, "Missing argument object-type\n");
2164 rc = EXIT_FAILURE;
2165 break;
2166 }
2167
2168 arg[1].w = args_info.object_id_arg;
2169 yrc = yh_string_to_type(args_info.object_type_arg, &arg[2].t);
2170 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse type: ");
2171
2172 yrc = yh_string_to_domains(args_info.domains_arg, &arg[3].w);
2173 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse domains: ");
2174
2175 memset(&arg[4].c, 0, sizeof(yh_capabilities));
2176 yrc =
2177 yh_string_to_capabilities(args_info.capabilities_arg, &arg[4].c);
2178 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse capabilities: ");
2179
2180 yrc = yh_string_to_algo(args_info.algorithm_arg, &arg[5].a);
2181 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse algorithm: ");
2182
2183 arg[6].s = args_info.label_arg;
2184 arg[6].len = strlen(args_info.label_arg);
2185
2186 comrc = yh_com_list_objects(&ctx, arg, fmt_nofmt);
2187 COM_SUCCEED_OR_DIE(comrc, "Unable to list objects");
2188 } break;
2189
2190 case action_arg_putMINUS_authenticationMINUS_key: {
2191 if (args_info.new_password_given == 0) {
2192 fprintf(stderr, "Missing argument new-password\n");
2193 rc = EXIT_FAILURE;
2194 break;
2195 }
2196
2197 arg[1].w = args_info.object_id_arg;
2198 arg[2].s = args_info.label_arg;
2199 arg[2].len = strlen(args_info.label_arg);
2200 yrc = yh_string_to_domains(args_info.domains_arg, &arg[3].w);
2201 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse domains: ");
2202
2203 memset(&arg[4].c, 0, sizeof(yh_capabilities));
2204 yrc =
2205 yh_string_to_capabilities(args_info.capabilities_arg, &arg[4].c);
2206 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse capabilities: ");
2207
2208 memset(&arg[5].c, 0, sizeof(yh_capabilities));
2209 yrc = yh_string_to_capabilities(args_info.delegated_arg, &arg[5].c);
2210 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse capabilities: ");
2211
2212 arg[6].x = (uint8_t *) args_info.new_password_arg;
2213 arg[6].len = strlen(args_info.new_password_arg);
2214
2215 comrc = yh_com_put_authentication(&ctx, arg, fmt_nofmt);
2216 COM_SUCCEED_OR_DIE(comrc, "Unable to store authentication key");
2217 } break;
2218
2219 case action_arg_putMINUS_asymmetricMINUS_key: {
2220 arg[1].w = args_info.object_id_arg;
2221 arg[2].s = args_info.label_arg;
2222 arg[2].len = strlen(args_info.label_arg);
2223
2224 yrc = yh_string_to_domains(args_info.domains_arg, &arg[3].w);
2225 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse domains: ");
2226
2227 memset(&arg[4].c, 0, sizeof(yh_capabilities));
2228 yrc =
2229 yh_string_to_capabilities(args_info.capabilities_arg, &arg[4].c);
2230 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse capabilities: ");
2231
2232 arg[5].x = buf;
2233 arg[5].len = sizeof(buf);
2234 if (get_input_data(args_info.in_arg, arg[5].x, &arg[5].len,
2235 ctx.in_fmt == fmt_nofmt ? fmt_PEM : ctx.in_fmt) ==
2236 false) {
2237 fprintf(stderr, "Failed to get input data\n");
2238 rc = EXIT_FAILURE;
2239 break;
2240 }
2241 comrc = yh_com_put_asymmetric(&ctx, arg, fmt_nofmt);
2242 COM_SUCCEED_OR_DIE(comrc, "Unable to store asymmetric key");
2243 } break;
2244
2245 case action_arg_putMINUS_opaque: {
2246 if (args_info.algorithm_given == 0) {
2247 fprintf(stderr, "Missing argument algorithm\n");
2248 rc = EXIT_FAILURE;
2249 break;
2250 }
2251
2252 arg[1].w = args_info.object_id_arg;
2253 arg[2].s = args_info.label_arg;
2254 arg[2].len = strlen(args_info.label_arg);
2255
2256 yrc = yh_string_to_domains(args_info.domains_arg, &arg[3].w);
2257 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse domains: ");
2258
2259 memset(&arg[4].c, 0, sizeof(yh_capabilities));
2260 yrc =
2261 yh_string_to_capabilities(args_info.capabilities_arg, &arg[4].c);
2262 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse capabilities: ");
2263
2264 yrc = yh_string_to_algo(args_info.algorithm_arg, &arg[5].a);
2265 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse algorithm: ");
2266
2267 arg[6].x = buf;
2268 arg[6].len = sizeof(buf);
2269 if (get_input_data(args_info.in_arg, arg[6].x, &arg[6].len,
2270 ctx.in_fmt == fmt_nofmt ? fmt_binary
2271 : ctx.in_fmt) == false) {
2272 fprintf(stderr, "Failed to get input data\n");
2273 rc = EXIT_FAILURE;
2274 break;
2275 }
2276
2277 comrc = yh_com_put_opaque(&ctx, arg, fmt_nofmt);
2278 COM_SUCCEED_OR_DIE(comrc, "Unable to store opaque object");
2279 } break;
2280
2281 case action_arg_setMINUS_option:
2282 LIB_SUCCEED_OR_DIE(YHR_GENERIC_ERROR, "Command not implemented: ");
2283
2284 case action_arg_putMINUS_hmacMINUS_key:
2285 LIB_SUCCEED_OR_DIE(YHR_GENERIC_ERROR, "Command not implemented: ");
2286 // TODO(adma): this requires a hex parser
2287
2288 case action_arg_putMINUS_wrapMINUS_key: {
2289
2290 if (args_info.delegated_given == 0) {
2291 fprintf(stderr, "Missing delegated capabilities\n");
2292 rc = EXIT_FAILURE;
2293 break;
2294 }
2295
2296 arg[1].w = args_info.object_id_arg;
2297
2298 arg[2].s = args_info.label_arg;
2299 arg[2].len = strlen(args_info.label_arg);
2300
2301 yrc = yh_string_to_domains(args_info.domains_arg, &arg[3].w);
2302 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse domains: ");
2303
2304 memset(&arg[4].c, 0, sizeof(yh_capabilities));
2305 yrc =
2306 yh_string_to_capabilities(args_info.capabilities_arg, &arg[4].c);
2307 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse capabilities: ");
2308
2309 memset(&arg[5].c, 0, sizeof(yh_capabilities));
2310 yrc = yh_string_to_capabilities(args_info.delegated_arg, &arg[5].c);
2311 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse capabilities: ");
2312
2313 arg[6].x = buf;
2314 arg[6].len = sizeof(buf);
2315 if (get_input_data(args_info.in_arg, arg[6].x, &arg[6].len,
2316 ctx.in_fmt == fmt_nofmt ? fmt_hex : ctx.in_fmt) ==
2317 false) {
2318 fprintf(stderr, "Failed to get input data\n");
2319 rc = EXIT_FAILURE;
2320 break;
2321 }
2322
2323 comrc = yh_com_put_wrapkey(&ctx, arg, fmt_nofmt);
2324 COM_SUCCEED_OR_DIE(comrc, "Unable to put wrapkey");
2325 } break;
2326
2327 case action_arg_putMINUS_wrapped: {
2328 if (args_info.wrap_id_given == 0) {
2329 fprintf(stderr, "Missing argument wrap-id\n");
2330 rc = EXIT_FAILURE;
2331 break;
2332 }
2333
2334 arg[1].w = args_info.wrap_id_arg;
2335 arg[2].x = buf;
2336 arg[2].len = sizeof(buf);
2337 if (get_input_data(args_info.in_arg, arg[2].x, &arg[2].len,
2338 ctx.in_fmt == fmt_nofmt ? fmt_base64
2339 : ctx.in_fmt) == false) {
2340 fprintf(stderr, "Failed to get input data\n");
2341 rc = EXIT_FAILURE;
2342 break;
2343 }
2344
2345 comrc = yh_com_put_wrapped(&ctx, arg, fmt_nofmt);
2346 COM_SUCCEED_OR_DIE(comrc, "Unable to store wrapped object");
2347 } break;
2348
2349 case action_arg_putMINUS_template: {
2350 if (args_info.algorithm_given == 0) {
2351 fprintf(stderr, "Missing argument algorithm\n");
2352 rc = EXIT_FAILURE;
2353 break;
2354 }
2355
2356 arg[1].w = args_info.object_id_arg;
2357 arg[2].s = args_info.label_arg;
2358 arg[2].len = strlen(args_info.label_arg);
2359
2360 yrc = yh_string_to_domains(args_info.domains_arg, &arg[3].w);
2361 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse domains: ");
2362
2363 memset(&arg[4].c, 0, sizeof(yh_capabilities));
2364 yrc =
2365 yh_string_to_capabilities(args_info.capabilities_arg, &arg[4].c);
2366 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse capabilities: ");
2367
2368 yrc = yh_string_to_algo(args_info.algorithm_arg, &arg[5].a);
2369 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse algorithm: ");
2370
2371 arg[6].x = buf;
2372 arg[6].len = sizeof(buf);
2373 if (get_input_data(args_info.in_arg, arg[6].x, &arg[6].len,
2374 ctx.in_fmt == fmt_nofmt ? fmt_binary
2375 : ctx.in_fmt) == false) {
2376 fprintf(stderr, "Failed to get input data\n");
2377 rc = EXIT_FAILURE;
2378 break;
2379 }
2380
2381 comrc = yh_com_put_template(&ctx, arg, fmt_nofmt);
2382 COM_SUCCEED_OR_DIE(comrc, "Unable to store template object");
2383 } break;
2384
2385 case action_arg_putMINUS_otpMINUS_aeadMINUS_key:
2386 LIB_SUCCEED_OR_DIE(YHR_GENERIC_ERROR, "Command not implemented: ");
2387 // TODO(adma): this requires a hex parser
2388
2389 case action_arg_signMINUS_eddsa:
2390 case action_arg_signMINUS_ecdsa: {
2391 if (args_info.algorithm_given == 0) {
2392 fprintf(stderr, "Missing argument algorithm\n");
2393 rc = EXIT_FAILURE;
2394 break;
2395 }
2396
2397 arg[1].w = args_info.object_id_arg;
2398 yrc = yh_string_to_algo(args_info.algorithm_arg, &arg[2].a);
2399 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse algorithm: ");
2400
2401 arg[3].x = buf;
2402 arg[3].len = sizeof(buf);
2403 if (get_input_data(args_info.in_arg, arg[3].x, &arg[3].len,
2404 ctx.in_fmt == fmt_nofmt ? fmt_binary
2405 : ctx.in_fmt) == false) {
2406 fprintf(stderr, "Failed to get input data\n");
2407 rc = EXIT_FAILURE;
2408 break;
2409 }
2410
2411 if (args_info.action_arg[i] == action_arg_signMINUS_ecdsa) {
2412 comrc = yh_com_sign_ecdsa(&ctx, arg,
2414 : ctx.out_fmt);
2415 } else {
2416 comrc = yh_com_sign_eddsa(&ctx, arg,
2418 : ctx.out_fmt);
2419 }
2420
2421 COM_SUCCEED_OR_DIE(comrc, "Unable to sign data");
2422 } break;
2423
2424 case action_arg_signMINUS_pkcs1v15: {
2425 if (args_info.algorithm_given == 0) {
2426 fprintf(stderr, "Missing argument algorithm\n");
2427 rc = EXIT_FAILURE;
2428 break;
2429 }
2430
2431 arg[1].w = args_info.object_id_arg;
2432 yrc = yh_string_to_algo(args_info.algorithm_arg, &arg[2].a);
2433 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse algorithm: ");
2434
2435 arg[3].x = buf;
2436 arg[3].len = sizeof(buf);
2437 if (get_input_data(args_info.in_arg, arg[3].x, &arg[3].len,
2438 ctx.in_fmt == fmt_nofmt ? fmt_binary
2439 : ctx.in_fmt) == false) {
2440 fprintf(stderr, "Failed to get input data\n");
2441 rc = EXIT_FAILURE;
2442 break;
2443 }
2444
2445 comrc = yh_com_sign_pkcs1v1_5(&ctx, arg,
2447 : ctx.out_fmt);
2448 COM_SUCCEED_OR_DIE(comrc, "Unable to sign data");
2449 } break;
2450
2451 case action_arg_signMINUS_pss: {
2452 if (args_info.algorithm_given == 0) {
2453 fprintf(stderr, "Missing argument algorithm\n");
2454 rc = EXIT_FAILURE;
2455 break;
2456 }
2457
2458 arg[1].w = args_info.object_id_arg;
2459 yrc = yh_string_to_algo(args_info.algorithm_arg, &arg[2].a);
2460 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse algorithm: ");
2461
2462 arg[3].x = buf;
2463 arg[3].len = sizeof(buf);
2464 if (get_input_data(args_info.in_arg, arg[3].x, &arg[3].len,
2465 ctx.in_fmt == fmt_nofmt ? fmt_binary
2466 : ctx.in_fmt) == false) {
2467 fprintf(stderr, "Failed to get input data\n");
2468 rc = EXIT_FAILURE;
2469 break;
2470 }
2471
2472 comrc = yh_com_sign_pss(&ctx, arg,
2474 : ctx.out_fmt);
2475 COM_SUCCEED_OR_DIE(comrc, "Unable to sign data");
2476 } break;
2477
2478 case action_arg_signMINUS_hmac:
2479 LIB_SUCCEED_OR_DIE(YHR_GENERIC_ERROR, "Command not implemented: ");
2480 // TODO(adma): this requires a hex parser
2481
2482 case action_arg_reset: {
2483 comrc = yh_com_reset(&ctx, arg, fmt_nofmt);
2484 COM_SUCCEED_OR_DIE(comrc, "Unable to reset device");
2485 } break;
2486
2487 case action_arg_deleteMINUS_object: {
2488 if (args_info.object_type_given == 0) {
2489 fprintf(stderr, "Missing argument object type\n");
2490 rc = EXIT_FAILURE;
2491 break;
2492 }
2493
2494 yrc = yh_string_to_type(args_info.object_type_arg, &arg[2].t);
2495 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse type: ");
2496 arg[1].w = args_info.object_id_arg;
2497
2498 comrc = yh_com_delete(&ctx, arg, fmt_nofmt);
2499 COM_SUCCEED_OR_DIE(comrc, "Unable to delete object");
2500 } break;
2501
2502 case action_arg_signMINUS_sshMINUS_certificate: {
2503 if (args_info.template_id_given == 0) {
2504 fprintf(stderr, "Missing argument template-id\n");
2505 rc = EXIT_FAILURE;
2506 break;
2507 }
2508
2509 if (args_info.algorithm_given == 0) {
2510 fprintf(stderr, "Missing argument algorithm\n");
2511 rc = EXIT_FAILURE;
2512 break;
2513 }
2514
2515 arg[1].w = args_info.object_id_arg;
2516 arg[2].w = args_info.template_id_arg;
2517 yrc = yh_string_to_algo(args_info.algorithm_arg, &arg[3].a);
2518 LIB_SUCCEED_OR_DIE(yrc, "Unable to parse algorithm: ");
2519
2520 arg[4].x = buf;
2521 arg[4].len = sizeof(buf);
2522 if (get_input_data(args_info.in_arg, arg[4].x, &arg[4].len,
2523 ctx.in_fmt == fmt_nofmt ? fmt_binary
2524 : ctx.in_fmt) ==
2525 false) { // TODO: correct format?
2526 fprintf(stderr, "Failed to get input data\n");
2527 rc = EXIT_FAILURE;
2528 break;
2529 }
2530
2531 comrc =
2534 : ctx.out_fmt);
2535 COM_SUCCEED_OR_DIE(comrc, "Unable to get ssh certificate");
2536 } break;
2537
2538 case action_arg_benchmark:
2539 LIB_SUCCEED_OR_DIE(YHR_GENERIC_ERROR, "Command not implemented: ");
2540
2541 case action_arg_createMINUS_otpMINUS_aead:
2542 LIB_SUCCEED_OR_DIE(YHR_GENERIC_ERROR, "Command not implemented: ");
2543 // TODO(adma): this requires a hex parser
2544
2545 case action_arg_randomizeMINUS_otpMINUS_aead: {
2546 arg[1].w = args_info.object_id_arg;
2547 arg[2].s = args_info.out_arg;
2548 arg[2].len = strlen(args_info.out_arg);
2549
2550 comrc =
2551 yh_com_otp_aead_random(&ctx, arg,
2553 : ctx.out_fmt);
2554 COM_SUCCEED_OR_DIE(comrc, "Unable to get aead from random");
2555 } break;
2556
2557 case action_arg_decryptMINUS_otp:
2558 LIB_SUCCEED_OR_DIE(YHR_GENERIC_ERROR, "Command not implemented: ");
2559 // TODO(adma): this requires a hex parser
2560
2561 case action_arg_signMINUS_attestationMINUS_certificate: {
2562 if (args_info.attestation_id_given == 0) {
2563 fprintf(stderr, "Missing argument attestation-id\n");
2564 rc = EXIT_FAILURE;
2565 break;
2566 }
2567
2568 arg[1].w = args_info.object_id_arg;
2569 arg[2].w = args_info.attestation_id_arg;
2570
2571 comrc = yh_com_sign_attestation_certificate(&ctx, arg,
2572 ctx.out_fmt == fmt_nofmt
2573 ? fmt_PEM
2574 : ctx.out_fmt);
2575 COM_SUCCEED_OR_DIE(comrc, "Unable to attest asymmetric key");
2576 } break;
2577
2578 case action_arg_getMINUS_logs: {
2579 comrc =
2580 yh_com_audit(&ctx, arg,
2581 ctx.out_fmt == fmt_nofmt ? fmt_ASCII : ctx.out_fmt);
2582 COM_SUCCEED_OR_DIE(comrc, "Unable to extract logs");
2583 } break;
2584
2585 case action_arg_setMINUS_logMINUS_index: {
2586 if (args_info.log_index_given == 0) {
2587 fprintf(stderr, "Missing argument log-index\n");
2588 rc = EXIT_FAILURE;
2589 break;
2590 }
2591
2592 arg[1].w = args_info.log_index_arg;
2593
2594 comrc = yh_com_set_log_index(&ctx, arg,
2595 ctx.out_fmt == fmt_nofmt ? fmt_ASCII
2596 : ctx.out_fmt);
2597 COM_SUCCEED_OR_DIE(comrc, "Unable to set log index");
2598 } break;
2599
2600 case action_arg_blinkMINUS_device: {
2601 if(args_info.duration_arg < 0 || args_info.duration_arg > 0xff) {
2602 fprintf(stderr, "Duration must be in [0, 256]\n");
2603 rc = EXIT_FAILURE;
2604 break;
2605 }
2606
2607 arg[1].w = args_info.duration_arg;
2608
2609 comrc = yh_com_blink(&ctx, arg, fmt_nofmt);
2610 COM_SUCCEED_OR_DIE(comrc, "Unable to blink device");
2611 } break;
2612
2613 case action__NULL:
2614 printf("ERROR !%u \n", args_info.action_given);
2615 rc = EXIT_FAILURE;
2616 }
2617
2618 if (rc == EXIT_FAILURE) {
2619 break;
2620 }
2621 }
2622
2623 calling_device = false;
2624
2625 if (requires_session == true) {
2626 yh_util_close_session(arg[0].e);
2627 }
2628
2629 } else {
2630 int num;
2631#ifndef __WIN32
2632 EditLine *el;
2633
2634 HistEvent ev;
2635
2636 g_hist = history_init();
2637
2638 history(g_hist, &ev, H_SETSIZE, 100); // NOTE(adma): 100 history items
2639
2640 el = el_init(*argv, stdin, stdout, stderr);
2641
2642 el_set(el, EL_EDITOR, "emacs");
2643
2644#ifdef EL_PROMPT_ESC
2645 el_set(el, EL_PROMPT_ESC, prompt, '\1'); /* Set the prompt function */
2646#else
2647 el_set(el, EL_PROMPT, prompt); /* Set the prompt function */
2648#endif /* EL_PROMPT_ESC */
2649
2650 el_set(el, EL_HIST, history, g_hist);
2651
2652 /* Add a user-defined function */
2653 el_set(el, EL_ADDFN, "yh_complete", "Complete argument", yubihsm_complete);
2654
2655 /* Bind tab to it */
2656 el_set(el, EL_BIND, "^I", "yh_complete", NULL);
2657
2658 el_source(el, NULL); // NOTE(adma): source the user's defaults file
2659#endif
2660
2662
2663 while (g_running == true) {
2664#ifdef __WIN32
2665 fprintf(stdout, PROMPT);
2666 char data[1025];
2667 char *buf = fgets(data, sizeof(data), stdin);
2668 if (buf) {
2669 num = strlen(buf);
2670 }
2671#else
2672 const char *buf = el_gets(el, &num);
2673#endif
2674
2675 if (buf == NULL) {
2676 // NOTE(adma): got Ctrl-D
2677 yh_com_quit(NULL, NULL, fmt_nofmt);
2678 fprintf(stdout, "\n");
2679 } else if (num > 0 && buf[0] != '\n' && buf[0] != '\r') {
2680#ifndef __WIN32
2681 history(g_hist, &ev, H_ENTER, buf);
2682#endif
2683 calling_device = true;
2685 calling_device = false;
2686 }
2687 }
2688
2689#ifndef __WIN32
2690 el_end(el);
2691 history_end(g_hist);
2692#endif
2693 }
2694
2695main_exit:
2696
2697 cmdline_parser_free(&args_info);
2698
2699 if (ctx.out != stdout && ctx.out != NULL) {
2700 fclose(ctx.out);
2701 }
2702
2703 if (ctx.cacert) {
2704 free(ctx.cacert);
2705 }
2706 if (ctx.proxy) {
2707 free(ctx.proxy);
2708 }
2709
2710 yh_exit();
2711
2712#ifdef USE_YKYH
2713 ykyh_done(ctx.state); // TODO(adma): more consistent naming
2714 ctx.state = NULL;
2715#endif
2716
2717 return rc;
2718}
char ** argv
lib::function< void(lib::error_code const &)> timer_handler
The type and signature of the callback passed to the read method.
#define LIB_SUCCEED_OR_DIE(x, s)
Definition main.c:65
int validate_and_call(yubihsm_context *ctx, CommandList l, const char *line)
Definition main.c:1507
void create_command_list(CommandList *c)
Definition main.c:221
bool g_running
Definition main.c:591
CommandList g_commands
Definition main.c:589
#define LOCAL_CONNECTOR_URL
Definition main.c:47
#define COM_SUCCEED_OR_DIE(x, s)
Definition main.c:72
History * g_hist
Definition main.c:62
unsigned char yubihsm_complete(EditLine *el, int ch)
Definition main.c:1163
unsigned char uint8_t
Definition stdint.h:124
const char * s
Definition commands.h:29
unsigned char * x
Definition commands.h:37
size_t len
Definition commands.h:38
uint16_t w
Definition commands.h:27
uint32_t d
Definition commands.h:28
yh_session * e
Definition commands.h:31
Capabilities representation.
Definition yubihsm.h:162
ykyh_state * state
cmd_format in_fmt
yh_session * sessions[YH_MAX_SESSIONS]
yh_connector * connector
cmd_format out_fmt
char ** connector_list
account_query_db::get_accounts_by_authorizers_params params
ykyh_rc ykyh_done(ykyh_state *state)
Definition ykyh.c:64
ykyh_rc ykyh_init(ykyh_state **state, int verbose)
Definition ykyh.c:35
ykyh_rc
Definition ykyh.h:76
@ YKYHR_SUCCESS
Definition ykyh.h:77
yh_rc yh_set_verbosity(yh_connector *connector, uint8_t verbosity)
Definition yubihsm.c:3825
yh_rc yh_exit(void)
Definition yubihsm.c:3910
yh_rc yh_init(void)
Definition yubihsm.c:3857
yh_rc yh_string_to_type(const char *string, yh_object_type *type)
Definition yubihsm.c:4442
yh_rc yh_util_close_session(yh_session *session)
Definition yubihsm.c:1257
yh_rc yh_string_to_domains(const char *domains, uint16_t *result)
Definition yubihsm.c:4535
yh_rc yh_string_to_capabilities(const char *capability, yh_capabilities *result)
Definition yubihsm.c:4115
yh_rc yh_string_to_algo(const char *string, yh_algorithm *algo)
Definition yubihsm.c:4403
#define YH_VERB_ALL
Debug level all. All previous options enabled.
Definition yubihsm.h:145
#define YH_MAX_SESSIONS
Max sessions the device may hold.
Definition yubihsm.h:105
yh_rc
Definition yubihsm.h:170
@ YHR_GENERIC_ERROR
Return value when encountering an unknown error.
Definition yubihsm.h:228
uint8_t buf[2048]
bool set
yh_rc yrc
memset(pInfo->slotDescription, ' ', 64)

◆ msort_list()

CommandList msort_list ( CommandList list)

Definition at line 137 of file main.c.

137 {
138
139 Command *left;
140 Command *right;
141 Command *e;
142
143 int in_size;
144 int left_size;
145 int right_size;
146
147 // NOTE(adma): do nothing on an empty list
148 if (!list) {
149 return NULL;
150 }
151
152 in_size = 1;
153
154 while (1) {
155 Command *tail = NULL;
156 left = list;
157 list = NULL;
158
159 int n_merges = 0;
160
161 while (left != NULL) {
162 n_merges++;
163
164 right = left;
165 left_size = 0;
166 for (int i = 0; i < in_size; i++) {
167 left_size++;
168 right = right->next;
169
170 if (right == NULL) {
171 break;
172 }
173 }
174
175 right_size = in_size;
176
177 while (left_size > 0 || (right_size > 0 && right)) {
178
179 if (left_size == 0) {
180 e = right;
181 right = right->next;
182 right_size--;
183 } else if (right_size == 0 || !right) {
184 e = left;
185 left = left->next;
186 left_size--;
187 } else if (strcmp(left->name, right->name) <= 0) {
188 e = left;
189 left = left->next;
190 left_size--;
191 } else {
192 e = right;
193 right = right->next;
194 right_size--;
195 }
196
197 if (tail) {
198 tail->next = e;
199 } else {
200 list = e;
201 }
202
203 tail = e;
204 }
205
206 left = right;
207 }
208
209 if (tail != NULL) {
210 tail->next = NULL;
211 }
212
213 if (n_merges <= 1) {
214 return list;
215 }
216
217 in_size *= 2;
218 }
219}
char * name
Definition main.c:99
Here is the caller graph for this function:

◆ register_command()

Command * register_command ( CommandList list,
Command command )

Definition at line 112 of file main.c.

112 {
113
114 Command *c = calloc(1, sizeof(Command));
115
116 assert(strlen(command.name) <= MAX_COMMAND_NAME);
117
118 memcpy(c, &command, sizeof(Command));
119 c->next = list;
120
121 return c;
122}
memcpy((char *) pInfo->slotDescription, s, l)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ register_subcommand()

void register_subcommand ( Command * parent,
Command command )

Definition at line 124 of file main.c.

124 {
125
126 Command *c = malloc(sizeof(Command));
127
128 if (c == NULL) {
129 fprintf(stderr, "Failed to allocate memory\n");
130 exit(EXIT_FAILURE);
131 }
132 memcpy(c, &command, sizeof(Command));
133 c->next = parent->subcommands;
134 parent->subcommands = c;
135}
Command * subcommands
Definition main.c:105
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tokenize()

int tokenize ( char * line,
char ** toks,
int max_toks,
int * cursorc,
int * cursoro,
const char * space )

Definition at line 852 of file main.c.

853 {
854 int i;
855 int tok = 0;
856 int length = strlen(line);
857 int start_of_word = 0;
858 enum states { SPACE, WORD, QUOTE } state = SPACE;
859 toks[0] = line; // set up as fall-through
860
861 for (i = 0; i <= length; i++) {
862 char c = line[i];
863 if (cursorc && i == *cursorc && tok > 0) {
864 if (state == SPACE) {
865 *cursoro = 0;
866 *cursorc = tok;
867 } else {
868 *cursoro = i - start_of_word;
869 *cursorc = tok - 1;
870 }
871 }
872 if (c == '\0') {
873 break;
874 }
875 if (tok >= max_toks) {
876 return -1;
877 }
878 switch (state) {
879 case SPACE: {
880 bool found = false;
881 for (size_t j = 0; j < strlen(space); j++) {
882 if (c == space[j]) {
883 found = true;
884 break;
885 }
886 }
887 if (found) {
888 break;
889 }
890 if (c == '"') {
891 state = QUOTE;
892 start_of_word = i + 1;
893 } else if (c == '#') {
894 return tok;
895 } else {
896 state = WORD;
897 start_of_word = i;
898 }
899 toks[tok++] = line + start_of_word;
900 } break;
901 case QUOTE:
902 if (c == '"') {
903 line[i] = '\0';
904 state = SPACE;
905 }
906 break;
907 case WORD:
908 for (size_t j = 0; j < strlen(space); j++) {
909 if (c == space[j]) {
910 line[i] = '\0';
911 state = SPACE;
912 }
913 }
914 break;
915 }
916 }
917 return tok;
918}
uint16_t j
Here is the caller graph for this function:

◆ validate_and_call()

int validate_and_call ( yubihsm_context * ctx,
CommandList l,
const char * line )

Definition at line 1507 of file main.c.

1507 {
1508
1509 int argc = 0;
1510 char *argv[64];
1511 int i = 0;
1512
1513 char data[ARGS_BUFFER_SIZE + 1];
1514
1515 char arg_data[ARGS_BUFFER_SIZE + 1] = {0};
1516
1517 Command *command = l;
1518
1519 bool completing_args = false;
1520
1521 const char *args = "";
1522
1523 Argument arguments[MAX_ARGUMENTS] = {{{0}, 0, 0}};
1524 int n_arguments = 0;
1525
1526 bool invalid_arg = false;
1527
1528 int match;
1529
1530 bool found = false;
1531
1532 CommandFunction *func = NULL;
1533
1534 memset(data, 0x0, sizeof(data));
1535 memset(arg_data, 0x0, sizeof(data));
1536
1537 if (strlen(line) > ARGS_BUFFER_SIZE) {
1538 printf("Command too long\n");
1539 return 0;
1540 }
1541
1542 strcpy(data, line);
1543
1544 argc = tokenize(data, argv, 64, NULL, NULL, SPACES);
1545
1546 while (i < argc) {
1547 // NOTE(adma): match the first n-1 items
1548 if (completing_args == false) {
1549 // NOTE(adma): match subcommands
1550 match = strncmp(argv[i], command->name, strlen(argv[i]));
1551 if (match == 0) {
1552 if (command->subcommands != NULL) {
1553 // NOTE(adma): if we were matching subcommands, keep
1554 // matching subcommands if any
1555 command = command->subcommands;
1556 } else {
1557 // NOTE(adma): start matching arguments otherwise. Also keep
1558 // track of the function because that's the one we want to
1559 // call later on
1560 completing_args = true;
1561 func = command->func;
1562 if (command->args != NULL) {
1563 char *arg_toks[64];
1564
1565 args = command->args;
1566 strncpy(arg_data, args,
1567 ARGS_BUFFER_SIZE); // since tokenize() modifies the buffer..
1568 int num_args = tokenize(arg_data, arg_toks, 64, NULL, NULL, ",");
1569 if (num_args + 1 + i !=
1570 argc) { // some arguments might have default values
1571 for (int j = 0; j < num_args; j++) {
1572 if (j < argc - 1 - i) {
1573 continue;
1574 }
1575 char *str = strchr(arg_toks[j], '=');
1576 if (str == NULL) {
1577 break;
1578 }
1579 str++;
1580 argv[j + 1 + i] = str;
1581 argc++;
1582 }
1583 }
1584 } else {
1585 // NOTE(adma): there are no args for this command
1586 found = true;
1587 break;
1588 }
1589 }
1590 i++; // NOTE(adma): next word
1591 } else {
1592 // NOTE(adma): command not found
1593 command = command->next;
1594 if (match < 0 || command == NULL) {
1595 command = NULL;
1596 break;
1597 }
1598 }
1599 } else {
1600 // NOTE(adma): match arguments
1601 if (validate_arg(ctx, *args, argv[i], arguments + n_arguments++,
1602 ctx->in_fmt != fmt_nofmt ? ctx->in_fmt
1603 : command->in_fmt) != 0) {
1604 invalid_arg = true;
1605 break;
1606 }
1607 while (*args != '\0' && *args != ',') {
1608 args++;
1609 }
1610 if (*args == ',') {
1611 args++;
1612 i++; // NOTE(adma): next word
1613 } else {
1614 found = true;
1615 break;
1616 }
1617 }
1618 }
1619
1620 if (found == true) {
1621 func(ctx, arguments,
1622 ctx->out_fmt == fmt_nofmt ? command->out_fmt : ctx->out_fmt);
1623
1624 for (int i = 0; i < n_arguments; i++) {
1625 if (arguments[i].x != NULL) {
1626 free(arguments[i].x);
1627 arguments[i].x = NULL;
1628 }
1629 }
1630 // NOTE: if ctx->in or ctx->out is changed, close and return state,
1631 // otherwise the next command that needs a file might get sad.
1632 if (ctx->out != stdout) {
1633 fclose(ctx->out);
1634 ctx->out = stdout;
1635 }
1636 } else {
1637 if (invalid_arg == true) {
1638 char arg[ARGS_BUFFER_SIZE + 1];
1639 memset(arg, 0x0, sizeof(arg));
1640 strncpy(arg, args, ARGS_BUFFER_SIZE);
1641 char *end = strchr(args, ',');
1642 if (end) {
1643 arg[end - args] = '\0';
1644 }
1645 printf("Invalid argument %d: %s (%s)\n", i, argv[i], arg);
1646 } else if (command == NULL) {
1647 printf("Command %s%s%s not found\n", argv[0], i ? " " : "",
1648 i ? argv[1] : "");
1649 } else if (*args != '\0' || argc - 1 == 0) {
1650 printf("Incomplete command\n");
1651 for (int i = 0; i < argc; i++) {
1652 arguments[i].s = argv[i];
1653 }
1654 yh_com_help(NULL, arguments, fmt_nofmt);
1655 }
1656 }
1657
1658 return 0;
1659}
int CommandFunction(yubihsm_context *ctx, Argument *argv, cmd_format fmt)
Definition commands.h:41
return str
Definition CLI11.hpp:1359
#define MAX_ARGUMENTS
Definition main.c:45
#define SPACES
Definition main.c:51
int validate_arg(yubihsm_context *ctx, char type, const char *value, Argument *parsed, cmd_format fmt)
Definition main.c:1383
#define ARGS_BUFFER_SIZE
Definition main.c:41
char * args
Definition main.c:101
CommandFunction * func
Definition main.c:100
cmd_format in_fmt
Definition main.c:102
cmd_format out_fmt
Definition main.c:103
int l
Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_arg()

int validate_arg ( yubihsm_context * ctx,
char type,
const char * value,
Argument * parsed,
cmd_format fmt )

Definition at line 1383 of file main.c.

1384 {
1385
1386 char buffer[ARGS_BUFFER_SIZE + 1];
1387
1388 memset(buffer, 0x0, sizeof(buffer));
1389
1390 switch (type) {
1391 case 'b': // byte
1392 case 'w': // word
1393 case 'e': // session
1394 case 'u': { // unsigned long
1395 uint32_t max = 0;
1396 if (type == 'b') {
1397 max = UCHAR_MAX;
1398 } else if (type == 'w' || type == 'e') {
1399 max = USHRT_MAX;
1400 } else if (type == 'u') {
1401 max = UINT_MAX;
1402 }
1403 // NOTE(adma): check that is a positive number in dec, hex or oct
1404 errno = 0;
1405 char *endptr;
1406 unsigned long num = strtoul(value, &endptr, 0);
1407
1408 if ((errno == ERANGE || num > max) || (errno != 0 && num == 0)) {
1409 return -1;
1410 }
1411
1412 if (endptr == value) {
1413 return -1;
1414 }
1415
1416 if (type == 'b') {
1417 parsed->b = (uint8_t) num;
1418 } else if (type == 'e') {
1419 if (num >= YH_MAX_SESSIONS || !probe_session(ctx, num)) {
1420 return -1;
1421 }
1422 parsed->e = ctx->sessions[num];
1423 } else if (type == 'w') {
1424 parsed->w = (uint16_t) num;
1425 } else if (type == 'u') {
1426 parsed->d = (uint32_t) num;
1427 }
1428 parsed->len = 1; // NOTE(adma): doesn't really have a meaning
1429
1430 } break;
1431
1432 case 'F':
1433 parsed->s = value;
1434 parsed->len = strlen(value);
1435
1436 ctx->out = open_file(value, false);
1437 if (!ctx->out) {
1438 return -1;
1439 }
1440
1441 break;
1442
1443 case 'i':
1444 parsed->x = calloc(ARGS_BUFFER_SIZE + 1, 1);
1445 if (parsed->x == NULL) {
1446 return -1;
1447 }
1448 parsed->len = ARGS_BUFFER_SIZE;
1449 if (get_input_data(value, parsed->x, &parsed->len, fmt) == false) {
1450 return -1;
1451 }
1452 break;
1453
1454 case 'I':
1455 case 's':
1456 // NOTE(adma): strings are pretty much always OK
1457 parsed->s = value;
1458 parsed->len = strlen(value);
1459
1460 break;
1461
1462 case 'k':
1463 if (strcmp(value, "stdin:") == 0) {
1464 if (EVP_read_pw_string(buffer, ARGS_BUFFER_SIZE,
1465 "Enter hex key: ", 0) != 0) {
1466 return -1;
1467 }
1468 value = buffer;
1469 }
1470 case 'd':
1471 if (yh_string_to_domains(value, &parsed->w) != YHR_SUCCESS) {
1472 return -1;
1473 }
1474 break;
1475 case 'c':
1476 if (yh_string_to_capabilities(value, &parsed->c) != YHR_SUCCESS) {
1477 return -1;
1478 }
1479 break;
1480
1481 case 'a':
1482 if (yh_string_to_algo(value, &parsed->a) != YHR_SUCCESS) {
1483 return -1;
1484 }
1485 break;
1486
1487 case 't':
1488 if (yh_string_to_type(value, &parsed->t) != YHR_SUCCESS) {
1489 return -1;
1490 }
1491 break;
1492
1493 case 'o':
1494 if (yh_string_to_option(value, &parsed->o) != YHR_SUCCESS) {
1495 return -1;
1496 }
1497 break;
1498
1499 default:
1500 // NOTE(adma): unknown type
1501 return -1;
1502 }
1503
1504 return 0;
1505}
#define value
Definition pkcs11.h:157
unsigned int uint32_t
Definition stdint.h:126
yh_option o
Definition commands.h:35
yh_capabilities c
Definition commands.h:32
yh_object_type t
Definition commands.h:34
uint8_t b
Definition commands.h:26
yh_algorithm a
Definition commands.h:33
yh_rc yh_string_to_option(const char *string, yh_option *option)
Definition yubihsm.c:4463
Here is the call graph for this function:
Here is the caller graph for this function:

◆ yh_com_help()

int yh_com_help ( yubihsm_context * ctx,
Argument * argv,
cmd_format fmt )

Definition at line 628 of file main.c.

628 {
629
630 UNUSED(fmt);
631 UNUSED(ctx);
632 bool match = false;
633
634 // TODO(adma): once we have optional commands we can have a real help
635 for (Command *command = g_commands; command; command = command->next) {
636 if (strncmp(argv[0].s, command->name, strlen(argv[0].s)) == 0) {
637 match = true;
638 printf("%-25s%s\n", command->name, command->doc);
639 if (strlen(argv[0].s)) {
640 if (command->args) {
641 printf("%-5s%s", "", command->args);
642 if (command->in_fmt != fmt_nofmt) {
643 printf(" (default input format: %s)",
644 fmt_to_string(command->in_fmt));
645 }
646 printf("\n");
647 }
648 for (Command *subcommand = command->subcommands; subcommand;
649 subcommand = subcommand->next) {
650 printf("%-5s%-25s%s", "", subcommand->name, subcommand->doc);
651 if (subcommand->args) {
652 if (subcommand->in_fmt != fmt_nofmt) {
653 printf(" (default input format: %s)",
654 fmt_to_string(subcommand->in_fmt));
655 }
656 printf("\n%-30s%s\n", "", subcommand->args);
657 } else {
658 printf("\n");
659 }
660 }
661 }
662 }
663 }
664
665 if (match == false) {
666 printf("Help for command %s not found\n", argv[0].s);
667 }
668 return 0;
669}
#define UNUSED(x)
Here is the caller graph for this function:

◆ yh_com_history()

int yh_com_history ( yubihsm_context * ctx,
Argument * argv,
cmd_format fmt )

Definition at line 595 of file main.c.

595 {
596
597 UNUSED(fmt);
598 UNUSED(ctx);
599 UNUSED(argv);
600
601#ifndef __WIN32
602 HistEvent ev;
603
604 int rv;
605
606 for (rv = history(g_hist, &ev, H_LAST); rv != -1;
607 rv = history(g_hist, &ev, H_PREV)) {
608 fprintf(ctx->out, "%4d %s", ev.num, ev.str);
609 }
610#endif
611
612 return 0;
613}
CK_RV rv
Here is the caller graph for this function:

◆ yh_com_keepalive_off()

int yh_com_keepalive_off ( yubihsm_context * ctx,
Argument * argv,
cmd_format fmt )

Definition at line 774 of file main.c.

774 {
775
776 UNUSED(ctx);
777 UNUSED(argv);
778 UNUSED(fmt);
779
780 return set_keepalive(0);
781}
Here is the caller graph for this function:

◆ yh_com_keepalive_on()

int yh_com_keepalive_on ( yubihsm_context * ctx,
Argument * argv,
cmd_format fmt )

Definition at line 763 of file main.c.

763 {
764
765 UNUSED(ctx);
766 UNUSED(argv);
767 UNUSED(fmt);
768
769 return set_keepalive(15);
770}
Here is the caller graph for this function:

◆ yh_com_quit()

int yh_com_quit ( yubihsm_context * ctx,
Argument * argv,
cmd_format fmt )

Definition at line 673 of file main.c.

673 {
674
675 UNUSED(fmt);
676 UNUSED(ctx);
677 UNUSED(argv);
678
679 g_running = false;
680
681 return 0;
682}
Here is the caller graph for this function:

◆ yh_com_set_informat()

int yh_com_set_informat ( yubihsm_context * ctx,
Argument * argv,
cmd_format fmt )

Definition at line 783 of file main.c.

783 {
784 UNUSED(fmt);
785
786 if (strcasecmp(argv[0].s, "default") == 0) {
787 ctx->in_fmt = fmt_nofmt;
788 return 0;
789 }
790 for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
791 if (strcasecmp(argv[0].s, formats[i].name) == 0) {
792 ctx->in_fmt = formats[i].format;
793 return 0;
794 }
795 }
796 fprintf(stderr, "Failed to parse input format\n");
797 return -1;
798}
Here is the caller graph for this function:

◆ yh_com_set_outformat()

int yh_com_set_outformat ( yubihsm_context * ctx,
Argument * argv,
cmd_format fmt )

Definition at line 800 of file main.c.

800 {
801 UNUSED(fmt);
802
803 if (strcasecmp(argv[0].s, "default") == 0) {
804 ctx->out_fmt = fmt_nofmt;
805 return 0;
806 }
807 for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
808 if (strcasecmp(argv[0].s, formats[i].name) == 0) {
809 if (formats[i].format == fmt_password) {
810 break;
811 }
812 ctx->out_fmt = formats[i].format;
813 return 0;
814 }
815 }
816 fprintf(stderr, "Failed to parse output format\n");
817 return -1;
818}
cmd_format format
Here is the caller graph for this function:

◆ yubihsm_complete()

unsigned char yubihsm_complete ( EditLine * el,
int ch )

Definition at line 1163 of file main.c.

1163 {
1164
1165 UNUSED(ch);
1166
1167 const LineInfo *li;
1168
1169 int argc, cursorc, cursoro;
1170 char *argv[64];
1171 char data[ARGS_BUFFER_SIZE + 1] = {0};
1172
1173 li = el_line(el);
1174
1175 cursorc = li->cursor - li->buffer;
1176 if (li->lastchar - li->buffer > 1024) {
1177 return CC_REDISPLAY;
1178 }
1179 memcpy(data, li->buffer, li->lastchar - li->buffer);
1180
1181 argc = tokenize(data, argv, 64, &cursorc, &cursoro, SPACES);
1182
1183 // printf("\nargc %d, cursorc: %d, cursoro: %d\n", argc, cursorc, cursoro);
1184
1185 if (argc == 0) {
1186 // NOTE(adma): no prompt, don't even bother with finding a match,
1187 // just show all commands, one per line
1188 printf("\n");
1189 for (Command *command = g_commands; command; command = command->next) {
1190 printf("%s\n", command->name);
1191 }
1192 return CC_REDISPLAY;
1193 } else {
1194 int i = 0;
1195 Command *command = g_commands;
1196 Command *to_complete = NULL;
1197 char *args = "";
1198
1199 bool completing_args = false;
1200
1201 while (i < cursorc) {
1202 // NOTE(adma): match the first n-1 items
1203 if (completing_args == false) {
1204 // NOTE(adma): match subcommands
1205 if (strncmp(argv[i], command->name, strlen(argv[i])) == 0) {
1206 // printf("\nmatched %s\n", command->name);
1207 to_complete = command;
1208 // to_complete_position = i;
1209 if (command->subcommands != NULL) {
1210 // NOTE(adma): if we were matching subcommands, keep
1211 // matching subcommands if any
1212 command = command->subcommands;
1213 } else {
1214 // NOTE(adma): start matching arguments otherwise
1215 completing_args = true;
1216 if (command->args != NULL) {
1217 args = command->args;
1218 } else {
1219 // NOTE(adma): there are no args for this command
1220 break;
1221 }
1222 }
1223 i++; // NOTE(adma): next word
1224 } else {
1225 command = command->next;
1226 if (command == NULL) {
1227 // NOTE(adma): command not found
1228 break;
1229 }
1230 }
1231 } else {
1232 // NOTE(adma): match arguments
1233 while (*args != '\0' && *args != ',') {
1234 args++;
1235 }
1236 if (*args == ',') {
1237 args++;
1238 i++; // NOTE(adma): next word
1239 } else {
1240 break;
1241 }
1242 }
1243 }
1244
1245 if (to_complete && cursorc != 0) {
1246 // NOTE(adma): 0 has a bit of a special meaning since the cursor
1247 // is after the last letter of the first word and we still want
1248 // to autocomplete commands and not subcommands nor args in that
1249 // case
1250 to_complete = to_complete->subcommands;
1251 }
1252
1253 if (argc == cursorc) {
1254 if (to_complete && completing_args == false) {
1255 // NOTE(adma): cursor is after a command but there is no more
1256 // text to match, show all subcommands
1257 printf("\n");
1258 for (Command *command = to_complete; command; command = command->next) {
1259 printf("%s\n", command->name);
1260 }
1261 return CC_REDISPLAY;
1262 } else {
1263 // NOTE(adma): or show the current argument
1264 return complete_arg(el, args, "", 0);
1265 }
1266 } else {
1267 if (completing_args == false) {
1268 if (to_complete == NULL) {
1269 to_complete = g_commands;
1270 }
1271 return complete_command(el, to_complete, argv[i], cursoro);
1272 } else {
1273 return complete_arg(el, args, argv[i], cursoro);
1274 }
1275 }
1276 }
1277
1278 return CC_ERROR;
1279}
unsigned char complete_command(EditLine *el, Command *to_complete, const char *line, int cursoro)
Definition main.c:1103
unsigned char complete_arg(EditLine *el, const char *arg, char *line, int cursoro)
Definition main.c:925
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ g_commands

CommandList g_commands

Definition at line 589 of file main.c.

◆ g_hist

History* g_hist

Definition at line 62 of file main.c.

◆ g_running

bool g_running = true

Definition at line 591 of file main.c.