diff options
author | Eduardo Chappa <chappa@washington.edu> | 2021-11-20 12:54:47 -0700 |
---|---|---|
committer | Eduardo Chappa <chappa@washington.edu> | 2021-11-20 12:54:47 -0700 |
commit | 626eccdd8d0a325842d736596348e9d1d81ca105 (patch) | |
tree | 2eb4695b74cf88e15b030e30a751ada1017a0528 /imap/src/c-client/sha.c | |
parent | a9e8d3c24b2bb6d30649d4d3c66f554ae38024bb (diff) | |
download | alpine-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.c | 65 |
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; +} |