diff --git a/centrallix/cxss/cxss_credentials_db.c b/centrallix/cxss/cxss_credentials_db.c index 5963d5d48..4f6c68c34 100644 --- a/centrallix/cxss/cxss_credentials_db.c +++ b/centrallix/cxss/cxss_credentials_db.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "cxss/credentials_db.h" #include "cxss/util.h" @@ -24,7 +25,7 @@ CXSS_DB_Context_t cxssCredentialsDatabaseInit(const char *db_path) { /* Allocate context struct */ - CXSS_DB_Context_t dbcontext = malloc(sizeof(struct _CXSS_DB_Context_t)); + CXSS_DB_Context_t dbcontext = (CXSS_DB_Context_t)nmMalloc(sizeof(struct _CXSS_DB_Context_t)); if (!dbcontext) { mssError(0, "CXSS", "Memory allocation error\n"); goto error; @@ -42,7 +43,7 @@ cxssCredentialsDatabaseInit(const char *db_path) return dbcontext; error: - free(dbcontext); + nmFree(dbcontext, sizeof(struct _CXSS_DB_Context_t)); return NULL; } @@ -60,7 +61,7 @@ cxssCredentialsDatabaseClose(CXSS_DB_Context_t dbcontext) { cxss_i_FinalizeSqliteStatements(dbcontext); sqlite3_close(dbcontext->db); - free(dbcontext); + nmFree(dbcontext, sizeof(struct _CXSS_DB_Context_t)); } /** @brief Setup database tables/statements @@ -89,17 +90,16 @@ cxss_i_SetupCredentialsDatabase(CXSS_DB_Context_t dbcontext) "CREATE TABLE IF NOT EXISTS UserAuth(" "PK_UserAuth INTEGER PRIMARY KEY," "CXSS_UserID TEXT," - "UserSalt BLOB," - "PrivateKeyIV BLOB," + "AuthClass TEXT," "UserPrivateKey BLOB," - "RemovalFlag INT," + "PrivateKeyIV BLOB," "DateCreated TEXT," - "DateLastUpdated TEXT);", + "DateLastUpdated TEXT," + "RemovalFlag INT);", (void*)NULL, NULL, &err_msg); sqlite3_exec(dbcontext->db, "CREATE TABLE IF NOT EXISTS UserResc(" "ResourceID TEXT PRIMARY KEY," - "AuthClass TEXT," "AESKey BLOB," "ResourceUsername BLOB," "ResourceAuthData BLOB," @@ -148,29 +148,45 @@ cxss_i_SetupCredentialsDatabase(CXSS_DB_Context_t dbcontext) -1, &dbcontext->delete_user_stmt, NULL); sqlite3_prepare_v2(dbcontext->db, "INSERT INTO UserAuth (CXSS_UserID" - ", UserSalt, UserPrivateKey, PrivateKeyIV, RemovalFlag" - ", DateCreated, DateLastUpdated)" - " VALUES (?, ?, ?, ?, ?, ?, ?);", + ", AuthClass, UserPrivateKey, PrivateKeyIV" + ", DateCreated, DateLastUpdated, RemovalFlag)" + " VALUES ( ?, ?, ?, ?, ?, ?, ?);", -1, &dbcontext->insert_user_auth_stmt, NULL); sqlite3_prepare_v2(dbcontext->db, - "SELECT UserPrivateKey, UserSalt, PrivateKeyIV" - ", DateCreated, DateLastUpdated FROM UserAuth" - " WHERE CXSS_UserID=? AND RemovalFlag=0;", + "UPDATE UserAuth SET CXSS_UserID=?" + ", AuthClass=?, UserPrivateKey=?, PrivateKeyIV=?" + ", DateLastUpdated=?, RemovalFlag=? WHERE PK_UserAuth=?;", + -1, &dbcontext->update_auth_stmt, NULL); + sqlite3_prepare_v2(dbcontext->db, + "SELECT CXSS_UserID, AuthClass, UserPrivateKey" + ", PrivateKeyIV, DateCreated, DateLastUpdated" + " FROM UserAuth WHERE PK_UserAuth=? AND RemovalFlag=0;", -1, &dbcontext->retrieve_user_auth_stmt, NULL); sqlite3_prepare_v2(dbcontext->db, - "SELECT UserPrivateKey, UserSalt, PrivateKeyIV" - ", RemovalFlag, DateCreated, DateLastUpdated FROM UserAuth" - " WHERE CXSS_UserID=?;", + "SELECT PK_UserAuth, AuthClass, UserPrivateKey" + ", PrivateKeyIV, DateCreated, DateLastUpdated RemovalFlag" + " FROM UserAuth WHERE CXSS_UserID=?;", -1, &dbcontext->retrieve_user_auths_stmt, NULL); + sqlite3_prepare_v2(dbcontext->db, + "SELECT PK_UserAuth, AuthClass, UserPrivateKey" + ", PrivateKeyIV, DateCreated, DateLastUpdated, RemovalFlag" + " FROM UserAuth WHERE CXSS_UserID=? AND AuthClass=?;", + -1, &dbcontext->retrieve_user_auths_class_stmt, NULL); + sqlite3_prepare_v2(dbcontext->db, + "DELETE FROM UserAuth WHERE PK_UserAuth=?;", + -1, &dbcontext->delete_user_auth_stmt, NULL); sqlite3_prepare_v2(dbcontext->db, "DELETE FROM UserAuth WHERE CXSS_UserID=?;", -1, &dbcontext->delete_user_auths_stmt, NULL); sqlite3_prepare_v2(dbcontext->db, - "INSERT INTO UserResc (ResourceID, AuthClass" - ", AESKey, ResourceUsernameIV, ResourceAuthDataIV" + "DELETE FROM UserAuth WHERE CXSS_UserID=? AND AuthClass=?;", + -1, &dbcontext->delete_user_auths_class_stmt, NULL); + sqlite3_prepare_v2(dbcontext->db, + "INSERT INTO UserResc (ResourceID, AESKey" + ", ResourceUsernameIV, ResourceAuthDataIV" ", ResourceUsername, ResourceAuthData, CXSS_UserID" ", DateCreated, DateLastUpdated)" - " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);", + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);", -1, &dbcontext->insert_resc_stmt, NULL); sqlite3_prepare_v2(dbcontext->db, "UPDATE UserResc SET AESKey=?, ResourceUsername=?" @@ -180,7 +196,7 @@ cxss_i_SetupCredentialsDatabase(CXSS_DB_Context_t dbcontext) -1, &dbcontext->update_resc_stmt, NULL); sqlite3_prepare_v2(dbcontext->db, "SELECT ResourceUsernameIV, ResourceAuthDataIV" - ", AuthClass, AESKey, ResourceUsername, ResourceAuthData" + ", AESKey, ResourceUsername, ResourceAuthData" ", DateCreated, DateLastUpdated FROM UserResc" " WHERE CXSS_UserID=? AND ResourceID=?;", -1, &dbcontext->retrieve_resc_stmt, NULL); @@ -257,8 +273,8 @@ cxssInsertUserAuth(CXSS_DB_Context_t dbcontext, CXSS_UserAuth *UserAuth) UserAuth->CXSS_UserID, -1, NULL) != SQLITE_OK) { goto bind_error; } - if (sqlite3_bind_blob(dbcontext->insert_user_auth_stmt, 2, - UserAuth->Salt, UserAuth->SaltLength, NULL) != SQLITE_OK) { + if (sqlite3_bind_text(dbcontext->insert_user_auth_stmt, 2, + UserAuth->AuthClass, -1, NULL) != SQLITE_OK) { goto bind_error; } if (sqlite3_bind_blob(dbcontext->insert_user_auth_stmt, 3, @@ -269,16 +285,16 @@ cxssInsertUserAuth(CXSS_DB_Context_t dbcontext, CXSS_UserAuth *UserAuth) UserAuth->PrivateKeyIV, UserAuth->IVLength, NULL) != SQLITE_OK) { goto bind_error; } - if (sqlite3_bind_int(dbcontext->insert_user_auth_stmt, 5, - UserAuth->RemovalFlag) != SQLITE_OK) { + if (sqlite3_bind_text(dbcontext->insert_user_auth_stmt, 5, + UserAuth->DateCreated, -1, NULL) != SQLITE_OK) { goto bind_error; } if (sqlite3_bind_text(dbcontext->insert_user_auth_stmt, 6, - UserAuth->DateCreated, -1, NULL) != SQLITE_OK) { + UserAuth->DateLastUpdated, -1, NULL) != SQLITE_OK) { goto bind_error; } - if (sqlite3_bind_text(dbcontext->insert_user_auth_stmt, 7, - UserAuth->DateLastUpdated, -1, NULL) != SQLITE_OK) { + if (sqlite3_bind_int(dbcontext->insert_user_auth_stmt, 7, + UserAuth->RemovalFlag) != SQLITE_OK) { goto bind_error; } @@ -287,6 +303,10 @@ cxssInsertUserAuth(CXSS_DB_Context_t dbcontext, CXSS_UserAuth *UserAuth) mssError(0, "CXSS", "Failed to insert user auth\n"); return CXSS_DB_QUERY_ERROR; } + + /* set id to assigned value */ + UserAuth->PK_UserAuth = sqlite3_last_insert_rowid(dbcontext->db); + return CXSS_DB_SUCCESS; bind_error: @@ -311,39 +331,35 @@ cxssInsertUserResc(CXSS_DB_Context_t dbcontext, CXSS_UserResc *UserResc) UserResc->ResourceID, -1, NULL) != SQLITE_OK) { goto bind_error; } - if (sqlite3_bind_text(dbcontext->insert_resc_stmt, 2, - UserResc->AuthClass, -1, NULL) != SQLITE_OK) { - goto bind_error; - } - if (sqlite3_bind_blob(dbcontext->insert_resc_stmt, 3, + if (sqlite3_bind_blob(dbcontext->insert_resc_stmt, 2, UserResc->AESKey, UserResc->AESKeyLength, NULL) != SQLITE_OK) { goto bind_error; } - if (sqlite3_bind_blob(dbcontext->insert_resc_stmt, 4, + if (sqlite3_bind_blob(dbcontext->insert_resc_stmt, 3, UserResc->UsernameIV, UserResc->UsernameIVLength, NULL) != SQLITE_OK) { goto bind_error; } - if (sqlite3_bind_blob(dbcontext->insert_resc_stmt, 5, + if (sqlite3_bind_blob(dbcontext->insert_resc_stmt, 4, UserResc->AuthDataIV, UserResc->AuthDataIVLength, NULL) != SQLITE_OK) { goto bind_error; } - if (sqlite3_bind_blob(dbcontext->insert_resc_stmt, 6, + if (sqlite3_bind_blob(dbcontext->insert_resc_stmt, 5, UserResc->ResourceUsername, UserResc->UsernameLength, NULL) != SQLITE_OK) { goto bind_error; } - if (sqlite3_bind_blob(dbcontext->insert_resc_stmt, 7, + if (sqlite3_bind_blob(dbcontext->insert_resc_stmt, 6, UserResc->ResourceAuthData, UserResc->AuthDataLength, NULL) != SQLITE_OK) { goto bind_error; } - if (sqlite3_bind_text(dbcontext->insert_resc_stmt, 8, + if (sqlite3_bind_text(dbcontext->insert_resc_stmt, 7, UserResc->CXSS_UserID, -1, NULL) != SQLITE_OK) { goto bind_error; } - if (sqlite3_bind_text(dbcontext->insert_resc_stmt, 9, + if (sqlite3_bind_text(dbcontext->insert_resc_stmt, 8, UserResc->DateCreated, -1, NULL) != SQLITE_OK) { goto bind_error; } - if (sqlite3_bind_text(dbcontext->insert_resc_stmt, 10, + if (sqlite3_bind_text(dbcontext->insert_resc_stmt, 9, UserResc->DateLastUpdated, -1, NULL) != SQLITE_OK) { goto bind_error; } @@ -412,20 +428,21 @@ cxssRetrieveUserData(CXSS_DB_Context_t dbcontext, const char *cxss_userid, * * @param dbcontext Database context handle * @param cxss_userid CXSS User ID - * @param UserAuth Pointer to head of a CXSS_UserAuth linked list + * @param cxss_pkUserAuth The key for the desired item * @return Status code */ int -cxssRetrieveUserAuth(CXSS_DB_Context_t dbcontext, const char *cxss_userid, +cxssRetrieveUserAuth(CXSS_DB_Context_t dbcontext, int cxss_pkUserAuth, CXSS_UserAuth *UserAuth) { - const char *privatekey, *salt, *iv; - const char *date_created, *date_last_updated; - size_t keylength, salt_length, iv_length; + const char *cxss_userid, *auth_class, *privatekey; + const char *iv, *date_created, *date_last_updated; + size_t keylength, iv_length; + int removal_flag; /* Bind data with sqlite3 stmt */ sqlite3_reset(dbcontext->retrieve_user_auth_stmt); - if (sqlite3_bind_text(dbcontext->retrieve_user_auth_stmt, 1, cxss_userid, -1, NULL) != SQLITE_OK) { + if (sqlite3_bind_int(dbcontext->retrieve_user_auth_stmt, 1, cxss_pkUserAuth) != SQLITE_OK) { goto bind_error; } @@ -436,26 +453,27 @@ cxssRetrieveUserAuth(CXSS_DB_Context_t dbcontext, const char *cxss_userid, } /* Retrieve results */ - privatekey = (char*)sqlite3_column_blob(dbcontext->retrieve_user_auth_stmt, 0); - keylength = sqlite3_column_bytes(dbcontext->retrieve_user_auth_stmt, 0); - salt = (char*)sqlite3_column_text(dbcontext->retrieve_user_auth_stmt, 1); - salt_length = sqlite3_column_bytes(dbcontext->retrieve_user_auth_stmt, 1); - iv = (char*)sqlite3_column_blob(dbcontext->retrieve_user_auth_stmt, 2); - iv_length = sqlite3_column_bytes(dbcontext->retrieve_user_auth_stmt, 2); - date_created = (char*)sqlite3_column_text(dbcontext->retrieve_user_auth_stmt, 3); - date_last_updated = (char*)sqlite3_column_text(dbcontext->retrieve_user_auth_stmt, 4); + cxss_userid = (char*) sqlite3_column_text(dbcontext->retrieve_user_auth_stmt, 0); + auth_class = (char*) sqlite3_column_text(dbcontext->retrieve_user_auth_stmt, 1); + privatekey = (char*)sqlite3_column_blob(dbcontext->retrieve_user_auth_stmt, 2); + keylength = sqlite3_column_bytes(dbcontext->retrieve_user_auth_stmt, 2); + iv = (char*)sqlite3_column_blob(dbcontext->retrieve_user_auth_stmt, 3); + iv_length = sqlite3_column_bytes(dbcontext->retrieve_user_auth_stmt, 3); + date_created = (char*)sqlite3_column_text(dbcontext->retrieve_user_auth_stmt, 4); + date_last_updated = (char*)sqlite3_column_text(dbcontext->retrieve_user_auth_stmt, 5); + removal_flag = (char*)sqlite3_column_int(dbcontext->retrieve_user_auth_stmt, 6); /* Populate UserAuth struct */ + UserAuth->PK_UserAuth = cxss_pkUserAuth; UserAuth->CXSS_UserID = cxssStrdup(cxss_userid); + UserAuth->AuthClass = cxssStrdup(auth_class); UserAuth->PrivateKey = cxssBlobdup(privatekey, keylength); UserAuth->PrivateKeyIV = cxssBlobdup(iv, iv_length); - UserAuth->Salt = cxssBlobdup(salt, salt_length); UserAuth->DateCreated = cxssStrdup(date_created); UserAuth->DateLastUpdated = cxssStrdup(date_last_updated); - UserAuth->RemovalFlag = false; + UserAuth->RemovalFlag = removal_flag; UserAuth->KeyLength = keylength; UserAuth->IVLength = iv_length; - UserAuth->SaltLength = salt_length; return CXSS_DB_SUCCESS; bind_error: @@ -472,58 +490,81 @@ cxssRetrieveUserAuth(CXSS_DB_Context_t dbcontext, const char *cxss_userid, * @param cxss_userid CXSS User ID * @return void */ + //FIXME: skipping for now int -cxssRetrieveUserAuthLL(CXSS_DB_Context_t dbcontext, const char *cxss_userid, +cxssRetrieveUserAuthLL(CXSS_DB_Context_t dbcontext, const char *cxss_userid, const char* auth_class, CXSS_UserAuth_LLNode **node) { CXSS_UserAuth_LLNode *head, *prev, *current; - const char *privatekey, *salt, *iv; - const char *date_created, *date_last_updated; - size_t keylength, salt_length, iv_length; + const char *pk_userAuth, *privatekey; + const char *iv, *date_created, *date_last_updated; + size_t keylength, iv_length; bool removal_flag; /* Bind data with sqlite3 stmt */ - sqlite3_reset(dbcontext->retrieve_user_auths_stmt); - if (sqlite3_bind_text(dbcontext->retrieve_user_auths_stmt, 1, cxss_userid, -1, NULL) != SQLITE_OK) { + /*determine if need auth_class or not */ + sqlite3_stmt *stmt; + + if(auth_class != NULL){ + stmt = dbcontext->retrieve_user_auths_class_stmt; + sqlite3_reset(stmt); + if (sqlite3_bind_text(stmt, 2, auth_class, -1, NULL) != SQLITE_OK) { + goto bind_error; + } + } else { + stmt = dbcontext->retrieve_user_auths_stmt; + sqlite3_reset(stmt); + } + if (sqlite3_bind_text(stmt, 1, cxss_userid, -1, NULL) != SQLITE_OK) { goto bind_error; } /* Allocate head (dummy node) */ - head = malloc(sizeof(CXSS_UserAuth_LLNode)); + head = (CXSS_UserAuth_LLNode*)nmMalloc(sizeof(CXSS_UserAuth_LLNode)); prev = head; + head->next = NULL; /* need to detect if failed */ /* Execute query */ - while (sqlite3_step(dbcontext->retrieve_user_auths_stmt) == SQLITE_ROW) { + int code = sqlite3_step(stmt); + while (code == SQLITE_ROW) { /* Allocate and chain new node */ - current = malloc(sizeof(CXSS_UserAuth_LLNode)); + current = (CXSS_UserAuth_LLNode*)nmMalloc(sizeof(CXSS_UserAuth_LLNode)); prev->next = current; /* Retrieve results */ - privatekey = (char*)sqlite3_column_blob(dbcontext->retrieve_user_auths_stmt, 0); - keylength = sqlite3_column_bytes(dbcontext->retrieve_user_auths_stmt, 0); - salt = (char*)sqlite3_column_text(dbcontext->retrieve_user_auths_stmt, 1); - salt_length = sqlite3_column_bytes(dbcontext->retrieve_user_auths_stmt, 1); - iv = (char*)sqlite3_column_blob(dbcontext->retrieve_user_auths_stmt, 2); - iv_length = sqlite3_column_bytes(dbcontext->retrieve_user_auths_stmt, 2); - removal_flag = sqlite3_column_int(dbcontext->retrieve_user_auths_stmt, 4); - date_created = (char*)sqlite3_column_text(dbcontext->retrieve_user_auths_stmt, 5); - date_last_updated = (char*)sqlite3_column_text(dbcontext->retrieve_user_auths_stmt, 6); - + char *tempUserid = nmSysMalloc(strlen(cxss_userid)); + strcpy(tempUserid, cxss_userid); + pk_userAuth = (int) sqlite3_column_int(stmt, 0); + auth_class = (char*) sqlite3_column_text(stmt, 1); + privatekey = (char*)sqlite3_column_blob(stmt, 2); + keylength = sqlite3_column_bytes(stmt, 2); + iv = (char*)sqlite3_column_blob(stmt, 3); + iv_length = sqlite3_column_bytes(stmt, 3); + date_created = (char*)sqlite3_column_text(stmt, 4); + date_last_updated = (char*)sqlite3_column_text(stmt, 5); + removal_flag = (bool) sqlite3_column_int(stmt, 6); + /* Populate node */ - current->UserAuth.CXSS_UserID = cxssStrdup(cxss_userid); + current->UserAuth.PK_UserAuth = pk_userAuth; + current->UserAuth.CXSS_UserID = tempUserid; + current->UserAuth.AuthClass = cxssStrdup(auth_class); current->UserAuth.PrivateKey = cxssBlobdup(privatekey, keylength); - current->UserAuth.Salt = cxssBlobdup(salt, salt_length); current->UserAuth.PrivateKeyIV = cxssBlobdup(iv, iv_length); current->UserAuth.DateCreated = cxssStrdup(date_created); current->UserAuth.DateLastUpdated = cxssStrdup(date_last_updated); current->UserAuth.RemovalFlag = removal_flag; current->UserAuth.KeyLength = keylength; - current->UserAuth.SaltLength = salt_length; current->UserAuth.IVLength = iv_length; /* Advance */ prev = current; + code = sqlite3_step(stmt); + } + + if(code != SQLITE_DONE || head->next == NULL){ + return CXSS_DB_QUERY_ERROR; + nmFree(head, sizeof(CXSS_UserAuth_LLNode)); } current->next = NULL; @@ -532,6 +573,7 @@ cxssRetrieveUserAuthLL(CXSS_DB_Context_t dbcontext, const char *cxss_userid, bind_error: mssError(0, "CXSS", "Failed to bind value with SQLite statement: %s\n", sqlite3_errmsg(dbcontext->db)); + if(head != NULL) nmFree(head, sizeof(CXSS_UserAuth_LLNode)); return CXSS_DB_BIND_ERROR; } @@ -550,7 +592,6 @@ int cxssRetrieveUserResc(CXSS_DB_Context_t dbcontext, const char *cxss_userid, const char *resource_id, CXSS_UserResc *UserResc) { - const char *auth_class; const char *resource_username, *resource_authdata; const char *aeskey; const char *username_iv, *authdata_iv; @@ -578,19 +619,17 @@ cxssRetrieveUserResc(CXSS_DB_Context_t dbcontext, const char *cxss_userid, username_iv_len = sqlite3_column_bytes(dbcontext->retrieve_resc_stmt, 0); authdata_iv = (char*)sqlite3_column_blob(dbcontext->retrieve_resc_stmt, 1); authdata_iv_len = sqlite3_column_bytes(dbcontext->retrieve_resc_stmt, 1); - auth_class = (char*)sqlite3_column_text(dbcontext->retrieve_resc_stmt, 2); - aeskey = (char*)sqlite3_column_blob(dbcontext->retrieve_resc_stmt, 3); - aeskey_len = sqlite3_column_bytes(dbcontext->retrieve_resc_stmt, 3); - resource_username = (char*)sqlite3_column_blob(dbcontext->retrieve_resc_stmt, 4); - username_len = sqlite3_column_bytes(dbcontext->retrieve_resc_stmt, 4); - resource_authdata = (char*)sqlite3_column_blob(dbcontext->retrieve_resc_stmt, 5); - authdata_len = sqlite3_column_bytes(dbcontext->retrieve_resc_stmt, 5); - date_created = (char*)sqlite3_column_text(dbcontext->retrieve_resc_stmt, 6); - date_last_updated = (char*)sqlite3_column_text(dbcontext->retrieve_resc_stmt, 7); + aeskey = (char*)sqlite3_column_blob(dbcontext->retrieve_resc_stmt, 2); + aeskey_len = sqlite3_column_bytes(dbcontext->retrieve_resc_stmt, 2); + resource_username = (char*)sqlite3_column_blob(dbcontext->retrieve_resc_stmt, 3); + username_len = sqlite3_column_bytes(dbcontext->retrieve_resc_stmt, 3); + resource_authdata = (char*)sqlite3_column_blob(dbcontext->retrieve_resc_stmt, 4); + authdata_len = sqlite3_column_bytes(dbcontext->retrieve_resc_stmt, 4); + date_created = (char*)sqlite3_column_text(dbcontext->retrieve_resc_stmt, 5); + date_last_updated = (char*)sqlite3_column_text(dbcontext->retrieve_resc_stmt, 6); /* Build struct */ UserResc->ResourceID = cxssStrdup(resource_id); - UserResc->AuthClass = cxssStrdup(auth_class); UserResc->CXSS_UserID = cxssStrdup(cxss_userid); UserResc->AESKey = cxssBlobdup(aeskey, aeskey_len); UserResc->ResourceUsername = cxssBlobdup(resource_username, username_len); @@ -642,12 +681,76 @@ cxssUpdateUserData(CXSS_DB_Context_t dbcontext, CXSS_UserData *UserData) mssError(0, "CXSS", "Failed to update user\n"); return CXSS_DB_QUERY_ERROR; } + if(sqlite3_changes(dbcontext->db) < 1) { /* Make sure an update occured */ + mssError(0, "CXSS", "No user found to update\n"); + return CXSS_DB_NOENT_ERROR; + } + + return CXSS_DB_SUCCESS; + +bind_error: + mssError(0, "CXSS", "Failed to bind value with SQLite statement: %s\n", sqlite3_errmsg(dbcontext->db)); + return CXSS_DB_BIND_ERROR; +} + +/** @brief Update user authentication + * + * Update a given user's authentication in CXSS + * + * @param dbcontext Database context handle + * @param UserAuth Pointer to a CXSS_UserAuth struct + * @return Status code + */ +int +cxssUpdateUserAuth(CXSS_DB_Context_t dbcontext, CXSS_UserAuth *UserAuth) +{ + /* Bind data with sqlite3 stmts */ + sqlite3_reset(dbcontext->update_auth_stmt); + if (sqlite3_bind_text(dbcontext->update_auth_stmt, 1, + UserAuth->CXSS_UserID, -1, NULL) != SQLITE_OK) { + goto bind_error; + } + if (sqlite3_bind_text(dbcontext->update_auth_stmt, 2, + UserAuth->AuthClass, -1, NULL) != SQLITE_OK) { + goto bind_error; + } + if (sqlite3_bind_blob(dbcontext->update_auth_stmt, 3, + UserAuth->PrivateKey, UserAuth->KeyLength, NULL) != SQLITE_OK) { + goto bind_error; + } + if (sqlite3_bind_blob(dbcontext->update_auth_stmt, 4, + UserAuth->PrivateKeyIV, UserAuth->IVLength, NULL) != SQLITE_OK) { + goto bind_error; + } + if (sqlite3_bind_text(dbcontext->update_auth_stmt, 5, + UserAuth->DateLastUpdated, -1, NULL) != SQLITE_OK) { + goto bind_error; + } + if (sqlite3_bind_int(dbcontext->update_auth_stmt, 6, + UserAuth->RemovalFlag) != SQLITE_OK) { + goto bind_error; + } + if (sqlite3_bind_int(dbcontext->update_auth_stmt, 7, + UserAuth->PK_UserAuth) != SQLITE_OK) { + goto bind_error; + } + + /* Execute query */ + if (sqlite3_step(dbcontext->update_auth_stmt) != SQLITE_DONE) { + mssError(0, "CXSS", "Failed to update resource\n"); + return CXSS_DB_QUERY_ERROR; + } + if(sqlite3_changes(dbcontext->db) < 1) { /* Make sure an update occured */ + mssError(0, "CXSS", "No resource found to update\n"); + return CXSS_DB_NOENT_ERROR; + } + return CXSS_DB_SUCCESS; bind_error: mssError(0, "CXSS", "Failed to bind value with SQLite statement: %s\n", sqlite3_errmsg(dbcontext->db)); return CXSS_DB_BIND_ERROR; -} +} /** @brief Update user resource * @@ -696,10 +799,15 @@ cxssUpdateUserResc(CXSS_DB_Context_t dbcontext, CXSS_UserResc *UserResc) } /* Execute query */ - if (sqlite3_step(dbcontext->update_user_stmt) != SQLITE_DONE) { + if (sqlite3_step(dbcontext->update_resc_stmt) != SQLITE_DONE) { mssError(0, "CXSS", "Failed to update resource\n"); return CXSS_DB_QUERY_ERROR; } + if(sqlite3_changes(dbcontext->db) < 1) { /* Make sure an update occured */ + mssError(0, "CXSS", "No resource found to update\n"); + return CXSS_DB_NOENT_ERROR; + } + return CXSS_DB_SUCCESS; bind_error: @@ -730,6 +838,44 @@ cxssDeleteUserData(CXSS_DB_Context_t dbcontext, const char *cxss_userid) mssError(0, "CXSS", "Failed to delete user\n"); return CXSS_DB_QUERY_ERROR; } + if(sqlite3_changes(dbcontext->db) < 1) { /* Make sure an update occured */ + mssError(0, "CXSS", "No user found to delete\n"); + return CXSS_DB_NOENT_ERROR; + } + return CXSS_DB_SUCCESS; + +bind_error: + mssError(0, "CXSS", "Failed to bind value with SQLite statement: %s\n", sqlite3_errmsg(dbcontext->db)); + return CXSS_DB_BIND_ERROR; +} + +/** @brief Delete user auth + * + * Delete user auth from CXSS + * + * @param dbcontext Database context handle + * @param pk_userAuth primary key for auth entry + * @return Status code + */ +int +cxssDeleteUserAuth(CXSS_DB_Context_t dbcontext, int pk_userAuth) +{ + /* Bind data with sqlite3 stmt */ + sqlite3_reset(dbcontext->delete_user_auth_stmt); + if (sqlite3_bind_int(dbcontext->delete_user_auth_stmt, 1, + pk_userAuth) != SQLITE_OK) { + goto bind_error; + } + + /* Execute query */ + if (sqlite3_step(dbcontext->delete_user_auth_stmt) != SQLITE_DONE) { + mssError(0, "CXSS", "Failed to delete user\n"); + return CXSS_DB_QUERY_ERROR; + } + if(sqlite3_changes(dbcontext->db) < 1) { /* Make sure an update occured */ + mssError(0, "CXSS", "No user found to delete\n"); + return CXSS_DB_NOENT_ERROR; + } return CXSS_DB_SUCCESS; bind_error: @@ -766,6 +912,10 @@ cxssDeleteUserResc(CXSS_DB_Context_t dbcontext, const char *cxss_userid, mssError(0, "CXSS", "Failed to delete resource\n"); return CXSS_DB_QUERY_ERROR; } + if(sqlite3_changes(dbcontext->db) < 1) { /* Make sure an update occured */ + mssError(0, "CXSS", "No resource found to delete\n"); + return CXSS_DB_NOENT_ERROR; + } return CXSS_DB_SUCCESS; bind_error: @@ -782,20 +932,35 @@ cxssDeleteUserResc(CXSS_DB_Context_t dbcontext, const char *cxss_userid, * @return Status code */ int -cxssDeleteAllUserAuth(CXSS_DB_Context_t dbcontext, const char *cxss_userid) +cxssDeleteAllUserAuth(CXSS_DB_Context_t dbcontext, const char *cxss_userid, const char *auth_class) { + /* base off of auth class as well as user, if inlcuded */ /* Bind data with sqlite3 stmts */ - sqlite3_reset(dbcontext->delete_user_auths_stmt); - if (sqlite3_bind_text(dbcontext->delete_user_auths_stmt, 1, - cxss_userid, -1, NULL) != SQLITE_OK) { + sqlite3_stmt *stmt; + if(auth_class != NULL){ + stmt = dbcontext->delete_user_auths_class_stmt; + sqlite3_reset(stmt); + + if (sqlite3_bind_text(stmt, 2, auth_class, -1, NULL) != SQLITE_OK) { + goto bind_error; + } + }else { + stmt = dbcontext->delete_user_auths_stmt; + sqlite3_reset(stmt); + } + if (sqlite3_bind_text(stmt, 1, cxss_userid, -1, NULL) != SQLITE_OK) { goto bind_error; } /* Execute query */ - if (sqlite3_step(dbcontext->delete_user_auths_stmt) != SQLITE_DONE) { - mssError(0, "CXSS", "Failed to delete resource\n"); + if (sqlite3_step(stmt) != SQLITE_DONE) { + mssError(0, "CXSS", "Failed to delete user auths\n"); return CXSS_DB_QUERY_ERROR; } + if(sqlite3_changes(dbcontext->db) < 1) { /* Make sure an update occured */ + mssError(0, "CXSS", "No user auths found to delete\n"); + return CXSS_DB_NOENT_ERROR; + } return CXSS_DB_SUCCESS; bind_error: @@ -826,6 +991,10 @@ cxssDeleteAllUserResc(CXSS_DB_Context_t dbcontext, const char *cxss_userid) mssError(0, "CXSS", "Failed to delete resource\n"); return CXSS_DB_QUERY_ERROR; } + if(sqlite3_changes(dbcontext->db) < 1) { /* Make sure an update occured */ + mssError(0, "CXSS", "No resources found to delete\n"); + return CXSS_DB_NOENT_ERROR; + } return CXSS_DB_SUCCESS; bind_error: @@ -845,13 +1014,13 @@ cxssFreeUserAuthLL(CXSS_UserAuth_LLNode *start) { /* Free head (dummy node) */ CXSS_UserAuth_LLNode *next = start->next; - free(start); + nmFree(start, sizeof(CXSS_UserAuth_LLNode)); start = next; while (start != NULL) { next = start->next; - cxssFreeUserAuth(&start->UserAuth); - free(start); + cxssFreeUserAuth(&start->UserAuth); + nmFree(start, sizeof(CXSS_UserAuth_LLNode)); start = next; } } @@ -968,10 +1137,10 @@ cxssDbContainsResc(CXSS_DB_Context_t dbcontext, const char *resource_id) void cxssFreeUserData(CXSS_UserData *UserData) { - free((void*)UserData->CXSS_UserID); - free((void*)UserData->PublicKey); - free((void*)UserData->DateCreated); - free((void*)UserData->DateLastUpdated); + nmSysFree((void*)UserData->CXSS_UserID); + nmSysFree((void*)UserData->PublicKey); + nmSysFree((void*)UserData->DateCreated); + nmSysFree((void*)UserData->DateLastUpdated); } /** @brief Free dynamic CXSS_UserAuth struct members @@ -985,12 +1154,11 @@ cxssFreeUserData(CXSS_UserData *UserData) void cxssFreeUserAuth(CXSS_UserAuth *UserAuth) { - free((void*)UserAuth->CXSS_UserID); - free((void*)UserAuth->PrivateKey); - free((void*)UserAuth->Salt); - free((void*)UserAuth->PrivateKeyIV); - free((void*)UserAuth->DateCreated); - free((void*)UserAuth->DateLastUpdated); + nmSysFree((void*)UserAuth->CXSS_UserID); + nmSysFree((void*)UserAuth->PrivateKey); + nmSysFree((void*)UserAuth->PrivateKeyIV); + nmSysFree((void*)UserAuth->DateCreated); + nmSysFree((void*)UserAuth->DateLastUpdated); } /** @brief Free dynamic CXSS_UserResc struct members @@ -1004,16 +1172,15 @@ cxssFreeUserAuth(CXSS_UserAuth *UserAuth) void cxssFreeUserResc(CXSS_UserResc *UserResc) { - free((void*)UserResc->CXSS_UserID); - free((void*)UserResc->ResourceID); - free((void*)UserResc->AuthClass); - free((void*)UserResc->AESKey); - free((void*)UserResc->ResourceUsername); - free((void*)UserResc->ResourceAuthData); - free((void*)UserResc->UsernameIV); - free((void*)UserResc->AuthDataIV); - free((void*)UserResc->DateCreated); - free((void*)UserResc->DateLastUpdated); + nmSysFree((void*)UserResc->CXSS_UserID); + nmSysFree((void*)UserResc->ResourceID); + nmSysFree((void*)UserResc->AESKey); + nmSysFree((void*)UserResc->ResourceUsername); + nmSysFree((void*)UserResc->ResourceAuthData); + nmSysFree((void*)UserResc->UsernameIV); + nmSysFree((void*)UserResc->AuthDataIV); + nmSysFree((void*)UserResc->DateCreated); + nmSysFree((void*)UserResc->DateLastUpdated); } /** @brief Cleanup sqlite3 statements @@ -1042,5 +1209,4 @@ cxss_i_FinalizeSqliteStatements(CXSS_DB_Context_t dbcontext) sqlite3_finalize(dbcontext->retrieve_resc_stmt); sqlite3_finalize(dbcontext->update_resc_stmt); sqlite3_finalize(dbcontext->delete_resc_stmt); -} - +} \ No newline at end of file diff --git a/centrallix/cxss/cxss_credentials_mgr.c b/centrallix/cxss/cxss_credentials_mgr.c index 806069d63..d3c37b12d 100644 --- a/centrallix/cxss/cxss_credentials_mgr.c +++ b/centrallix/cxss/cxss_credentials_mgr.c @@ -62,13 +62,10 @@ cxssCredentialsManagerClose(void) * @param cxss_userid Centrallix User ID * @param pb_userk ey Password-based user encryption key (used to encrypt private key) * @param keylength Length of password-based user encryption key - * @param salt User salt - * @param salt_len Length of user salt * @return Status code */ int -cxssAddUser(const char *cxss_userid, const char *pb_userkey, size_t pb_userkey_len, - const char *salt, size_t salt_len) +cxssAddUser(const char *cxss_userid, const char *pb_userkey, size_t pb_userkey_len) { CXSS_UserData UserData = {}; CXSS_UserAuth UserAuth = {}; @@ -110,11 +107,9 @@ cxssAddUser(const char *cxss_userid, const char *pb_userkey, size_t pb_userkey_l UserAuth.CXSS_UserID = cxss_userid; UserAuth.PrivateKey = encrypted_privatekey; UserAuth.PrivateKeyIV = iv; - UserAuth.Salt = salt; UserAuth.DateCreated = current_timestamp; UserAuth.DateLastUpdated = current_timestamp; UserAuth.RemovalFlag = false; - UserAuth.SaltLength = salt_len; UserAuth.KeyLength = encr_privatekey_len; UserAuth.IVLength = sizeof(iv); @@ -127,13 +122,13 @@ cxssAddUser(const char *cxss_userid, const char *pb_userkey, size_t pb_userkey_l goto error; } - free(encrypted_privatekey); + nmSysFree(encrypted_privatekey); cxssDestroyKey(privatekey, privatekey_len); cxssShred(pb_userkey, pb_userkey_len); return CXSS_MGR_SUCCESS; error: - free(encrypted_privatekey); + nmSysFree(encrypted_privatekey); cxssDestroyKey(privatekey, privatekey_len); cxssShred(pb_userkey, pb_userkey_len); return CXSS_MGR_INSERT_ERROR; @@ -173,7 +168,7 @@ cxssRetrieveUserPrivateKey(const char *cxss_userid, const char *pb_userkey, size return CXSS_MGR_SUCCESS; error: - free(*privatekey); + nmSysFree(*privatekey); cxssFreeUserAuth(&UserAuth); cxssShred(pb_userkey, pb_userkey_len); return CXSS_MGR_RETRIEVE_ERROR; @@ -198,7 +193,7 @@ cxssRetrieveUserPublicKey(const char *cxss_userid, char **publickey, int *public } /* Allocate buffer for public key */ - *publickey = malloc(UserData.KeyLength); + *publickey = nmSysMalloc(UserData.KeyLength); if (!(*publickey)) { mssError(0, "CXSS", "Memory allocation error\n"); goto error; @@ -227,7 +222,7 @@ cxssRetrieveUserPublicKey(const char *cxss_userid, char **publickey, int *public * @return Status code */ int -cxssAddResource(const char *cxss_userid, const char *resource_id, const char *auth_class, +cxssAddResource(const char *cxss_userid, const char *resource_id, const char *resource_username, size_t username_len, const char *resource_authdata, size_t authdata_len) { @@ -290,7 +285,6 @@ cxssAddResource(const char *cxss_userid, const char *resource_id, const char *au /* Build struct */ UserResc.CXSS_UserID = cxss_userid; UserResc.ResourceID = resource_id; - UserResc.AuthClass = auth_class; UserResc.AESKey = encrypted_rand_key; UserResc.ResourceUsername = encrypted_username; UserResc.ResourceAuthData = encrypted_password; @@ -310,17 +304,17 @@ cxssAddResource(const char *cxss_userid, const char *resource_id, const char *au goto error; } - free(publickey); - free(encrypted_username); - free(encrypted_password); + nmSysFree(publickey); + nmSysFree(encrypted_username); + nmSysFree(encrypted_password); cxssShred(resource_username, username_len); cxssShred(resource_authdata, authdata_len); return CXSS_MGR_SUCCESS; error: - free(publickey); - free(encrypted_username); - free(encrypted_password); + nmSysFree(publickey); + nmSysFree(encrypted_username); + nmSysFree(encrypted_password); cxssShred(resource_username, username_len); cxssShred(resource_authdata, authdata_len); return CXSS_MGR_INSERT_ERROR; @@ -416,7 +410,7 @@ cxss_deleteUser(const char *cxss_userid) mssError(0, "CXSS", "Failed to delete user data\n"); return CXSS_MGR_DELETE_ERROR; } - if (cxssDeleteAllUserAuth(dbcontext, cxss_userid) < 0) { + if (cxssDeleteAllUserAuth(dbcontext, cxss_userid, NULL) < 0) { mssError(0, "CXSS", "Failed to delete user auth data\n"); return CXSS_MGR_DELETE_ERROR; } diff --git a/centrallix/cxss/cxss_crypto.c b/centrallix/cxss/cxss_crypto.c index b1c11bb27..e5b23c9bf 100644 --- a/centrallix/cxss/cxss_crypto.c +++ b/centrallix/cxss/cxss_crypto.c @@ -10,6 +10,7 @@ #include #include "cxss/crypto.h" #include "cxss/credentials_db.h" +#include "cxlib/newmalloc.h" static bool CSPRNG_Initialized = false; @@ -73,7 +74,7 @@ cxssEncryptAES256(const char *plaintext, int plaintext_len, int len; /* Allocate buffer to store ciphertext */ - *ciphertext = malloc(cxssAES256CiphertextLength(plaintext_len)); + *ciphertext = (char*)nmSysMalloc(cxssAES256CiphertextLength(plaintext_len)); if (!(*ciphertext)) { mssError(0, "CXSS", "Memory allocation error\n"); goto error; @@ -112,7 +113,7 @@ cxssEncryptAES256(const char *plaintext, int plaintext_len, error: EVP_CIPHER_CTX_free(ctx); - free(*ciphertext); + nmSysFree(*ciphertext); return CXSS_CRYPTO_ENCR_ERROR; } @@ -140,7 +141,7 @@ cxssDecryptAES256(const char *ciphertext, int ciphertext_len, int len; /* Allocate buffer to store plaintext */ - *plaintext = malloc(cxssAES256CiphertextLength(ciphertext_len)); + *plaintext = (char*)nmSysMalloc(cxssAES256CiphertextLength(ciphertext_len)); if (!(*plaintext)) { mssError(0, "CXSS", "Memory allocation error\n"); goto error; @@ -180,7 +181,7 @@ cxssDecryptAES256(const char *ciphertext, int ciphertext_len, error: EVP_CIPHER_CTX_free(ctx); - free(*plaintext); + nmSysFree(*plaintext); return CXSS_CRYPTO_DECR_ERROR; } @@ -346,8 +347,8 @@ cxssGenerateRSA4096bitKeypair(char **privatekey, int *privatekey_len, goto error; } - *privatekey = malloc(pri_len + 1); - *publickey = malloc(pub_len + 1); + *privatekey = nmSysMalloc(pri_len + 1); + *publickey = nmSysMalloc(pub_len + 1); if (!(*publickey) || !(*privatekey)) { mssError(0, "CXSS", "Memory allocation error\n"); goto error; @@ -496,7 +497,7 @@ cxssDestroyKey(char *key, size_t keylength) { if (key && keylength >= 0) { memset(key, 0, keylength); - free(key); + nmSysFree(key); } } diff --git a/centrallix/cxss/cxss_util.c b/centrallix/cxss/cxss_util.c index c32ef3adb..060a86e6f 100644 --- a/centrallix/cxss/cxss_util.c +++ b/centrallix/cxss/cxss_util.c @@ -4,6 +4,7 @@ #include #include #include "cxss/util.h" +#include "cxlib/newmalloc.h" /** @brief Duplicate a string * @@ -18,7 +19,7 @@ cxssStrdup(const char *str) { if (!str) return NULL; - return strdup(str); + return nmSysStrdup(str); } /** @brief Duplicate an array of bytes @@ -39,7 +40,7 @@ cxssBlobdup(const char *blob, size_t len) if (!blob) return NULL; - copy = malloc(sizeof(char) * len); + copy = nmSysMalloc(sizeof(char) * len); if (!copy) { mssError(0, "CXSS", "Memory allocation error\n"); exit(EXIT_FAILURE); diff --git a/centrallix/include/cxss/credentials_db.h b/centrallix/include/cxss/credentials_db.h index 67461843b..f831ed9f8 100644 --- a/centrallix/include/cxss/credentials_db.h +++ b/centrallix/include/cxss/credentials_db.h @@ -3,6 +3,7 @@ #include #include +#include /* DB Context struct */ typedef struct _CXSS_DB_Context_t { @@ -16,9 +17,13 @@ typedef struct _CXSS_DB_Context_t { sqlite3_stmt *update_user_stmt; sqlite3_stmt *delete_user_stmt; sqlite3_stmt *insert_user_auth_stmt; + sqlite3_stmt *update_auth_stmt; sqlite3_stmt *retrieve_user_auth_stmt; sqlite3_stmt *retrieve_user_auths_stmt; + sqlite3_stmt *retrieve_user_auths_class_stmt; + sqlite3_stmt *delete_user_auth_stmt; sqlite3_stmt *delete_user_auths_stmt; + sqlite3_stmt *delete_user_auths_class_stmt; sqlite3_stmt *insert_resc_stmt; sqlite3_stmt *retrieve_resc_stmt; sqlite3_stmt *update_resc_stmt; @@ -35,22 +40,21 @@ typedef struct { } CXSS_UserData; typedef struct { + int PK_UserAuth; const char *CXSS_UserID; - const char *Salt; + const char *AuthClass; const char *PrivateKey; const char *PrivateKeyIV; const char *DateCreated; const char *DateLastUpdated; bool RemovalFlag; size_t KeyLength; - size_t SaltLength; size_t IVLength; } CXSS_UserAuth; typedef struct { const char *CXSS_UserID; const char *ResourceID; - const char *AuthClass; const char *AESKey; const char *UsernameIV; const char *AuthDataIV; @@ -71,6 +75,7 @@ typedef struct _CXSS_LLNode { } CXSS_UserAuth_LLNode; typedef enum { + CXSS_DB_NOENT_ERROR = -ENOENT, CXSS_DB_SETUP_ERROR = -3, CXSS_DB_BIND_ERROR = -2, CXSS_DB_QUERY_ERROR = -1, @@ -83,18 +88,20 @@ int cxssInsertUserData(CXSS_DB_Context_t dbcontext, CXSS_UserData *UserData); int cxssInsertUserAuth(CXSS_DB_Context_t dbcontext, CXSS_UserAuth *UserAuth); int cxssInsertUserResc(CXSS_DB_Context_t dbcontext, CXSS_UserResc *UserResc); int cxssRetrieveUserData(CXSS_DB_Context_t dbcontext, const char *cxss_userid, CXSS_UserData *UserData); -int cxssRetrieveUserAuth(CXSS_DB_Context_t dbcontext, const char *cxss_userid, CXSS_UserAuth *UserAuth); +int cxssRetrieveUserAuth(CXSS_DB_Context_t dbcontext, int pk_userAuth, CXSS_UserAuth *UserAuth); int cxssRetrieveUserResc(CXSS_DB_Context_t dbcontext, const char *cxss_userid, const char *resource_id, CXSS_UserResc *UserResc); int cxssUpdateUserData(CXSS_DB_Context_t dbcontext, CXSS_UserData *UserData); +int cxssUpdateUserAuth(CXSS_DB_Context_t dbcontext, CXSS_UserAuth *UserAuth); int cxssUpdateUserResc(CXSS_DB_Context_t dbcontext, CXSS_UserResc *UserResc); int cxssDeleteUserData(CXSS_DB_Context_t dbcontext, const char *cxss_userid); +int cxssDeleteUserAuth(CXSS_DB_Context_t dbcontext, int pk_userAuth); int cxssDeleteUserResc(CXSS_DB_Context_t dbcontext, const char *cxss_userid, const char *resource_id); -int cxssDeleteAllUserAuth(CXSS_DB_Context_t dbcontext, const char *cxss_userid); +int cxssDeleteAllUserAuth(CXSS_DB_Context_t dbcontext, const char *cxss_userid, const char*auth_class); int cxssDeleteAllUserResc(CXSS_DB_Context_t dbcontext, const char *cxss_userid); void cxssFreeUserData(CXSS_UserData *UserData); void cxssFreeUserAuth(CXSS_UserAuth *UserAuth); void cxssFreeUserResc(CXSS_UserResc *UserResc); -int cxssRetrieveUserAuthLL(CXSS_DB_Context_t dbcontext, const char *cxss_userid, CXSS_UserAuth_LLNode **node); +int cxssRetrieveUserAuthLL(CXSS_DB_Context_t dbcontext, const char *cxss_userid, const char *auth_class, CXSS_UserAuth_LLNode **node); void cxssFreeUserAuthLL(CXSS_UserAuth_LLNode *start); int cxssGetUserCount(CXSS_DB_Context_t dbcontext); int cxssGetUserRescCount(CXSS_DB_Context_t dbcontext, const char *cxss_userid); diff --git a/centrallix/include/cxss/credentials_mgr.h b/centrallix/include/cxss/credentials_mgr.h index 778081905..34b46630d 100644 --- a/centrallix/include/cxss/credentials_mgr.h +++ b/centrallix/include/cxss/credentials_mgr.h @@ -13,11 +13,11 @@ typedef enum { int cxssCredentialsManagerInit(void); void cxssCredentialsManagerClose(void); -int cxssAddUser(const char *cxss_userid, const char *encryption_key, size_t encryption_key_length, const char *salt, size_t salt_len); +int cxssAddUser(const char *cxss_userid, const char *encryption_key, size_t encryption_key_length); int cxssRetrieveUserPrivateKey(const char *cxss_userid, const char *user_key, size_t user_key_len, char **privatekey, int *privatekey_len); int cxssRetrieveUserPublicKey(const char *cxss_userid, char **publickey, int *publickey_len); int cxssDeleteUser(const char *cxss_userid); -int cxssAddResource(const char *cxss_userid, const char *resource_id, const char *auth_class, const char *resource_username, size_t username_len, const char *resource_password, size_t password_len); +int cxssAddResource(const char *cxss_userid, const char *resource_id, const char *resource_username, size_t username_len, const char *resource_password, size_t password_len); int cxssGetResource(const char *cxss_userid, const char *resource_id, const char *user_key, size_t user_key_len, char **resource_username, char **resource_data); int cxssDeleteResource(const char *cxss_userid, const char *resource_id); diff --git a/centrallix/tests/tempFiles/README.md b/centrallix/tests/tempFiles/README.md new file mode 100644 index 000000000..518f206b5 --- /dev/null +++ b/centrallix/tests/tempFiles/README.md @@ -0,0 +1,2 @@ +# Temporary Files +This folder is intended for storing temp files generated by tests. One example of this is the database created by the cxss-credDB tests. Files within this folder, besides this readme, should not be added to the git. \ No newline at end of file diff --git a/centrallix/tests/test_cxss-credDB_00.c b/centrallix/tests/test_cxss-credDB_00.c new file mode 100644 index 000000000..539d6a6d7 --- /dev/null +++ b/centrallix/tests/test_cxss-credDB_00.c @@ -0,0 +1,20 @@ +#include +#include +#include "cxss/credentials_db.h" + +long long +test(char** name) + { + *name = "CXSS Cred DB 00: Basic Init"; + + + /** Basic test of init and release */ + char * PATH = "./tests/tempFiles/test.db"; + CXSS_DB_Context_t dbCon = cxssCredentialsDatabaseInit(PATH); + + assert(dbCon != NULL); + + cxssCredentialsDatabaseClose(dbCon); + + return 0; + } diff --git a/centrallix/tests/test_cxss-credDB_01.c b/centrallix/tests/test_cxss-credDB_01.c new file mode 100644 index 000000000..968ee84b0 --- /dev/null +++ b/centrallix/tests/test_cxss-credDB_01.c @@ -0,0 +1,137 @@ +#include +#include +#include "cxss/credentials_db.h" + +long long +test(char** name) + { + *name = "CXSS Cred DB 01: Test user table"; + + /** Set up DB. **/ + char * PATH = "./tests/tempFiles/test.db"; + + /** Reset DB file if needed **/ + if(access(PATH, 0) == 0) + { + assert(remove(PATH) == 0); + } + assert(access(PATH, 0) != 0); + + CXSS_DB_Context_t dbCon = cxssCredentialsDatabaseInit(PATH); + assert(dbCon != NULL); + + + /*** Insert ***/ + + /** insert one entry **/ + CXSS_UserData data; + data.CXSS_UserID = "1"; + data.PublicKey = "not a real public key"; + data.DateCreated = "7/5/2022"; + data.DateLastUpdated = "7/4/2022"; + data.KeyLength = strlen(data.PublicKey); + int result = cxssInsertUserData(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + + + /*** Retrieve ***/ + + /** retrieve: **/ + CXSS_UserData retData; + result = cxssRetrieveUserData(dbCon, data.CXSS_UserID, &retData); + assert(result == CXSS_DB_SUCCESS); + + assert(strcmp(data.CXSS_UserID, retData.CXSS_UserID) == 0); + assert(strcmp(data.PublicKey, retData.PublicKey) == 0); + assert(strcmp(data.DateCreated, retData.DateCreated) == 0); + assert(strcmp(data.DateLastUpdated, retData.DateLastUpdated) == 0); + assert(data.KeyLength == retData.KeyLength); + + /** retrive item not in DB **/ + CXSS_UserData noData; + result = cxssRetrieveUserData(dbCon, "2", &noData); + assert(result == CXSS_DB_QUERY_ERROR); + + + /*** Update ***/ + + /** update one field **/ + data.PublicKey = "yet another fake key."; + result = cxssUpdateUserData(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + + result = cxssRetrieveUserData(dbCon, data.CXSS_UserID, &retData); + assert(result == CXSS_DB_SUCCESS); + assert(strcmp(data.CXSS_UserID, retData.CXSS_UserID) == 0); /* only this field changed */ + assert(strcmp(data.PublicKey, retData.PublicKey) == 0); + assert(strcmp(data.DateCreated, retData.DateCreated) == 0); + assert(strcmp(data.DateLastUpdated, retData.DateLastUpdated) == 0); + assert(data.KeyLength == retData.KeyLength); + + /** update all fields **/ + data.PublicKey = "-----BEGIN RSA PUBLIC KEY-----\n\ + MIICCgKCAgEAw4/Eqoi/sBB/O+gFne66/UAnico6oVncS1kn42iQ4aV/2zHha0ML\n\ + EozmpD97v6TPumdqQNdudkL2FATHouaegGLuz2Mj+njVcNLtaNcXmDsgw7Nzn8HV\n\ + k+XiPk3T2tq/LuqdrYjC9tgl0RAWsqIpx3k6MNhNGR63n5WpvTLPLF1m3upGWcx8\n\ + jUflMuy3fmw+Jd0nr0gbrENYDcqy9AayouCWtC7MVXSghISXYRqNQ6M1tSACMGjY\n\ + f1lsBQ/gieI7GZseitI5DP4uHzDWgPu8+nqIbLS/Ugf90H5cf16IB1GUIA77TjO4\n\ + J/c51xi9uDlCofPX2BkRxrehSt+nBUxKMR5qdbDA3+SsUUJfk4RLi4rdJOauBvNL\n\ + S0N4P+K4H45yLMe4mtFeBNxiaGgKmv2R6YTRrQmGVrqyve/9Bg99xM7xcVVCjCME\n\ + SbNMdr/bc0Pc0yJTdyY04cH0SbLs46/sQ4j22zc6bggdzKZQ9HchdJoSx+VbOf8G\n\ + ZlhzqJ9JEsH/+MRi9iGikMtCcZY4tFVC7iHVhJzCQ5lRB0MECtGVEPEcx2Oldfh9\n\ + 3L3wuhMx+mNoeMJYXjdK9/qQSgcqGsJZEgJHG3uMfEKrHyJaNHfnlDCEsgUpHD6l\n\ + ITs60TTQbDAdLipygnF3MRPk0WMlx74HxbKRbJDzZc2v936KiFxqVh0CAwEAAQ==\n\ + -----END RSA PUBLIC KEY-----"; + data.DateCreated = "1/2/2034"; + data.DateLastUpdated = "4/3/2010"; + data.KeyLength = strlen(data.PublicKey); + + result = cxssUpdateUserData(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + + result = cxssRetrieveUserData(dbCon, data.CXSS_UserID, &retData); + assert(result == CXSS_DB_SUCCESS); + assert(strcmp(data.CXSS_UserID, retData.CXSS_UserID) == 0); + assert(strcmp(data.PublicKey, retData.PublicKey) == 0); + assert(strcmp(data.DateCreated, retData.DateCreated) != 0); /* the date created cannot be updted. */ + assert(strcmp(data.DateLastUpdated, retData.DateLastUpdated) == 0); + assert(data.KeyLength == retData.KeyLength); + + /** update item not in db **/ + data.CXSS_UserID = "2"; + data.PublicKey = "back to fake"; + data.DateCreated = "not a date"; + data.DateLastUpdated = "this isn't either"; + data.KeyLength = strlen(data.PublicKey); + result = cxssUpdateUserData(dbCon, &data); + assert(result == CXSS_DB_NOENT_ERROR); + + result = cxssRetrieveUserData(dbCon, data.CXSS_UserID, &noData); + assert(result == CXSS_DB_QUERY_ERROR); /* Should not have created anything new*/ + + result = cxssRetrieveUserData(dbCon, "1", &retData); + assert(result == CXSS_DB_SUCCESS); + /* these should not match */ + assert(strcmp(data.CXSS_UserID, retData.CXSS_UserID) != 0); + assert(strcmp(data.PublicKey, retData.PublicKey) != 0); + assert(strcmp(data.DateCreated, retData.DateCreated) != 0); /* the date created cannot be updated. */ + assert(strcmp(data.DateLastUpdated, retData.DateLastUpdated) != 0); + assert(data.KeyLength != retData.KeyLength); + + + /** Delete **/ + + /** delete entry **/ + result = cxssDeleteUserData(dbCon, "1"); + assert(result == CXSS_DB_SUCCESS); + + result = cxssRetrieveUserData(dbCon, "1", &noData); /* attempt to retrieve */ + assert(result == CXSS_DB_QUERY_ERROR); + + /** attempt to delete item not there **/ + result = cxssDeleteUserData(dbCon, "2"); + assert(result == CXSS_DB_NOENT_ERROR); + + cxssCredentialsDatabaseClose(dbCon); + return 0; + } diff --git a/centrallix/tests/test_cxss-credDB_02.c b/centrallix/tests/test_cxss-credDB_02.c new file mode 100644 index 000000000..a1a0589ac --- /dev/null +++ b/centrallix/tests/test_cxss-credDB_02.c @@ -0,0 +1,131 @@ +#include +#include +#include "cxss/credentials_db.h" +#include "cxss/crypto.h" + +long long +test(char** name) + { + *name = "CXSS Cred DB 02: Basic auth table tests"; + + /** Set up DB. **/ + char * PATH = "./tests/tempFiles/test.db"; + + /** Reset DB file if needed **/ + if(access(PATH, 0) == 0) + { + assert(remove(PATH) == 0); + } + assert(access(PATH, 0) != 0); + + CXSS_DB_Context_t dbCon = cxssCredentialsDatabaseInit(PATH); + assert(dbCon != NULL); + + + /*** Insert ***/ + + /** insert one entry **/ + char *pubKey, *privKey; + size_t pubLen, privLen; + char ivBuf[16]; + + /* generate valid inputs for key, iv, and their lengths */ + cxss_internal_InitEntropy(1280); + cxssCryptoInit(); + int result = cxssGenerateRSA4096bitKeypair(&privKey, &privLen, &pubKey, &pubLen); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssGenerate128bitIV(ivBuf); + assert(result == CXSS_CRYPTO_SUCCESS); + cxssCryptoCleanup(); + + CXSS_UserAuth data; + data.CXSS_UserID = "2"; + data.AuthClass = "something"; + data.PrivateKey = privKey; + data.PrivateKeyIV = ivBuf; + data.DateCreated = "03/02/2001"; + data.DateLastUpdated = "1/2/03"; + data.RemovalFlag = 0; + data.KeyLength = strlen(data.PrivateKey); + data.IVLength = 16; + + result = cxssInsertUserAuth(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + assert(data.PK_UserAuth == 1); /* should have been set by call */ + + /*** Retrieve ***/ + + /** retrieve: **/ + CXSS_UserAuth retData; + result = cxssRetrieveUserAuth(dbCon, data.PK_UserAuth, &retData); + assert(result == CXSS_DB_SUCCESS); + + assert(data.PK_UserAuth == retData.PK_UserAuth); + assert(strcmp(data.CXSS_UserID, retData.CXSS_UserID) == 0); + assert(strcmp(data.AuthClass, retData.AuthClass) == 0); + assert(memcmp(data.PrivateKey, retData.PrivateKey, data.KeyLength) == 0); + assert(memcmp(data.PrivateKeyIV, retData.PrivateKeyIV, 16) == 0); + assert(strcmp(data.DateCreated, retData.DateCreated) == 0); + assert(strcmp(data.DateLastUpdated, retData.DateLastUpdated) == 0); + assert(data.RemovalFlag == retData.RemovalFlag); + assert(data.KeyLength == retData.KeyLength); + assert(data.IVLength == retData.IVLength); + + /** retrive item not in DB **/ + CXSS_UserAuth noData; + result = cxssRetrieveUserAuth(dbCon, 2, &noData); + assert(result == CXSS_DB_QUERY_ERROR); + + + /*** Update ***/ + + /** update the entry and test results **/ + data.CXSS_UserID = "3"; + data.AuthClass = "another thing"; + privKey[0] = -privKey[0]; /* points to same mem, so this is ok */ + ivBuf[0] = -ivBuf[0]; + data.DateCreated = "02/20/2002"; + data.DateLastUpdated = "2/2/22"; + + result = cxssUpdateUserAuth(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + + /* now retrieve and check output */ + result = cxssRetrieveUserAuth(dbCon, data.PK_UserAuth, &retData); + assert(result == CXSS_DB_SUCCESS); + + assert(data.PK_UserAuth == retData.PK_UserAuth); + assert(strcmp(data.CXSS_UserID, retData.CXSS_UserID) == 0); + assert(strcmp(data.AuthClass, retData.AuthClass) == 0); + assert(memcmp(data.PrivateKey, retData.PrivateKey, data.KeyLength) == 0); + assert(memcmp(data.PrivateKeyIV, retData.PrivateKeyIV, 16) == 0); + assert(strcmp(data.DateCreated, retData.DateCreated) != 0); /* date created is never updated */ + assert(strcmp(data.DateLastUpdated, retData.DateLastUpdated) == 0); + assert(data.RemovalFlag == retData.RemovalFlag); + assert(data.KeyLength == retData.KeyLength); + assert(data.IVLength == retData.IVLength); + + /** attempt to update nonexistent entry **/ + data.PK_UserAuth = 2; + result = cxssUpdateUserAuth(dbCon, &data); + assert(result == CXSS_DB_NOENT_ERROR); + data.PK_UserAuth = 1; /* fix before next test*/ + + + /*** Delete ***/ + + /** delete the entry and confirm is gone **/ + result = cxssDeleteUserAuth(dbCon, data.PK_UserAuth); + assert(result == CXSS_DB_SUCCESS); + + result = cxssRetrieveUserAuth(dbCon, data.PK_UserAuth, &retData); + assert(result == CXSS_DB_QUERY_ERROR); + + /** confirm duplicate delete fails **/ + result = cxssDeleteUserAuth(dbCon, data.PK_UserAuth); + assert(result == CXSS_DB_NOENT_ERROR); + + cxssCredentialsDatabaseClose(dbCon); + + return 0; + } diff --git a/centrallix/tests/test_cxss-credDB_03.c b/centrallix/tests/test_cxss-credDB_03.c new file mode 100644 index 000000000..5c4ee3d62 --- /dev/null +++ b/centrallix/tests/test_cxss-credDB_03.c @@ -0,0 +1,184 @@ +#include +#include +#include "cxss/credentials_db.h" +#include "cxss/crypto.h" + +long long +test(char** name) + { + *name = "CXSS Cred DB 03: resource table basic tests "; + + /** Set up DB. **/ + char * PATH = "./tests/tempFiles/test.db"; + + /** Reset DB file if needed **/ + if(access(PATH, 0) == 0) + { + assert(remove(PATH) == 0); + } + assert(access(PATH, 0) != 0); + + CXSS_DB_Context_t dbCon = cxssCredentialsDatabaseInit(PATH); + assert(dbCon != NULL); + + + /*** Insert ***/ + + /** generate valid inputs for key, salt, iv, and their lengths **/ + char key[32]; + char uNameIV[16]; + char aDataIV[16]; + cxss_internal_InitEntropy(1280); + cxssCryptoInit(); + int result = cxssGenerate256bitRandomKey(&key); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssGenerate64bitSalt(uNameIV); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssGenerate128bitIV(aDataIV); + assert(result == CXSS_CRYPTO_SUCCESS); + cxssCryptoCleanup(); + + + /** insert one entry **/ + CXSS_UserResc data; + data.CXSS_UserID = "1"; + data.ResourceID = "1"; + data.AESKey = key; + data.UsernameIV = uNameIV; + data.AuthDataIV = aDataIV; + data.ResourceUsername = "aUsername"; + data.ResourceAuthData = "some auth data"; + data.DateCreated = "7/5/2022"; + data.DateLastUpdated = "7/4/2022"; + data.AESKeyLength = 32; + data.UsernameIVLength = 16; + data.AuthDataIVLength = 16; + data.UsernameLength = strlen(data.ResourceUsername); + data.AuthDataLength = strlen(data.ResourceAuthData); + + result = cxssInsertUserResc(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + + + /*** Retrieve ***/ + + /** retrieve: **/ + CXSS_UserResc retData; + result = cxssRetrieveUserResc(dbCon, data.CXSS_UserID, data.ResourceID, &retData); + assert(result == CXSS_DB_SUCCESS); + + assert(strcmp(data.CXSS_UserID, retData.CXSS_UserID) == 0); + assert(strcmp(data.ResourceID, retData.ResourceID) == 0); + assert(memcmp(data.AESKey, retData.AESKey, 32) == 0); + assert(memcmp(data.UsernameIV, retData.UsernameIV, 16) == 0); + assert(memcmp(data.AuthDataIV, retData.AuthDataIV, 16) == 0); + assert(strcmp(data.ResourceUsername, retData.ResourceUsername) == 0); + assert(strcmp(data.ResourceAuthData, retData.ResourceAuthData) == 0); + assert(strcmp(data.DateCreated, retData.DateCreated) == 0); + assert(strcmp(data.DateLastUpdated, retData.DateLastUpdated) == 0); + assert(data.AESKeyLength == retData.AESKeyLength); + assert(data.UsernameIVLength == retData.UsernameIVLength); + assert(data.AuthDataIVLength == retData.AuthDataIVLength); + assert(data.UsernameLength == retData.UsernameLength); + assert(data.AuthDataLength == retData.AuthDataLength); + + /** retrive item not in DB **/ + CXSS_UserResc noData; + result = cxssRetrieveUserResc(dbCon, "2", "1", &noData); + assert(result == CXSS_DB_QUERY_ERROR); + + + /*** Update ***/ + + /** update one field **/ + data.DateLastUpdated = "2/2/22"; + result = cxssUpdateUserResc(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + + result = cxssRetrieveUserResc(dbCon, data.CXSS_UserID, data.ResourceID, &retData); + assert(result == CXSS_DB_SUCCESS); + assert(strcmp(data.CXSS_UserID, retData.CXSS_UserID) == 0); + assert(strcmp(data.ResourceID, retData.ResourceID) == 0); + assert(memcmp(data.AESKey, retData.AESKey, 32) == 0); + assert(memcmp(data.UsernameIV, retData.UsernameIV, 16) == 0); + assert(memcmp(data.AuthDataIV, retData.AuthDataIV, 16) == 0); + assert(strcmp(data.ResourceUsername, retData.ResourceUsername) == 0); + assert(strcmp(data.ResourceAuthData, retData.ResourceAuthData) == 0); + assert(strcmp(data.DateCreated, retData.DateCreated) == 0); + assert(strcmp(data.DateLastUpdated, retData.DateLastUpdated) == 0); + assert(data.AESKeyLength == retData.AESKeyLength); + assert(data.UsernameIVLength == retData.UsernameIVLength); + assert(data.AuthDataIVLength == retData.AuthDataIVLength); + assert(data.UsernameLength == retData.UsernameLength); + assert(data.AuthDataLength == retData.AuthDataLength); + + /** update all fields **/ + data.CXSS_UserID = "1"; + data.ResourceID = "1"; + key[0] = -key[0]; /* just chaninging one piece is enough */ + uNameIV[0] = -uNameIV[0]; + aDataIV[0] = -aDataIV[0]; + data.ResourceUsername = "another name"; + data.ResourceAuthData = "more, different, auth data"; + data.DateCreated = "02/02/2020"; + data.DateLastUpdated = "01/02/2010"; + data.AESKeyLength = 32; + data.UsernameIVLength = 16; + data.AuthDataIVLength = 16; + data.UsernameLength = strlen(data.ResourceUsername); + data.AuthDataLength = strlen(data.ResourceAuthData); + + result = cxssUpdateUserResc(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + + result = cxssRetrieveUserResc(dbCon, data.CXSS_UserID, data.ResourceID, &retData); + assert(result == CXSS_DB_SUCCESS); + assert(strcmp(data.CXSS_UserID, retData.CXSS_UserID) == 0); + assert(strcmp(data.ResourceID, retData.ResourceID) == 0); + assert(memcmp(data.AESKey, retData.AESKey, 32) == 0); + assert(memcmp(data.UsernameIV, retData.UsernameIV, 16) == 0); + assert(memcmp(data.AuthDataIV, retData.AuthDataIV, 16) == 0); + assert(strcmp(data.ResourceUsername, retData.ResourceUsername) == 0); + assert(strcmp(data.ResourceAuthData, retData.ResourceAuthData) == 0); + assert(strcmp(data.DateCreated, retData.DateCreated) != 0); /* cannot update date created class */ + assert(strcmp(data.DateLastUpdated, retData.DateLastUpdated) == 0); + assert(data.AESKeyLength == retData.AESKeyLength); + assert(data.UsernameIVLength == retData.UsernameIVLength); + assert(data.AuthDataIVLength == retData.AuthDataIVLength); + assert(data.UsernameLength == retData.UsernameLength); + assert(data.AuthDataLength == retData.AuthDataLength); + + /** update item not in db **/ + data.CXSS_UserID = "2"; + data.DateLastUpdated = "notADate"; + result = cxssUpdateUserResc(dbCon, &data); + assert(result == CXSS_DB_NOENT_ERROR); + + result = cxssRetrieveUserResc(dbCon, data.CXSS_UserID, data.ResourceID, &noData); + assert(result == CXSS_DB_QUERY_ERROR); /* Should not have created anything new */ + + result = cxssRetrieveUserResc(dbCon, "1", data.ResourceID, &retData); + assert(result == CXSS_DB_SUCCESS); + + /* these should not match */ + assert(strcmp(data.CXSS_UserID, retData.CXSS_UserID) != 0); + assert(strcmp(data.DateLastUpdated, retData.DateLastUpdated) != 0); + data.CXSS_UserID = "1"; + + /** Delete **/ + + /** delete entry **/ + result = cxssDeleteUserResc(dbCon, data.CXSS_UserID, data.ResourceID); + assert(result == CXSS_DB_SUCCESS); + + result = cxssRetrieveUserResc(dbCon, data.CXSS_UserID, data.ResourceID, &noData); /* attempt to retrieve */ + assert(result == CXSS_DB_QUERY_ERROR); + + /** attempt to delete item not there **/ + result = cxssDeleteUserResc(dbCon, data.CXSS_UserID, data.ResourceID); + assert(result == CXSS_DB_NOENT_ERROR); + + + cxssCredentialsDatabaseClose(dbCon); + return 0; + } diff --git a/centrallix/tests/test_cxss-credDB_04.c b/centrallix/tests/test_cxss-credDB_04.c new file mode 100644 index 000000000..b7c2960e8 --- /dev/null +++ b/centrallix/tests/test_cxss-credDB_04.c @@ -0,0 +1,111 @@ +#include +#include +#include "cxss/credentials_db.h" +#include "cxss/crypto.h" + +long long +test(char** name) + { + *name = "CXSS Cred DB 04: Delete All Auth"; + + int n = 100; + + /** Set up DB. **/ + char * PATH = "./tests/tempFiles/test.db"; + /* Reset DB file if needed */ + if(access(PATH, 0) == 0) + { + assert(remove(PATH) == 0); + } + assert(access(PATH, 0) != 0); + CXSS_DB_Context_t dbCon = cxssCredentialsDatabaseInit(PATH); + assert(dbCon != NULL); + + /* generate valid inputs for key, iv, and their lengths */ + char *pubKey, *privKey; + size_t pubLen, privLen; + char ivBuf[16]; + + cxss_internal_InitEntropy(1280); + cxssCryptoInit(); + int result = cxssGenerateRSA4096bitKeypair(&privKey, &privLen, &pubKey, &pubLen); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssGenerate128bitIV(ivBuf); + assert(result == CXSS_CRYPTO_SUCCESS); + cxssCryptoCleanup(); + + CXSS_UserAuth data, temp; + data.PK_UserAuth = 1; + data.CXSS_UserID = "1"; + data.AuthClass = "something"; + data.PrivateKey = privKey; + data.PrivateKeyIV = ivBuf; + data.DateCreated = "03/02/2001"; + data.DateLastUpdated = "1/2/03"; + data.RemovalFlag = 0; + data.KeyLength = strlen(data.PrivateKey); + data.IVLength = 16; + + for(int i = 0 ; i < n ; i++) + { + result = cxssInsertUserAuth(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + } + + /* delete all and confirm all were deleted */ + result = cxssDeleteAllUserAuth(dbCon, "1", NULL); + assert(result == CXSS_DB_SUCCESS); + + for(int i = 0 ; i < n ; i++) + { + result = cxssRetrieveUserAuth(dbCon, i, &temp); + assert(result == CXSS_DB_QUERY_ERROR); + } + /* test deleting nothing */ + result = cxssDeleteAllUserAuth(dbCon, "1", NULL); + assert(result == CXSS_DB_NOENT_ERROR); + + /** Delete by user **/ + for(int i = 0 ; i < n ; i++) + { + data.CXSS_UserID = (i < n/2)? "1":"2"; + result = cxssInsertUserAuth(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + } + + /* delete all from user and confirm */ + result = cxssDeleteAllUserAuth(dbCon, "1", NULL); + assert(result == CXSS_DB_SUCCESS); + + for(int i = 0 ; i < n ; i++) + { + result = cxssRetrieveUserAuth(dbCon, i+1, &temp); + assert(result == ((i < n/2)? CXSS_DB_QUERY_ERROR : CXSS_DB_SUCCESS)); + } + /* test deleting nothing */ + result = cxssDeleteAllUserAuth(dbCon, "1", NULL); + assert(result == CXSS_DB_NOENT_ERROR); + + /** test delete by user and auth class **/ + for(int i = 0 ; i < n ; i++) + { + /* split users into 4 groups */ + data.CXSS_UserID = (i < n/2)? "1":"2"; + data.AuthClass = (i < n/4 || i > n*3/4)? "1":"2"; + result = cxssInsertUserAuth(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + } + result = cxssDeleteAllUserAuth(dbCon, "1", "1"); /* deletes first 4th */ + assert(result == CXSS_DB_SUCCESS); + for(int i = 0 ; i < n ; i++) + { + result = cxssRetrieveUserAuth(dbCon, i+n+1, &temp); + assert(result == ((i < n/4)? CXSS_DB_QUERY_ERROR : CXSS_DB_SUCCESS)); + } + /* test deleting nothing */ + result = cxssDeleteAllUserAuth(dbCon, "1", "1"); + assert(result == CXSS_DB_NOENT_ERROR); + + cxssCredentialsDatabaseClose(dbCon); + return 0; + } diff --git a/centrallix/tests/test_cxss-credDB_05.c b/centrallix/tests/test_cxss-credDB_05.c new file mode 100644 index 000000000..14e3ce2c0 --- /dev/null +++ b/centrallix/tests/test_cxss-credDB_05.c @@ -0,0 +1,187 @@ +#include +#include +#include "cxss/credentials_db.h" +#include "cxss/crypto.h" + +long long +test(char** name) + { + *name = "CXSS Cred DB 05: Retrieve All Auth"; + + int n = 100; + + /** Set up DB. **/ + char * PATH = "./tests/tempFiles/test.db"; + /* Reset DB file if needed */ + if(access(PATH, 0) == 0) + { + assert(remove(PATH) == 0); + } + assert(access(PATH, 0) != 0); + CXSS_DB_Context_t dbCon = cxssCredentialsDatabaseInit(PATH); + assert(dbCon != NULL); + + /* generate valid inputs for key, iv, and their lengths */ + char *pubKey, *privKey; + size_t pubLen, privLen; + char ivBuf[16]; + + cxss_internal_InitEntropy(1280); + cxssCryptoInit(); + int result = cxssGenerateRSA4096bitKeypair(&privKey, &privLen, &pubKey, &pubLen); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssGenerate128bitIV(ivBuf); + assert(result == CXSS_CRYPTO_SUCCESS); + cxssCryptoCleanup(); + + char class[16], create[16], update[16], test[16]; + CXSS_UserAuth data, temp; + data.CXSS_UserID = "1"; + data.AuthClass = class; + data.PrivateKey = privKey; + data.PrivateKeyIV = ivBuf; + data.DateCreated = create; + data.DateLastUpdated = update; + data.RemovalFlag = 0; + data.KeyLength = strlen(data.PrivateKey); + data.IVLength = 16; + + for(int i = 0 ; i < n ; i++) + { + /* provide unique, repeatable values */ + sprintf(class, "something%d",i); + sprintf(create, "1/%d/2022",i); + sprintf(update, "1/2/20%d",i); + + result = cxssInsertUserAuth(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + assert(data.PK_UserAuth == i+1); + } + + CXSS_UserAuth_LLNode *head, *cur; + result = cxssRetrieveUserAuthLL(dbCon, "1", NULL, &head); + assert(result == CXSS_DB_SUCCESS); + cur = head->next; /* get past sentinel */ + + /* iterate through nodes and check results */ + int count = 0; + while(cur != NULL) + { + /* generate old values again */ + sprintf(class, "something%d", count); + sprintf(create, "1/%d/2022", count); + sprintf(update, "1/2/20%d", count); + + assert(count+1 == cur->UserAuth.PK_UserAuth); + assert(strcmp(data.CXSS_UserID, cur->UserAuth.CXSS_UserID) == 0); + assert(strcmp(class, cur->UserAuth.AuthClass) == 0); + assert(memcmp(data.PrivateKey, cur->UserAuth.PrivateKey, data.KeyLength) == 0); + assert(memcmp(data.PrivateKeyIV, cur->UserAuth.PrivateKeyIV, data.IVLength) == 0); + assert(strcmp(create, cur->UserAuth.DateCreated) == 0); + assert(strcmp(update, cur->UserAuth.DateLastUpdated) == 0); + assert(data.RemovalFlag == cur->UserAuth.RemovalFlag); + assert(data.KeyLength == cur->UserAuth.KeyLength); + assert(data.IVLength == cur->UserAuth.IVLength); + count++; + cur = cur->next; + } + assert(count == n); + /* clean up */ + cxssFreeUserAuthLL(head); + + /** test with user id **/ + data.CXSS_UserID = "2"; + for(int i = n ; i < 2*n ; i++) + { + sprintf(class, "something%d", i); + sprintf(create, "1/%d/2022", i); + sprintf(update, "1/2/20%d", i); + + result = cxssInsertUserAuth(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + assert(data.PK_UserAuth == i+1); + } + + result = cxssRetrieveUserAuthLL(dbCon, "2", NULL, &head); + assert(result == CXSS_DB_SUCCESS); + cur = head->next; /* get past sentinel */ + + /* iterate through nodes and check results */ + count = n; + while(cur != NULL) + { + sprintf(class, "something%d", count); + sprintf(create, "1/%d/2022", count); + sprintf(update, "1/2/20%d", count); + + assert(count+1 == cur->UserAuth.PK_UserAuth); + assert(strcmp(data.CXSS_UserID, cur->UserAuth.CXSS_UserID) == 0); + assert(strcmp(class, cur->UserAuth.AuthClass) == 0); + assert(memcmp(data.PrivateKey, cur->UserAuth.PrivateKey, data.KeyLength) == 0); + assert(memcmp(data.PrivateKeyIV, cur->UserAuth.PrivateKeyIV, data.IVLength) == 0); + assert(strcmp(create, cur->UserAuth.DateCreated) == 0); + assert(strcmp(update, cur->UserAuth.DateLastUpdated) == 0); + assert(data.RemovalFlag == cur->UserAuth.RemovalFlag); + assert(data.KeyLength == cur->UserAuth.KeyLength); + assert(data.IVLength == cur->UserAuth.IVLength); + count++; + cur = cur->next; + } + assert(count == 2*n); + /* clean up */ + cxssFreeUserAuthLL(head); + + /** test with user id and class **/ + data.CXSS_UserID = "2"; + data.AuthClass = "something else"; + for(int i = 2*n ; i < 3*n ; i++) + { + sprintf(create, "1/%d/2022", i); + sprintf(update, "1/2/20%d", i); + + result = cxssInsertUserAuth(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + assert(data.PK_UserAuth == i+1); + } + + result = cxssRetrieveUserAuthLL(dbCon, "2", "something else", &head); + assert(result == CXSS_DB_SUCCESS); + cur = head->next; /* get past sentinel */ + + /* iterate through nodes and check results */ + count = 2*n; + while(cur != NULL) + { + sprintf(create, "1/%d/2022", count); + sprintf(update, "1/2/20%d", count); + + assert(count+1 == cur->UserAuth.PK_UserAuth); + assert(strcmp(data.CXSS_UserID, cur->UserAuth.CXSS_UserID) == 0); + assert(strcmp(data.AuthClass, cur->UserAuth.AuthClass) == 0); + assert(memcmp(data.PrivateKey, cur->UserAuth.PrivateKey, data.KeyLength) == 0); + assert(memcmp(data.PrivateKeyIV, cur->UserAuth.PrivateKeyIV, data.IVLength) == 0); + assert(strcmp(create, cur->UserAuth.DateCreated) == 0); + assert(strcmp(update, cur->UserAuth.DateLastUpdated) == 0); + assert(data.RemovalFlag == cur->UserAuth.RemovalFlag); + assert(data.KeyLength == cur->UserAuth.KeyLength); + assert(data.IVLength == cur->UserAuth.IVLength); + count++; + cur = cur->next; + } + assert(count == 3*n); + /* clean up */ + cxssFreeUserAuthLL(head); + + /** test sets with no results **/ + result = cxssRetrieveUserAuthLL(dbCon, "3", NULL, &head); + assert(result == CXSS_DB_QUERY_ERROR); + + result = cxssRetrieveUserAuthLL(dbCon, "1", "nothing", &head); + assert(result == CXSS_DB_QUERY_ERROR); + + result = cxssRetrieveUserAuthLL(dbCon, "2", "something", &head); + assert(result == CXSS_DB_QUERY_ERROR); + + cxssCredentialsDatabaseClose(dbCon); + return 0; + } diff --git a/centrallix/tests/test_cxss-credDB_06.c b/centrallix/tests/test_cxss-credDB_06.c new file mode 100644 index 000000000..e4e6a441c --- /dev/null +++ b/centrallix/tests/test_cxss-credDB_06.c @@ -0,0 +1,112 @@ +#include +#include +#include +#include +#include "cxss/credentials_db.h" +#include "cxss/crypto.h" + +long long +test(char** name) + { + *name = "CXSS Cred DB 06: Delete All Resc"; + + int n = 100; /* WARNING: if set to higher than 255, things will break */ + + /** Set up DB. **/ + char * PATH = "./tests/tempFiles/test.db"; + /* Reset DB file if needed */ + if(access(PATH, 0) == 0) + { + assert(remove(PATH) == 0); + } + assert(access(PATH, 0) != 0); + CXSS_DB_Context_t dbCon = cxssCredentialsDatabaseInit(PATH); + assert(dbCon != NULL); + + + /* generate valid inputs for key, salt, iv, and their lengths */ + char resc[2]; + resc[1] = '\0'; + char key[32]; + char uNameIV[16]; + char aDataIV[16]; + cxss_internal_InitEntropy(1280); + cxssCryptoInit(); + int result = cxssGenerate256bitRandomKey(&key); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssGenerate64bitSalt(uNameIV); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssGenerate128bitIV(aDataIV); + assert(result == CXSS_CRYPTO_SUCCESS); + cxssCryptoCleanup(); + + + /** insert n entries **/ + CXSS_UserResc data, temp; + data.CXSS_UserID = "1"; + data.ResourceID = resc; + data.AESKey = key; + data.UsernameIV = uNameIV; + data.AuthDataIV = aDataIV; + data.ResourceUsername = "aUsername"; + data.ResourceAuthData = "some auth data"; + data.DateCreated = "7/5/2022"; + data.DateLastUpdated = "7/4/2022"; + data.AESKeyLength = 32; + data.UsernameIVLength = 16; + data.AuthDataIVLength = 16; + data.UsernameLength = strlen(data.ResourceUsername); + data.AuthDataLength = strlen(data.ResourceAuthData); + + assert(result == CXSS_DB_SUCCESS); + for(int i = 0 ; i < n ; i++) + { + resc[0] = (char) i; + result = cxssInsertUserResc(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + } + /* test deleting nothing */ + result = cxssDeleteAllUserResc(dbCon, "2"); + assert(result == CXSS_DB_NOENT_ERROR); + + /* delete all and confirm all were deleted */ + result = cxssDeleteAllUserResc(dbCon, "1"); + assert(result == CXSS_DB_SUCCESS); + + for(int i = 0 ; i < n ; i++) + { + resc[0] = (char) i; + result = cxssRetrieveUserResc(dbCon, "1", resc, &temp); + assert(result == CXSS_DB_QUERY_ERROR); + } + /* test deleting nothing */ + result = cxssDeleteAllUserResc(dbCon, "1"); + assert(result == CXSS_DB_NOENT_ERROR); + + /** Delete by user **/ + for(int i = 0 ; i < n ; i++) + { + resc[0] = (char) i; + data.CXSS_UserID = (i < n/2)? "1":"2"; + result = cxssInsertUserResc(dbCon, &data); + assert(result == CXSS_DB_SUCCESS); + } + + /* delete all from user and confirm */ + result = cxssDeleteAllUserResc(dbCon, "1"); + assert(result == CXSS_DB_SUCCESS); + + for(int i = 0 ; i < n ; i++) + { + char* id = (i < n/2)? "1":"2"; + resc[0] = (char) i; + result = cxssRetrieveUserResc(dbCon, id, resc, &temp); + assert(result == ((i < n/2)? CXSS_DB_QUERY_ERROR : CXSS_DB_SUCCESS)); + } + /* test deleting nothing */ + result = cxssDeleteAllUserResc(dbCon, "1"); + assert(result == CXSS_DB_NOENT_ERROR); + + cxssCredentialsDatabaseClose(dbCon); + return 0; + } diff --git a/centrallix/tests/test_cxss-crypto_00.c b/centrallix/tests/test_cxss-crypto_00.c new file mode 100644 index 000000000..f15344f0f --- /dev/null +++ b/centrallix/tests/test_cxss-crypto_00.c @@ -0,0 +1,16 @@ +#include +#include +#include "cxss/crypto.h" + +long long +test(char** name) + { + *name = "CXSS Crypto 00: Basic Init"; + + /** Basic test of init and release */ + cxss_internal_InitEntropy(1280); + cxssCryptoInit(); + cxssCryptoCleanup(); + + return 0; + } diff --git a/centrallix/tests/test_cxss-crypto_01.c b/centrallix/tests/test_cxss-crypto_01.c new file mode 100644 index 000000000..6b5ea9a23 --- /dev/null +++ b/centrallix/tests/test_cxss-crypto_01.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include "cxss/crypto.h" + +long long +test(char** name) + { + *name = "CXSS Crypto 01: Gen IV randomness"; + + + const int n = 10000; + const int b = 16; + unsigned char ivs [n][b]; + unsigned char bytes [n*b]; + int freq [256]; + + /** init byte freq **/ + for(int i = 0 ; i < 256 ; i++) + { + freq[i] = 0; + } + + /** Setup **/ + cxss_internal_InitEntropy(1280); /* must be into first */ + cxssCryptoInit(); + + /** get n values **/ + for(int i = 0 ; i < n ; i++) + { + int result = cxssGenerate128bitIV(&ivs[i][0]); + assert(result == CXSS_CRYPTO_SUCCESS); + + /** update byte freq and store bytes **/ + for(int j = 0 ; j < b ; j++) + { + bytes[i*b + j] = ivs[i][j]; + freq[ivs[i][j]]++; + } + + + /** Test for duplicates**/ + for(int j = 0 ; j < i ; j++) + { + int isMatch = 1; + for(int k = 0 ; k < b ; k++) + { + isMatch &= ivs[i][k] == ivs[j][k]; + } + assert(!isMatch); + } + } + + /** Calculate standard dev for frequency **/ + double mean = ((double) (n*b))/256.0; + long double avgDev = 0; + for(int i = 0 ; i < 256 ; i++) + { + long double cur = (freq[i] - mean)*(freq[i] - mean); + avgDev += cur; + } + avgDev /= 256; + double stdDev = sqrt(avgDev); + + printf("Mean : %f\n", mean); + printf("Std Dev : %f\n", stdDev); + printf("Dev/Mean: %f%%\n", stdDev/mean*100); + + /** Make sure standard Deviation is good **/ + assert(stdDev/mean <= 0.1); + + + cxssCryptoCleanup(); + + return 0; + } diff --git a/centrallix/tests/test_cxss-crypto_02.c b/centrallix/tests/test_cxss-crypto_02.c new file mode 100644 index 000000000..10b0f246a --- /dev/null +++ b/centrallix/tests/test_cxss-crypto_02.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include "cxss/crypto.h" + +long long +test(char** name) + { + *name = "CXSS Crypto 02: Gen salt randomness"; + + + const int n = 10000; + const int b = 8; + unsigned char salts [n][b]; + unsigned char bytes [n*b]; + int freq [256]; + + /** init byte freq **/ + for(int i = 0 ; i < 256 ; i++) + { + freq[i] = 0; + } + + /** Setup **/ + cxss_internal_InitEntropy(1280); /* must be into first */ + cxssCryptoInit(); + + /** get n values **/ + for(int i = 0 ; i < n ; i++) + { + int result = cxssGenerate64bitSalt(salts[i]); + assert(result == CXSS_CRYPTO_SUCCESS); + + /** update byte freq and store bytes **/ + for(int j = 0 ; j < b ; j++) + { + bytes[i*b + j] = salts[i][j]; + freq[salts[i][j]]++; + } + + + /** Test for duplicates**/ + for(int j = 0 ; j < i ; j++) + { + int isMatch = 1; + for(int k = 0 ; k < b ; k++) + { + isMatch &= salts[i][k] == salts[j][k]; + } + assert(!isMatch); + } + } + + /** Calculate standard dev for frequency **/ + double mean = ((double) (n*b))/256.0; + long double avgDev = 0; + for(int i = 0 ; i < 256 ; i++) + { + long double cur = (freq[i] - mean)*(freq[i] - mean); + avgDev += cur; + } + avgDev /= 256; + double stdDev = sqrt(avgDev); + + printf("Mean : %f\n", mean); + printf("Std Dev : %f\n", stdDev); + printf("Dev/mean: %f%%\n", stdDev/mean*100); + + /** Make sure standard Deviation is good **/ + assert(stdDev/mean <= 0.1); + + + cxssCryptoCleanup(); + + return 0; + } diff --git a/centrallix/tests/test_cxss-crypto_03.c b/centrallix/tests/test_cxss-crypto_03.c new file mode 100644 index 000000000..837448200 --- /dev/null +++ b/centrallix/tests/test_cxss-crypto_03.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include "cxss/crypto.h" + +long long +test(char** name) + { + *name = "CXSS Crypto 03: Gen random key randomness"; + + + const int n = 5000; + const int b = 32; + unsigned char keys [n][b]; + unsigned char bytes [n*b]; + int freq [256]; + + /** init byte freq **/ + for(int i = 0 ; i < 256 ; i++) + { + freq[i] = 0; + } + + /** Setup **/ + cxss_internal_InitEntropy(1280); /* must be into first */ + cxssCryptoInit(); + + /** get n values **/ + for(int i = 0 ; i < n ; i++) + { + int result = cxssGenerate256bitRandomKey(&keys[i][0]); + assert(result == CXSS_CRYPTO_SUCCESS); + + /** update byte freq and store bytes **/ + for(int j = 0 ; j < b ; j++) + { + bytes[i*b + j] = keys[i][j]; + freq[keys[i][j]]++; + } + + + /** Test for duplicates**/ + for(int j = 0 ; j < i ; j++) + { + int isMatch = 1; + for(int k = 0 ; k < b ; k++) + { + isMatch &= keys[i][k] == keys[j][k]; + } + assert(!isMatch); + } + } + + /** Calculate standard dev for frequency **/ + double mean = ((double) (n*b))/256.0; + long double avgDev = 0; + for(int i = 0 ; i < 256 ; i++) + { + long double cur = (freq[i] - mean)*(freq[i] - mean); + avgDev += cur; + } + avgDev /= 256; + double stdDev = sqrt(avgDev); + + printf("Mean : %f\n", mean); + printf("Std Dev : %f\n", stdDev); + printf("Dev/mean: %f%%\n", stdDev/mean*100); + + /** Make sure standard Deviation is good **/ + assert(stdDev/mean <= 0.1); + + + cxssCryptoCleanup(); + + return 0; + } diff --git a/centrallix/tests/test_cxss-crypto_04.c b/centrallix/tests/test_cxss-crypto_04.c new file mode 100644 index 000000000..acde55a53 --- /dev/null +++ b/centrallix/tests/test_cxss-crypto_04.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include "cxss/crypto.h" + +long long +test(char** name) + { + *name = "CXSS Crypto 04: RSA Key Generation"; + + int pubSize1 = 0; + int priSize1 = 0; + char* pubKey1 = NULL; + char* priKey1 = NULL; + int pubSize2 = 0; + int priSize2 = 0; + char* pubKey2 = NULL; + char* priKey2 = NULL; + + + /** Setup **/ + cxss_internal_InitEntropy(1280); /* must be into first */ + cxssCryptoInit(); + + int result = cxssGenerateRSA4096bitKeypair(&priKey1, &priSize1, &pubKey1, &pubSize1); + assert(result == CXSS_CRYPTO_SUCCESS); + + assert(pubSize1 > 0); + assert(priSize1 > 0); + assert(pubKey1 != 0); + assert(priKey1 != 0); + + result = cxssGenerateRSA4096bitKeypair(&priKey2, &priSize2, &pubKey2, &pubSize2); + assert(result == CXSS_CRYPTO_SUCCESS); + + assert(pubSize2 > 0); + assert(priSize2 > 0); + assert(pubKey2 != 0); + assert(priKey2 != 0); + + /** make sure keys are not the same **/ + int minLen = (pubSize1 < pubSize2)? pubSize1 : pubSize2; + int isMatch = 1; + for(int i = 0 ; i < minLen ; i++) + { + isMatch &= pubKey1[i] == pubKey2[i]; + } + assert(!isMatch); + + /** now check private key **/ + minLen = (priSize1 < priSize2)? priSize1 : priSize2; + isMatch = 1; + for(int i = 0 ; i < minLen ; i++) + { + isMatch &= priKey1[i] == priKey2[i]; + } + assert(!isMatch); + + /** check for header text **/ + assert(strstr(pubKey1, "BEGIN RSA PUBLIC KEY") > 0); + assert(strstr(pubKey2, "BEGIN RSA PUBLIC KEY") > 0); + assert(strstr(priKey1, "BEGIN RSA PRIVATE KEY") > 0); + assert(strstr(priKey2, "BEGIN RSA PRIVATE KEY") > 0); + + /** now footer **/ + assert(strstr(pubKey1, "END RSA PUBLIC KEY") > 0); + assert(strstr(pubKey2, "END RSA PUBLIC KEY") > 0); + assert(strstr(priKey1, "END RSA PRIVATE KEY") > 0); + assert(strstr(priKey2, "END RSA PRIVATE KEY") > 0); + + cxssCryptoCleanup(); + + return 0; + } diff --git a/centrallix/tests/test_cxss-crypto_05.c b/centrallix/tests/test_cxss-crypto_05.c new file mode 100644 index 000000000..4e299b242 --- /dev/null +++ b/centrallix/tests/test_cxss-crypto_05.c @@ -0,0 +1,109 @@ +#include +#include +#include +#include "cxss/crypto.h" + + +long long +test(char** name) + { + *name = "CXSS Crypto 05: RSA Encyrpt and Decrypt"; + + char * short1 = "a quick test"; + char * short2 = "a diff test."; + char * data = "For God so loved the world that he gave his only begoten son, that whoever belives in him shall not perish but have everlasting life"; + + /** Setup **/ + cxss_internal_InitEntropy(1280); /* must be into first */ + cxssCryptoInit(); + + /** Generate keys for use **/ + int pubSize1 = 0; + int privSize1 = 0; + char* pubKey1 = NULL; + char* privKey1 = NULL; + + int result = cxssGenerateRSA4096bitKeypair(&privKey1, &privSize1, &pubKey1, &pubSize1); + assert(result == CXSS_CRYPTO_SUCCESS); + + int pubSize2 = 0; + int privSize2 = 0; + char* pubKey2 = NULL; + char* privKey2 = NULL; + + result = cxssGenerateRSA4096bitKeypair(&privKey2, &privSize2, &pubKey2, &pubSize2); + assert(result == CXSS_CRYPTO_SUCCESS); + + /** Test encryption for key 1**/ + size_t dataLen = strlen(data); + int cipherLen = 4096; + char ciphertext[4096]; + + result = cxssEncryptRSA(data, dataLen, pubKey1, pubSize1, ciphertext, &cipherLen); + assert(result == CXSS_CRYPTO_SUCCESS); + assert(ciphertext != NULL); + assert(cipherLen > 0); + assert(memcmp(data, ciphertext, strlen(data)) != 0); + + /** test decryption for key 1 **/ + char plaintext[4096]; + int plainLen = 0; + + result = cxssDecryptRSA(ciphertext, cipherLen, privKey1, privSize1, plaintext, &plainLen); + assert(result == CXSS_CRYPTO_SUCCESS); + assert(plaintext != NULL); + assert(plainLen > 0); + assert(strcmp(data, plaintext) == 0); + + /** make sure different messages with same key are not the same **/ + int cipherLen2 = 4096; + char ciphertext2[4096]; + bzero(ciphertext, 4096); + bzero(ciphertext2, 4096); + + result = cxssEncryptRSA(short1, strlen(short1), pubKey1, pubSize1, ciphertext, &cipherLen); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssEncryptRSA(short2, strlen(short2), pubKey1, pubSize1, ciphertext2, &cipherLen2); + assert(result == CXSS_CRYPTO_SUCCESS); + assert(memcmp(ciphertext, ciphertext2, 4096) != 0); + + /** make sure same data and same key do not match (padding) but decrypt correctly **/ + bzero(ciphertext, 4096); + bzero(ciphertext2, 4096); + result = cxssEncryptRSA(short1, strlen(short1)+1, pubKey1, pubSize1, ciphertext, &cipherLen); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssEncryptRSA(short1, strlen(short1)+1, pubKey1, pubSize1, ciphertext2, &cipherLen2); + assert(result == CXSS_CRYPTO_SUCCESS); + assert(memcmp(ciphertext, ciphertext2, 4096) != 0); + + int plainLen2 = 4096; + char plaintext2[4096]; + + result = cxssDecryptRSA(ciphertext, cipherLen, privKey1, privSize1, plaintext, &plainLen); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssDecryptRSA(ciphertext2, cipherLen2, privKey1, privSize1, plaintext2, &plainLen2); + assert(result == CXSS_CRYPTO_SUCCESS); + assert(strcmp(plaintext, plaintext2) == 0); + + + /** make sure same data and different key are not the same, but match on decrypt **/ + bzero(ciphertext, 4096); + bzero(ciphertext2, 4096); + result = cxssEncryptRSA(short1, strlen(short1)+1, pubKey1, pubSize1, ciphertext, &cipherLen); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssEncryptRSA(short1, strlen(short1)+1, pubKey2, pubSize2, ciphertext2, &cipherLen2);; + assert(result == CXSS_CRYPTO_SUCCESS); + assert(memcmp(ciphertext, ciphertext2, 4096) != 0); + + result = cxssDecryptRSA(ciphertext, cipherLen, privKey1, privSize1, plaintext, &plainLen); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssDecryptRSA(ciphertext2, cipherLen2, privKey2, privSize2, plaintext2, &plainLen2); + assert(result == CXSS_CRYPTO_SUCCESS); + assert(strcmp(plaintext, plaintext2) == 0); + assert(strcmp(plaintext, short1) == 0); + + + cxssCryptoCleanup(); + + return 0; + } diff --git a/centrallix/tests/test_cxss-crypto_06.c b/centrallix/tests/test_cxss-crypto_06.c new file mode 100644 index 000000000..9b2b33d5d --- /dev/null +++ b/centrallix/tests/test_cxss-crypto_06.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include "cxss/crypto.h" + + +long long +test(char** name) + { + *name = "CXSS Crypto 06: AES Encyrpt and Decrypt"; + + char * short1 = "a quick test"; + char * short2 = "a diff test."; + char * data = "For God so loved the world that he gave his only begotten son, that whoever belives in him shall not perish but have everlasting life"; + + /** Setup **/ + cxss_internal_InitEntropy(1280); + cxssCryptoInit(); + + /** test encrypt changes data **/ + char key1 [32]; + char iv1 [16]; + char* ciphertext1 = NULL; + int cipherLen1 = 0; + + int result = cxssGenerate256bitRandomKey(&key1); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssGenerate128bitIV(&iv1); + assert(result == CXSS_CRYPTO_SUCCESS); + + result = cxssEncryptAES256(data, strlen(data)+1, key1, iv1, &ciphertext1, &cipherLen1); + assert(result == CXSS_CRYPTO_SUCCESS); + assert(memcmp(data, ciphertext1, strlen(data)) != 0); + + /** test decrpty restores data **/ + char* plaintext1 = NULL; + int plainLen1 = 0; + + result = cxssDecryptAES256(ciphertext1, cipherLen1, key1, iv1, &plaintext1, &plainLen1); + assert(result == CXSS_CRYPTO_SUCCESS); + assert(strcmp(data, plaintext1) == 0); + assert(cxssAES256CiphertextLength(plainLen1) == cipherLen1); /* check length prediction */ + + /** make sure same key, iv, and text comes out the same **/ + char* ciphertext2 = NULL; + int cipherLen2 = 0; + + result = cxssEncryptAES256(data, strlen(data)+1, key1, iv1, &ciphertext2, &cipherLen2); + assert(result == CXSS_CRYPTO_SUCCESS); + int len = cxssAES256CiphertextLength(strlen(data)); + assert(memcmp(ciphertext2, ciphertext1, len) == 0); + assert(cipherLen1 == cipherLen2); + + /** make sure same key, iv with idfferent text is different. **/ + result = cxssEncryptAES256(short1, strlen(short1)+1, key1, iv1, &ciphertext1, &cipherLen1); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssEncryptAES256(short2, strlen(short2)+1, key1, iv1, &ciphertext2, &cipherLen2); + assert(result == CXSS_CRYPTO_SUCCESS); + len = cxssAES256CiphertextLength(strlen(short1)); + assert(memcmp(ciphertext2, ciphertext1, len) != 0); + + /** make sure changing the IV changes it **/ + char iv2 [16]; + result = cxssGenerate128bitIV(&iv2); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssEncryptAES256(short1, strlen(short1)+1, key1, iv2, &ciphertext2, &cipherLen2); + assert(result == CXSS_CRYPTO_SUCCESS); + len = cxssAES256CiphertextLength(strlen(short1)); + assert(memcmp(ciphertext2, ciphertext1, len) != 0); + + /** make sure key changes it **/ + char key2 [32]; + result = cxssGenerate256bitRandomKey(&key2); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssEncryptAES256(short1, strlen(short1)+1, key2, iv1, &ciphertext2, &cipherLen2); + assert(result == CXSS_CRYPTO_SUCCESS); + len = cxssAES256CiphertextLength(strlen(short1)); + assert(memcmp(ciphertext2, ciphertext1, len) != 0); + + cxssCryptoCleanup(); + + return 0; + } diff --git a/centrallix/tests/test_cxss-crypto_07.c b/centrallix/tests/test_cxss-crypto_07.c new file mode 100644 index 000000000..d5a676968 --- /dev/null +++ b/centrallix/tests/test_cxss-crypto_07.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include "cxss/crypto.h" + +long long +test(char** name) + { + *name = "CXSS Crypto 07: RSA Key Destruction"; + + int pubSize = 0; + int priSize = 0; + char* pubKey = NULL; + char* priKey = NULL; + + + /** Setup **/ + cxss_internal_InitEntropy(1280); /* must be into first */ + cxssCryptoInit(); + + int result = cxssGenerateRSA4096bitKeypair(&priKey, &priSize, &pubKey, &pubSize); + assert(result == CXSS_CRYPTO_SUCCESS); + + + /** Make sure it is able to destroy the public key **/ + char* backup; + backup = nmSysMalloc(pubSize); + strcpy(backup, pubKey); + + cxssDestroyKey(pubKey, pubSize); + int match = 0; + for(int i = 0 ; i < pubSize ; i++) + { + if(pubKey[i] == backup[i]) match++; + } + /** Data is deallocated so may have new data in it. Assert no more than twice the + ** number of matches expected from random chance + **/ + assert(match < (((pubSize/256)+1))*2); + nmFree(backup, pubSize); + + /** now test on private key **/ + backup = nmSysMalloc(priSize); + strcpy(backup, priKey); + + cxssDestroyKey(priKey, priSize); + match = 0; + for(int i = 0 ; i < priSize ; i++) + { + if(priKey[i] == backup[i]) match++; + } + + assert(match < (((priSize/256)+1))*2); + nmFree(backup, priSize); + + cxssCryptoCleanup(); + + return 0; + } diff --git a/centrallix/tests/test_cxss-crypto_08.c b/centrallix/tests/test_cxss-crypto_08.c new file mode 100644 index 000000000..c29cd71ff --- /dev/null +++ b/centrallix/tests/test_cxss-crypto_08.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include "cxss/crypto.h" + +long long +test(char** name) + { + /** Setup **/ + cxss_internal_InitEntropy(1280); /* must be into first */ + cxssCryptoInit(); + + *name = "CXSS Crypto 08: Gen key from password"; + + char key1[32]; + char key2[32]; + unsigned char salt1[12]; + unsigned char salt2[8]; + char * test = salt1; + + int result = cxssGenerate64bitSalt(test); + assert(result == CXSS_CRYPTO_SUCCESS); + + /** check consistency **/ + result = cxssGenerate256bitPasswordBasedKey("password", salt1, key1); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssGenerate256bitPasswordBasedKey("password", salt1, key2); + assert(result == CXSS_CRYPTO_SUCCESS); + + for(int i = 0 ; i < 32 ; i++) + { + assert(key1[i] == key2[i]); + } + + /** check that salts change result **/ + result = cxssGenerate64bitSalt(salt2); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssGenerate256bitPasswordBasedKey("password", salt1, key1); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssGenerate256bitPasswordBasedKey("password", salt2, key2); + assert(result == CXSS_CRYPTO_SUCCESS); + + int isMatch = 1; + for(int i = 0 ; i < 32 ; i++) + { + isMatch &= (key1[i] == key2[i]); + } + assert(!isMatch); + + /** check that passfrase matters **/ + result = cxssGenerate256bitPasswordBasedKey("password", salt1, key1); + assert(result == CXSS_CRYPTO_SUCCESS); + result = cxssGenerate256bitPasswordBasedKey("newFraze", salt1, key2); + assert(result == CXSS_CRYPTO_SUCCESS); + + isMatch = 1; + for(int i = 0 ; i < 32 ; i++) + { + isMatch &= (key1[i] == key2[i]); + } + assert(!isMatch); + + cxssCryptoCleanup(); + + return 0; + }