Make prompt_input accept fixed-length and variable-length input.

Now that strings have the correct size, but no trailing \0, puts() cannot safely be
used any more.
This commit is contained in:
Frank Denis 2015-05-27 18:10:28 +02:00
parent cf6106e022
commit 9060457fac
9 changed files with 94 additions and 47 deletions

View File

@ -44,14 +44,9 @@ auth(void)
puts("Example: crypto_auth\n");
memset(key, 0, sizeof key);
prompt_input("Enter a key > ", (char*)key, sizeof key);
puts("Complete key:");
print_hex(key, sizeof key);
putchar('\n');
prompt_input("a key", (char*)key, sizeof key, 0);
message_len = prompt_input("Enter a message > ",
(char*)message, sizeof message);
message_len = prompt_input("a message", (char*)message, sizeof message, 1);
putchar('\n');
printf("Generating %s authentication...\n", crypto_auth_primitive());

View File

@ -96,8 +96,7 @@ box(void)
putchar('\n');
/* read input */
message_len = prompt_input("Enter a message > ",
(char*)message, sizeof message);
message_len = prompt_input("a message", (char*)message, sizeof message, 1);
print_hex(message, message_len);
putchar('\n');

View File

@ -96,8 +96,7 @@ box_detached(void)
putchar('\n');
/* read input */
message_len = prompt_input("Enter a message > ",
(char*)message, sizeof message);
message_len = prompt_input("a message", (char*)message, sizeof message, 1);
print_hex(message, message_len);
putchar('\n');

View File

@ -11,34 +11,68 @@
#include "utils.h" /* utility functions shared by demos */
/*
* Generic hash is intended as a variable output hash with enough strength
* to ensure data integrity. The hash out put is also able to vary in size.
* Key is optional and is able to vary in size.
* This function computes a fixed-length fingerprint for an arbitrary long message.
*
* Note that it is recommended to stay within the range of MIN and MAX
* output because larger output will produce gaps.
* Sample use cases:
*
* File integrity checking
* Creating unique identifiers to index arbitrary long data
*
* The crypto_generichash() function puts a fingerprint of the
* message in whose length is inlen bytes into out. The output size
* can be chosen by the application.
*
* The minimum recommended output size is crypto_generichash_BYTES.
* This size makes it practically impossible for two messages to
* produce the same fingerprint.
*
* But for specific use cases, the size can be any value between
* crypto_generichash_BYTES_MIN (included) and
* crypto_generichash_BYTES_MAX (included).
*
* key can be NULL and keylen can be 0. In this case, a message will
* always have the same fingerprint, similar to the MD5 or SHA-1
* functions for which crypto_generichash() is a faster and more
* secure alternative.
*
* But a key can also be specified. A message will always have the
* same fingerprint for a given key, but different keys used to hash
* the same message are very likely to produce distinct fingerprints.
*
* In particular, the key can be used to make sure that different
* applications generate different fingerprints even if they process
* the same data.
*
* The recommended key size is crypto_generichash_KEYBYTES bytes.
*
* However, the key size can by any value between
* crypto_generichash_KEYBYTES_MIN (included) and
* crypto_generichash_KEYBYTES_MAX (included).
*/
void
generichash(void)
{
unsigned char k[crypto_generichash_KEYBYTES_MAX]; /* key */
unsigned char h[crypto_generichash_BYTES_MIN]; /* hash output */
unsigned char m[MAX_INPUT_SIZE]; /* message */
size_t mlen; /* length */
unsigned char key[crypto_generichash_KEYBYTES_MAX];
unsigned char hash[crypto_generichash_BYTES_MIN];
unsigned char message[MAX_INPUT_SIZE];
size_t message_len;
size_t key_len;
puts("Example: crypto_generichash\n");
memset(k, 0, sizeof k);
prompt_input("Input your key > ", (char*)k, sizeof k);
key_len = prompt_input("a key", (char*)key, sizeof key, 1);
mlen = prompt_input("Input your message > ", (char*)m, sizeof m);
message_len = prompt_input("a message", (char*)message, sizeof message, 1);
putchar('\n');
printf("Hashing message with %s\n", crypto_generichash_primitive());
crypto_generichash(h, sizeof h, m, mlen, k, sizeof k);
fputs("Hash: ", stdout);
print_hex(h, sizeof h);
putchar('\n');
if (crypto_generichash(hash, sizeof hash, message, message_len,
key, key_len) != 0) {
puts("Couldn't hash the message, probably due to the key length");
} else {
fputs("Hash: ", stdout);
print_hex(hash, sizeof hash);
}
putchar('\n');
}

