diff --git a/examples/coap-client.c b/examples/coap-client.c index 7d3af2fef5..ddff7d79cf 100644 --- a/examples/coap-client.c +++ b/examples/coap-client.c @@ -586,7 +586,9 @@ usage(const char *program, const char *version) { "\t \t\t hint_to_match,use_user,with_key\n" "\t \t\tNote: -k and -u still need to be defined for the default\n" "\t \t\tin case there is no match\n" - "\t-k key \t\tPre-shared key for the specified user identity\n" + "\t-k key \t\tPre-shared key for the specified user identityt. If the\n" + "\t \t\tkey begins with 0x, then the hex text (two [0-9a-f] per\n" + "\t \t\tbyte) is converted to binary data\n" "\t-u user\t\tUser identity to send for pre-shared key mode\n" "PKI Options (if supported by underlying (D)TLS library)\n" "\tNote: If any one of '-c certfile', '-j keyfile' or '-C cafile' is in\n" @@ -1258,6 +1260,12 @@ static ssize_t cmdline_read_key(char *arg, unsigned char **buf, size_t maxlen) { size_t len = strnlen(arg, maxlen); if (len) { + /* read hex string alternative when arg starts with "0x" */ + if (len >= 4 && arg[0] == '0' && arg[1] == 'x') { + /* As the command line option is part of our environment we can do + * the conversion in place. */ + len = convert_hex_string(arg + 2, (uint8_t *)arg); + } *buf = (unsigned char *)arg; return len; } diff --git a/examples/coap-server.c b/examples/coap-server.c index 1dd1253d41..b2acc65f34 100644 --- a/examples/coap-server.c +++ b/examples/coap-server.c @@ -2233,7 +2233,9 @@ usage(const char *program, const char *version) { "\t-k key \t\tPre-Shared Key. This argument requires (D)TLS with PSK\n" "\t \t\tto be available. This cannot be empty if defined.\n" "\t \t\tNote that both -c and -k need to be defined for both\n" - "\t \t\tPSK and PKI to be concurrently supported\n" + "\t \t\tPSK and PKI to be concurrently supported. If the\n" + "\t \t\tkey begins with 0x, then the hex text (two [0-9a-f] per\n" + "\t \t\tbyte) is converted to binary data\n" "\t-s match_psk_sni_file\n" "\t \t\tThis is a file that contains one or more lines of\n" "\t \t\treceived Subject Name Identifier (SNI) to match to use\n" @@ -2512,10 +2514,59 @@ cmdline_tls_engine(char *arg) { return 1; } +/** + * Utility function to convert a hex digit to its corresponding + * numerical value. + * + * param c The hex digit to convert. Must be in [0-9A-Fa-f]. + * + * return The numerical representation of @p c. + */ +static uint8_t +hex2char(char c) { + assert(isxdigit(c)); + if ('a' <= c && c <= 'f') + return c - 'a' + 10; + else if ('A' <= c && c <= 'F') + return c - 'A' + 10; + else + return c - '0'; +} + +/** + * Converts the sequence of hex digits in src to a sequence of bytes. + * + * This function returns the number of bytes that have been written to + * @p dst. + * + * param[in] src The null-terminated hex string to convert. + * param[out] dst Conversion result. + * + * return The length of @p dst. + */ +static size_t +convert_hex_string(const char *src, uint8_t *dst) { + uint8_t *p = dst; + while (isxdigit((int)src[0]) && isxdigit((int)src[1])) { + *p++ = (hex2char(src[0]) << 4) + hex2char(src[1]); + src += 2; + } + if (src[0] != '\0') { /* error in hex input */ + coap_log_warn("invalid hex string in option '%s'\n", src); + } + return p - dst; +} + static ssize_t cmdline_read_key(char *arg, unsigned char **buf, size_t maxlen) { size_t len = strnlen(arg, maxlen); if (len) { + /* read hex string alternative when arg starts with "0x" */ + if (len >= 4 && arg[0] == '0' && arg[1] == 'x') { + /* As the command line option is part of our environment we can do + * the conversion in place. */ + len = convert_hex_string(arg + 2, (uint8_t *)arg); + } *buf = (unsigned char *)arg; return len; } diff --git a/man/coap-client.txt.in b/man/coap-client.txt.in index 731e262096..bb889128ed 100644 --- a/man/coap-client.txt.in +++ b/man/coap-client.txt.in @@ -210,7 +210,9 @@ OPTIONS - PSK case there is no match. *-k* key:: - Pre-shared key for the specified user identity (*-u* option also required). + Pre-shared key for the specified user identity (*-u* option also required). + + If the key begins with 0x, then the hex text (two [0-9a-f] per byte) is + converted to binary data. *-u* user:: User identity to send for pre-shared key mode (*-k* option also required). diff --git a/man/coap-server.txt.in b/man/coap-server.txt.in index 48680b6cab..a7911e9f23 100644 --- a/man/coap-server.txt.in +++ b/man/coap-server.txt.in @@ -176,6 +176,8 @@ OPTIONS - PSK *-k* key:: Pre-shared key to use for inbound connections. This cannot be empty if defined. + + If the key begins with 0x, then the hex text (two [0-9a-f] per byte) is + converted to binary data. + Note: if *-c cafile* is defined, you need to define *-k key* as well to have the server support both PSK and PKI.