diff options
Diffstat (limited to 'surveil/surveil/dgst.c')
| -rw-r--r-- | surveil/surveil/dgst.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/surveil/surveil/dgst.c b/surveil/surveil/dgst.c new file mode 100644 index 0000000..72eb6fa --- /dev/null +++ b/surveil/surveil/dgst.c @@ -0,0 +1,118 @@ +/* vim: set ts=4 sw=4 ai: */ +#include <stdlib.h> +#include <limits.h> +#include <stdio.h> +#include <sys/types.h> +#include <err.h> + +#include <openssl/evp.h> +#include <openssl/bio.h> +#include <openssl/err.h> + +#include "util.h" + +#define LONG_STR_SIZE (((sizeof(long)*CHAR_BIT)/3)+2) + +static const char xdigits[16] = { + "0123456789abcdef" +}; + +char *dgst2asc(unsigned char *dgst, size_t len) +{ + char *s; + size_t i; + int c; + + s = xmalloc((len * 2) + 1); + + for (i = 0; i < len; i++) { + c = xdigits[(dgst[i]&15)]; + s[(i*2)+1] = c ? c : '0'; + dgst[i] >>= 4; + c = xdigits[(dgst[i]&15)]; + s[(i*2)] = c ? c : '0'; + } + s[(i*2)] = '\0'; + + return s; +} + +unsigned char *calcdgst(const char *impl, char *buf, ssize_t sz, unsigned *rlen) +{ + unsigned int len = 0; + EVP_MD_CTX *ctx; + EVP_MD *digestimpl; + unsigned char *outdigest = NULL; + + ctx = EVP_MD_CTX_new(); + if (ctx == NULL) { + warnx("EVP_MD_CTX_new failed"); + goto calcdigest_fail0; + } + + digestimpl = EVP_MD_fetch(NULL, impl, NULL); + if (digestimpl == NULL) { + warnx("EVP_MD_fetch failed"); + goto calcdigest_fail1; + } + + if (!EVP_DigestInit_ex(ctx, digestimpl, NULL)) { + warnx("EVP_DigestInit_ex failed"); + goto calcdigest_fail; + } + + if (!EVP_DigestUpdate(ctx, buf, sz)) { + warnx("EVP_DigestUpdate failed"); + goto calcdigest_fail; + } + + outdigest = OPENSSL_malloc(EVP_MD_get_size(digestimpl)); + if (outdigest == NULL) { + warnx("OPENSSL_malloc failed"); + goto calcdigest_fail; + } + + if (!EVP_DigestFinal_ex(ctx, outdigest, &len)) { + warnx("EVP_DigestFinal_ex failed"); + goto calcdigest_fail; + } + +calcdigest_fail: + EVP_MD_free(digestimpl); +calcdigest_fail1: + EVP_MD_CTX_free(ctx); +calcdigest_fail0: + if (!outdigest) + ERR_print_errors_fp(stderr); + else + *rlen = len; + + return outdigest; +} + + +void print_digest(EVP_MD *md, void *unused __attribute__((unused))) +{ + int sz = EVP_MD_size(md); + + if (sz) + printf("%s (%d bit)\n", EVP_MD_get0_name(md), sz * 8); +} + +void print_digests(void) +{ + EVP_MD_do_all_provided(NULL, print_digest, NULL); +} + +int digest_is_provided(const char *digest) +{ + EVP_MD *md; + int ret = 0; + + if ((md = EVP_MD_fetch(NULL, digest, NULL)) != NULL) { + EVP_MD_free(md); + ret++; + } + + return ret; +} |