View File

@ -26,8 +26,7 @@ generichashstream(void)
puts("Example: crypto_generichashstream\n");
memset(k, 0, sizeof k);
prompt_input("Input your key > ", (char*)k, sizeof k);
prompt_input("a key", (char*)k, sizeof k, 0);
putchar('\n');
printf("Hashing message with %s\n", crypto_generichash_primitive());
@ -35,8 +34,8 @@ generichashstream(void)
/* initialize the stream */
crypto_generichash_init(&state, k, sizeof k, sizeof h);
while (1) {
mlen = prompt_input("> ", (char*)m, sizeof m);
for(;;) {
mlen = prompt_input("the next part of the message", (char*)m, sizeof m);
if (mlen == 0)
break;

View File

@ -42,11 +42,9 @@ shorthash(void)
puts("Example: crypto_shorthash\n");
memset(key, 0, sizeof key);
prompt_input("Enter a key > ", (char*)key, sizeof key);
prompt_input("a key", (char*)key, sizeof key, 0);
message_len = prompt_input("Enter a message > ",
(char*)message, sizeof message);
message_len = prompt_input("a message", (char*)message, sizeof message, 1);
putchar('\n');
printf("Hashing the message with %s\n", crypto_shorthash_primitive());

View File

@ -43,8 +43,8 @@ sign(void)
puts("\n");
/* read input */
mlen = prompt_input("Input your message > ", (char*)m,
sizeof m - crypto_sign_BYTES);
mlen = prompt_input("a message", (char*)m,
sizeof m - crypto_sign_BYTES, 1);
putc('\n', stdout);
puts("Notice the message has no prepended padding");

View File

@ -45,22 +45,44 @@ print_hex(const void *bin, const size_t bin_len)
* trailing newline characters.
*/
size_t
prompt_input(char *prompt, char *input, const size_t max_input_len)
prompt_input(const char *prompt, char *input, const size_t max_input_len,
int variable_length)
{
char input_tmp[MAX_INPUT_SIZE + 1U];
size_t actual_input_len;
fputs(prompt, stdout);
if (variable_length != 0) {
printf("Enter %s (%zu bytes max) > ", prompt, max_input_len);
} else {
printf("Enter %s (%zu bytes) > ", prompt, max_input_len);
}
fflush(stdout);
fgets(input, max_input_len, stdin); /* grab input with room for \0 */
fgets(input_tmp, sizeof input_tmp, stdin);
actual_input_len = strlen(input_tmp);
actual_input_len = strlen(input);
/* trim excess new line */
if (actual_input_len > 0 && input[actual_input_len - 1] == '\n') {
input[actual_input_len - 1] = '\0';
/* trim \n */
if (actual_input_len > 0 && input_tmp[actual_input_len - 1] == '\n') {
input_tmp[actual_input_len - 1] = '\0';
--actual_input_len;
}
return actual_input_len;
if (actual_input_len > max_input_len) {
printf("Warning: truncating input to %zu bytes\n", max_input_len);
actual_input_len = max_input_len;
} else if (actual_input_len < max_input_len && variable_length == 0) {
printf("Warning: %zu bytes expected, %zu bytes given: padding with zeros\n",
max_input_len, actual_input_len);
memset(input, 0, max_input_len);
} else {
printf("Length: %zu bytes\n", actual_input_len);
}
memcpy(input, input_tmp, actual_input_len);
if (variable_length == 0) {
return max_input_len;
} else {
return actual_input_len;
}
}
/*

View File

@ -10,7 +10,8 @@
void print_hex(const void *bin, const size_t bin_len);
size_t prompt_input(char *prompt, char *input, const size_t max_input_len);
size_t prompt_input(const char *prompt, char *input, const size_t max_input_len,
int variable_length);
void print_verification(int r);