1 /* 2 Copyright 2021 Northern.tech AS 3 4 This file is part of CFEngine 3 - written and maintained by Northern.tech AS. 5 6 This program is free software; you can redistribute it and/or modify it 7 under the terms of the GNU General Public License as published by the 8 Free Software Foundation; version 3. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 18 19 To the extent this program is licensed as part of the Enterprise 20 versions of CFEngine, the applicable Commercial Open Source License 21 (COSL) may apply to this file if you as a licensee so wish it. See 22 included file COSL.txt. 23 */ 24 25 #ifndef CFENGINE_HASH_H 26 #define CFENGINE_HASH_H 27 28 /** 29 @brief Hash implementations 30 */ 31 32 #include <openssl/rsa.h> 33 #include <openssl/evp.h> 34 35 #include <stdbool.h> 36 #include <hash_method.h> /* HashMethod, HashSize */ 37 38 39 typedef struct Hash Hash; 40 41 /** 42 @brief Creates a new structure of type Hash. 43 @param data String to hash. 44 @param length Length of the string to hash. 45 @param method Hash method. 46 @return A structure of type Hash or NULL in case of error. 47 */ 48 Hash *HashNew(const char *data, const unsigned int length, HashMethod method); 49 50 /** 51 @brief Creates a new structure of type Hash. 52 @param descriptor Either file descriptor or socket descriptor. 53 @param method Hash method. 54 @return A structure of type Hash or NULL in case of error. 55 */ 56 Hash *HashNewFromDescriptor(const int descriptor, HashMethod method); 57 58 /** 59 @brief Creates a new structure of type Hash. 60 @param rsa RSA key to be hashed. 61 @param method Hash method. 62 @return A structure of type Hash or NULL in case of error. 63 */ 64 Hash *HashNewFromKey(const RSA *rsa, HashMethod method); 65 66 /** 67 @brief Destroys a structure of type Hash. 68 @param hash The structure to be destroyed. 69 */ 70 void HashDestroy(Hash **hash); 71 72 /** 73 @brief Copy a hash 74 @param origin Hash to be copied. 75 @param destination Hash to be copied to. 76 @return 0 if successful, -1 in any other case. 77 */ 78 int HashCopy(Hash *origin, Hash **destination); 79 80 /** 81 @brief Checks if two hashes are equal. 82 @param a 1st hash to be compared. 83 @param b 2nd hash to be compared. 84 @return True if both hashes are equal and false in any other case. 85 */ 86 bool HashEqual(const Hash *a, const Hash *b); 87 88 /** 89 @brief Pointer to the raw digest data. 90 @note Notice that this is a binary representation and not '\0' terminated. 91 @param hash Hash structure. 92 @param length Pointer to an unsigned int to hold the length of the data. 93 @return A pointer to the raw digest data. 94 */ 95 const unsigned char *HashData(const Hash *hash, unsigned int *length); 96 97 /** 98 @brief Printable hash representation. 99 @param hash Hash structure. 100 @return A pointer to the printable digest representation. 101 */ 102 const char *HashPrintable(const Hash *hash); 103 104 /** 105 @brief Hash type. 106 @param hash Hash structure 107 @return The hash method used by this hash structure. 108 */ 109 HashMethod HashType(const Hash *hash); 110 111 /** 112 @brief Hash length in bytes. 113 @param hash Hash structure 114 @return The hash length in bytes. 115 */ 116 HashSize HashLength(const Hash *hash); 117 118 /** 119 @brief Returns the ID of the hash based on the name 120 @param hash_name Name of the hash. 121 @return Returns the ID of the hash from the name. 122 */ 123 HashMethod HashIdFromName(const char *hash_name); 124 125 /** 126 @brief Returns the name of the hash based on the ID. 127 @param hash_id Id of the hash. 128 @return Returns the name of the hash. 129 */ 130 const char *HashNameFromId(HashMethod hash_id); 131 132 133 /** 134 @brief Returns pointer to an openssl digest struct 135 136 Equivalent to EVP_get_digestbyname(HashNameFromId(type)), 137 but with added error checking. 138 139 Returns NULL in case of error. 140 */ 141 const EVP_MD *HashDigestFromId(HashMethod type); 142 143 /** 144 @brief Size of the hash 145 @param method Hash method 146 @return Returns the size of the hash or 0 in case of error. 147 */ 148 HashSize HashSizeFromId(HashMethod hash_id); 149 150 /* Enough room for "SHA=asdfasdfasdf". */ 151 #define CF_HOSTKEY_STRING_SIZE (4 + 2 * EVP_MAX_MD_SIZE + 1) 152 153 154 void HashFile(const char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type, bool text_mode); 155 void HashString(const char *buffer, int len, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type); 156 bool HashesMatch( 157 const unsigned char digest1[EVP_MAX_MD_SIZE + 1], 158 const unsigned char digest2[EVP_MAX_MD_SIZE + 1], 159 HashMethod type); 160 char *HashPrintSafe(char *dst, size_t dst_size, const unsigned char *digest, 161 HashMethod type, bool use_prefix); 162 char *SkipHashType(char *hash); 163 void HashPubKey(const RSA *key, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type); 164 165 /** 166 * @brief Copy a string from src to dst, if src is too big, truncate and hash. 167 * 168 * If the src string (including NUL terminator) does not fit in dst 169 * (according to dst_size), the last part of dst is a hash of the full src 170 * string, before truncation. 171 * 172 * This function is primarily intended to limit the length of keys in a 173 * key-value store, like LMDB, while still keeping the strings readable AND 174 * unique. 175 * 176 * Examples: 177 * "short_string" -> "short_string" 178 * "string_which_is_too_long_for_size" -> "string_which_is#MD5=" 179 * 180 * If this function returns dst_size, the string was truncated and hashed, 181 * the destination string is exactly dst_size - 1 bytes long in this case. 182 * 183 * @param src[in] String to copy from, must be '\0'-terminated 184 * @param dst[out] Destination to copy to, will always be '\0'-terminated 185 * @param dst_size[in] Size of destination buffer (including '\0'-terminator) 186 * @return dst_size if string was truncated, string length (src/dst) otherwise 187 * @note dst must always be of size dst_size or bigger, regardless of src 188 * @see StringCopy() 189 */ 190 size_t StringCopyTruncateAndHashIfNecessary( 191 const char *src, char *dst, size_t dst_size); 192 193 #endif // CFENGINE_HASH_H 194