void HashString(const char *buffer, int len, unsigned char digest[EVP_MAX_MD_SIZE + 1], enum cfhashes type) { EVP_MD_CTX context; const EVP_MD *md = NULL; int md_len; CfDebug("HashString(%c)\n", type); switch (type) { case cf_crypt: CfOut(OUTPUT_LEVEL_ERROR, "", "The crypt support is not presently implemented, please use another algorithm instead"); memset(digest, 0, EVP_MAX_MD_SIZE + 1); break; default: md = EVP_get_digestbyname(FileHashName(type)); if (md == NULL) { CfOut(OUTPUT_LEVEL_INFORM, "", " !! Digest type %s not supported by OpenSSL library", CF_DIGEST_TYPES[type][0]); } EVP_DigestInit(&context, md); EVP_DigestUpdate(&context, (unsigned char *) buffer, (size_t) len); EVP_DigestFinal(&context, digest, &md_len); break; } }
void HashFile(char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], enum cfhashes type) { FILE *file; EVP_MD_CTX context; int len, md_len; unsigned char buffer[1024]; const EVP_MD *md = NULL; CfDebug("HashFile(%d,%s)\n", type, filename); if ((file = fopen(filename, "rb")) == NULL) { CfOut(OUTPUT_LEVEL_INFORM, "fopen", "%s can't be opened\n", filename); } else { md = EVP_get_digestbyname(FileHashName(type)); EVP_DigestInit(&context, md); while ((len = fread(buffer, 1, 1024, file))) { EVP_DigestUpdate(&context, buffer, len); } EVP_DigestFinal(&context, digest, &md_len); /* Digest length stored in md_len */ fclose(file); } }
void HashPubKey(RSA *key, unsigned char digest[EVP_MAX_MD_SIZE + 1], enum cfhashes type) { EVP_MD_CTX context; const EVP_MD *md = NULL; int md_len, i, buf_len, actlen; unsigned char *buffer; CfDebug("HashPubKey(%d)\n", type); if (key->n) { buf_len = (size_t) BN_num_bytes(key->n); } else { buf_len = 0; } if (key->e) { if (buf_len < (i = (size_t) BN_num_bytes(key->e))) { buf_len = i; } } buffer = xmalloc(buf_len + 10); switch (type) { case cf_crypt: CfOut(OUTPUT_LEVEL_ERROR, "", "The crypt support is not presently implemented, please use sha256 instead"); break; default: md = EVP_get_digestbyname(FileHashName(type)); if (md == NULL) { CfOut(OUTPUT_LEVEL_INFORM, "", " !! Digest type %s not supported by OpenSSL library", CF_DIGEST_TYPES[type][0]); } EVP_DigestInit(&context, md); actlen = BN_bn2bin(key->n, buffer); EVP_DigestUpdate(&context, buffer, actlen); actlen = BN_bn2bin(key->e, buffer); EVP_DigestUpdate(&context, buffer, actlen); EVP_DigestFinal(&context, digest, &md_len); break; } free(buffer); }
static char *NewIndexKey(char type, char *name, int *size) { char *chk_key; // Filename plus index_str in one block + \0 *size = strlen(name) + CF_INDEX_OFFSET + 1; chk_key = xcalloc(1, *size); // Data start after offset for index strncpy(chk_key, FileHashName(type), CF_INDEX_FIELD_LEN); strncpy(chk_key + CF_INDEX_OFFSET, name, strlen(name)); return chk_key; }
int FileHashChanged(char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], int warnlevel, enum cfhashes type, Attributes attr, Promise *pp) /* Returns false if filename never seen before, and adds a checksum to the database. Returns true if hashes do not match and also potentially updates database to the new value */ { int i, size = 21; unsigned char dbdigest[EVP_MAX_MD_SIZE + 1]; CF_DB *dbp; CfDebug("HashChanged: key %s (type=%d) with data %s\n", filename, type, HashPrint(type, digest)); size = FileHashSize(type); if (!OpenDB(&dbp, dbid_checksums)) { cfPS(OUTPUT_LEVEL_ERROR, CF_FAIL, "", pp, attr, "Unable to open the hash database!"); return false; } if (ReadHash(dbp, type, filename, dbdigest)) { for (i = 0; i < size; i++) { if (digest[i] != dbdigest[i]) { CfDebug("Found cryptohash for %s in database but it didn't match\n", filename); CfOut(warnlevel, "", "ALERT: Hash (%s) for %s changed!", FileHashName(type), filename); if (pp->ref) { CfOut(warnlevel, "", "Preceding promise: %s", pp->ref); } if (attr.change.update) { cfPS(warnlevel, CF_CHG, "", pp, attr, " -> Updating hash for %s to %s", filename, HashPrint(type, digest)); DeleteHash(dbp, type, filename); WriteHash(dbp, type, filename, digest); } else { cfPS(warnlevel, CF_FAIL, "", pp, attr, "!! Hash for file \"%s\" changed", filename); } CloseDB(dbp); return true; } } cfPS(OUTPUT_LEVEL_VERBOSE, CF_NOP, "", pp, attr, " -> File hash for %s is correct", filename); CloseDB(dbp); return false; } else { /* Key was not found, so install it */ cfPS(warnlevel, CF_CHG, "", pp, attr, " !! File %s was not in %s database - new file found", filename, FileHashName(type)); CfDebug("Storing checksum for %s in database %s\n", filename, HashPrint(type, digest)); WriteHash(dbp, type, filename, digest); LogHashChange(filename, cf_file_new, "New file found", pp); CloseDB(dbp); return false; } }
int FileHashChanged(EvalContext *ctx, char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type, Attributes attr, Promise *pp) { int i, size = 21; unsigned char dbdigest[EVP_MAX_MD_SIZE + 1]; CF_DB *dbp; char buffer[EVP_MAX_MD_SIZE * 4]; CfDebug("HashChanged: key %s (type=%d) with data %s\n", filename, type, HashPrintSafe(type, digest, buffer)); size = FileHashSize(type); if (!OpenDB(&dbp, dbid_checksums)) { cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_FAIL, "", pp, attr, "Unable to open the hash database!"); return false; } if (ReadHash(dbp, type, filename, dbdigest)) { for (i = 0; i < size; i++) { if (digest[i] != dbdigest[i]) { CfDebug("Found cryptohash for %s in database but it didn't match\n", filename); CfOut(OUTPUT_LEVEL_ERROR, "", "ALERT: Hash (%s) for %s changed!", FileHashName(type), filename); if (pp->comment) { CfOut(OUTPUT_LEVEL_ERROR, "", "Preceding promise: %s", pp->comment); } if (attr.change.update) { cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_CHANGE, "", pp, attr, " -> Updating hash for %s to %s", filename, HashPrintSafe(type, digest, buffer)); DeleteHash(dbp, type, filename); WriteHash(dbp, type, filename, digest); } else { cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_FAIL, "", pp, attr, "!! Hash for file \"%s\" changed", filename); } CloseDB(dbp); return true; } } cfPS(ctx, OUTPUT_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, "", pp, attr, " -> File hash for %s is correct", filename); CloseDB(dbp); return false; } else { /* Key was not found, so install it */ cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_CHANGE, "", pp, attr, " !! File %s was not in %s database - new file found", filename, FileHashName(type)); CfDebug("Storing checksum for %s in database %s\n", filename, HashPrintSafe(type, digest, buffer)); WriteHash(dbp, type, filename, digest); LogHashChange(filename, FILE_STATE_NEW, "New file found", pp); CloseDB(dbp); return false; } }
int FileHashChanged(EvalContext *ctx, char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type, Attributes attr, Promise *pp) { int i, size = 21; unsigned char dbdigest[EVP_MAX_MD_SIZE + 1]; CF_DB *dbp; char buffer[EVP_MAX_MD_SIZE * 4]; size = FileHashSize(type); if (!OpenDB(&dbp, dbid_checksums)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, attr, "Unable to open the hash database!"); return false; } if (ReadHash(dbp, type, filename, dbdigest)) { for (i = 0; i < size; i++) { if (digest[i] != dbdigest[i]) { Log(LOG_LEVEL_ERR, "Hash '%s' for '%s' changed!", FileHashName(type), filename); if (pp->comment) { Log(LOG_LEVEL_ERR, "Preceding promise: %s", pp->comment); } if (attr.change.update) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_CHANGE, pp, attr, "Updating hash for %s to %s", filename, HashPrintSafe(type, digest, buffer)); DeleteHash(dbp, type, filename); WriteHash(dbp, type, filename, digest); } else { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, attr, "!! Hash for file \"%s\" changed", filename); } CloseDB(dbp); return true; } } cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, attr, "File hash for %s is correct", filename); CloseDB(dbp); return false; } else { /* Key was not found, so install it */ cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_CHANGE, pp, attr, "File '%s' was not in '%s' database - new file found", filename, FileHashName(type)); Log(LOG_LEVEL_DEBUG, "Storing checksum for '%s' in database '%s'", filename, HashPrintSafe(type, digest, buffer)); WriteHash(dbp, type, filename, digest); LogHashChange(filename, FILE_STATE_NEW, "New file found", pp); CloseDB(dbp); return false; } }