### Build and Install libcotp Source: https://github.com/paolostivanin/libcotp/blob/master/README.md Instructions for cloning the libcotp repository, configuring the build with CMake, compiling, and installing the library. It outlines the necessary steps to get the library set up on a system. ```sh git clone https://github.com/paolostivanin/libcotp.git cd libcotp mkdir build && cd build cmake -DCMAKE_INSTALL_PREFIX=/usr .. make sudo make install ``` -------------------------------- ### Installation and Packaging (CMake) Source: https://github.com/paolostivanin/libcotp/blob/master/CMakeLists.txt Configures the installation of the 'cotp' library, including headers and CMake package configuration files. It also generates a pkg-config file to facilitate integration with other projects. ```cmake set(COTP_LIB_DIR "${CMAKE_INSTALL_LIBDIR}") set(COTP_INC_DIR "${CMAKE_INSTALL_INCLUDEDIR}") install( TARGETS cotp EXPORT cotpTargets ARCHIVE DESTINATION ${COTP_LIB_DIR} LIBRARY DESTINATION ${COTP_LIB_DIR} COMPONENT library ) install( FILES ${COTP_HEADERS} DESTINATION ${COTP_INC_DIR} ) # CMake package config for find_package(COTP CONFIG) write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/COTPConfigVersion.cmake" VERSION ${PROJECT_VERSION} COMPATIBILITY SameMajorVersion ) configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/COTPConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/COTPConfig.cmake" INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/COTP ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/COTPConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/COTPConfigVersion.cmake" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/COTP ) install(EXPORT cotpTargets NAMESPACE COTP:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/COTP) if (PkgConfig_FOUND) # Allow adding prefix if CMAKE_INSTALL_INCLUDEDIR not absolute. if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}") set(PKGCONFIG_TARGET_INCLUDES "${CMAKE_INSTALL_INCLUDEDIR}") else() set(PKGCONFIG_TARGET_INCLUDES "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") endif() # Allow adding prefix if CMAKE_INSTALL_LIBDIR not absolute. if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}") set(PKGCONFIG_TARGET_LIBS "${CMAKE_INSTALL_LIBDIR}") else() set(PKGCONFIG_TARGET_LIBS "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") endif() configure_file("cotp.pc.in" "cotp.pc" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/cotp.pc" DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig/) endif() ``` -------------------------------- ### CMake Project Setup and Options Source: https://github.com/paolostivanin/libcotp/blob/master/CMakeLists.txt Initializes the CMake project, sets the C++ standard, and defines build options such as building shared libraries and enabling tests. It also configures the HMAC wrapper selection, allowing users to choose between gcrypt, openssl, or mbedtls. ```cmake cmake_minimum_required(VERSION 3.16) project(cotp VERSION "4.0.0" LANGUAGES "C") set(CMAKE_C_STANDARD 11) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) include(GNUInstallDirs) include(CMakePackageConfigHelpers) find_package(PkgConfig) option(BUILD_SHARED_LIBS "Build libcotp as a shared library" ON) option(BUILD_TESTS "Build base32 and cotp tests" OFF) set(HMAC_WRAPPER "gcrypt" CACHE STRING "Choose between gcrypt (default), openssl or mbedtls for HMAC computation") set_property(CACHE HMAC_WRAPPER PROPERTY STRINGS "gcrypt" "openssl" "mbedtls") ``` -------------------------------- ### libcotp Example Usage for TOTP Source: https://github.com/paolostivanin/libcotp/blob/master/README.md A C code snippet demonstrating how to use the `get_totp` function to generate a Time-based One-Time Password. It includes error handling by checking the return value and freeing the allocated memory upon success. ```c cotp_error_t err; char *code = get_totp("HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ", 6, 30, COTP_SHA1, &err); if (!code) { // handle error } free(code); ``` -------------------------------- ### C Error Handling Example for libcotp Source: https://context7.com/paolostivanin/libcotp/llms.txt This C code snippet demonstrates how to use the `cotp_error_t` enum to handle errors returned by libcotp functions. It includes a helper function `error_to_string` to convert error codes to human-readable strings and a `main` function that tests various error conditions like NULL secrets, invalid Base32 input, invalid digits, invalid periods, invalid algorithms, and negative counters. It also shows a successful OTP generation and how to free the result. ```c #include #include #include "cotp.h" const char* error_to_string(cotp_error_t err) { switch (err) { case NO_ERROR: return "Success"; case VALID: return "Valid (validation matched)"; case WCRYPT_VERSION_MISMATCH: return "Crypto library version mismatch"; case INVALID_B32_INPUT: return "Invalid Base32 input"; case INVALID_ALGO: return "Invalid algorithm (use COTP_SHA1/256/512)"; case INVALID_DIGITS: return "Invalid digits (must be 4-10)"; case INVALID_PERIOD: return "Invalid period (must be 1-120)"; case MEMORY_ALLOCATION_ERROR: return "Memory allocation failed"; case INVALID_USER_INPUT: return "Invalid user input (NULL or malformed)"; case EMPTY_STRING: return "Empty string provided"; case MISSING_LEADING_ZERO: return "Leading zeros stripped in conversion"; case INVALID_COUNTER: return "Invalid counter (must be >= 0)"; case WHMAC_ERROR: return "HMAC computation error"; default: return "Unknown error"; } } int main(void) { cotp_error_t err; char *result; // Test various error conditions printf("Testing error conditions:\n\n"); // NULL secret result = get_totp(NULL, 6, 30, COTP_SHA1, &err); printf("NULL secret: %s\n", error_to_string(err)); // Invalid Base32 result = get_totp("Invalid!Secret", 6, 30, COTP_SHA1, &err); printf("Invalid B32: %s\n", error_to_string(err)); // Invalid digits result = get_totp("JBSWY3DPEHPK3PXP", 3, 30, COTP_SHA1, &err); printf("3 digits: %s\n", error_to_string(err)); // Invalid period result = get_totp("JBSWY3DPEHPK3PXP", 6, 200, COTP_SHA1, &err); printf("200s period: %s\n", error_to_string(err)); // Invalid algorithm result = get_totp("JBSWY3DPEHPK3PXP", 6, 30, 99, &err); printf("Invalid algo: %s\n", error_to_string(err)); // Negative counter for HOTP result = get_hotp("JBSWY3DPEHPK3PXP", -5, 6, COTP_SHA1, &err); printf("Negative counter: %s\n", error_to_string(err)); // Valid call result = get_totp("JBSWY3DPEHPK3PXP", 6, 30, COTP_SHA1, &err); printf("Valid call: %s (code: %s)\n", error_to_string(err), result); free(result); // Output: // Testing error conditions: // NULL secret: Invalid user input (NULL or malformed) // Invalid B32: Invalid Base32 input // 3 digits: Invalid digits (must be 4-10) // 200s period: Invalid period (must be 1-120) // Invalid algo: Invalid algorithm (use COTP_SHA1/256/512) // Negative counter: Invalid counter (must be >= 0) // Valid call: Success (code: xxxxxx) return 0; } ``` -------------------------------- ### Generate HOTP Code (C) Source: https://context7.com/paolostivanin/libcotp/llms.txt Generates an HMAC-based One-Time Password (HOTP) using a Base32-encoded secret and a counter value. This is suitable for systems where synchronization is counter-based. The example demonstrates generating HOTP codes for counters 0 through 9 and compares them against RFC 4226 test vectors. The function returns a dynamically allocated string that must be freed. ```c #include #include #include "cotp.h" int main(void) { const char *secret = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ"; cotp_error_t err; // Generate HOTP for counters 0-9 (RFC 4226 test vectors) const char *expected[] = {"755224", "287082", "359152", "969429", "338314", "254676", "287922", "162583", "399871", "520489"}; for (long counter = 0; counter < 10; counter++) { char *hotp = get_hotp(secret, counter, 6, COTP_SHA1, &err); if (hotp == NULL) { fprintf(stderr, "Error generating HOTP: %d\n", err); return 1; } printf("Counter %ld: %s (expected: %s)\n", counter, hotp, expected[counter]); free(hotp); } // Output: // Counter 0: 755224 (expected: 755224) // Counter 1: 287082 (expected: 287082) // ... return 0; } ``` -------------------------------- ### Reusable TOTP Configuration with libcotp Context API Source: https://context7.com/paolostivanin/libcotp/llms.txt Demonstrates the Context API for creating reusable TOTP configurations. This reduces boilerplate code when generating multiple TOTP codes with the same parameters (digits, period, algorithm). The context can be created once and reused for multiple secret keys. ```c #include #include #include "cotp.h" int main(void) { // Create context with: 6 digits, 30 second period, SHA1 cotp_ctx *ctx = cotp_ctx_create(6, 30, COTP_SHA1); if (ctx == NULL) { fprintf(stderr, "Failed to create context (invalid parameters)\n"); return 1; } const char *secrets[] = { "HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ", "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ", "JBSWY3DPEHPK3PXP" }; cotp_error_t err; // Generate current TOTP for multiple accounts for (int i = 0; i < 3; i++) { char *totp = cotp_ctx_totp(ctx, secrets[i], &err); if (totp) { printf("Account %d: %s\n", i + 1, totp); free(totp); } } // Generate TOTP at specific timestamp long timestamp = 1506268800; char *totp = cotp_ctx_totp_at(ctx, secrets[0], timestamp, &err); if (totp) { printf("At timestamp %ld: %s\n", timestamp, totp); // Output: At timestamp 1506268800: 488431 free(totp); } // Clean up cotp_ctx_free(ctx); return 0; } ``` -------------------------------- ### libcotp Context API for OTP Management Source: https://github.com/paolostivanin/libcotp/blob/master/README.md Provides functions to create, use, and free a context (`cotp_ctx`) for managing OTP generation parameters like digits, period, and algorithm. This API allows for more efficient repeated OTP generation with consistent settings. ```c cotp_ctx *cotp_ctx_create(int digits, int period, int sha_algo); char *cotp_ctx_totp_at(cotp_ctx *ctx, const char *base32_secret, long timestamp, cotp_error_t *err); char *cotp_ctx_totp(cotp_ctx *ctx, const char *base32_secret, cotp_error_t *err); void cotp_ctx_free(cotp_ctx *ctx); ``` -------------------------------- ### HMAC Backend Configuration (CMake) Source: https://github.com/paolostivanin/libcotp/blob/master/CMakeLists.txt Configures the HMAC computation backend based on the selected HMAC_WRAPPER option. It finds the necessary packages (Gcrypt, OpenSSL, or MbedTLS) and sets the corresponding source files, include directories, and libraries. If an unknown wrapper is selected, it raises a fatal error. ```cmake if("${HMAC_WRAPPER}" STREQUAL "gcrypt") set(HMAC_SOURCE_FILES src/utils/whmac_gcrypt.c ) find_package(Gcrypt 1.8.0 REQUIRED) set(HMAC_INCLUDE_DIR ${GCRYPT_INCLUDE_DIR}) set(HMAC_LIBRARIES ${GCRYPT_LIBRARIES}) message(STATUS "libcotp: HMAC backend set to gcrypt") elseif("${HMAC_WRAPPER}" STREQUAL "openssl") find_package(OpenSSL 3.0.0 REQUIRED) set(HMAC_SOURCE_FILES src/utils/whmac_openssl.c ) set(HMAC_INCLUDE_DIR ${OPENSSL_INCLUDE_DIR}) set(HMAC_LIBRARIES ${OPENSSL_LIBRARIES}) message(STATUS "libcotp: HMAC backend set to openssl") elseif("${HMAC_WRAPPER}" STREQUAL "mbedtls") find_package(MbedTLS REQUIRED) set(HMAC_SOURCE_FILES src/utils/whmac_mbedtls.c ) set(HMAC_INCLUDE_DIR ${MBEDTLS_INCLUDE_DIRS}) set(HMAC_LIBRARIES ${MBEDTLS_LIBRARIES}) message(STATUS "libcotp: HMAC backend set to mbedtls") else() message(FATAL_ERROR "libcotp: unknown HMAC_WRAPPER '${HMAC_WRAPPER}'. Choose gcrypt, openssl, or mbedtls.") endif() ``` -------------------------------- ### Library Definition and Linking (CMake) Source: https://github.com/paolostivanin/libcotp/blob/master/CMakeLists.txt Defines the main library target 'cotp' with its source files, including conditional inclusion of validation utilities. It links against the selected HMAC libraries and sets public and private include directories, along with compile options for enhanced code quality and security. ```cmake set(COTP_HEADERS src/cotp.h ) option(COTP_ENABLE_VALIDATION "Enable helper APIs for OTP validation in a time window" OFF) set(SOURCE_FILES src/otp.c ${HMAC_SOURCE_FILES} src/utils/base32.c src/utils/secure_zero.c src/ctx.c ) if (COTP_ENABLE_VALIDATION) list(APPEND SOURCE_FILES src/utils/validation.c) endif() add_library(cotp ${SOURCE_FILES}) if (COTP_ENABLE_VALIDATION) target_compile_definitions(cotp PUBLIC COTP_ENABLE_VALIDATION) endif() target_link_libraries(cotp PRIVATE ${HMAC_LIBRARIES}) target_include_directories(cotp PUBLIC $ $ PRIVATE ${HMAC_INCLUDE_DIR}) target_compile_options(cotp PRIVATE -Wall -Wextra -O3 -Wformat=2 -Wmissing-format-attribute -fstack-protector-strong -Wundef -Wmissing-format-attribute -fdiagnostics-color=always -Wstrict-prototypes -Wunreachable-code -Wchar-subscripts -Wwrite-strings -Wpointer-arith -Wbad-function-cast -Wcast-align -Werror=format-security -Werror=implicit-function-declaration -Wno-sign-compare -Wno-format-nonliteral -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3) set_target_properties(cotp PROPERTIES VERSION ${CMAKE_PROJECT_VERSION} SOVERSION ${CMAKE_PROJECT_VERSION_MAJOR}) ``` -------------------------------- ### Decode Base32 String to Binary - C Source: https://context7.com/paolostivanin/libcotp/llms.txt Decodes a Base32 encoded string back into its original raw binary data. This function handles Base32 strings that may contain spaces and automatically normalizes them to uppercase before decoding. It returns a pointer to the decoded binary data. ```c #include #include #include #include "cotp.h" int main(void) { // Base32 with spaces is accepted const char *encoded = "GEZDG NBVGY 3TQOJ Q"; cotp_error_t err; uint8_t *decoded = base32_decode(encoded, strlen(encoded), &err); if (decoded == NULL) { fprintf(stderr, "Decoding error: %d\n", err); return 1; } printf("Base32: %s\n", encoded); printf("Decoded: %s\n", decoded); // Output: // Base32: GEZDG NBVGY 3TQOJ Q // Decoded: 1234567890 free(decoded); return 0; } ``` -------------------------------- ### get_totp_at - Generate TOTP at Specific Timestamp Source: https://context7.com/paolostivanin/libcotp/llms.txt Generates a TOTP code for a specific Unix timestamp instead of the current system time. This is useful for testing, validation, or generating codes for past or future time periods. ```APIDOC ## get_totp_at ### Description Generates a TOTP code for a specific Unix timestamp rather than the current time. Useful for testing, validation, or generating codes for past/future time periods. ### Method C Function Call ### Endpoint N/A (C Library Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **secret** (const char *) - Required - Base32-encoded secret key. * **timestamp** (long) - Required - The Unix timestamp for which to generate the TOTP code. * **digits** (int) - Required - The number of digits in the OTP code (4-10). * **period** (int) - Required - The time period in seconds for the TOTP code (1-120). * **algorithm** (cotp_algorithm_t) - Required - The hash algorithm to use (e.g., COTP_SHA1, COTP_SHA256). * **err** (cotp_error_t *) - Output - Pointer to store the error code if an error occurs. ### Request Example ```c #include "cotp.h" const char *secret = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ"; // Base32 of "12345678901234567890" long timestamp = 1234567890; cotp_error_t err; char *totp = get_totp_at(secret, timestamp, 8, 30, COTP_SHA1, &err); ``` ### Response #### Success Response (char *) * **totp** (char *) - The generated TOTP code as a string. Caller must free this memory. #### Error Response (NULL) * Returns NULL if an error occurs. The `err` parameter will be set to indicate the error type. #### Response Example ``` // On success: "89005924" // On error: NULL ``` ``` -------------------------------- ### libcotp Base32 Encoding and Decoding Source: https://github.com/paolostivanin/libcotp/blob/master/README.md C functions for encoding arbitrary data into Base32 format and decoding Base32 strings back into binary data. It handles potential errors, including invalid input and memory allocation failures, returning NULL on error. ```c char *base32_encode(const unsigned char *data, size_t len, cotp_error_t *err); unsigned char *base32_decode(const char *user_data, size_t data_len, cotp_error_t *err); bool is_string_valid_b32(const char *user_data); ``` -------------------------------- ### libcotp Validation Helper API Source: https://github.com/paolostivanin/libcotp/blob/master/README.md The C function `validate_totp_in_window` checks if a user-provided OTP matches a generated OTP within a specified time window. It returns 1 on a match and 0 otherwise, optionally setting a `VALID` error code. ```c int validate_totp_in_window(const char *user_code, const char *base32_secret, long timestamp, int digits, int period, int sha_algo, int window, int *matched_delta, cotp_error_t *err); ``` -------------------------------- ### libcotp Public API for OTP Generation Source: https://github.com/paolostivanin/libcotp/blob/master/README.md Defines the core C functions for generating TOTP and HOTP. These functions take a base32 secret, digits, period/counter, and algorithm as input, returning a dynamically allocated string representing the OTP or NULL on error. The caller is responsible for freeing the returned string. ```c char *get_totp(const char *base32_secret, int digits, int period, int algo, cotp_error_t *err); char *get_steam_totp(const char *base32_secret, int period, cotp_error_t *err); char *get_hotp(const char *base32_secret, long counter, int digits, int algo, cotp_error_t *err); char *get_totp_at(const char *base32_secret, long timestamp, int digits, int period, int algo, cotp_error_t *err); int64_t otp_to_int(const char *otp, cotp_error_t *err); ``` -------------------------------- ### Define Executable Targets in CMake Source: https://github.com/paolostivanin/libcotp/blob/master/tests/CMakeLists.txt This snippet defines executable targets for various test programs within the libcotp project. Each executable is built from a corresponding C source file. These are essential for creating runnable test binaries. ```cmake add_executable (test_cotp test_otp.c) add_executable (test_base32encode test_base32encode.c) add_executable (test_base32decode test_base32decode.c) add_executable (test_base32_roundtrip test_base32_roundtrip.c) ``` -------------------------------- ### Encode Binary Data to Base32 - C Source: https://context7.com/paolostivanin/libcotp/llms.txt Encodes raw binary data into a Base32 string, which is a common format for OTP secrets. This function is useful for preparing secrets before passing them to OTP generation functions. It takes raw data and its length as input and returns a null-terminated Base32 encoded string. ```c #include #include #include #include "cotp.h" int main(void) { const char *raw_secret = "12345678901234567890"; cotp_error_t err; char *encoded = base32_encode((const uint8_t *)raw_secret, strlen(raw_secret) + 1, &err); if (encoded == NULL) { fprintf(stderr, "Encoding error: %d\n", err); return 1; } printf("Raw: %s\n", raw_secret); printf("Base32: %s\n", encoded); // Output: // Raw: 12345678901234567890 // Base32: GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQAA====== // Now use encoded secret to generate TOTP char *totp = get_totp_at(encoded, 59, 8, 30, COTP_SHA1, &err); if (totp) { printf("TOTP: %s\n", totp); // Output: TOTP: 94287082 free(totp); } free(encoded); return 0; } ``` -------------------------------- ### get_hotp - Generate HMAC-Based One-Time Password Source: https://context7.com/paolostivanin/libcotp/llms.txt Generates an HOTP code using a counter value instead of time. This is suitable for hardware tokens and systems where synchronization is counter-based rather than time-based. ```APIDOC ## get_hotp ### Description Generates an HOTP code using a counter value instead of time. Suitable for hardware tokens and systems where synchronization is counter-based rather than time-based. ### Method C Function Call ### Endpoint N/A (C Library Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **secret** (const char *) - Required - Base32-encoded secret key. * **counter** (long) - Required - The counter value for generating the HOTP code. * **digits** (int) - Required - The number of digits in the OTP code (4-10). * **algorithm** (cotp_algorithm_t) - Required - The hash algorithm to use (e.g., COTP_SHA1). * **err** (cotp_error_t *) - Output - Pointer to store the error code if an error occurs. ### Request Example ```c #include "cotp.h" const char *secret = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ"; cotp_error_t err; char *hotp = get_hotp(secret, 0, 6, COTP_SHA1, &err); ``` ### Response #### Success Response (char *) * **hotp** (char *) - The generated HOTP code as a string. Caller must free this memory. #### Error Response (NULL) * Returns NULL if an error occurs. The `err` parameter will be set to indicate the error type. #### Response Example ``` // On success: "755224" // On error: NULL ``` ``` -------------------------------- ### Convert OTP String to Integer with libcotp Source: https://context7.com/paolostivanin/libcotp/llms.txt Converts an OTP string to a 64-bit integer using the `otp_to_int` function. It handles potential errors such as missing leading zeros or invalid user input. The function returns the integer value of the OTP and an error code. ```c #include #include #include #include "cotp.h" int main(void) { cotp_error_t err; // Normal conversion int64_t val1 = otp_to_int("123456", &err); printf("'123456' -> %ld (err: %d)\n", val1, err); // Output: '123456' -> 123456 (err: 0 = NO_ERROR) // OTP with leading zero int64_t val2 = otp_to_int("012345", &err); printf("'012345' -> %ld (err: %d = MISSING_LEADING_ZERO)\n", val2, err); // Output: '012345' -> 12345 (err: 9 = MISSING_LEADING_ZERO) // Invalid input - too short int64_t val3 = otp_to_int("123", &err); printf("'123' -> %ld (err: %d = INVALID_USER_INPUT)\n", val3, err); // Output: '123' -> -1 (err: 8 = INVALID_USER_INPUT) // Invalid input - non-digit characters int64_t val4 = otp_to_int("12a456", &err); printf("'12a456' -> %ld (err: %d = INVALID_USER_INPUT)\n", val4, err); // Output: '12a456' -> -1 (err: 8 = INVALID_USER_INPUT) return 0; } ``` -------------------------------- ### Generate Steam Guard Compatible TOTP - C Source: https://context7.com/paolostivanin/libcotp/llms.txt Generates a 5-character alphanumeric TOTP code compatible with Steam Guard. It uses a custom alphabet and requires a Base32 encoded secret and a timestamp. The function `get_steam_totp_at` generates a code for a specific time, while `get_steam_totp` generates for the current time. ```c #include #include #include "cotp.h" int main(void) { // Steam secret must be Base32 encoded const char *steam_secret = "ON2XAZLSMR2XAZLSONSWG4TFOQ======"; long timestamp = 3000030; cotp_error_t err; char *steam_code = get_steam_totp_at(steam_secret, timestamp, 30, &err); if (steam_code == NULL) { fprintf(stderr, "Error generating Steam TOTP: %d\n", err); return 1; } printf("Steam Guard code: %s\n", steam_code); // Output: Steam Guard code: YRGQJ free(steam_code); // Current time Steam code char *current_steam = get_steam_totp(steam_secret, 30, &err); if (current_steam) { printf("Current Steam code: %s\n", current_steam); free(current_steam); } return 0; } ``` -------------------------------- ### Define CTest Tests in CMake Source: https://github.com/paolostivanin/libcotp/blob/master/tests/CMakeLists.txt This CMake code defines tests to be run using CTest, the CMake testing utility. Each test is named and associated with a command that executes the corresponding test executable. This allows for automated testing of the project's components. ```cmake add_test (NAME TestCOTP COMMAND test_cotp) add_test (NAME TestBase32Encode COMMAND test_base32encode) add_test (NAME TestBase32Decode COMMAND test_base32decode) add_test (NAME TestBase32Roundtrip COMMAND test_base32_roundtrip) ``` -------------------------------- ### Validate Base32 String - C Source: https://context7.com/paolostivanin/libcotp/llms.txt Checks if a given string consists solely of valid Base32 characters. This function is efficient as it does not allocate any memory and can be safely used on any string, including NULL pointers. It returns true for valid Base32 strings and false otherwise. ```c #include #include #include "cotp.h" int main(void) { // Valid Base32 examples const char *valid1 = "HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ"; const char *valid2 = "hxdm vjec jjws rb3h"; // Lowercase + spaces OK const char *valid3 = "MFRGGZDFMY======'"; // Padding OK // Invalid Base32 examples const char *invalid1 = "HXDM!VJEC"; // Invalid character '!' const char *invalid2 = "HXDM8VJEC"; // '8' not in Base32 alphabet const char *invalid3 = NULL; // NULL returns false printf("'%s' valid: %s\n", valid1, is_string_valid_b32(valid1) ? "yes" : "no"); printf("'%s' valid: %s\n", valid2, is_string_valid_b32(valid2) ? "yes" : "no"); printf("'%s' valid: %s\n", valid3, is_string_valid_b32(valid3) ? "yes" : "no"); printf("'%s' valid: %s\n", invalid1, is_string_valid_b32(invalid1) ? "yes" : "no"); printf("'%s' valid: %s\n", invalid2, is_string_valid_b32(invalid2) ? "yes" : "no"); // Output: // 'HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ' valid: yes // 'hxdm vjec jjws rb3h' valid: yes // 'MFRGGZDFMY======' valid: yes // 'HXDM!VJEC' valid: no // 'HXDM8VJEC' valid: no return 0; } ``` -------------------------------- ### Generate TOTP Code (C) Source: https://context7.com/paolostivanin/libcotp/llms.txt Generates a Time-based One-Time Password (TOTP) using a Base32-encoded secret and the current system time. It requires the 'cotp.h' header and handles potential errors like invalid secrets or parameters. The function returns a dynamically allocated string that must be freed by the caller. ```c #include #include #include "cotp.h" int main(void) { const char *secret = "HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ"; cotp_error_t err; char *totp = get_totp(secret, 6, 30, COTP_SHA1, &err); if (totp == NULL) { switch (err) { case INVALID_B32_INPUT: fprintf(stderr, "Invalid Base32 secret\n"); break; case INVALID_DIGITS: fprintf(stderr, "Digits must be 4-10\n"); break; case INVALID_PERIOD: fprintf(stderr, "Period must be 1-120 seconds\n"); break; default: fprintf(stderr, "Error generating TOTP: %d\n", err); } return 1; } printf("Current TOTP: %s\n", totp); // Output: Current TOTP: 123456 (varies with time) free(totp); return 0; } ``` -------------------------------- ### Link Libraries to Executable Targets in CMake Source: https://github.com/paolostivanin/libcotp/blob/master/tests/CMakeLists.txt This CMake snippet specifies the private libraries that each test executable depends on. It links the 'cotp' library (presumably the main library being tested) and the 'criterion' testing framework to the executables. This ensures the tests can access the necessary functionalities. ```cmake target_link_libraries (test_cotp PRIVATE cotp criterion) target_link_libraries (test_base32encode PRIVATE cotp criterion) target_link_libraries (test_base32decode PRIVATE cotp criterion) target_link_libraries (test_base32_roundtrip PRIVATE cotp criterion) ``` -------------------------------- ### Generate TOTP at Specific Timestamp (C) Source: https://context7.com/paolostivanin/libcotp/llms.txt Generates a Time-based One-Time Password (TOTP) for a specific Unix timestamp, allowing for testing or generating codes for past/future periods. This function supports different hash algorithms like SHA1 and SHA256. It returns a dynamically allocated string that must be freed by the caller. ```c #include #include #include "cotp.h" int main(void) { const char *secret = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ"; // Base32 of "12345678901234567890" long timestamp = 1234567890; // Specific Unix timestamp cotp_error_t err; char *totp = get_totp_at(secret, timestamp, 8, 30, COTP_SHA1, &err); if (totp == NULL) { fprintf(stderr, "Error: %d\n", err); return 1; } printf("TOTP at timestamp %ld: %s\n", timestamp, totp); // Output: TOTP at timestamp 1234567890: 89005924 free(totp); // SHA256 example with 32-byte key const char *secret256 = "GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQGEZA===="; totp = get_totp_at(secret256, timestamp, 8, 30, COTP_SHA256, &err); if (totp) { printf("TOTP (SHA256): %s\n", totp); // Output: TOTP (SHA256): 91819424 free(totp); } return 0; } ``` -------------------------------- ### get_totp - Generate Time-Based One-Time Password Source: https://context7.com/paolostivanin/libcotp/llms.txt Generates a TOTP code for the current system time using a Base32-encoded secret. The function returns a newly allocated string that the caller must free. On error, it returns NULL and sets an error code. ```APIDOC ## get_totp ### Description Generates a TOTP code for the current system time using a Base32-encoded secret. Returns a newly allocated string that the caller must free. On error, returns NULL and sets the error code. ### Method C Function Call ### Endpoint N/A (C Library Function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **secret** (const char *) - Required - Base32-encoded secret key. * **digits** (int) - Required - The number of digits in the OTP code (4-10). * **period** (int) - Required - The time period in seconds for the TOTP code (1-120). * **algorithm** (cotp_algorithm_t) - Required - The hash algorithm to use (e.g., COTP_SHA1). * **err** (cotp_error_t *) - Output - Pointer to store the error code if an error occurs. ### Request Example ```c #include "cotp.h" const char *secret = "HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ"; cotp_error_t err; char *totp = get_totp(secret, 6, 30, COTP_SHA1, &err); ``` ### Response #### Success Response (char *) * **totp** (char *) - The generated TOTP code as a string. Caller must free this memory. #### Error Response (NULL) * Returns NULL if an error occurs. The `err` parameter will be set to indicate the error type (e.g., INVALID_B32_INPUT, INVALID_DIGITS, INVALID_PERIOD). #### Response Example ``` // On success: "123456" // (varies with time) // On error: NULL ``` ``` -------------------------------- ### Validate TOTP Within Time Window using libcotp Source: https://context7.com/paolostivanin/libcotp/llms.txt Validates a user-provided TOTP code against a secret within a configurable time window using `validate_totp_in_window`. This function accounts for clock drift by checking codes from adjacent time periods. It requires building with `-DCOTP_ENABLE_VALIDATION=ON` and returns 1 on a successful match, 0 otherwise. ```c #include #include #include "cotp.h" #ifdef COTP_ENABLE_VALIDATION int main(void) { const char *secret = "HXDMVJECJJWSRB3HWIZR4IFUGFTMXBOZ"; const char *user_code = "488431"; long timestamp = 1506268800; int matched_delta = 0; cotp_error_t err; // Validate with ±1 period window (allows 30 seconds clock drift) int result = validate_totp_in_window( user_code, // User-provided code secret, // Base32 secret timestamp, // Current timestamp 6, // Digits 30, // Period COTP_SHA1, // Algorithm 1, // Window (±1 period) &matched_delta, // Output: which offset matched &err ); if (result == 1) { printf("TOTP valid! Matched at delta: %d periods\n", matched_delta); // Output: TOTP valid! Matched at delta: 0 periods } else { printf("TOTP invalid (err: %d)\n", err); } // Validate code from previous period const char *old_code = "previous_period_code"; // Would be actual code result = validate_totp_in_window(old_code, secret, timestamp, 6, 30, COTP_SHA1, 2, &matched_delta, &err); if (result == 1) { printf("Old code valid, matched at delta: %d\n", matched_delta); // Would show delta: -1 or -2 for codes from previous periods } return 0; } #endif ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.