feat(ssl): add digest execution pipeline

This commit is contained in:
lohhiiccc 2026-04-29 22:22:59 +02:00
parent df1f050d68
commit 6c8bb5a3c0
10 changed files with 299 additions and 4 deletions

View file

@ -15,5 +15,6 @@ struct ssl_config
}; };
enum cli_code cli_parse_arguments(int argc, char **argv, struct ssl_config *config); enum cli_code cli_parse_arguments(int argc, char **argv, struct ssl_config *config);
int ssl_run(const struct ssl_config *config);
#endif #endif

View file

@ -0,0 +1,19 @@
#ifndef FT_SSL_SSL_H
#define FT_SSL_SSL_H
#include <stdint.h>
#include "ft_ssl.h"
#define MAX_DIGEST_SIZE 64
#define READ_BUFSIZE 4096
int run_string(const struct ssl_config *config);
int run_file(const struct ssl_config *config, const char *path);
int run_stdin(const struct ssl_config *config);
int digest_stream(const struct ssl_config *config, int fd,
const char *label, int show_algo, int echo);
void print_digest(const struct ssl_config *config, const uint8_t *digest,
const char *label, int show_algo);
#endif

View file

@ -41,6 +41,12 @@ FORCE:
ft_ssl_SOURCES = \ ft_ssl_SOURCES = \
main.c \ main.c \
ssl_run.c \
ssl/run_stdin.c \
ssl/run_string.c \
ssl/run_file.c \
ssl/digest.c \
ssl/output.c \
cli/parse.c \ cli/parse.c \
cli/handlers/option_map.c \ cli/handlers/option_map.c \
cli/handlers/handle_help.c \ cli/handlers/handle_help.c \

View file

@ -17,10 +17,7 @@ main(int argc, char **argv)
ret = cli_parse_arguments(argc, argv, &config); ret = cli_parse_arguments(argc, argv, &config);
if (CLI_SUCCESS != ret) if (CLI_SUCCESS != ret)
goto cleanup; goto cleanup;
ret = ssl_run(&config);
/* TODO:
* ret = ssl_run(&config);
*/
cleanup: cleanup:
return (CLI_ERROR == ret) ? 2 : EXIT_SUCCESS; return (CLI_ERROR == ret) ? 2 : EXIT_SUCCESS;

40
src/ssl/digest.c Normal file
View file

@ -0,0 +1,40 @@
#include <unistd.h>
#include <cli.h>
#include <libft_ssl.h>
#include "ft_ssl.h"
#include "internal/ssl/ssl.h"
/* Forward declarations */
static void process_chunk(const struct ssl_config *config, union digest_ctx *ctx,
const uint8_t *buf, size_t n, int echo);
/* ------------------- */
int
digest_stream(const struct ssl_config *config, int fd,
const char *label, int show_algo, int echo)
{
union digest_ctx ctx;
uint8_t buf[READ_BUFSIZE];
uint8_t digest[MAX_DIGEST_SIZE];
ssize_t n;
config->algo->init(&ctx);
while (0 < (n = read(fd, buf, sizeof(buf))))
process_chunk(config, &ctx, buf, (size_t)n, echo);
if (0 > n)
return CLI_ERROR;
config->algo->final(&ctx, digest);
print_digest(config, digest, label, show_algo);
return CLI_SUCCESS;
}
static void
process_chunk(const struct ssl_config *config, union digest_ctx *ctx,
const uint8_t *buf, size_t n, int echo)
{
if (echo)
(void)write(STDOUT_FILENO, buf, n);
config->algo->update(ctx, buf, n);
}

109
src/ssl/output.c Normal file
View file

