* New version 2.26
[alpine.git] / imap / src / c-client / sha.c
bloba1f959a89bcd7b5aabb8aeea85c4a4e9a416b755
1 /*
2 * Copyright 2021-2022 Eduardo Chappa
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
11 /* This algorithm is taken from the code in RFC 4634 */
13 #include "c-client.h"
14 #include "sha.h"
15 #include "hmac.c"
16 #include "sha1.c"
17 #include "usha.c"
18 #include "sha224-256.c"
19 #include "sha384-512.c"
21 struct hash {
22 char *name;
23 SHAversion whichSha;
24 int hashsize;
25 } hashes[] = {
26 {"SHA1", CCSHA1, SHA1HashSize},
27 {"SHA224", CCSHA224, SHA224HashSize},
28 {"SHA256", CCSHA256, SHA256HashSize},
29 {"SHA384", CCSHA384, SHA384HashSize},
30 {"SHA512", CCSHA512, SHA512HashSize},
31 {NIL, CCSHA512, SHA512HashSize}
33 static const char hexdigits[] = "0123456789abcdef";
35 char *hash_from_sizedtext(char *hash, char *text, size_t len, unsigned char **digest)
37 char *rv = NIL;
38 USHAContext sha;
39 HMACContext hmac;
40 uint8_t Message_Digest[USHAMaxHashSize];
41 int i, hashno;
42 unsigned long len2;
44 if(digest) *digest = NIL;
46 if(!hash || !text) return NIL;
48 for(hashno = 0; hashes[hashno].name != NIL; hashno++)
49 if(!compare_cstring(hashes[hashno].name, hash))
50 break;
52 if(hashno >= 0 && hashno <= USHAMaxHashSize && hashes[hashno].name){
53 memset(&sha, '\343', sizeof(USHAContext));
54 memset(&hmac, '\343', sizeof(HMACContext));
55 if(USHAReset(&sha, hashes[hashno].whichSha) == shaSuccess
56 && USHAInput(&sha, (const uint8_t *) text, len) == shaSuccess){
57 if(USHAResult(&sha, (uint8_t *) Message_Digest) == shaSuccess){
58 if(digest) *digest = rfc822_urlbinary((void *) Message_Digest, hashes[hashno].hashsize, &len2);
59 rv = fs_get(2*hashes[hashno].hashsize + 1);
60 for (i = 0; i < hashes[hashno].hashsize ; ++i) {
61 rv[2*i] = hexdigits[(Message_Digest[i] >> 4) & 0xF];
62 rv[2*i+1] = hexdigits[Message_Digest[i] & 0xF];
64 rv[2*i] = '\0';
68 return rv;