diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk3chks.ctr |
Initial commit
Diffstat (limited to 'support/dktools/dk3chks.ctr')
-rw-r--r-- | support/dktools/dk3chks.ctr | 416 |
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 : */ + |