@ -0,0 +1,109 @@
#include <ctype.h>
#include <stdio.h>
#include <libft_ssl.h>
#include "compiler.h"
#include "ft_ssl.h"
#include "ft_ssl_flags.h"
#include "internal/ssl/ssl.h"
enum fmt_mode
{
FMT_STDIN,
FMT_DEFAULT,
FMT_QUIET,
FMT_REVERSE,
};
typedef void (*t_formatter)(const char *hex, const char *name_upper,
const char *label);
/* Forward declarations */
static enum fmt_mode resolve_fmt(const struct ssl_config *config,
int show_algo);
static void build_hex(char *buf, const uint8_t *digest, size_t size);
static void build_upper(char *buf, const char *src, size_t size);
static inline void fmt_stdin(const char *hex, const char *name_upper,
const char *label);
static inline void fmt_default(const char *hex, const char *name_upper,
const char *label);
static inline void fmt_quiet(const char *hex, const char *name_upper,
const char *label);
static inline void fmt_reverse(const char *hex, const char *name_upper,
const char *label);
/* ------------------- */
static const t_formatter s_formatters[] = {
[FMT_STDIN] = fmt_stdin,
[FMT_DEFAULT] = fmt_default,
[FMT_QUIET] = fmt_quiet,
[FMT_REVERSE] = fmt_reverse,
};
void
print_digest(const struct ssl_config *config, const uint8_t *digest,
const char *label, int show_algo)
{
char hex[MAX_DIGEST_SIZE * 2 + 1];
char name_upper[32];
build_hex(hex, digest, config->algo->digest_size);
build_upper(name_upper, config->algo->name, sizeof(name_upper));
s_formatters[resolve_fmt(config, show_algo)](hex, name_upper, label);
}
static enum fmt_mode
resolve_fmt(const struct ssl_config *config, int show_algo)
{
if (HAS_FLAG(config->flags, FLAG_Q))
return FMT_QUIET;
if (HAS_FLAG(config->flags, FLAG_R))
return FMT_REVERSE;
return show_algo ? FMT_DEFAULT : FMT_STDIN;
}
static void
build_hex(char *buf, const uint8_t *digest, size_t size)
{
size_t i;
for (i = 0; i < size; i++)
(void)snprintf(buf + i * 2, 3, "%02x", (unsigned int)digest[i]);
}
static void
build_upper(char *buf, const char *src, size_t size)
{
size_t i;
for (i = 0; i + 1 < size && '\0' != src[i]; i++)
buf[i] = (char)toupper((unsigned char)src[i]);
buf[i] = '\0';
}
static inline void
fmt_stdin(const char *hex, __unused const char *name_upper, const char *label)
{
printf("(%s)= %s\n", label, hex);
}
static inline void
fmt_default(const char *hex, const char *name_upper, const char *label)
{
printf("%s (%s) = %s\n", name_upper, label, hex);
}
static inline void
fmt_quiet(const char *hex, __unused const char *name_upper,
__unused const char *label)
{
printf("%s\n", hex);
}
static inline void
fmt_reverse(const char *hex, __unused const char *name_upper,
const char *label)
{
printf("%s %s\n", hex, label);
}

28
src/ssl/run_file.c Normal file
View file

@ -0,0 +1,28 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <cli.h>
#include "ft_ssl.h"
#include "internal/ssl/ssl.h"
#include "version_gen.h"
int
run_file(const struct ssl_config *config, const char *path)
{
int fd;
int ret;
fd = open(path, O_RDONLY);
if (0 > fd)
{
fprintf(stderr, "%s: %s: %s\n", g_prog_name, path, strerror(errno));
return CLI_ERROR;
}
ret = digest_stream(config, fd, path, 1, 0);
close(fd);
return ret;
}

15
src/ssl/run_stdin.c Normal file
View file

@ -0,0 +1,15 @@
#include <unistd.h>
#include <cli.h>
#include "compiler.h"
#include "ft_ssl.h"
#include "ft_ssl_flags.h"
#include "internal/ssl/ssl.h"
int
run_stdin(const struct ssl_config *config)
{
return digest_stream(config, STDIN_FILENO, "stdin", 0,
HAS_FLAG(config->flags, FLAG_P));
}

24
src/ssl/run_string.c Normal file
View file

@ -0,0 +1,24 @@
#include <stdio.h>
#include <string.h>
#include <cli.h>
#include <libft_ssl.h>
#include "ft_ssl.h"
#include "internal/ssl/ssl.h"
int
run_string(const struct ssl_config *config)
{
union digest_ctx ctx;
uint8_t digest[MAX_DIGEST_SIZE];
char label[4096];
config->algo->init(&ctx);
config->algo->update(&ctx, (const uint8_t *)config->string,
strlen(config->string));
config->algo->final(&ctx, digest);
(void)snprintf(label, sizeof(label), "\"%s\"", config->string);
print_digest(config, digest, label, 1);
return CLI_SUCCESS;
}

56
src/ssl_run.c Normal file
View file

@ -0,0 +1,56 @@
#include <stdio.h>
#include <cli.h>
#include <libft_ssl.h>
#include "compiler.h"
#include "ft_ssl.h"
#include "ft_ssl_flags.h"
#include "internal/ssl/ssl.h"
#include "version_gen.h"
/* Forward declarations */
static int check_algo(const struct ssl_config *config);
static inline void update_ret(int *ret, int result);
/* ------------------- */
int
ssl_run(const struct ssl_config *config)
{
int ret;
int has_input;
int i;
if (CLI_SUCCESS != check_algo(config))
return CLI_ERROR;
ret = CLI_SUCCESS;
has_input = (NULL != config->string || 0 < config->nb_files);
if (HAS_FLAG(config->flags, FLAG_P) || !has_input)
update_ret(&ret, run_stdin(config));
if (NULL != config->string)
update_ret(&ret, run_string(config));
for (i = 0; i < config->nb_files; i++)
update_ret(&ret, run_file(config, config->files[i]));
return ret;
}
static int
check_algo(const struct ssl_config *config)
{
if (NULL == config->algo->init
|| NULL == config->algo->update
|| NULL == config->algo->final)
{
fprintf(stderr, "%s: %s: not yet implemented\n",
g_prog_name, config->algo->name);
return CLI_ERROR;
}
return CLI_SUCCESS;
}
static inline void
update_ret(int *ret, int result)
{
if (CLI_ERROR == result)
*ret = CLI_ERROR;
}