summaryrefslogtreecommitdiff
path: root/surveil/surveil/dgst.c
diff options
context:
space:
mode:
Diffstat (limited to 'surveil/surveil/dgst.c')
-rw-r--r--surveil/surveil/dgst.c118
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;
+}