From 8bda70b1fb25c815e7fbcf13b3d16b458177b5fd Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Sat, 17 Jun 2023 17:36:11 +0000 Subject: [PATCH] Refactor Sha API to return raw bytes, added Sha1() function. --- Cytoplasm/src/{include/Sha2.h => Sha.c} | 44 +++++++------- Cytoplasm/src/{Sha2.c => Sha/Sha256.c} | 19 +++---- Cytoplasm/src/include/Sha.h | 76 +++++++++++++++++++++++++ TODO.txt | 7 ++- src/User.c | 12 +++- 5 files changed, 117 insertions(+), 41 deletions(-) rename Cytoplasm/src/{include/Sha2.h => Sha.c} (57%) rename Cytoplasm/src/{Sha2.c => Sha/Sha256.c} (96%) create mode 100644 Cytoplasm/src/include/Sha.h diff --git a/Cytoplasm/src/include/Sha2.h b/Cytoplasm/src/Sha.c similarity index 57% rename from Cytoplasm/src/include/Sha2.h rename to Cytoplasm/src/Sha.c index 6d582f4..0f0c500 100644 --- a/Cytoplasm/src/include/Sha2.h +++ b/Cytoplasm/src/Sha.c @@ -21,30 +21,28 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +#include +#include -#ifndef CYTOPLASM_SHA2_H -#define CYTOPLASM_SHA2_H +#include +#include -/*** - * @Nm Sha2 - * @Nd A simple implementation of the SHA2 hashing functions. - * @Dd December 19 2022 - * @Xr Memory Base64 - * - * This API defines simple functions for computing SHA2 hashes. - * At the moment, it only defines - * .Fn Sha256 , - * which computes the SHA-256 hash of the given C string. It is - * not trivial to implement SHA-512 in ANSI C due to the lack of - * a 64-bit integer type, so that hash function has been omitted. - */ +char * +ShaToHex(unsigned char *bytes) +{ + size_t i = 0; + char *str = Malloc(((strlen((char *) bytes) * 2) + 1) * sizeof(char)); -/** - * This function takes a pointer to a NULL-terminated C string, and - * returns a string allocated on the heap using the Memory API, or - * NULL if there was an error allocating memory. The returned string - * should be freed when it is no longer needed. - */ -extern char * Sha256(char *); + if (!str) + { + return NULL; + } -#endif /* CYTOPLASM_SHA2_H */ + while (bytes[i] != '\0') + { + snprintf(str + (2 * i), 3, "%02x", bytes[i]); + i++; + } + + return str; +} diff --git a/Cytoplasm/src/Sha2.c b/Cytoplasm/src/Sha/Sha256.c similarity index 96% rename from Cytoplasm/src/Sha2.c rename to Cytoplasm/src/Sha/Sha256.c index 613d420..836edfb 100644 --- a/Cytoplasm/src/Sha2.c +++ b/Cytoplasm/src/Sha/Sha256.c @@ -21,7 +21,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include +#include #include #include @@ -170,13 +170,12 @@ Sha256Process(Sha256Context * context, unsigned char *data, size_t length) } } -char * +unsigned char * Sha256(char *str) { Sha256Context context; size_t i; - unsigned char out[32]; - char *outStr; + unsigned char *out; unsigned char fill[64]; UInt32 fillLen; @@ -189,8 +188,8 @@ Sha256(char *str) return NULL; } - outStr = Malloc(65); - if (!outStr) + out = Malloc(33 * sizeof(unsigned char)); + if (!out) { return NULL; } @@ -228,11 +227,7 @@ Sha256(char *str) PUT_UINT32(&out[4 * i], context.state[i]); } - /* Convert to string */ - for (i = 0; i < 32; i++) - { - snprintf(outStr + (2 * i), 3, "%02x", out[i]); - } + out[32] = '\0'; - return outStr; + return out; } diff --git a/Cytoplasm/src/include/Sha.h b/Cytoplasm/src/include/Sha.h new file mode 100644 index 0000000..25b6247 --- /dev/null +++ b/Cytoplasm/src/include/Sha.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net> + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef CYTOPLASM_SHA_H +#define CYTOPLASM_SHA_H + +/*** + * @Nm Sha + * @Nd A simple implementation of a few SHA hashing functions. + * @Dd December 19 2022 + * @Xr Memory Base64 + * + * This API defines simple functions for computing SHA hashes. + * At the moment, it only defines + * .Fn Sha256 + * and + * .Fn Sha1 , + * which compute the SHA-256 and SHA-1 hashes of the given C string, + * respectively. It is not trivial to implement SHA-512 in ANSI C + * due to the lack of a 64-bit integer type, so that hash + * function has been omitted. + */ + +/** + * This function takes a pointer to a NULL-terminated C string, and + * returns a NULL-terminated byte buffer allocated on the heap using + * the Memory API, or NULL if there was an error allocating memory. + * The returned byte buffer should be freed when it is no longer + * needed. It is important to note that the returned buffer is not + * a printable string; to get a printable string, use + * .Fn ShaToHex . + */ +extern unsigned char * Sha256(char *); + +/** + * This function takes a pointer to a NULL-terminated C string, and + * returns a NULL-terminated byte buffer allocated on the heap using + * the Memory API, or NULL if there was an error allocating memory. + * The returned byte buffer should be freed when it is no longer + * needed. It is important to note that the returned buffer is not + * a printable string; to get a printable string, use + * .Fn ShaToHex . + */ +extern unsigned char * Sha1(char *); + +/** + * Convert a SHA byte buffer into a hex string. These hex strings + * are typically what is transmitted, stored, and compared, however + * there may be times when it is necessary to work with the raw + * bytes directly, which is why the conversion to a hex string is + * a separate step. + */ +extern char * ShaToHex(unsigned char *); + +#endif /* CYTOPLASM_SHA_H */ diff --git a/TODO.txt b/TODO.txt index 0629090..63e3947 100644 --- a/TODO.txt +++ b/TODO.txt @@ -16,10 +16,11 @@ Milestone: v0.4.0 [ ] Client-Server API [ ] 6: Filtering - [ ] 7: Events + [~] 7: Events [ ] Compute size of JSON object in Canonical JSON - [ ] Rename Sha2.h to just Sha; add Sha1() function - [ ] Make Sha256() return raw bytes; add function to convert to string + [x] Rename Sha2.h to just Sha; add Sha1() function + [x] Make Sha256() return raw bytes; add function to + convert to hex string. [ ] 8: Rooms [~] 9: User Data [x] Profiles diff --git a/src/User.c b/src/User.c index e8364e3..63ff8c6 100644 --- a/src/User.c +++ b/src/User.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -358,6 +358,7 @@ UserCheckPassword(User * user, char *password) char *storedHash; char *salt; + unsigned char *hashBytes; char *hashedPwd; char *tmp; @@ -379,8 +380,10 @@ UserCheckPassword(User * user, char *password) } tmp = StrConcat(2, password, salt); - hashedPwd = Sha256(tmp); + hashBytes = Sha256(tmp); + hashedPwd = ShaToHex(hashBytes); Free(tmp); + Free(hashBytes); result = StrEquals(hashedPwd, storedHash); @@ -394,6 +397,7 @@ UserSetPassword(User * user, char *password) { HashMap *json; + unsigned char *hashBytes; char *hash = NULL; char *salt = NULL; char *tmpstr = NULL; @@ -407,13 +411,15 @@ UserSetPassword(User * user, char *password) salt = StrRandom(16); tmpstr = StrConcat(2, password, salt); - hash = Sha256(tmpstr); + hashBytes = Sha256(tmpstr); + hash = ShaToHex(hashBytes); JsonValueFree(HashMapSet(json, "salt", JsonValueString(salt))); JsonValueFree(HashMapSet(json, "password", JsonValueString(hash))); Free(salt); Free(hash); + Free(hashBytes); Free(tmpstr); return 1;