aboutsummaryrefslogtreecommitdiffstats
path: root/libsecauth_server_hash.c
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2021-04-12 23:05:22 +0200
committerMattias Andrée <maandree@kth.se>2021-04-12 23:05:22 +0200
commit90054e8a7df36eea21b612de6bd28d88e67989f9 (patch)
tree2fddd2123ea3aa13f7d4d031e685bd13979c4a38 /libsecauth_server_hash.c
downloadsecauth-90054e8a7df36eea21b612de6bd28d88e67989f9.tar.gz
secauth-90054e8a7df36eea21b612de6bd28d88e67989f9.tar.bz2
secauth-90054e8a7df36eea21b612de6bd28d88e67989f9.tar.xz
First commit
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'libsecauth_server_hash.c')
-rw-r--r--libsecauth_server_hash.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/libsecauth_server_hash.c b/libsecauth_server_hash.c
new file mode 100644
index 0000000..6f0d4f0
--- /dev/null
+++ b/libsecauth_server_hash.c
@@ -0,0 +1,55 @@
+/* See LICENSE file for copyright and license details. */
+#include "libsecauth.h"
+
+#include <crypt.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+int
+libsecauth_server_hash(const struct libsecauth_spec *spec, const char *inhash, const char *pepper, char **resultp)
+{
+ struct crypt_data hashbuf[2];
+ const char *hash = inhash, *result;
+ char *posthash = NULL, *p;
+ uint32_t rounds;
+ size_t i = 0;
+
+ *resultp = NULL;
+ memset(hashbuf, 0, sizeof(hashbuf));
+
+ for (i = 0, rounds = spec->server_rounds; rounds--; i ^= 1) {
+ hash = crypt_r(hash, spec->xferhash, &hashbuf[i]);
+ if (!hash)
+ return -1;
+ }
+
+ if (pepper) {
+ posthash = malloc(strlen(spec->posthash) + strlen(pepper) + 2);
+ if (!posthash)
+ return -1;
+ p = stpcpy(posthash, spec->posthash);
+ if (*posthash && p[-1] == '$')
+ p -= 1;
+ stpcpy(p, pepper);
+ }
+
+ hash = crypt_r(hash, posthash ? posthash : spec->posthash, &hashbuf[i]);
+ free(posthash);
+ if (!hash)
+ return -1;
+
+ result = strrchr(hash, '$');
+ result = result ? &result[1] : hash;
+
+ if (resultp) {
+ *resultp = strdup(result);
+ if (!*resultp)
+ return -1;
+ }
+
+ if (!spec->expected || !*spec->expected)
+ return 0;
+
+ return !strcmp(result, spec->expected);
+}