{"id":13806872,"url":"https://github.com/paolostivanin/libcotp","last_synced_at":"2025-04-05T06:03:48.417Z","repository":{"id":36770085,"uuid":"41076795","full_name":"paolostivanin/libcotp","owner":"paolostivanin","description":"C library that generates TOTP and HOTP","archived":false,"fork":false,"pushed_at":"2024-10-04T11:48:28.000Z","size":170,"stargazers_count":89,"open_issues_count":0,"forks_count":30,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-29T05:04:34.055Z","etag":null,"topics":["c","hotp","totp"],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/paolostivanin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-08-20T05:11:46.000Z","updated_at":"2025-03-09T22:14:00.000Z","dependencies_parsed_at":"2023-01-17T04:39:19.305Z","dependency_job_id":"df2a0802-166f-4b3a-bbbc-3594ce32341d","html_url":"https://github.com/paolostivanin/libcotp","commit_stats":{"total_commits":89,"total_committers":7,"mean_commits":"12.714285714285714","dds":0.3707865168539326,"last_synced_commit":"c413038ec0491e7286d0c2849b8fe60c7ad75520"},"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paolostivanin%2Flibcotp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paolostivanin%2Flibcotp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paolostivanin%2Flibcotp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paolostivanin%2Flibcotp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paolostivanin","download_url":"https://codeload.github.com/paolostivanin/libcotp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247294516,"owners_count":20915340,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","hotp","totp"],"created_at":"2024-08-04T01:01:17.342Z","updated_at":"2025-04-05T06:03:48.394Z","avatar_url":"https://github.com/paolostivanin.png","language":"C","funding_links":[],"categories":["C"],"sub_categories":[],"readme":"# libcotp\n\u003ca href=\"https://scan.coverity.com/projects/paolostivanin-libcotp\"\u003e\n  \u003cimg alt=\"Coverity Scan Build Status\"\n       src=\"https://scan.coverity.com/projects/12748/badge.svg\"/\u003e\n\u003c/a\u003e\n\nC library that generates TOTP and HOTP according to [RFC-6238](https://tools.ietf.org/html/rfc6238)\n\n## Requirements\n- GCC/Clang and CMake to build the library\n- libgcrypt \u003e= 1.8.0 or openssl \u003e= 3.0.0 or mbedtls (works with both 2.x and 3.x)\n\n## Build and Install\n```\n$ git clone https://github.com/paolostivanin/libcotp.git\n$ cd libcotp\n$ mkdir build \u0026\u0026 cd $_\n$ cmake -DCMAKE_INSTALL_PREFIX=/usr ..\n$ make\n$ sudo make install\n```\n\nAvailable options you can pass to `cmake`:\n* `-DBUILD_TESTS=ON`: if you want to compile also the tests (default **OFF**, requires criterion)\n* `-DBUILD_SHARED_LIBS=OFF`: if you want to build libcotp as a static library (default **ON**)\n* `-DHMAC_WRAPPER=\"\u003cgcrypt|openssl|mbedtls\u003e\"`: you can choose between GCrypt, OpenSSL or MbedTLS (default **Gcrypt**)\n\n## How To Use It\n```\nchar *totp        = get_totp       (const char   *base32_encoded_secret,\n                                    int           digits,\n                                    int           period,\n                                    int           algo,\n                                    cotp_error_t *err);\n\nchar *steam_totp  = get_steam_totp (const char   *secret,\n                                    int           period,\n                                    cotp_error_t *err);\n\nchar *hotp        = get_hotp       (const char   *base32_encoded_secret,\n                                    long          counter,\n                                    int           digits,\n                                    int           algo,\n                                    cotp_error_t *err);\n\nchar *totp_at     = get_totp_at    (const char   *base32_encoded_secret,\n                                    long          target_date,\n                                    int           digits,\n                                    int           algo,\n                                    cotp_error_t *err);\n\nint64_t otp_i     = otp_to_int     (const char   *otp,\n                                    cotp_error_t *err_code);\n```\n\nwhere:\n- `secret_key` is the **base32 encoded** secret. Usually, a website gives you the secret already base32 encoded, so you should pay attention to not encode the secret again.\nThe format of the secret can either be `hxdm vjec jjws` or `HXDMVJECJJWS`. In the first case, the library will normalize the secret to second format before computing the OTP.\n- `digits` is between `3` and `10` inclusive\n- `period` is between `1` and `120` inclusive\n- `counter` is a value decided with the server\n- `target_date` is the target date specified as the **unix epoch format in seconds**\n- `algo` is either `SHA1`, `SHA256` or `SHA512`\n\n## Return values\n`get_totp`, `get_hotp` and `get_totp_at` return `NULL` if an error occurs and `err` is set to one of the following values:\n\nErrors:\n- `GCRYPT_VERSION_MISMATCH`, set if the installed Gcrypt library is too old\n- `INVALID_B32_INPUT`, set if the given input is not valid base32 text\n- `INVALID_ALGO`, set if the given algo is not supported by the library\n- `INVALID_PERIOD`, set if `period` is `\u003c= 0` or `\u003e 120` seconds\n- `INVALID_DIGITS`, set if `digits` is `\u003c 4` or `\u003e 10`\n- `MEMORY_ALLOCATION_ERROR`, set if an error happened during memory allocation\n- `INVALID_USER_INPUT`, set if the given input is not valid\n- `INVALID_COUNTER`, set if `counter` is `\u003c 0`\n\nAll good:\n- `NO_ERROR`, set if no error occurred\n- `VALID`, set if the given OTP is valid\n\nThe function `otp_to_int`:\n* returns `-1` if an error occurs and sets `err` to `INVALID_USER_INPUT`.\n* warns the user if the leading zero is missing. For example, since the otp string `\"012345\"` **can't** be returned as the integer `012345` (because it would be interpreted as octal number), the function returns `12345` and sets `err` to `MISSING_LEADING_ZERO`)\n\nIn case of success, the value returned by `get_totp`, `get_hotp`, `get_totp_at` and `get_steam_totp` **must be freed** once no longer needed.\n\n# Base32 encoding and decoding\nSince release 2.0.0, libbaseencode has been merged with libcotp. This means that you can now use base32 functions by just including `cotp.h`:\n\n```\nchar  *base32_encode (const uchar  *user_data,\n                      size_t        data_len,\n                      cotp_error_t *err_code);\n\nuchar *base32_decode (const char   *user_data,\n                      size_t        data_len,\n                      cotp_error_t *err_code);\n\nbool   is_string_valid_b32 (const char *user_data);\n```\n\nwhere:\n- `user_data` is the data to be encoded or decoded\n- `data_len` is the length of the data to be encoded/decoded\n- `err_code` is where the error is stored\n\n`base32_encode` returns `NULL` if an error occurs and `err_code` is set to one of the following values:\n  - `INVALID_USER_INPUT`, set if the given input is not valid\n  - `MEMORY_ALLOCATION_ERROR`, set if an error happened during memory allocation\n  - `INVALID_USER_INPUT`, set if the given input is not valid\n\n`base32_decode` returns `NULL` if an error occurs and `err_code` is set to one of the following values:\n- `INVALID_USER_INPUT`, set if the given input is not valid\n- `MEMORY_ALLOCATION_ERROR`, set if an error happened during memory allocation\n- `INVALID_B32_INPUT`, set if the given input is not valid base32 text\n- `INVALID_USER_INPUT`, set if the given input is not valid\n\nBoth functions return and empty string if the input is an empty string. In such a case, `err` is set to `EMPTY_STRING`.\n\n`is_string_valid_b32` returns `true` if `user_data` is a valid base32 encoded string, `false` otherwise. Please note that `user_data` can contain spaces, since\nthe fucntion will also take care of trimming those.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaolostivanin%2Flibcotp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaolostivanin%2Flibcotp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaolostivanin%2Flibcotp/lists"}