summaryrefslogtreecommitdiff
path: root/support/dktools/dk3chks.ctr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk3chks.ctr
Initial commit
Diffstat (limited to 'support/dktools/dk3chks.ctr')
-rw-r--r--support/dktools/dk3chks.ctr416
1 files changed, 416 insertions, 0 deletions
diff --git a/support/dktools/dk3chks.ctr b/support/dktools/dk3chks.ctr
new file mode 100644
index 0000000000..5d1c48c477
--- /dev/null
+++ b/support/dktools/dk3chks.ctr
@@ -0,0 +1,416 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+license = bsd
+
+
+
+%% header
+
+#include "dk3conf.h"
+#include "dk3types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Get checksum type for a given name.
+ @param n Message digest name ("MD5", "SHA-1", "SHA-224",
+ "SHA-256", "SHA-384", "SHA-512", or "RIPEMD-160").
+ @param app Application structure for diagnostics, may be NULL.
+ @return Integer representation (see @ref mdtypes) on success,
+ -1 on error.
+*/
+int
+dk3checksum_get_type_app(dkChar const *n, dk3_app_t *app);
+
+/** Build checksum for a file.
+ @param db Destination buffer.
+ @param sz Size of destination buffer.
+ @param fn File name to process.
+ @param cst Checksum type (message digest type,
+ see @ref mdtypes).
+ @param cse Binary to text encoding for message digest
+ (see @ref dataencoding).
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+int
+dk3checksum_build_app(
+ char *db, size_t sz, dkChar const *fn, int cst, int cse, dk3_app_t *app
+);
+
+/** Get string length produced for a message digest and encoding type.
+ @param cst Message digest type, see @ref mdtypes.
+ @param cse Binary to text encoding, see @ref dataencoding.
+ @return Number of characters produced.
+*/
+size_t
+dk3checksum_length(int cst, int cse);
+
+/** Get name for message digest type.
+ @param tp Digest type, see @ref mdtypes.
+ @return Name for digest type.
+*/
+dkChar const *
+dk3checksum_get_type_name(int tp);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+%% module
+
+#include "dk3all.h"
+
+#if DK3_HAVE_OPENSSL_MD5_H
+#include <openssl/md5.h>
+#endif
+#if DK3_HAVE_OPENSSL_SHA_H
+#include <openssl/sha.h>
+#endif
+#if DK3_HAVE_OPENSSL_RIPEMD_H
+#include <openssl/ripemd.h>
+#endif
+
+
+$!trace-include
+
+
+
+/** Names of message digest algorithms.
+ Order here must match order of DK3_MD_TYPE_xxx in dk3const.h.
+*/
+static dkChar const * const dk3_checksum_type_names[] = {
+/* 0 */ dkT("MD5"),
+/* 1 */ dkT("SHA-1"),
+/* 2 */ dkT("SHA-224"),
+/* 3 */ dkT("SHA-256"),
+/* 4 */ dkT("SHA-384"),
+/* 5 */ dkT("SHA-512"),
+/* 6 */ dkT("RIPEMD-160"),
+NULL
+};
+
+
+
+/** String constants.
+*/
+static dkChar const * const kw[] = {
+#if DK3_ON_WINDOWS
+/* 0 */ dkT("rb"), /* File mode, read binary. */
+#else
+/* 0 */ dkT("r"), /* no difference on non-Windows. */
+#endif
+};
+
+
+
+int
+dk3checksum_get_type_app(dkChar const *n, dk3_app_t *app)
+{
+ int back = -1;
+ if(n) {
+ back = dk3str_array_index(dk3_checksum_type_names, n, 0);
+ if(back == -1) {
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 127, 128, n);
+ }
+ } else {
+ back++;
+ }
+ }
+ return back;
+}
+
+
+
+/** Convert length of binary message digest to length of encoded string.
+ @param l Number of binary bytes to encode.
+ @param cse Message digest encoding.
+ @return Number of text characters produced by encoding.
+*/
+static
+size_t
+dk3chksum_conv_length(size_t l, int cse)
+{
+ size_t back = 0;
+ $? "+ dk3chksum_conv_length %lu %d", (unsigned long)l, cse
+ switch(cse) {
+ case DK3_DATA_ENCODING_HEX: {
+ back = dk3enc_size_bin_to_hex(l);
+ } break;
+ default: {
+ back = dk3enc_size_bin_to_a85(l);
+ } break;
+ } $? "- dk3chksum_conv_length %lu", (unsigned long)back
+ return back;
+}
+
+
+
+/** Get length of binary message digest.
+ @param cst Message digest type.
+ @return Number of binary bytes produced.
+*/
+static
+size_t
+dk3chksum_min_length(int cst)
+{
+ size_t back = 0;
+ switch(cst) {
+ case DK3_MD_TYPE_MD5: back = 16; break;
+ case DK3_MD_TYPE_SHA_1: back = 20; break;
+ case DK3_MD_TYPE_SHA_224: back = 28; break;
+ case DK3_MD_TYPE_SHA_256: back = 32; break;
+ case DK3_MD_TYPE_SHA_384: back = 48; break;
+ case DK3_MD_TYPE_SHA_512: back = 64; break;
+ case DK3_MD_TYPE_RIPEMD_160: back = 20; break;
+ }
+ return back;
+}
+
+
+
+/** Build binary checksum from file.
+ @param db Destination buffer.
+ @param sz Size of \a db.
+ @param fipo File pointer for read access.
+ @param cst Checksum type.
+ @param app Application structure for diagnostics, may be NULL.
+ @return 1 on success, 0 on error.
+*/
+static
+int
+dk3checksum_binary(char *db, size_t sz, FILE *fipo, int cst, dk3_app_t *app)
+{
+ int back = 0;
+#if DK3_HAVE_OPENSSL_SHA_H
+ SHA_CTX sha_ctx; /* SHA-1 context. */
+#if DK3_HAVE_SHA224 || DK3_HAVE_SHA256
+ SHA256_CTX sha256_ctx; /* SHA-256 context. */
+#endif
+#if DK3_HAVE_SHA384 || DK3_HAVE_SHA512
+ SHA512_CTX sha512_ctx; /* SHA-512 context. */
+#endif
+#endif
+#if DK3_HAVE_OPENSSL_MD5_H
+ MD5_CTX md5_ctx; /* MD5 context. */
+#endif
+#if DK3_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_CTX ripemd160_ctx; /* RIPEMD-160 context. */
+#endif
+ char buffer[4096]; /* Buffer for input. */
+ size_t rb = 0; /* Number of bytes read. */
+ switch(cst) {
+ case DK3_MD_TYPE_MD5: {
+#if DK3_HAVE_OPENSSL_MD5_H
+ MD5_Init(&md5_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ MD5_Update(&md5_ctx, buffer, rb);
+ }
+ MD5_Final((unsigned char *)db, &md5_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[0]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_1: {
+#if DK3_HAVE_OPENSSL_SHA_H
+ SHA1_Init(&sha_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA1_Update(&sha_ctx, buffer, rb);
+ }
+ SHA1_Final((unsigned char *)db, &sha_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[1]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_224: {
+#if DK3_HAVE_OPENSSL_SHA_H && DK3_HAVE_SHA224
+ SHA224_Init(&sha256_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA224_Update(&sha256_ctx, buffer, rb);
+ }
+ SHA224_Final((unsigned char *)db, &sha256_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[2]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_256: {
+#if DK3_HAVE_OPENSSL_SHA_H && DK3_HAVE_SHA256
+ SHA256_Init(&sha256_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA256_Update(&sha256_ctx, buffer, rb);
+ }
+ SHA256_Final((unsigned char *)db, &sha256_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[3]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_384: {
+#if DK3_HAVE_OPENSSL_SHA_H && DK3_HAVE_SHA384
+ SHA384_Init(&sha512_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA384_Update(&sha512_ctx, buffer, rb);
+ }
+ SHA384_Final((unsigned char *)db, &sha512_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[4]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_SHA_512: {
+#if DK3_HAVE_OPENSSL_SHA_H && DK3_HAVE_SHA512
+ SHA512_Init(&sha512_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ SHA512_Update(&sha512_ctx, buffer, rb);
+ }
+ SHA512_Final((unsigned char *)db, &sha512_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[5]);
+ }
+#endif
+ } break;
+ case DK3_MD_TYPE_RIPEMD_160 : {
+#if DK3_HAVE_OPENSSL_RIPEMD_H
+ RIPEMD160_Init(&ripemd160_ctx);
+ while((rb = dk3sf_fread_app(buffer,1,sizeof(buffer),fipo,app)) > 0) {
+ RIPEMD160_Update(&ripemd160_ctx, buffer, rb);
+ }
+ RIPEMD160_Final((unsigned char *)db, &ripemd160_ctx);
+ back = 1;
+#else
+ if(app) {
+ dk3app_log_i3(app, DK3_LL_ERROR, 156, 157, dk3_checksum_type_names[6]);
+ }
+#endif
+ } break;
+ default: {
+ if(app) {
+ /* ERROR: Unknown message digest type. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 158);
+ }
+ } break;
+ }
+ return back;
+}
+
+
+
+size_t
+dk3checksum_length(int cst, int cse)
+{
+ size_t back;
+ back = dk3chksum_conv_length(dk3chksum_min_length(cst), cse);
+ return back;
+}
+
+
+
+int
+dk3checksum_build_app(
+ char *db, size_t sz, dkChar const *fn, int cst, int cse, dk3_app_t *app
+)
+{
+ int back = 0;
+ size_t minlgt = 0; /* Length of binary message digest. */
+ size_t convlgt = 0; /* Length of digest converted to text. */
+ size_t i = 0; /* Used to write zeroes. */
+ dk3_stat_t stb; /* Test for existance. */
+ char mybuffer[256]; /* ASCII text version of digest. */
+ FILE *fipo = NULL; /* Input file. */
+ if(db) { *db = '\0'; }
+ if((db) && (sz) && (fn)) {
+ if((cst > 0) && (cst <= DK3_MD_TYPE_MAX)) {
+ if((cse >= 0) && (cse <= DK3_DATA_ENCODING_MAX)) {
+ minlgt = dk3chksum_min_length(cst);
+ convlgt = dk3chksum_conv_length(minlgt, cse);
+ if(sz > convlgt) {
+ for(i = 0; i < convlgt; i++) { db[i] = '-'; } db[convlgt] = '\0';
+ if(dk3sf_stat_app(&stb, fn, app)) {
+ if(((stb.ft) & (~(DK3_FT_SYMLINK))) == DK3_FT_REGULAR) {
+ fipo = dk3sf_fopen_app(fn, kw[0], app);
+ if(fipo) {
+ if(dk3checksum_binary(mybuffer,sizeof(mybuffer),fipo, cst,app))
+ {
+ switch(cse) {
+ case DK3_DATA_ENCODING_HEX: {
+ back = dk3enc_bin_to_hex_app(db,sz,mybuffer,minlgt,app);
+ } break;
+ case DK3_DATA_ENCODING_ASCII85: {
+ back = dk3enc_bin_to_a85_app(db,sz,mybuffer,minlgt,app);
+ } break;
+ case DK3_DATA_ENCODING_REVERSE_ASCII85: {
+ back = dk3enc_bin_to_ra85_app(db,sz,mybuffer,minlgt,app);
+ } break;
+ default: {
+ /* Illegal encoding type! */
+ dk3app_log_i1(app, DK3_LL_ERROR, 158);
+ } break;
+ }
+ }
+ fclose(fipo);
+ }
+ } else {
+ if(app) {
+ /* ERROR: Checksumming for regular files only .*/
+ dk3app_log_i1(app, DK3_LL_ERROR, 159);
+ }
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Destination buffer too small */
+ dk3app_log_i1(app, DK3_LL_ERROR, 38);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Illegal encoding number. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 158);
+ }
+ }
+ } else {
+ if(app) {
+ /* ERROR: Illegal digest type. */
+ dk3app_log_i1(app, DK3_LL_ERROR, 158);
+ }
+ }
+ }
+ return back;
+}
+
+
+dkChar const *
+dk3checksum_get_type_name(int tp)
+{
+ dkChar const *back = NULL;
+ if((tp > 0) && (tp <= DK3_MD_TYPE_MAX)) {
+ back = dk3_checksum_type_names[tp - 1];
+ }
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+