tomato/other/fun/create_common.h
Green Sky 227425b90e Squashed 'external/toxcore/c-toxcore/' content from commit 67badf69
git-subtree-dir: external/toxcore/c-toxcore
git-subtree-split: 67badf69416a74e74f6d7eb51dd96f37282b8455
2023-07-25 11:53:09 +02:00

90 lines
2.9 KiB
C

/* SPDX-License-Identifier: GPL-3.0-or-later
*
* Shared functions of create_*.c programs.
*/
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sodium.h>
#include "../../toxcore/ccompat.h"
static void init_sodium(void)
{
if (sodium_init() < 0) {
printf("Error: Failed to initialize sodium.\n");
exit(1);
}
}
static int tox_strcasecmp(const char *s1, const char *s2)
{
while (true) {
const int c1 = tolower(*(s1++));
const int c2 = tolower(*(s2++));
if (c1 == '\0' || c2 == '\0' || c1 != c2) {
return c1 - c2;
}
}
}
static void print_usage(const char *const argv0, const char *const does_what)
{
printf("%s for a given secret key, if provided, or a random key otherwise.\n", does_what);
printf("The data is written to stderr, human-readable key info is written to stdout.\n");
printf("\nUsage: %s [secret-key] 2>data\n", argv0);
}
static void handle_args(const int argc, const char *const argv[], const char *const does_what,
unsigned char *const public_key, unsigned char *const secret_key)
{
if (argc == 2 && (!tox_strcasecmp(argv[1], "-h") || !tox_strcasecmp(argv[1], "--help"))) {
print_usage(argv[0], does_what);
exit(0);
}
if (argc == 1) {
crypto_box_keypair(public_key, secret_key);
} else if (argc == 2 && strlen(argv[1]) == crypto_box_SECRETKEYBYTES * 2) {
size_t bin_len = 0;
if (sodium_hex2bin(secret_key, crypto_box_SECRETKEYBYTES, argv[1], crypto_box_SECRETKEYBYTES * 2, nullptr, &bin_len,
nullptr) != 0 || bin_len != crypto_box_SECRETKEYBYTES) {
printf("Error: Secret key must be a hex string.\n");
exit(1);
}
crypto_scalarmult_base(public_key, secret_key);
} else if (argc == 2) {
printf("Error: Secret key must be a %u character hex string.\n", crypto_box_SECRETKEYBYTES * 2);
exit(1);
} else {
print_usage(argv[0], does_what);
exit(1);
}
}
static void bin2hex_toupper(char *const hex, const size_t hex_maxlen, const unsigned char *const bin,
const size_t bin_len)
{
sodium_bin2hex(hex, hex_maxlen, bin, bin_len);
for (size_t i = 0; i < hex_maxlen; i ++) {
hex[i] = (char)toupper(hex[i]);
}
}
static void print_keys(const unsigned char *const public_key, const unsigned char *const secret_key)
{
char public_key_str[crypto_box_PUBLICKEYBYTES * 2 + 1];
char secret_key_str[crypto_box_SECRETKEYBYTES * 2 + 1];
bin2hex_toupper(public_key_str, sizeof(public_key_str), public_key, crypto_box_PUBLICKEYBYTES);
bin2hex_toupper(secret_key_str, sizeof(secret_key_str), secret_key, crypto_box_SECRETKEYBYTES);
fprintf(stdout, "Public key: %s\n", public_key_str);
fprintf(stdout, "Secret key: %s\n", secret_key_str);
}