summaryrefslogtreecommitdiff
path: root/imap/src/c-client/sha.c
diff options
context:
space:
mode:
authorEduardo Chappa <chappa@washington.edu>2021-11-20 12:54:47 -0700
committerEduardo Chappa <chappa@washington.edu>2021-11-20 12:54:47 -0700
commit626eccdd8d0a325842d736596348e9d1d81ca105 (patch)
tree2eb4695b74cf88e15b030e30a751ada1017a0528 /imap/src/c-client/sha.c
parenta9e8d3c24b2bb6d30649d4d3c66f554ae38024bb (diff)
downloadalpine-626eccdd8d0a325842d736596348e9d1d81ca105.tar.xz
* Addition of support for SHA1 to SHA512 needed for future additions to
Alpine. The code is taken and adapted from code in RFC 4634.
Diffstat (limited to 'imap/src/c-client/sha.c')
-rw-r--r--imap/src/c-client/sha.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/imap/src/c-client/sha.c b/imap/src/c-client/sha.c
new file mode 100644
index 00000000..3c4b43c3
--- /dev/null
+++ b/imap/src/c-client/sha.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2021 Eduardo Chappa
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ */
+/* This algorithm is taken from the code in RFC 4634 */
+
+#include "c-client.h"
+#include "sha.h"
+#include "hmac.c"
+#include "sha1.c"
+#include "usha.c"
+#include "sha224-256.c"
+#include "sha384-512.c"
+
+struct hash {
+ char *name;
+ SHAversion whichSha;
+ int hashsize;
+} hashes[] = {
+ {"SHA1", CCSHA1, SHA1HashSize},
+ {"SHA224", CCSHA224, SHA224HashSize},
+ {"SHA256", CCSHA256, SHA256HashSize},
+ {"SHA384", CCSHA384, SHA384HashSize},
+ {"SHA512", CCSHA512, SHA512HashSize},
+ {NIL, CCSHA512, SHA512HashSize}
+};
+static const char hexdigits[] = "0123456789abcdef";
+
+char *hash_from_sizedtext(char *hash, char *text, size_t len)
+{
+ char *rv = NIL;
+ USHAContext sha;
+ HMACContext hmac;
+ uint8_t Message_Digest[USHAMaxHashSize];
+ int i, hashno;
+
+ if(!hash || !text) return NIL;
+
+ for(hashno = 0; hashes[hashno].name != NIL; hashno++)
+ if(!compare_cstring(hashes[hashno].name, hash))
+ break;
+
+ if(hashno >= 0 && hashno <= USHAMaxHashSize && hashes[hashno].name){
+ memset(&sha, '\343', sizeof(USHAContext));
+ memset(&hmac, '\343', sizeof(HMACContext));
+ if(USHAReset(&sha, hashes[hashno].whichSha) == shaSuccess
+ && USHAInput(&sha, (const uint8_t *) text, len) == shaSuccess){
+ if(USHAResult(&sha, (uint8_t *) Message_Digest) == shaSuccess){
+ rv = fs_get(2*hashes[hashno].hashsize + 1);
+ for (i = 0; i < hashes[hashno].hashsize ; ++i) {
+ rv[2*i] = hexdigits[(Message_Digest[i] >> 4) & 0xF];
+ rv[2*i+1] = hexdigits[Message_Digest[i] & 0xF];
+ }
+ rv[2*i] = '\0';
+ }
+ }
+ }
+ return rv;
+}