From bbddb556ef96a64129783fefbee5a9a1a82eb0c3 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Wed, 21 Oct 2020 14:01:57 +0000 Subject: [PATCH] Feature: Added abstract refobject for digest calculation --- src/Makefile.am | 2 + src/digest.c | 118 +++++++++++++++++++++++++++++++++++++++++++++ src/digest.h | 27 +++++++++++ src/icecasttypes.h | 5 ++ 4 files changed, 152 insertions(+) create mode 100644 src/digest.c create mode 100644 src/digest.h diff --git a/src/Makefile.am b/src/Makefile.am index 8051f707..78da816c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -28,6 +28,7 @@ noinst_HEADERS = \ xslt.h \ yp.h \ md5.h \ + digest.h \ matchfile.h \ tls.h \ refobject.h \ @@ -77,6 +78,7 @@ icecast_SOURCES = \ admin.c \ resourcematch.c \ md5.c \ + digest.c \ matchfile.c \ tls.c \ refobject.c \ diff --git a/src/digest.c b/src/digest.c new file mode 100644 index 00000000..d9b30465 --- /dev/null +++ b/src/digest.c @@ -0,0 +1,118 @@ +/* Icecast + * + * This program is distributed under the GNU General Public License, version 2. + * A copy of this license is included with this source. + * + * Copyright 2020, Philipp "ph3-der-loewe" Schafft + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "digest.h" +#include "md5.h" + +#include "logging.h" +#define CATMODULE "digest" + +struct digest_tag { + /* base object */ + refobject_base_t __base; + + /* metadata */ + digest_algo_t algo; + + /* state */ + int done; + union { + struct MD5Context md5; + } state; +}; + +REFOBJECT_DEFINE_TYPE(digest_t); + +digest_t * digest_new(digest_algo_t algo) +{ + digest_t *digest = refobject_new__new(digest_t, NULL, NULL, NULL); + + if (!digest) + return NULL; + + digest->algo = algo; + switch (algo) { + case DIGEST_ALGO_MD5: + MD5Init(&(digest->state.md5)); + break; + default: + refobject_unref(digest); + return NULL; + break; + } + + return digest; +} + +ssize_t digest_write(digest_t *digest, const void *data, size_t len) +{ + if (!digest || !data) + return -1; + + if (digest->done) + return -1; + + switch (digest->algo) { + case DIGEST_ALGO_MD5: + MD5Update(&(digest->state.md5), (const unsigned char *)data, len); + return len; + break; + default: + return -1; + break; + } +} + +ssize_t digest_read(digest_t *digest, void *buf, size_t len) +{ + if (!digest || !buf) + return -1; + + if (digest->done) + return -1; + + digest->done = 1; + + switch (digest->algo) { + case DIGEST_ALGO_MD5: + if (len < HASH_LEN) { + unsigned char buffer[HASH_LEN]; + MD5Final(buffer, &(digest->state.md5)); + memcpy(buf, buffer, len); + return len; + } else { + MD5Final((unsigned char*)buf, &(digest->state.md5)); + return HASH_LEN; + } + break; + default: + return -1; + break; + } +} + +ssize_t digest_length_bytes(digest_t *digest) +{ + if (!digest) + return -1; + + switch (digest->algo) { + case DIGEST_ALGO_MD5: + return 16; + break; + default: + return -1; + break; + } +} diff --git a/src/digest.h b/src/digest.h new file mode 100644 index 00000000..934c827a --- /dev/null +++ b/src/digest.h @@ -0,0 +1,27 @@ +/* Icecast + * + * This program is distributed under the GNU General Public License, version 2. + * A copy of this license is included with this source. + * + * Copyright 2020, Philipp "ph3-der-loewe" Schafft + */ + +#ifndef __DIGEST_H__ +#define __DIGEST_H__ + +#include "refobject.h" + +REFOBJECT_FORWARD_TYPE(digest_t); + +typedef enum { + DIGEST_ALGO_MD5 +} digest_algo_t; + +digest_t * digest_new(digest_algo_t algo); +ssize_t digest_write(digest_t *digest, const void *data, size_t len); +ssize_t digest_read(digest_t *digest, void *buf, size_t len); + +/* Returns the digest size in bytes */ +ssize_t digest_length_bytes(digest_t *digest); + +#endif diff --git a/src/icecasttypes.h b/src/icecasttypes.h index 4b340e72..f0c643c1 100644 --- a/src/icecasttypes.h +++ b/src/icecasttypes.h @@ -122,6 +122,10 @@ typedef struct reportxml_database_tag reportxml_database_t; typedef struct listensocket_container_tag listensocket_container_t; typedef struct listensocket_tag listensocket_t; +/* ---[ digest.[ch] ]--- */ + +typedef struct digest_tag digest_t; + /* ---[ refobject.[ch] ]--- */ typedef struct refobject_base_tag refobject_base_t; @@ -137,6 +141,7 @@ typedef union __attribute__ ((__transparent_union__)) { reportxml_database_t *reportxml_database; listensocket_container_t *listensocket_container; listensocket_t *listensocket; + digest_t *digest; } refobject_t; #else typedef void * refobject_t;